]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/FdfParser.py
BaseTools: Nested !include support in DSC and FDF files
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FdfParser.py
CommitLineData
30fdf114
LG
1## @file\r
2# parse FDF file\r
3#\r
2bc3256c 4# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
118bf096 5# Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>\r
30fdf114 6#\r
40d841f6 7# This program and the accompanying materials\r
30fdf114
LG
8# are licensed and made available under the terms and conditions of the BSD License\r
9# which accompanies this distribution. The full text of the license may be found at\r
10# http://opensource.org/licenses/bsd-license.php\r
11#\r
12# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14#\r
15\r
16##\r
17# Import Modules\r
18#\r
0d2711a6
LG
19import re\r
20\r
30fdf114
LG
21import Fd\r
22import Region\r
23import Fv\r
24import AprioriSection\r
25import FfsInfStatement\r
26import FfsFileStatement\r
27import VerSection\r
28import UiSection\r
29import FvImageSection\r
30import DataSection\r
31import DepexSection\r
32import CompressSection\r
33import GuidSection\r
34import Capsule\r
35import CapsuleData\r
36import Rule\r
37import RuleComplexFile\r
38import RuleSimpleFile\r
39import EfiSection\r
40import Vtf\r
41import ComponentStatement\r
42import OptionRom\r
43import OptRomInfStatement\r
44import OptRomFileStatement\r
45\r
52302d4d 46from GenFdsGlobalVariable import GenFdsGlobalVariable\r
30fdf114
LG
47from Common.BuildToolError import *\r
48from Common import EdkLogger\r
14c48571 49from Common.Misc import PathClass\r
50from Common.String import NormPath\r
0d2711a6
LG
51import Common.GlobalData as GlobalData\r
52from Common.Expression import *\r
df692f02 53from Common import GlobalData\r
2bcc713e 54from Common.String import ReplaceMacro\r
30fdf114 55\r
d0acc87a
LG
56from Common.Misc import tdict\r
57\r
30fdf114 58import re\r
1be2ed90
HC
59import Common.LongFilePathOs as os\r
60from Common.LongFilePathSupport import OpenLongFilePath as open\r
30fdf114
LG
61\r
62##define T_CHAR_SPACE ' '\r
63##define T_CHAR_NULL '\0'\r
64##define T_CHAR_CR '\r'\r
65##define T_CHAR_TAB '\t'\r
66##define T_CHAR_LF '\n'\r
67##define T_CHAR_SLASH '/'\r
68##define T_CHAR_BACKSLASH '\\'\r
69##define T_CHAR_DOUBLE_QUOTE '\"'\r
70##define T_CHAR_SINGLE_QUOTE '\''\r
71##define T_CHAR_STAR '*'\r
72##define T_CHAR_HASH '#'\r
73\r
74(T_CHAR_SPACE, T_CHAR_NULL, T_CHAR_CR, T_CHAR_TAB, T_CHAR_LF, T_CHAR_SLASH, \\r
75T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_HASH) = \\r
76(' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#')\r
77\r
78SEPERATOR_TUPLE = ('=', '|', ',', '{', '}')\r
79\r
0d2711a6
LG
80RegionSizePattern = re.compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")\r
81RegionSizeGuidPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*\|\s*(?P<size>\w+\.\w+)\s*")\r
2bc3256c 82RegionOffsetPcdPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*$")\r
64b2609f 83ShortcutPcdPattern = re.compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")\r
0d2711a6 84\r
118bf096
CS
85AllIncludeFileList = []\r
86\r
87# Get the closest parent\r
88def GetParentAtLine (Line):\r
89 for Profile in AllIncludeFileList:\r
90 if Profile.IsLineInFile(Line):\r
91 return Profile\r
92 return None\r
93\r
94# Check include loop\r
95def IsValidInclude (File, Line):\r
96 for Profile in AllIncludeFileList:\r
97 if Profile.IsLineInFile(Line) and Profile.FileName == File:\r
98 return False\r
99\r
100 return True\r
30fdf114
LG
101\r
102def GetRealFileLine (File, Line):\r
103\r
104 InsertedLines = 0\r
118bf096
CS
105 for Profile in AllIncludeFileList:\r
106 if Profile.IsLineInFile(Line):\r
107 return Profile.GetLineInFile(Line)\r
108 elif Line >= Profile.InsertStartLineNumber and Profile.Level == 1:\r
109 InsertedLines += Profile.GetTotalLines()\r
30fdf114
LG
110\r
111 return (File, Line - InsertedLines)\r
112\r
113## The exception class that used to report error messages when parsing FDF\r
114#\r
115# Currently the "ToolName" is set to be "FDF Parser".\r
116#\r
117class Warning (Exception):\r
118 ## The constructor\r
119 #\r
120 # @param self The object pointer\r
121 # @param Str The message to record\r
122 # @param File The FDF name\r
123 # @param Line The Line number that error occurs\r
124 #\r
125 def __init__(self, Str, File = None, Line = None):\r
126\r
127 FileLineTuple = GetRealFileLine(File, Line)\r
128 self.FileName = FileLineTuple[0]\r
129 self.LineNumber = FileLineTuple[1]\r
118bf096 130 self.OriginalLineNumber = Line\r
30fdf114
LG
131 self.Message = Str\r
132 self.ToolName = 'FdfParser'\r
133\r
134 def __str__(self):\r
135 return self.Message\r
136\r
137## The MACRO class that used to record macro value data when parsing include file\r
138#\r
139#\r
140class MacroProfile :\r
141 ## The constructor\r
142 #\r
143 # @param self The object pointer\r
144 # @param FileName The file that to be parsed\r
145 #\r
146 def __init__(self, FileName, Line):\r
147 self.FileName = FileName\r
148 self.DefinedAtLine = Line\r
149 self.MacroName = None\r
150 self.MacroValue = None\r
151\r
152## The Include file content class that used to record file data when parsing include file\r
153#\r
154# May raise Exception when opening file.\r
155#\r
156class IncludeFileProfile :\r
157 ## The constructor\r
158 #\r
159 # @param self The object pointer\r
160 # @param FileName The file that to be parsed\r
161 #\r
162 def __init__(self, FileName):\r
163 self.FileName = FileName\r
164 self.FileLinesList = []\r
165 try:\r
166 fsock = open(FileName, "rb", 0)\r
167 try:\r
168 self.FileLinesList = fsock.readlines()\r
169 finally:\r
170 fsock.close()\r
171\r
172 except:\r
173 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)\r
174\r
175 self.InsertStartLineNumber = None\r
176 self.InsertAdjust = 0\r
118bf096
CS
177 self.IncludeFileList = []\r
178 self.Level = 1 # first level include file\r
179 \r
180 def GetTotalLines(self):\r
181 TotalLines = self.InsertAdjust + len(self.FileLinesList)\r
182\r
183 for Profile in self.IncludeFileList:\r
184 TotalLines += Profile.GetTotalLines()\r
185\r
186 return TotalLines\r
187\r
188 def IsLineInFile(self, Line):\r
189 if Line >= self.InsertStartLineNumber and Line < self.InsertStartLineNumber + self.GetTotalLines():\r
190 return True\r
191\r
192 return False\r
193\r
194 def GetLineInFile(self, Line):\r
195 if not self.IsLineInFile (Line):\r
196 return (self.FileName, -1)\r
197 \r
198 InsertedLines = self.InsertStartLineNumber\r
199\r
200 for Profile in self.IncludeFileList:\r
201 if Profile.IsLineInFile(Line):\r
202 return Profile.GetLineInFile(Line)\r
203 elif Line >= Profile.InsertStartLineNumber:\r
204 InsertedLines += Profile.GetTotalLines()\r
205\r
206 return (self.FileName, Line - InsertedLines + 1)\r
207\r
208\r
30fdf114
LG
209\r
210## The FDF content class that used to record file data when parsing FDF\r
211#\r
212# May raise Exception when opening file.\r
213#\r
214class FileProfile :\r
215 ## The constructor\r
216 #\r
217 # @param self The object pointer\r
218 # @param FileName The file that to be parsed\r
219 #\r
220 def __init__(self, FileName):\r
221 self.FileLinesList = []\r
222 try:\r
223 fsock = open(FileName, "rb", 0)\r
224 try:\r
225 self.FileLinesList = fsock.readlines()\r
226 finally:\r
227 fsock.close()\r
228\r
229 except:\r
230 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)\r
231\r
232\r
233 self.PcdDict = {}\r
234 self.InfList = []\r
d0acc87a
LG
235 # ECC will use this Dict and List information\r
236 self.PcdFileLineDict = {}\r
237 self.InfFileLineList = []\r
238 \r
30fdf114 239 self.FdDict = {}\r
52302d4d 240 self.FdNameNotSet = False\r
30fdf114 241 self.FvDict = {}\r
fd171542 242 self.CapsuleDict = {}\r
30fdf114
LG
243 self.VtfList = []\r
244 self.RuleDict = {}\r
245 self.OptRomDict = {}\r
a3251d84 246 self.FmpPayloadDict = {}\r
30fdf114
LG
247\r
248## The syntax parser for FDF\r
249#\r
250# PreprocessFile method should be called prior to ParseFile\r
251# CycleReferenceCheck method can detect cycles in FDF contents\r
252#\r
253# GetNext*** procedures mean these procedures will get next token first, then make judgement.\r
254# Get*** procedures mean these procedures will make judgement on current token only.\r
255#\r
256class FdfParser:\r
257 ## The constructor\r
258 #\r
259 # @param self The object pointer\r
260 # @param FileName The file that to be parsed\r
261 #\r
262 def __init__(self, FileName):\r
263 self.Profile = FileProfile(FileName)\r
264 self.FileName = FileName\r
265 self.CurrentLineNumber = 1\r
266 self.CurrentOffsetWithinLine = 0\r
267 self.CurrentFdName = None\r
268 self.CurrentFvName = None\r
269 self.__Token = ""\r
270 self.__SkippedChars = ""\r
97fa0ee9 271 GlobalData.gFdfParser = self\r
30fdf114 272\r
d0acc87a
LG
273 # Used to section info\r
274 self.__CurSection = []\r
275 # Key: [section name, UI name, arch]\r
276 # Value: {MACRO_NAME : MACRO_VALUE}\r
277 self.__MacroDict = tdict(True, 3)\r
278 self.__PcdDict = {}\r
279\r
30fdf114 280 self.__WipeOffArea = []\r
14c48571 281 if GenFdsGlobalVariable.WorkSpaceDir == '':\r
282 GenFdsGlobalVariable.WorkSpaceDir = os.getenv("WORKSPACE")\r
30fdf114
LG
283\r
284 ## __IsWhiteSpace() method\r
285 #\r
286 # Whether char at current FileBufferPos is whitespace\r
287 #\r
288 # @param self The object pointer\r
289 # @param Char The char to test\r
290 # @retval True The char is a kind of white space\r
291 # @retval False The char is NOT a kind of white space\r
292 #\r
293 def __IsWhiteSpace(self, Char):\r
294 if Char in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_SPACE, T_CHAR_TAB, T_CHAR_LF):\r
295 return True\r
296 else:\r
297 return False\r
298\r
299 ## __SkipWhiteSpace() method\r
300 #\r
301 # Skip white spaces from current char, return number of chars skipped\r
302 #\r
303 # @param self The object pointer\r
304 # @retval Count The number of chars skipped\r
305 #\r
306 def __SkipWhiteSpace(self):\r
307 Count = 0\r
308 while not self.__EndOfFile():\r
309 Count += 1\r
310 if self.__CurrentChar() in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_LF, T_CHAR_SPACE, T_CHAR_TAB):\r
311 self.__SkippedChars += str(self.__CurrentChar())\r
312 self.__GetOneChar()\r
313\r
314 else:\r
315 Count = Count - 1\r
316 return Count\r
317\r
318 ## __EndOfFile() method\r
319 #\r
320 # Judge current buffer pos is at file end\r
321 #\r
322 # @param self The object pointer\r
323 # @retval True Current File buffer position is at file end\r
324 # @retval False Current File buffer position is NOT at file end\r
325 #\r
326 def __EndOfFile(self):\r
327 NumberOfLines = len(self.Profile.FileLinesList)\r
328 SizeOfLastLine = len(self.Profile.FileLinesList[-1])\r
329 if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1:\r
330 return True\r
331 elif self.CurrentLineNumber > NumberOfLines:\r
332 return True\r
333 else:\r
334 return False\r
335\r
336 ## __EndOfLine() method\r
337 #\r
338 # Judge current buffer pos is at line end\r
339 #\r
340 # @param self The object pointer\r
341 # @retval True Current File buffer position is at line end\r
342 # @retval False Current File buffer position is NOT at line end\r
343 #\r
344 def __EndOfLine(self):\r
345 if self.CurrentLineNumber > len(self.Profile.FileLinesList):\r
346 return True\r
347 SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1])\r
348 if self.CurrentOffsetWithinLine >= SizeOfCurrentLine:\r
349 return True\r
350 else:\r
351 return False\r
352\r
353 ## Rewind() method\r
354 #\r
355 # Reset file data buffer to the initial state\r
356 #\r
357 # @param self The object pointer\r
118bf096
CS
358 # @param DestLine Optional new destination line number.\r
359 # @param DestOffset Optional new destination offset. \r
30fdf114 360 #\r
118bf096
CS
361 def Rewind(self, DestLine = 1, DestOffset = 0): \r
362 self.CurrentLineNumber = DestLine \r
363 self.CurrentOffsetWithinLine = DestOffset \r
30fdf114
LG
364\r
365 ## __UndoOneChar() method\r
366 #\r
367 # Go back one char in the file buffer\r
368 #\r
369 # @param self The object pointer\r
370 # @retval True Successfully go back one char\r
371 # @retval False Not able to go back one char as file beginning reached\r
372 #\r
373 def __UndoOneChar(self):\r
374\r
375 if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0:\r
376 return False\r
377 elif self.CurrentOffsetWithinLine == 0:\r
378 self.CurrentLineNumber -= 1\r
379 self.CurrentOffsetWithinLine = len(self.__CurrentLine()) - 1\r
380 else:\r
381 self.CurrentOffsetWithinLine -= 1\r
382 return True\r
383\r
384 ## __GetOneChar() method\r
385 #\r
386 # Move forward one char in the file buffer\r
387 #\r
388 # @param self The object pointer\r
389 #\r
390 def __GetOneChar(self):\r
391 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:\r
0d2711a6
LG
392 self.CurrentLineNumber += 1\r
393 self.CurrentOffsetWithinLine = 0\r
30fdf114 394 else:\r
0d2711a6 395 self.CurrentOffsetWithinLine += 1\r
30fdf114
LG
396\r
397 ## __CurrentChar() method\r
398 #\r
399 # Get the char pointed to by the file buffer pointer\r
400 #\r
401 # @param self The object pointer\r
402 # @retval Char Current char\r
403 #\r
404 def __CurrentChar(self):\r
405 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine]\r
406\r
407 ## __NextChar() method\r
408 #\r
409 # Get the one char pass the char pointed to by the file buffer pointer\r
410 #\r
411 # @param self The object pointer\r
412 # @retval Char Next char\r
413 #\r
414 def __NextChar(self):\r
415 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:\r
416 return self.Profile.FileLinesList[self.CurrentLineNumber][0]\r
417 else:\r
418 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1]\r
419\r
420 ## __SetCurrentCharValue() method\r
421 #\r
422 # Modify the value of current char\r
423 #\r
424 # @param self The object pointer\r
425 # @param Value The new value of current char\r
426 #\r
427 def __SetCurrentCharValue(self, Value):\r
428 self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value\r
429\r
430 ## __CurrentLine() method\r
431 #\r
432 # Get the list that contains current line contents\r
433 #\r
434 # @param self The object pointer\r
435 # @retval List current line contents\r
436 #\r
437 def __CurrentLine(self):\r
438 return self.Profile.FileLinesList[self.CurrentLineNumber - 1]\r
439\r
440 def __StringToList(self):\r
441 self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList]\r
442 self.Profile.FileLinesList[-1].append(' ')\r
443\r
30fdf114
LG
444 def __ReplaceFragment(self, StartPos, EndPos, Value = ' '):\r
445 if StartPos[0] == EndPos[0]:\r
446 Offset = StartPos[1]\r
447 while Offset <= EndPos[1]:\r
448 self.Profile.FileLinesList[StartPos[0]][Offset] = Value\r
449 Offset += 1\r
450 return\r
451\r
452 Offset = StartPos[1]\r
453 while self.Profile.FileLinesList[StartPos[0]][Offset] not in ('\r', '\n'):\r
454 self.Profile.FileLinesList[StartPos[0]][Offset] = Value\r
455 Offset += 1\r
456\r
457 Line = StartPos[0]\r
458 while Line < EndPos[0]:\r
459 Offset = 0\r
460 while self.Profile.FileLinesList[Line][Offset] not in ('\r', '\n'):\r
461 self.Profile.FileLinesList[Line][Offset] = Value\r
462 Offset += 1\r
463 Line += 1\r
464\r
465 Offset = 0\r
466 while Offset <= EndPos[1]:\r
467 self.Profile.FileLinesList[EndPos[0]][Offset] = Value\r
468 Offset += 1\r
469\r
470\r
d5d56f1b
LG
471 def __GetMacroName(self):\r
472 if not self.__GetNextToken():\r
473 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)\r
474 MacroName = self.__Token\r
475 NotFlag = False\r
476 if MacroName.startswith('!'):\r
477 NotFlag = True\r
478 MacroName = MacroName[1:].strip()\r
479 \r
480 if not MacroName.startswith('$(') or not MacroName.endswith(')'):\r
481 raise Warning("Macro name expected(Please use '$(%(Token)s)' if '%(Token)s' is a macro.)" % {"Token" : MacroName},\r
482 self.FileName, self.CurrentLineNumber)\r
483 MacroName = MacroName[2:-1]\r
484 return MacroName, NotFlag\r
d0acc87a
LG
485\r
486 def __SetMacroValue(self, Macro, Value):\r
487 if not self.__CurSection:\r
488 return\r
489\r
490 MacroDict = {}\r
491 if not self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]]:\r
492 self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]] = MacroDict\r
493 else:\r
494 MacroDict = self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]]\r
495 MacroDict[Macro] = Value\r
496\r
497 def __GetMacroValue(self, Macro):\r
498 # Highest priority\r
499 if Macro in GlobalData.gCommandLineDefines:\r
500 return GlobalData.gCommandLineDefines[Macro]\r
501 if Macro in GlobalData.gGlobalDefines:\r
502 return GlobalData.gGlobalDefines[Macro]\r
503\r
504 if self.__CurSection:\r
505 MacroDict = self.__MacroDict[\r
506 self.__CurSection[0],\r
507 self.__CurSection[1],\r
508 self.__CurSection[2]\r
509 ]\r
510 if MacroDict and Macro in MacroDict:\r
511 return MacroDict[Macro]\r
512\r
513 # Lowest priority\r
514 if Macro in GlobalData.gPlatformDefines:\r
515 return GlobalData.gPlatformDefines[Macro]\r
516 return None\r
517\r
518 def __SectionHeaderParser(self, Section):\r
519 # [Defines]\r
520 # [FD.UiName]: use dummy instead if UI name is optional\r
521 # [FV.UiName]\r
522 # [Capsule.UiName]\r
523 # [Rule]: don't take rule section into account, macro is not allowed in this section\r
524 # [VTF.arch.UiName, arch]\r
525 # [OptionRom.DriverName]\r
526 self.__CurSection = []\r
527 Section = Section.strip()[1:-1].upper().replace(' ', '').strip('.')\r
528 ItemList = Section.split('.')\r
529 Item = ItemList[0]\r
530 if Item == '' or Item == 'RULE':\r
531 return\r
532\r
533 if Item == 'DEFINES':\r
534 self.__CurSection = ['COMMON', 'COMMON', 'COMMON']\r
535 elif Item == 'VTF' and len(ItemList) == 3:\r
536 UiName = ItemList[2]\r
537 Pos = UiName.find(',')\r
538 if Pos != -1:\r
539 UiName = UiName[:Pos]\r
540 self.__CurSection = ['VTF', UiName, ItemList[1]]\r
541 elif len(ItemList) > 1:\r
542 self.__CurSection = [ItemList[0], ItemList[1], 'COMMON']\r
543 elif len(ItemList) > 0:\r
544 self.__CurSection = [ItemList[0], 'DUMMY', 'COMMON']\r
545\r
30fdf114
LG
546 ## PreprocessFile() method\r
547 #\r
548 # Preprocess file contents, replace comments with spaces.\r
549 # In the end, rewind the file buffer pointer to the beginning\r
550 # BUGBUG: No !include statement processing contained in this procedure\r
551 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]\r
552 #\r
553 # @param self The object pointer\r
554 #\r
555 def PreprocessFile(self):\r
556\r
557 self.Rewind()\r
558 InComment = False\r
559 DoubleSlashComment = False\r
560 HashComment = False\r
561 # HashComment in quoted string " " is ignored.\r
562 InString = False\r
563\r
564 while not self.__EndOfFile():\r
565\r
566 if self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment:\r
567 InString = not InString\r
568 # meet new line, then no longer in a comment for // and '#'\r
569 if self.__CurrentChar() == T_CHAR_LF:\r
570 self.CurrentLineNumber += 1\r
571 self.CurrentOffsetWithinLine = 0\r
572 if InComment and DoubleSlashComment:\r
573 InComment = False\r
574 DoubleSlashComment = False\r
575 if InComment and HashComment:\r
576 InComment = False\r
577 HashComment = False\r
578 # check for */ comment end\r
579 elif InComment and not DoubleSlashComment and not HashComment and self.__CurrentChar() == T_CHAR_STAR and self.__NextChar() == T_CHAR_SLASH:\r
580 self.__SetCurrentCharValue(T_CHAR_SPACE)\r
581 self.__GetOneChar()\r
582 self.__SetCurrentCharValue(T_CHAR_SPACE)\r
583 self.__GetOneChar()\r
584 InComment = False\r
585 # set comments to spaces\r
586 elif InComment:\r
587 self.__SetCurrentCharValue(T_CHAR_SPACE)\r
588 self.__GetOneChar()\r
589 # check for // comment\r
590 elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH and not self.__EndOfLine():\r
591 InComment = True\r
592 DoubleSlashComment = True\r
593 # check for '#' comment\r
594 elif self.__CurrentChar() == T_CHAR_HASH and not self.__EndOfLine() and not InString:\r
595 InComment = True\r
596 HashComment = True\r
597 # check for /* comment start\r
598 elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_STAR:\r
599 self.__SetCurrentCharValue( T_CHAR_SPACE)\r
600 self.__GetOneChar()\r
601 self.__SetCurrentCharValue( T_CHAR_SPACE)\r
602 self.__GetOneChar()\r
603 InComment = True\r
604 else:\r
605 self.__GetOneChar()\r
606\r
607 # restore from ListOfList to ListOfString\r
608 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]\r
609 self.Rewind()\r
610\r
611 ## PreprocessIncludeFile() method\r
612 #\r
613 # Preprocess file contents, replace !include statements with file contents.\r
614 # In the end, rewind the file buffer pointer to the beginning\r
615 #\r
616 # @param self The object pointer\r
617 #\r
618 def PreprocessIncludeFile(self):\r
118bf096
CS
619 # nested include support\r
620 Processed = False\r
30fdf114
LG
621 while self.__GetNextToken():\r
622\r
623 if self.__Token == '!include':\r
118bf096 624 Processed = True\r
30fdf114
LG
625 IncludeLine = self.CurrentLineNumber\r
626 IncludeOffset = self.CurrentOffsetWithinLine - len('!include')\r
627 if not self.__GetNextToken():\r
628 raise Warning("expected include file name", self.FileName, self.CurrentLineNumber)\r
629 IncFileName = self.__Token\r
2bcc713e 630 __IncludeMacros = {}\r
d0acc87a
LG
631 for Macro in ['WORKSPACE', 'ECP_SOURCE', 'EFI_SOURCE', 'EDK_SOURCE']:\r
632 MacroVal = self.__GetMacroValue(Macro)\r
633 if MacroVal:\r
634 __IncludeMacros[Macro] = MacroVal\r
635\r
636 try:\r
637 IncludedFile = NormPath(ReplaceMacro(IncFileName, __IncludeMacros, RaiseError=True))\r
638 except:\r
639 raise Warning("only these system environment variables are permitted to start the path of the included file: "\r
640 "$(WORKSPACE), $(ECP_SOURCE), $(EFI_SOURCE), $(EDK_SOURCE)",\r
641 self.FileName, self.CurrentLineNumber)\r
2bcc713e
LG
642 #\r
643 # First search the include file under the same directory as FDF file\r
644 #\r
645 IncludedFile1 = PathClass(IncludedFile, os.path.dirname(self.FileName))\r
646 ErrorCode = IncludedFile1.Validate()[0]\r
647 if ErrorCode != 0:\r
648 #\r
649 # Then search the include file under the same directory as DSC file\r
650 #\r
d0acc87a
LG
651 PlatformDir = ''\r
652 if GenFdsGlobalVariable.ActivePlatform:\r
653 PlatformDir = GenFdsGlobalVariable.ActivePlatform.Dir\r
654 elif GlobalData.gActivePlatform:\r
655 PlatformDir = GlobalData.gActivePlatform.MetaFile.Dir\r
656 IncludedFile1 = PathClass(IncludedFile, PlatformDir)\r
2bcc713e
LG
657 ErrorCode = IncludedFile1.Validate()[0]\r
658 if ErrorCode != 0:\r
659 #\r
660 # Also search file under the WORKSPACE directory\r
661 #\r
662 IncludedFile1 = PathClass(IncludedFile, GlobalData.gWorkspace)\r
663 ErrorCode = IncludedFile1.Validate()[0]\r
664 if ErrorCode != 0:\r
d0acc87a 665 raise Warning("The include file does not exist under below directories: \n%s\n%s\n%s\n"%(os.path.dirname(self.FileName), PlatformDir, GlobalData.gWorkspace), \r
2bcc713e 666 self.FileName, self.CurrentLineNumber)\r
30fdf114 667\r
118bf096
CS
668 if not IsValidInclude (IncludedFile1.Path, self.CurrentLineNumber):\r
669 raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1.Path), self.FileName, self.CurrentLineNumber)\r
670\r
2bcc713e 671 IncFileProfile = IncludeFileProfile(IncludedFile1.Path)\r
30fdf114
LG
672\r
673 CurrentLine = self.CurrentLineNumber\r
674 CurrentOffset = self.CurrentOffsetWithinLine\r
675 # list index of the insertion, note that line number is 'CurrentLine + 1'\r
676 InsertAtLine = CurrentLine\r
118bf096
CS
677 ParentProfile = GetParentAtLine (CurrentLine)\r
678 if ParentProfile != None:\r
679 ParentProfile.IncludeFileList.insert(0, IncFileProfile)\r
680 IncFileProfile.Level = ParentProfile.Level + 1\r
30fdf114
LG
681 IncFileProfile.InsertStartLineNumber = InsertAtLine + 1\r
682 # deal with remaining portions after "!include filename", if exists.\r
683 if self.__GetNextToken():\r
684 if self.CurrentLineNumber == CurrentLine:\r
685 RemainingLine = self.__CurrentLine()[CurrentOffset:]\r
686 self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine)\r
687 IncFileProfile.InsertAdjust += 1\r
688 self.CurrentLineNumber += 1\r
689 self.CurrentOffsetWithinLine = 0\r
690\r
691 for Line in IncFileProfile.FileLinesList:\r
692 self.Profile.FileLinesList.insert(InsertAtLine, Line)\r
693 self.CurrentLineNumber += 1\r
694 InsertAtLine += 1\r
695\r
118bf096
CS
696 # reversely sorted to better determine error in file\r
697 AllIncludeFileList.insert(0, IncFileProfile)\r
30fdf114
LG
698\r
699 # comment out the processed include file statement\r
700 TempList = list(self.Profile.FileLinesList[IncludeLine - 1])\r
701 TempList.insert(IncludeOffset, '#')\r
702 self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList)\r
118bf096
CS
703 if Processed: # Nested and back-to-back support\r
704 self.Rewind(DestLine = IncFileProfile.InsertStartLineNumber - 1)\r
705 Processed = False\r
706 # Preprocess done.\r
30fdf114 707 self.Rewind()\r
0d2711a6 708 \r
da92f276
LG
709 def __GetIfListCurrentItemStat(self, IfList):\r
710 if len(IfList) == 0:\r
711 return True\r
712 \r
713 for Item in IfList:\r
714 if Item[1] == False:\r
715 return False\r
716 \r
717 return True\r
0d2711a6 718 \r
6780eef1 719 ## PreprocessConditionalStatement() method\r
30fdf114 720 #\r
6780eef1 721 # Preprocess conditional statement.\r
30fdf114
LG
722 # In the end, rewind the file buffer pointer to the beginning\r
723 #\r
724 # @param self The object pointer\r
725 #\r
726 def PreprocessConditionalStatement(self):\r
727 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]\r
728 IfList = []\r
0d2711a6 729 RegionLayoutLine = 0\r
d0acc87a 730 ReplacedLine = -1\r
30fdf114 731 while self.__GetNextToken():\r
d0acc87a
LG
732 # Determine section name and the location dependent macro\r
733 if self.__GetIfListCurrentItemStat(IfList):\r
734 if self.__Token.startswith('['):\r
735 Header = self.__Token\r
736 if not self.__Token.endswith(']'):\r
737 self.__SkipToToken(']')\r
738 Header += self.__SkippedChars\r
739 if Header.find('$(') != -1:\r
740 raise Warning("macro cannot be used in section header", self.FileName, self.CurrentLineNumber)\r
741 self.__SectionHeaderParser(Header)\r
742 continue\r
743 # Replace macros except in RULE section or out of section\r
744 elif self.__CurSection and ReplacedLine != self.CurrentLineNumber:\r
745 ReplacedLine = self.CurrentLineNumber\r
746 self.__UndoToken()\r
747 CurLine = self.Profile.FileLinesList[ReplacedLine - 1]\r
748 PreIndex = 0\r
749 StartPos = CurLine.find('$(', PreIndex)\r
750 EndPos = CurLine.find(')', StartPos+2)\r
64b2609f 751 while StartPos != -1 and EndPos != -1 and self.__Token not in ['!ifdef', '!ifndef', '!if', '!elseif']:\r
d0acc87a
LG
752 MacroName = CurLine[StartPos+2 : EndPos]\r
753 MacorValue = self.__GetMacroValue(MacroName)\r
754 if MacorValue != None:\r
755 CurLine = CurLine.replace('$(' + MacroName + ')', MacorValue, 1)\r
756 if MacorValue.find('$(') != -1:\r
757 PreIndex = StartPos\r
758 else:\r
759 PreIndex = StartPos + len(MacorValue)\r
760 else:\r
761 PreIndex = EndPos + 1\r
762 StartPos = CurLine.find('$(', PreIndex)\r
763 EndPos = CurLine.find(')', StartPos+2)\r
764 self.Profile.FileLinesList[ReplacedLine - 1] = CurLine\r
765 continue\r
766\r
30fdf114 767 if self.__Token == 'DEFINE':\r
d0acc87a
LG
768 if self.__GetIfListCurrentItemStat(IfList):\r
769 if not self.__CurSection:\r
770 raise Warning("macro cannot be defined in Rule section or out of section", self.FileName, self.CurrentLineNumber)\r
da92f276
LG
771 DefineLine = self.CurrentLineNumber - 1\r
772 DefineOffset = self.CurrentOffsetWithinLine - len('DEFINE')\r
773 if not self.__GetNextToken():\r
774 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)\r
775 Macro = self.__Token\r
776 if not self.__IsToken( "="):\r
777 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
778 \r
d0acc87a
LG
779 Value = self.__GetExpression()\r
780 self.__SetMacroValue(Macro, Value)\r
da92f276 781 self.__WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
0d2711a6 782 elif self.__Token == 'SET':\r
2f04e527
YL
783 if not self.__GetIfListCurrentItemStat(IfList):\r
784 continue\r
64b2609f
LG
785 SetLine = self.CurrentLineNumber - 1\r
786 SetOffset = self.CurrentOffsetWithinLine - len('SET')\r
0d2711a6
LG
787 PcdPair = self.__GetNextPcdName()\r
788 PcdName = "%s.%s" % (PcdPair[1], PcdPair[0])\r
789 if not self.__IsToken( "="):\r
790 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
791\r
d0acc87a
LG
792 Value = self.__GetExpression()\r
793 Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)\r
30fdf114 794\r
d0acc87a 795 self.__PcdDict[PcdName] = Value\r
64b2609f
LG
796\r
797 self.Profile.PcdDict[PcdPair] = Value\r
798 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
799 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple\r
800\r
801 self.__WipeOffArea.append(((SetLine, SetOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
30fdf114
LG
802 elif self.__Token in ('!ifdef', '!ifndef', '!if'):\r
803 IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))\r
804 IfList.append([IfStartPos, None, None])\r
0d2711a6 805\r
30fdf114 806 CondLabel = self.__Token\r
0d2711a6 807 Expression = self.__GetExpression()\r
d5d56f1b 808 \r
30fdf114 809 if CondLabel == '!if':\r
0d2711a6 810 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')\r
30fdf114 811 else:\r
0d2711a6
LG
812 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'in')\r
813 if CondLabel == '!ifndef':\r
30fdf114 814 ConditionSatisfied = not ConditionSatisfied\r
30fdf114 815\r
0d2711a6
LG
816 BranchDetermined = ConditionSatisfied\r
817 IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]\r
818 if ConditionSatisfied:\r
819 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) \r
30fdf114
LG
820 elif self.__Token in ('!elseif', '!else'):\r
821 ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))\r
822 if len(IfList) <= 0:\r
823 raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)\r
0d2711a6 824\r
30fdf114
LG
825 if IfList[-1][1]:\r
826 IfList[-1] = [ElseStartPos, False, True]\r
827 self.__WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
828 else:\r
829 self.__WipeOffArea.append((IfList[-1][0], ElseStartPos))\r
830 IfList[-1] = [ElseStartPos, True, IfList[-1][2]]\r
831 if self.__Token == '!elseif':\r
0d2711a6
LG
832 Expression = self.__GetExpression()\r
833 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')\r
30fdf114
LG
834 IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]]\r
835\r
836 if IfList[-1][1]:\r
837 if IfList[-1][2]:\r
838 IfList[-1][1] = False\r
839 else:\r
840 IfList[-1][2] = True\r
841 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
30fdf114 842 elif self.__Token == '!endif':\r
d0acc87a
LG
843 if len(IfList) <= 0:\r
844 raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
845 if IfList[-1][1]:\r
846 self.__WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
847 else:\r
848 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
849\r
850 IfList.pop()\r
0d2711a6
LG
851 elif not IfList: # Don't use PCDs inside conditional directive\r
852 if self.CurrentLineNumber <= RegionLayoutLine:\r
853 # Don't try the same line twice\r
854 continue\r
64b2609f
LG
855 SetPcd = ShortcutPcdPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])\r
856 if SetPcd:\r
857 self.__PcdDict[SetPcd.group('name')] = SetPcd.group('value')\r
858 RegionLayoutLine = self.CurrentLineNumber\r
859 continue\r
0d2711a6
LG
860 RegionSize = RegionSizePattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])\r
861 if not RegionSize:\r
862 RegionLayoutLine = self.CurrentLineNumber\r
863 continue\r
864 RegionSizeGuid = RegionSizeGuidPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber])\r
865 if not RegionSizeGuid:\r
866 RegionLayoutLine = self.CurrentLineNumber + 1\r
867 continue\r
d0acc87a
LG
868 self.__PcdDict[RegionSizeGuid.group('base')] = RegionSize.group('base')\r
869 self.__PcdDict[RegionSizeGuid.group('size')] = RegionSize.group('size')\r
0d2711a6
LG
870 RegionLayoutLine = self.CurrentLineNumber + 1\r
871\r
872 if IfList:\r
30fdf114
LG
873 raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber)\r
874 self.Rewind()\r
875\r
d0acc87a
LG
876 def __CollectMacroPcd(self):\r
877 MacroDict = {}\r
878\r
879 # PCD macro\r
64b2609f 880 MacroDict.update(GlobalData.gPlatformPcds)\r
d0acc87a
LG
881 MacroDict.update(self.__PcdDict)\r
882\r
883 # Lowest priority\r
884 MacroDict.update(GlobalData.gPlatformDefines)\r
885\r
886 if self.__CurSection:\r
887 # Defines macro\r
888 ScopeMacro = self.__MacroDict['COMMON', 'COMMON', 'COMMON']\r
889 if ScopeMacro:\r
890 MacroDict.update(ScopeMacro)\r
891 \r
892 # Section macro\r
893 ScopeMacro = self.__MacroDict[\r
894 self.__CurSection[0],\r
895 self.__CurSection[1],\r
896 self.__CurSection[2]\r
897 ]\r
898 if ScopeMacro:\r
899 MacroDict.update(ScopeMacro)\r
900\r
901 MacroDict.update(GlobalData.gGlobalDefines)\r
902 MacroDict.update(GlobalData.gCommandLineDefines)\r
903 # Highest priority\r
904\r
905 return MacroDict\r
906\r
0d2711a6 907 def __EvaluateConditional(self, Expression, Line, Op = None, Value = None):\r
30fdf114 908 FileLineTuple = GetRealFileLine(self.FileName, Line)\r
d0acc87a 909 MacroPcdDict = self.__CollectMacroPcd()\r
0d2711a6
LG
910 if Op == 'eval':\r
911 try:\r
d0acc87a
LG
912 if Value:\r
913 return ValueExpression(Expression, MacroPcdDict)(True)\r
914 else:\r
915 return ValueExpression(Expression, MacroPcdDict)()\r
0d2711a6
LG
916 except WrnExpression, Excpt:\r
917 # \r
918 # Catch expression evaluation warning here. We need to report\r
919 # the precise number of line and return the evaluation result\r
920 #\r
921 EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),\r
922 File=self.FileName, ExtraData=self.__CurrentLine(), \r
923 Line=Line)\r
924 return Excpt.result\r
925 except Exception, Excpt:\r
64b2609f
LG
926 if hasattr(Excpt, 'Pcd'):\r
927 if Excpt.Pcd in GlobalData.gPlatformOtherPcds:\r
928 Info = GlobalData.gPlatformOtherPcds[Excpt.Pcd]\r
929 raise Warning("Cannot use this PCD (%s) in an expression as"\r
930 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"\r
931 " of the DSC file (%s), and it is currently defined in this section:"\r
932 " %s, line #: %d." % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE'], Info[0], Info[1]),\r
933 *FileLineTuple)\r
934 else:\r
935 raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE']),\r
936 *FileLineTuple)\r
937 else:\r
938 raise Warning(str(Excpt), *FileLineTuple)\r
0d2711a6
LG
939 else:\r
940 if Expression.startswith('$(') and Expression[-1] == ')':\r
941 Expression = Expression[2:-1] \r
d0acc87a 942 return Expression in MacroPcdDict\r
30fdf114
LG
943\r
944 ## __IsToken() method\r
945 #\r
946 # Check whether input string is found from current char position along\r
947 # If found, the string value is put into self.__Token\r
948 #\r
949 # @param self The object pointer\r
950 # @param String The string to search\r
951 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive\r
952 # @retval True Successfully find string, file buffer pointer moved forward\r
953 # @retval False Not able to find string, file buffer pointer not changed\r
954 #\r
955 def __IsToken(self, String, IgnoreCase = False):\r
956 self.__SkipWhiteSpace()\r
957\r
958 # Only consider the same line, no multi-line token allowed\r
959 StartPos = self.CurrentOffsetWithinLine\r
960 index = -1\r
961 if IgnoreCase:\r
962 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())\r
963 else:\r
964 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)\r
965 if index == 0:\r
966 self.CurrentOffsetWithinLine += len(String)\r
967 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]\r
968 return True\r
969 return False\r
970\r
971 ## __IsKeyword() method\r
972 #\r
973 # Check whether input keyword is found from current char position along, whole word only!\r
974 # If found, the string value is put into self.__Token\r
975 #\r
976 # @param self The object pointer\r
977 # @param Keyword The string to search\r
978 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive\r
979 # @retval True Successfully find string, file buffer pointer moved forward\r
980 # @retval False Not able to find string, file buffer pointer not changed\r
981 #\r
982 def __IsKeyword(self, KeyWord, IgnoreCase = False):\r
983 self.__SkipWhiteSpace()\r
984\r
985 # Only consider the same line, no multi-line token allowed\r
986 StartPos = self.CurrentOffsetWithinLine\r
987 index = -1\r
988 if IgnoreCase:\r
989 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(KeyWord.upper())\r
990 else:\r
991 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(KeyWord)\r
992 if index == 0:\r
993 followingChar = self.__CurrentLine()[self.CurrentOffsetWithinLine + len(KeyWord)]\r
994 if not str(followingChar).isspace() and followingChar not in SEPERATOR_TUPLE:\r
995 return False\r
996 self.CurrentOffsetWithinLine += len(KeyWord)\r
997 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]\r
998 return True\r
999 return False\r
1000\r
0d2711a6
LG
1001 def __GetExpression(self):\r
1002 Line = self.Profile.FileLinesList[self.CurrentLineNumber - 1]\r
1003 Index = len(Line) - 1\r
1004 while Line[Index] in ['\r', '\n']:\r
1005 Index -= 1\r
1006 ExpressionString = self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:Index+1]\r
1007 self.CurrentOffsetWithinLine += len(ExpressionString)\r
1008 ExpressionString = ExpressionString.strip()\r
1009 return ExpressionString\r
1010\r
30fdf114
LG
1011 ## __GetNextWord() method\r
1012 #\r
1013 # Get next C name from file lines\r
1014 # If found, the string value is put into self.__Token\r
1015 #\r
1016 # @param self The object pointer\r
1017 # @retval True Successfully find a C name string, file buffer pointer moved forward\r
1018 # @retval False Not able to find a C name string, file buffer pointer not changed\r
1019 #\r
1020 def __GetNextWord(self):\r
1021 self.__SkipWhiteSpace()\r
1022 if self.__EndOfFile():\r
1023 return False\r
1024\r
1025 TempChar = self.__CurrentChar()\r
1026 StartPos = self.CurrentOffsetWithinLine\r
1027 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_':\r
1028 self.__GetOneChar()\r
1029 while not self.__EndOfLine():\r
1030 TempChar = self.__CurrentChar()\r
1031 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \\r
1032 or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-':\r
1033 self.__GetOneChar()\r
1034\r
1035 else:\r
1036 break\r
1037\r
1038 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]\r
1039 return True\r
1040\r
1041 return False\r
1042\r
1043 ## __GetNextToken() method\r
1044 #\r
1045 # Get next token unit before a seperator\r
1046 # If found, the string value is put into self.__Token\r
1047 #\r
1048 # @param self The object pointer\r
1049 # @retval True Successfully find a token unit, file buffer pointer moved forward\r
1050 # @retval False Not able to find a token unit, file buffer pointer not changed\r
1051 #\r
1052 def __GetNextToken(self):\r
1053 # Skip leading spaces, if exist.\r
1054 self.__SkipWhiteSpace()\r
1055 if self.__EndOfFile():\r
1056 return False\r
1057 # Record the token start position, the position of the first non-space char.\r
1058 StartPos = self.CurrentOffsetWithinLine\r
1059 StartLine = self.CurrentLineNumber\r
d0acc87a 1060 while StartLine == self.CurrentLineNumber:\r
30fdf114
LG
1061 TempChar = self.__CurrentChar()\r
1062 # Try to find the end char that is not a space and not in seperator tuple.\r
1063 # That is, when we got a space or any char in the tuple, we got the end of token.\r
1064 if not str(TempChar).isspace() and TempChar not in SEPERATOR_TUPLE:\r
1065 self.__GetOneChar()\r
1066 # if we happen to meet a seperator as the first char, we must proceed to get it.\r
1067 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.\r
1068 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:\r
1069 self.__GetOneChar()\r
1070 break\r
1071 else:\r
1072 break\r
1073# else:\r
1074# return False\r
1075\r
1076 EndPos = self.CurrentOffsetWithinLine\r
1077 if self.CurrentLineNumber != StartLine:\r
1078 EndPos = len(self.Profile.FileLinesList[StartLine-1])\r
1079 self.__Token = self.Profile.FileLinesList[StartLine-1][StartPos : EndPos]\r
1080 if StartPos != self.CurrentOffsetWithinLine:\r
1081 return True\r
1082 else:\r
1083 return False\r
1084\r
1085 def __GetNextOp(self):\r
1086 # Skip leading spaces, if exist.\r
1087 self.__SkipWhiteSpace()\r
1088 if self.__EndOfFile():\r
1089 return False\r
1090 # Record the token start position, the position of the first non-space char.\r
1091 StartPos = self.CurrentOffsetWithinLine\r
1092 while not self.__EndOfLine():\r
1093 TempChar = self.__CurrentChar()\r
1094 # Try to find the end char that is not a space\r
1095 if not str(TempChar).isspace():\r
1096 self.__GetOneChar()\r
1097 else:\r
1098 break\r
1099 else:\r
1100 return False\r
1101\r
1102 if StartPos != self.CurrentOffsetWithinLine:\r
1103 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]\r
1104 return True\r
1105 else:\r
1106 return False\r
1107 ## __GetNextGuid() method\r
1108 #\r
1109 # Get next token unit before a seperator\r
1110 # If found, the GUID string is put into self.__Token\r
1111 #\r
1112 # @param self The object pointer\r
1113 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward\r
1114 # @retval False Not able to find a registry format GUID, file buffer pointer not changed\r
1115 #\r
1116 def __GetNextGuid(self):\r
1117\r
1118 if not self.__GetNextToken():\r
1119 return False\r
1120 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
1121 if p.match(self.__Token) != None:\r
1122 return True\r
1123 else:\r
1124 self.__UndoToken()\r
1125 return False\r
1126\r
1127 ## __UndoToken() method\r
1128 #\r
1129 # Go back one token unit in file buffer\r
1130 #\r
1131 # @param self The object pointer\r
1132 #\r
1133 def __UndoToken(self):\r
1134 self.__UndoOneChar()\r
1135 while self.__CurrentChar().isspace():\r
1136 if not self.__UndoOneChar():\r
1137 self.__GetOneChar()\r
1138 return\r
1139\r
1140\r
1141 StartPos = self.CurrentOffsetWithinLine\r
1142 CurrentLine = self.CurrentLineNumber\r
1143 while CurrentLine == self.CurrentLineNumber:\r
1144\r
1145 TempChar = self.__CurrentChar()\r
1146 # Try to find the end char that is not a space and not in seperator tuple.\r
1147 # That is, when we got a space or any char in the tuple, we got the end of token.\r
1148 if not str(TempChar).isspace() and not TempChar in SEPERATOR_TUPLE:\r
1149 if not self.__UndoOneChar():\r
d0acc87a 1150 return\r
30fdf114
LG
1151 # if we happen to meet a seperator as the first char, we must proceed to get it.\r
1152 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.\r
1153 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:\r
1154 return\r
1155 else:\r
1156 break\r
1157\r
1158 self.__GetOneChar()\r
1159\r
1160 ## __HexDigit() method\r
1161 #\r
1162 # Whether char input is a Hex data bit\r
1163 #\r
1164 # @param self The object pointer\r
1165 # @param TempChar The char to test\r
1166 # @retval True The char is a Hex data bit\r
1167 # @retval False The char is NOT a Hex data bit\r
1168 #\r
1169 def __HexDigit(self, TempChar):\r
1170 if (TempChar >= 'a' and TempChar <= 'f') or (TempChar >= 'A' and TempChar <= 'F') \\r
1171 or (TempChar >= '0' and TempChar <= '9'):\r
1172 return True\r
1173 else:\r
1174 return False\r
1175\r
1176 def __IsHex(self, HexStr):\r
1177 if not HexStr.upper().startswith("0X"):\r
1178 return False\r
1179 if len(self.__Token) <= 2:\r
1180 return False\r
1181 charList = [c for c in HexStr[2 : ] if not self.__HexDigit( c)]\r
1182 if len(charList) == 0:\r
1183 return True\r
1184 else:\r
1185 return False\r
1186 ## __GetNextHexNumber() method\r
1187 #\r
1188 # Get next HEX data before a seperator\r
1189 # If found, the HEX data is put into self.__Token\r
1190 #\r
1191 # @param self The object pointer\r
1192 # @retval True Successfully find a HEX data, file buffer pointer moved forward\r
1193 # @retval False Not able to find a HEX data, file buffer pointer not changed\r
1194 #\r
1195 def __GetNextHexNumber(self):\r
1196 if not self.__GetNextToken():\r
1197 return False\r
1198 if self.__IsHex(self.__Token):\r
1199 return True\r
1200 else:\r
1201 self.__UndoToken()\r
1202 return False\r
1203\r
1204 ## __GetNextDecimalNumber() method\r
1205 #\r
1206 # Get next decimal data before a seperator\r
1207 # If found, the decimal data is put into self.__Token\r
1208 #\r
1209 # @param self The object pointer\r
1210 # @retval True Successfully find a decimal data, file buffer pointer moved forward\r
1211 # @retval False Not able to find a decimal data, file buffer pointer not changed\r
1212 #\r
1213 def __GetNextDecimalNumber(self):\r
1214 if not self.__GetNextToken():\r
1215 return False\r
1216 if self.__Token.isdigit():\r
1217 return True\r
1218 else:\r
1219 self.__UndoToken()\r
1220 return False\r
1221\r
1222 ## __GetNextPcdName() method\r
1223 #\r
1224 # Get next PCD token space C name and PCD C name pair before a seperator\r
1225 # If found, the decimal data is put into self.__Token\r
1226 #\r
1227 # @param self The object pointer\r
1228 # @retval Tuple PCD C name and PCD token space C name pair\r
1229 #\r
1230 def __GetNextPcdName(self):\r
1231 if not self.__GetNextWord():\r
1232 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)\r
1233 pcdTokenSpaceCName = self.__Token\r
1234\r
1235 if not self.__IsToken( "."):\r
1236 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)\r
1237\r
1238 if not self.__GetNextWord():\r
1239 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)\r
1240 pcdCName = self.__Token\r
1241\r
1242 return (pcdCName, pcdTokenSpaceCName)\r
1243\r
1244 ## __GetStringData() method\r
1245 #\r
1246 # Get string contents quoted in ""\r
1247 # If found, the decimal data is put into self.__Token\r
1248 #\r
1249 # @param self The object pointer\r
1250 # @retval True Successfully find a string data, file buffer pointer moved forward\r
1251 # @retval False Not able to find a string data, file buffer pointer not changed\r
1252 #\r
1253 def __GetStringData(self):\r
1254 if self.__Token.startswith("\"") or self.__Token.startswith("L\""):\r
1255 self.__UndoToken()\r
1256 self.__SkipToToken("\"")\r
1257 currentLineNumber = self.CurrentLineNumber\r
1258\r
1259 if not self.__SkipToToken("\""):\r
1260 raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber)\r
1261 if currentLineNumber != self.CurrentLineNumber:\r
1262 raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber)\r
1263 self.__Token = self.__SkippedChars.rstrip('\"')\r
1264 return True\r
1265\r
1266 elif self.__Token.startswith("\'") or self.__Token.startswith("L\'"):\r
1267 self.__UndoToken()\r
1268 self.__SkipToToken("\'")\r
1269 currentLineNumber = self.CurrentLineNumber\r
1270\r
1271 if not self.__SkipToToken("\'"):\r
1272 raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber)\r
1273 if currentLineNumber != self.CurrentLineNumber:\r
1274 raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber)\r
1275 self.__Token = self.__SkippedChars.rstrip('\'')\r
1276 return True\r
1277\r
1278 else:\r
1279 return False\r
1280\r
1281 ## __SkipToToken() method\r
1282 #\r
1283 # Search forward in file buffer for the string\r
1284 # The skipped chars are put into self.__SkippedChars\r
1285 #\r
1286 # @param self The object pointer\r
1287 # @param String The string to search\r
1288 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive\r
1289 # @retval True Successfully find the string, file buffer pointer moved forward\r
1290 # @retval False Not able to find the string, file buffer pointer not changed\r
1291 #\r
1292 def __SkipToToken(self, String, IgnoreCase = False):\r
1293 StartPos = self.GetFileBufferPos()\r
1294\r
1295 self.__SkippedChars = ""\r
1296 while not self.__EndOfFile():\r
1297 index = -1\r
1298 if IgnoreCase:\r
1299 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())\r
1300 else:\r
1301 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)\r
1302 if index == 0:\r
1303 self.CurrentOffsetWithinLine += len(String)\r
1304 self.__SkippedChars += String\r
1305 return True\r
1306 self.__SkippedChars += str(self.__CurrentChar())\r
1307 self.__GetOneChar()\r
1308\r
1309 self.SetFileBufferPos( StartPos)\r
1310 self.__SkippedChars = ""\r
1311 return False\r
1312\r
1313 ## GetFileBufferPos() method\r
1314 #\r
1315 # Return the tuple of current line and offset within the line\r
1316 #\r
1317 # @param self The object pointer\r
1318 # @retval Tuple Line number and offset pair\r
1319 #\r
1320 def GetFileBufferPos(self):\r
1321 return (self.CurrentLineNumber, self.CurrentOffsetWithinLine)\r
1322\r
1323 ## SetFileBufferPos() method\r
1324 #\r
1325 # Restore the file buffer position\r
1326 #\r
1327 # @param self The object pointer\r
1328 # @param Pos The new file buffer position\r
1329 #\r
1330 def SetFileBufferPos(self, Pos):\r
1331 (self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos\r
1332\r
d40b2ee6
LG
1333 ## Preprocess() method\r
1334 #\r
1335 # Preprocess comment, conditional directive, include directive, replace macro.\r
1336 # Exception will be raised if syntax error found\r
1337 #\r
1338 # @param self The object pointer\r
1339 #\r
1340 def Preprocess(self):\r
1341 self.__StringToList()\r
1342 self.PreprocessFile()\r
1343 self.PreprocessIncludeFile()\r
1344 self.__StringToList()\r
1345 self.PreprocessFile()\r
1346 self.PreprocessConditionalStatement()\r
1347 self.__StringToList()\r
1348 for Pos in self.__WipeOffArea:\r
1349 self.__ReplaceFragment(Pos[0], Pos[1])\r
1350 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]\r
1351\r
1352 while self.__GetDefines():\r
1353 pass\r
d40b2ee6 1354\r
30fdf114
LG
1355 ## ParseFile() method\r
1356 #\r
1357 # Parse the file profile buffer to extract fd, fv ... information\r
1358 # Exception will be raised if syntax error found\r
1359 #\r
1360 # @param self The object pointer\r
1361 #\r
1362 def ParseFile(self):\r
1363\r
1364 try:\r
d40b2ee6 1365 self.Preprocess()\r
30fdf114
LG
1366 while self.__GetFd():\r
1367 pass\r
1368\r
1369 while self.__GetFv():\r
1370 pass\r
1371\r
a3251d84
YL
1372 while self.__GetFmp():\r
1373 pass\r
1374\r
30fdf114
LG
1375 while self.__GetCapsule():\r
1376 pass\r
1377\r
1378 while self.__GetVtf():\r
1379 pass\r
1380\r
1381 while self.__GetRule():\r
1382 pass\r
1383 \r
1384 while self.__GetOptionRom():\r
1385 pass\r
1386\r
1387 except Warning, X:\r
1388 self.__UndoToken()\r
30fdf114 1389 #'\n\tGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \\r
118bf096
CS
1390 # At this point, the closest parent would be the included file itself\r
1391 Profile = GetParentAtLine(X.OriginalLineNumber)\r
1392 if Profile != None:\r
1393 X.Message += ' near line %d, column %d: %s' \\r
1394 % (X.LineNumber, 0, Profile.FileLinesList[X.LineNumber-1])\r
1395 else:\r
1396 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1397 X.Message += ' near line %d, column %d: %s' \\r
30fdf114
LG
1398 % (FileLineTuple[1], self.CurrentOffsetWithinLine + 1, self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :].rstrip('\n').rstrip('\r'))\r
1399 raise\r
1400\r
1401 ## __GetDefines() method\r
1402 #\r
1403 # Get Defines section contents and store its data into AllMacrosList\r
1404 #\r
1405 # @param self The object pointer\r
1406 # @retval True Successfully find a Defines\r
1407 # @retval False Not able to find a Defines\r
1408 #\r
1409 def __GetDefines(self):\r
1410\r
1411 if not self.__GetNextToken():\r
1412 return False\r
1413\r
1414 S = self.__Token.upper()\r
1415 if S.startswith("[") and not S.startswith("[DEFINES"):\r
1416 if not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \\r
1417 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):\r
1418 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
1419 self.__UndoToken()\r
1420 return False\r
1421\r
1422 self.__UndoToken()\r
1423 if not self.__IsToken("[DEFINES", True):\r
1424 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1425 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
1426 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
1427 raise Warning("expected [DEFINES", self.FileName, self.CurrentLineNumber)\r
1428\r
1429 if not self.__IsToken( "]"):\r
1430 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
1431\r
1432 while self.__GetNextWord():\r
6780eef1
LG
1433 # handle the SET statement\r
1434 if self.__Token == 'SET':\r
1435 self.__UndoToken()\r
1436 self.__GetSetStatement(None)\r
1437 continue\r
1438 \r
30fdf114
LG
1439 Macro = self.__Token\r
1440 \r
1441 if not self.__IsToken("="):\r
1442 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1443 if not self.__GetNextToken() or self.__Token.startswith('['):\r
1444 raise Warning("expected MACRO value", self.FileName, self.CurrentLineNumber)\r
1445 Value = self.__Token\r
30fdf114
LG
1446\r
1447 return False\r
1448\r
1449 ## __GetFd() method\r
1450 #\r
1451 # Get FD section contents and store its data into FD dictionary of self.Profile\r
1452 #\r
1453 # @param self The object pointer\r
1454 # @retval True Successfully find a FD\r
1455 # @retval False Not able to find a FD\r
1456 #\r
1457 def __GetFd(self):\r
1458\r
1459 if not self.__GetNextToken():\r
1460 return False\r
1461\r
1462 S = self.__Token.upper()\r
1463 if S.startswith("[") and not S.startswith("[FD."):\r
a3251d84 1464 if not S.startswith("[FV.") and not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \\r
30fdf114
LG
1465 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):\r
1466 raise Warning("Unknown section", self.FileName, self.CurrentLineNumber)\r
1467 self.__UndoToken()\r
1468 return False\r
1469\r
1470 self.__UndoToken()\r
1471 if not self.__IsToken("[FD.", True):\r
1472 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1473 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
1474 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
1475 raise Warning("expected [FD.]", self.FileName, self.CurrentLineNumber)\r
1476\r
1477 FdName = self.__GetUiName()\r
52302d4d
LG
1478 if FdName == "":\r
1479 if len (self.Profile.FdDict) == 0:\r
1480 FdName = GenFdsGlobalVariable.PlatformName\r
d0acc87a
LG
1481 if FdName == "" and GlobalData.gActivePlatform:\r
1482 FdName = GlobalData.gActivePlatform.PlatformName\r
52302d4d
LG
1483 self.Profile.FdNameNotSet = True\r
1484 else:\r
1485 raise Warning("expected FdName in [FD.] section", self.FileName, self.CurrentLineNumber)\r
30fdf114 1486 self.CurrentFdName = FdName.upper()\r
52302d4d
LG
1487 \r
1488 if self.CurrentFdName in self.Profile.FdDict:\r
1489 raise Warning("Unexpected the same FD name", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
1490\r
1491 if not self.__IsToken( "]"):\r
1492 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
1493\r
1494 FdObj = Fd.FD()\r
1495 FdObj.FdUiName = self.CurrentFdName\r
1496 self.Profile.FdDict[self.CurrentFdName] = FdObj\r
52302d4d
LG
1497\r
1498 if len (self.Profile.FdDict) > 1 and self.Profile.FdNameNotSet:\r
1499 raise Warning("expected all FDs have their name", self.FileName, self.CurrentLineNumber)\r
1500\r
30fdf114
LG
1501 Status = self.__GetCreateFile(FdObj)\r
1502 if not Status:\r
1503 raise Warning("FD name error", self.FileName, self.CurrentLineNumber)\r
1504\r
e8a47801
LG
1505 while self.__GetTokenStatements(FdObj):\r
1506 pass\r
1507 for Attr in ("BaseAddress", "Size", "ErasePolarity"):\r
1508 if getattr(FdObj, Attr) == None:\r
1509 self.__GetNextToken()\r
1510 raise Warning("Keyword %s missing" % Attr, self.FileName, self.CurrentLineNumber)\r
1511\r
1512 if not FdObj.BlockSizeList:\r
1513 FdObj.BlockSizeList.append((1, FdObj.Size, None))\r
30fdf114
LG
1514\r
1515 self.__GetDefineStatements(FdObj)\r
1516\r
1517 self.__GetSetStatements(FdObj)\r
1518\r
1519 if not self.__GetRegionLayout(FdObj):\r
1520 raise Warning("expected region layout", self.FileName, self.CurrentLineNumber)\r
1521\r
1522 while self.__GetRegionLayout(FdObj):\r
1523 pass\r
1524 return True\r
1525\r
1526 ## __GetUiName() method\r
1527 #\r
1528 # Return the UI name of a section\r
1529 #\r
1530 # @param self The object pointer\r
1531 # @retval FdName UI name\r
1532 #\r
1533 def __GetUiName(self):\r
1534 Name = ""\r
1535 if self.__GetNextWord():\r
1536 Name = self.__Token\r
1537\r
1538 return Name\r
1539\r
1540 ## __GetCreateFile() method\r
1541 #\r
1542 # Return the output file name of object\r
1543 #\r
1544 # @param self The object pointer\r
1545 # @param Obj object whose data will be stored in file\r
1546 # @retval FdName UI name\r
1547 #\r
1548 def __GetCreateFile(self, Obj):\r
1549\r
1550 if self.__IsKeyword( "CREATE_FILE"):\r
1551 if not self.__IsToken( "="):\r
1552 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1553\r
1554 if not self.__GetNextToken():\r
1555 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)\r
1556\r
1557 FileName = self.__Token\r
1558 Obj.CreateFileName = FileName\r
1559\r
1560 return True\r
1561\r
1562 ## __GetTokenStatements() method\r
1563 #\r
1564 # Get token statements\r
1565 #\r
1566 # @param self The object pointer\r
1567 # @param Obj for whom token statement is got\r
30fdf114
LG
1568 #\r
1569 def __GetTokenStatements(self, Obj):\r
e8a47801
LG
1570 if self.__IsKeyword( "BaseAddress"):\r
1571 if not self.__IsToken( "="):\r
1572 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1573 \r
1574 if not self.__GetNextHexNumber():\r
1575 raise Warning("expected Hex base address", self.FileName, self.CurrentLineNumber)\r
1576 \r
1577 Obj.BaseAddress = self.__Token\r
1578 \r
1579 if self.__IsToken( "|"):\r
1580 pcdPair = self.__GetNextPcdName()\r
1581 Obj.BaseAddressPcd = pcdPair\r
1582 self.Profile.PcdDict[pcdPair] = Obj.BaseAddress\r
1583 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1584 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple\r
1585 return True\r
30fdf114 1586\r
e8a47801
LG
1587 if self.__IsKeyword( "Size"):\r
1588 if not self.__IsToken( "="):\r
1589 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1590 \r
1591 if not self.__GetNextHexNumber():\r
1592 raise Warning("expected Hex size", self.FileName, self.CurrentLineNumber)\r
30fdf114 1593\r
e8a47801
LG
1594 Size = self.__Token\r
1595 if self.__IsToken( "|"):\r
1596 pcdPair = self.__GetNextPcdName()\r
1597 Obj.SizePcd = pcdPair\r
1598 self.Profile.PcdDict[pcdPair] = Size\r
1599 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1600 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple\r
1601 Obj.Size = long(Size, 0)\r
1602 return True\r
30fdf114 1603\r
e8a47801
LG
1604 if self.__IsKeyword( "ErasePolarity"):\r
1605 if not self.__IsToken( "="):\r
1606 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1607 \r
1608 if not self.__GetNextToken():\r
1609 raise Warning("expected Erase Polarity", self.FileName, self.CurrentLineNumber)\r
1610 \r
1611 if self.__Token != "1" and self.__Token != "0":\r
1612 raise Warning("expected 1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber)\r
1613 \r
1614 Obj.ErasePolarity = self.__Token\r
1615 return True\r
30fdf114 1616\r
e8a47801 1617 return self.__GetBlockStatements(Obj)\r
30fdf114
LG
1618\r
1619 ## __GetAddressStatements() method\r
1620 #\r
1621 # Get address statements\r
1622 #\r
1623 # @param self The object pointer\r
1624 # @param Obj for whom address statement is got\r
1625 # @retval True Successfully find\r
1626 # @retval False Not able to find\r
1627 #\r
1628 def __GetAddressStatements(self, Obj):\r
1629\r
1630 if self.__IsKeyword("BsBaseAddress"):\r
1631 if not self.__IsToken( "="):\r
1632 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1633\r
1634 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():\r
1635 raise Warning("expected address", self.FileName, self.CurrentLineNumber)\r
1636\r
1637 BsAddress = long(self.__Token, 0)\r
1638 Obj.BsBaseAddress = BsAddress\r
1639\r
1640 if self.__IsKeyword("RtBaseAddress"):\r
1641 if not self.__IsToken( "="):\r
1642 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1643\r
1644 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():\r
1645 raise Warning("expected address", self.FileName, self.CurrentLineNumber)\r
1646\r
1647 RtAddress = long(self.__Token, 0)\r
1648 Obj.RtBaseAddress = RtAddress\r
1649\r
1650 ## __GetBlockStatements() method\r
1651 #\r
1652 # Get block statements\r
1653 #\r
1654 # @param self The object pointer\r
1655 # @param Obj for whom block statement is got\r
30fdf114
LG
1656 #\r
1657 def __GetBlockStatements(self, Obj):\r
e8a47801 1658 IsBlock = False\r
30fdf114 1659 while self.__GetBlockStatement(Obj):\r
e8a47801 1660 IsBlock = True\r
52302d4d 1661 \r
e8a47801 1662 Item = Obj.BlockSizeList[-1]\r
52302d4d 1663 if Item[0] == None or Item[1] == None:\r
6780eef1 1664 raise Warning("expected block statement", self.FileName, self.CurrentLineNumber)\r
e8a47801 1665 return IsBlock\r
30fdf114
LG
1666\r
1667 ## __GetBlockStatement() method\r
1668 #\r
1669 # Get block statement\r
1670 #\r
1671 # @param self The object pointer\r
1672 # @param Obj for whom block statement is got\r
1673 # @retval True Successfully find\r
1674 # @retval False Not able to find\r
1675 #\r
1676 def __GetBlockStatement(self, Obj):\r
1677 if not self.__IsKeyword( "BlockSize"):\r
1678 return False\r
1679\r
1680 if not self.__IsToken( "="):\r
1681 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1682\r
1683 if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():\r
6780eef1 1684 raise Warning("expected Hex or Integer block size", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
1685\r
1686 BlockSize = self.__Token\r
1687 BlockSizePcd = None\r
1688 if self.__IsToken( "|"):\r
1689 PcdPair = self.__GetNextPcdName()\r
1690 BlockSizePcd = PcdPair\r
1691 self.Profile.PcdDict[PcdPair] = BlockSize\r
d0acc87a
LG
1692 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1693 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple\r
52302d4d 1694 BlockSize = long(BlockSize, 0)\r
30fdf114
LG
1695\r
1696 BlockNumber = None\r
1697 if self.__IsKeyword( "NumBlocks"):\r
1698 if not self.__IsToken( "="):\r
1699 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1700\r
1701 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():\r
1702 raise Warning("expected block numbers", self.FileName, self.CurrentLineNumber)\r
1703\r
1704 BlockNumber = long(self.__Token, 0)\r
1705\r
1706 Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd))\r
1707 return True\r
1708\r
1709 ## __GetDefineStatements() method\r
1710 #\r
1711 # Get define statements\r
1712 #\r
1713 # @param self The object pointer\r
1714 # @param Obj for whom define statement is got\r
1715 # @retval True Successfully find\r
1716 # @retval False Not able to find\r
1717 #\r
1718 def __GetDefineStatements(self, Obj):\r
1719 while self.__GetDefineStatement( Obj):\r
1720 pass\r
1721\r
1722 ## __GetDefineStatement() method\r
1723 #\r
1724 # Get define statement\r
1725 #\r
1726 # @param self The object pointer\r
1727 # @param Obj for whom define statement is got\r
1728 # @retval True Successfully find\r
1729 # @retval False Not able to find\r
1730 #\r
1731 def __GetDefineStatement(self, Obj):\r
1732 if self.__IsKeyword("DEFINE"):\r
1733 self.__GetNextToken()\r
1734 Macro = self.__Token\r
1735 if not self.__IsToken( "="):\r
1736 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1737\r
1738 if not self.__GetNextToken():\r
1739 raise Warning("expected value", self.FileName, self.CurrentLineNumber)\r
1740\r
1741 Value = self.__Token\r
1742 Macro = '$(' + Macro + ')'\r
1743 Obj.DefineVarDict[Macro] = Value\r
1744 return True\r
1745\r
1746 return False\r
1747\r
1748 ## __GetSetStatements() method\r
1749 #\r
1750 # Get set statements\r
1751 #\r
1752 # @param self The object pointer\r
1753 # @param Obj for whom set statement is got\r
1754 # @retval True Successfully find\r
1755 # @retval False Not able to find\r
1756 #\r
1757 def __GetSetStatements(self, Obj):\r
1758 while self.__GetSetStatement(Obj):\r
1759 pass\r
1760\r
1761 ## __GetSetStatement() method\r
1762 #\r
1763 # Get set statement\r
1764 #\r
1765 # @param self The object pointer\r
1766 # @param Obj for whom set statement is got\r
1767 # @retval True Successfully find\r
1768 # @retval False Not able to find\r
1769 #\r
1770 def __GetSetStatement(self, Obj):\r
1771 if self.__IsKeyword("SET"):\r
1772 PcdPair = self.__GetNextPcdName()\r
1773\r
1774 if not self.__IsToken( "="):\r
1775 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1776\r
d0acc87a
LG
1777 Value = self.__GetExpression()\r
1778 Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)\r
30fdf114 1779\r
6780eef1
LG
1780 if Obj:\r
1781 Obj.SetVarDict[PcdPair] = Value\r
30fdf114 1782 self.Profile.PcdDict[PcdPair] = Value\r
d0acc87a
LG
1783 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1784 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple\r
30fdf114
LG
1785 return True\r
1786\r
1787 return False\r
1788\r
4afd3d04
LG
1789 ## __CalcRegionExpr(self)\r
1790 #\r
1791 # Calculate expression for offset or size of a region\r
1792 #\r
1793 # @return: None if invalid expression\r
1794 # Calculated number if successfully\r
1795 #\r
1796 def __CalcRegionExpr(self):\r
1797 StartPos = self.GetFileBufferPos()\r
1798 Expr = ''\r
1799 PairCount = 0\r
1800 while not self.__EndOfFile():\r
1801 CurCh = self.__CurrentChar()\r
1802 if CurCh == '(':\r
1803 PairCount += 1\r
1804 elif CurCh == ')':\r
1805 PairCount -= 1\r
1806\r
1807 if CurCh in '|\r\n' and PairCount == 0:\r
1808 break\r
1809 Expr += CurCh\r
1810 self.__GetOneChar()\r
1811 try:\r
1812 return long(\r
1813 ValueExpression(Expr,\r
2bc3256c 1814 self.__CollectMacroPcd()\r
4afd3d04
LG
1815 )(True),0)\r
1816 except Exception:\r
1817 self.SetFileBufferPos(StartPos)\r
1818 return None\r
1819\r
30fdf114
LG
1820 ## __GetRegionLayout() method\r
1821 #\r
1822 # Get region layout for FD\r
1823 #\r
1824 # @param self The object pointer\r
1825 # @param Fd for whom region is got\r
1826 # @retval True Successfully find\r
1827 # @retval False Not able to find\r
1828 #\r
1829 def __GetRegionLayout(self, Fd):\r
4afd3d04
LG
1830 Offset = self.__CalcRegionExpr() \r
1831 if Offset == None:\r
30fdf114
LG
1832 return False\r
1833\r
1834 RegionObj = Region.Region()\r
4afd3d04 1835 RegionObj.Offset = Offset\r
30fdf114
LG
1836 Fd.RegionList.append(RegionObj)\r
1837\r
1838 if not self.__IsToken( "|"):\r
1839 raise Warning("expected '|'", self.FileName, self.CurrentLineNumber)\r
1840\r
4afd3d04
LG
1841 Size = self.__CalcRegionExpr()\r
1842 if Size == None:\r
30fdf114 1843 raise Warning("expected Region Size", self.FileName, self.CurrentLineNumber)\r
4afd3d04 1844 RegionObj.Size = Size\r
30fdf114
LG
1845\r
1846 if not self.__GetNextWord():\r
1847 return True\r
1848\r
fd171542 1849 if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE"):\r
2bc3256c
LG
1850 #\r
1851 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]\r
1852 # Or it might be next region's offset described by an expression which starts with a PCD.\r
1853 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size\r
1854 #\r
30fdf114 1855 self.__UndoToken()\r
2bc3256c
LG
1856 IsRegionPcd = (RegionSizeGuidPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]) or\r
1857 RegionOffsetPcdPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]))\r
1858 if IsRegionPcd:\r
1859 RegionObj.PcdOffset = self.__GetNextPcdName()\r
1860 self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0))\r
1861 self.__PcdDict['%s.%s' % (RegionObj.PcdOffset[1], RegionObj.PcdOffset[0])] = "0x%x" % RegionObj.Offset\r
d0acc87a 1862 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2bc3256c
LG
1863 self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple\r
1864 if self.__IsToken( "|"):\r
1865 RegionObj.PcdSize = self.__GetNextPcdName()\r
1866 self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size\r
1867 self.__PcdDict['%s.%s' % (RegionObj.PcdSize[1], RegionObj.PcdSize[0])] = "0x%x" % RegionObj.Size\r
1868 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1869 self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple\r
30fdf114
LG
1870\r
1871 if not self.__GetNextWord():\r
1872 return True\r
1873\r
1874 if self.__Token == "SET":\r
1875 self.__UndoToken()\r
1876 self.__GetSetStatements( RegionObj)\r
1877 if not self.__GetNextWord():\r
1878 return True\r
1879\r
fd171542 1880 elif self.__Token == "FV":\r
30fdf114
LG
1881 self.__UndoToken()\r
1882 self.__GetRegionFvType( RegionObj)\r
1883\r
fd171542 1884 elif self.__Token == "CAPSULE":\r
1885 self.__UndoToken()\r
1886 self.__GetRegionCapType( RegionObj)\r
1887\r
30fdf114
LG
1888 elif self.__Token == "FILE":\r
1889 self.__UndoToken()\r
1890 self.__GetRegionFileType( RegionObj)\r
1891\r
79b74a03 1892 elif self.__Token == "DATA":\r
30fdf114
LG
1893 self.__UndoToken()\r
1894 self.__GetRegionDataType( RegionObj)\r
79b74a03 1895 else:\r
2bc3256c
LG
1896 self.__UndoToken()\r
1897 if self.__GetRegionLayout(Fd):\r
1898 return True\r
79b74a03
LG
1899 raise Warning("A valid region type was not found. "\r
1900 "Valid types are [SET, FV, CAPSULE, FILE, DATA]. This error occurred",\r
1901 self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
1902\r
1903 return True\r
1904\r
1905 ## __GetRegionFvType() method\r
1906 #\r
1907 # Get region fv data for region\r
1908 #\r
1909 # @param self The object pointer\r
1910 # @param RegionObj for whom region data is got\r
1911 #\r
1912 def __GetRegionFvType(self, RegionObj):\r
1913\r
1914 if not self.__IsKeyword( "FV"):\r
1915 raise Warning("expected Keyword 'FV'", self.FileName, self.CurrentLineNumber)\r
1916\r
1917 if not self.__IsToken( "="):\r
1918 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1919\r
1920 if not self.__GetNextToken():\r
1921 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)\r
1922\r
1923 RegionObj.RegionType = "FV"\r
1924 RegionObj.RegionDataList.append(self.__Token)\r
1925\r
1926 while self.__IsKeyword( "FV"):\r
1927\r
1928 if not self.__IsToken( "="):\r
1929 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1930\r
1931 if not self.__GetNextToken():\r
1932 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)\r
1933\r
1934 RegionObj.RegionDataList.append(self.__Token)\r
1935\r
fd171542 1936 ## __GetRegionCapType() method\r
1937 #\r
1938 # Get region capsule data for region\r
1939 #\r
1940 # @param self The object pointer\r
1941 # @param RegionObj for whom region data is got\r
1942 #\r
1943 def __GetRegionCapType(self, RegionObj):\r
1944\r
1945 if not self.__IsKeyword("CAPSULE"):\r
1946 raise Warning("expected Keyword 'CAPSULE'", self.FileName, self.CurrentLineNumber)\r
1947\r
1948 if not self.__IsToken("="):\r
1949 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1950\r
1951 if not self.__GetNextToken():\r
1952 raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)\r
1953\r
1954 RegionObj.RegionType = "CAPSULE"\r
1955 RegionObj.RegionDataList.append(self.__Token)\r
1956\r
1957 while self.__IsKeyword("CAPSULE"):\r
1958\r
1959 if not self.__IsToken("="):\r
1960 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1961\r
1962 if not self.__GetNextToken():\r
1963 raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)\r
1964\r
1965 RegionObj.RegionDataList.append(self.__Token)\r
1966\r
30fdf114
LG
1967 ## __GetRegionFileType() method\r
1968 #\r
1969 # Get region file data for region\r
1970 #\r
1971 # @param self The object pointer\r
1972 # @param RegionObj for whom region data is got\r
1973 #\r
1974 def __GetRegionFileType(self, RegionObj):\r
1975\r
1976 if not self.__IsKeyword( "FILE"):\r
1977 raise Warning("expected Keyword 'FILE'", self.FileName, self.CurrentLineNumber)\r
1978\r
1979 if not self.__IsToken( "="):\r
1980 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1981\r
1982 if not self.__GetNextToken():\r
1983 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)\r
1984\r
1985 RegionObj.RegionType = "FILE"\r
1986 RegionObj.RegionDataList.append( self.__Token)\r
1987\r
1988 while self.__IsKeyword( "FILE"):\r
1989\r
1990 if not self.__IsToken( "="):\r
1991 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
1992\r
1993 if not self.__GetNextToken():\r
1994 raise Warning("expected FILE name", self.FileName, self.CurrentLineNumber)\r
1995\r
1996 RegionObj.RegionDataList.append(self.__Token)\r
1997\r
1998 ## __GetRegionDataType() method\r
1999 #\r
2000 # Get region array data for region\r
2001 #\r
2002 # @param self The object pointer\r
2003 # @param RegionObj for whom region data is got\r
2004 #\r
2005 def __GetRegionDataType(self, RegionObj):\r
2006\r
2007 if not self.__IsKeyword( "DATA"):\r
2008 raise Warning("expected Region Data type", self.FileName, self.CurrentLineNumber)\r
2009\r
2010 if not self.__IsToken( "="):\r
2011 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2012\r
2013 if not self.__IsToken( "{"):\r
2014 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2015\r
2016 if not self.__GetNextHexNumber():\r
2017 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)\r
2018\r
636f2be6
LG
2019 if len(self.__Token) > 18:\r
2020 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)\r
2021\r
2022 # convert hex string value to byte hex string array\r
2023 AllString = self.__Token\r
2024 AllStrLen = len (AllString)\r
2025 DataString = ""\r
2026 while AllStrLen > 4:\r
2027 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + ","\r
2028 AllStrLen = AllStrLen - 2\r
2029 DataString = DataString + AllString[:AllStrLen] + ","\r
2030\r
2031 # byte value array\r
2032 if len (self.__Token) <= 4:\r
2033 while self.__IsToken(","):\r
2034 if not self.__GetNextHexNumber():\r
2035 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)\r
2036 if len(self.__Token) > 4:\r
2037 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
2038 DataString += self.__Token\r
2039 DataString += ","\r
30fdf114
LG
2040\r
2041 if not self.__IsToken( "}"):\r
2042 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2043\r
2044 DataString = DataString.rstrip(",")\r
2045 RegionObj.RegionType = "DATA"\r
2046 RegionObj.RegionDataList.append( DataString)\r
2047\r
2048 while self.__IsKeyword( "DATA"):\r
2049\r
2050 if not self.__IsToken( "="):\r
2051 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2052\r
2053 if not self.__IsToken( "{"):\r
2054 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2055\r
2056 if not self.__GetNextHexNumber():\r
2057 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)\r
2058\r
636f2be6
LG
2059 if len(self.__Token) > 18:\r
2060 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)\r
2061\r
2062 # convert hex string value to byte hex string array\r
2063 AllString = self.__Token\r
2064 AllStrLen = len (AllString)\r
2065 DataString = ""\r
2066 while AllStrLen > 4:\r
2067 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + ","\r
2068 AllStrLen = AllStrLen - 2\r
2069 DataString = DataString + AllString[:AllStrLen] + ","\r
2070\r
2071 # byte value array\r
2072 if len (self.__Token) <= 4:\r
2073 while self.__IsToken(","):\r
2074 if not self.__GetNextHexNumber():\r
2075 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)\r
2076 if len(self.__Token) > 4:\r
2077 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
2078 DataString += self.__Token\r
2079 DataString += ","\r
30fdf114
LG
2080\r
2081 if not self.__IsToken( "}"):\r
2082 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2083\r
2084 DataString = DataString.rstrip(",")\r
2085 RegionObj.RegionDataList.append( DataString)\r
2086\r
2087 ## __GetFv() method\r
2088 #\r
2089 # Get FV section contents and store its data into FV dictionary of self.Profile\r
2090 #\r
2091 # @param self The object pointer\r
2092 # @retval True Successfully find a FV\r
2093 # @retval False Not able to find a FV\r
2094 #\r
2095 def __GetFv(self):\r
2096 if not self.__GetNextToken():\r
2097 return False\r
2098\r
2099 S = self.__Token.upper()\r
2100 if S.startswith("[") and not S.startswith("[FV."):\r
a3251d84 2101 if not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \\r
30fdf114
LG
2102 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):\r
2103 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
2104 self.__UndoToken()\r
2105 return False\r
2106\r
2107 self.__UndoToken()\r
2108 if not self.__IsToken("[FV.", True):\r
2109 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2110 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
2111 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
2112 raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
2113\r
2114 FvName = self.__GetUiName()\r
2115 self.CurrentFvName = FvName.upper()\r
2116\r
2117 if not self.__IsToken( "]"):\r
2118 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
2119\r
2120 FvObj = Fv.FV()\r
2121 FvObj.UiFvName = self.CurrentFvName\r
2122 self.Profile.FvDict[self.CurrentFvName] = FvObj\r
2123\r
2124 Status = self.__GetCreateFile(FvObj)\r
2125 if not Status:\r
2126 raise Warning("FV name error", self.FileName, self.CurrentLineNumber)\r
2127\r
2128 self.__GetDefineStatements(FvObj)\r
2129\r
2130 self.__GetAddressStatements(FvObj)\r
2131\r
b303ea72
LG
2132 FvObj.FvExtEntryTypeValue = []\r
2133 FvObj.FvExtEntryType = []\r
2134 FvObj.FvExtEntryData = []\r
2135 while True:\r
e8a47801
LG
2136 self.__GetSetStatements(FvObj)\r
2137\r
2138 if not (self.__GetBlockStatement(FvObj) or self.__GetFvBaseAddress(FvObj) or \r
2139 self.__GetFvForceRebase(FvObj) or self.__GetFvAlignment(FvObj) or \r
2140 self.__GetFvAttributes(FvObj) or self.__GetFvNameGuid(FvObj) or \r
aaf8aa7b 2141 self.__GetFvExtEntryStatement(FvObj) or self.__GetFvNameString(FvObj)):\r
b303ea72
LG
2142 break\r
2143\r
aaf8aa7b
YL
2144 if FvObj.FvNameString == 'TRUE' and not FvObj.FvNameGuid:\r
2145 raise Warning("FvNameString found but FvNameGuid was not found", self.FileName, self.CurrentLineNumber)\r
2146\r
30fdf114
LG
2147 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())\r
2148 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())\r
2149\r
2150 while True:\r
2151 isInf = self.__GetInfStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())\r
2152 isFile = self.__GetFileStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())\r
2153 if not isInf and not isFile:\r
2154 break\r
2155\r
2156 return True\r
2157\r
2158 ## __GetFvAlignment() method\r
2159 #\r
2160 # Get alignment for FV\r
2161 #\r
2162 # @param self The object pointer\r
2163 # @param Obj for whom alignment is got\r
2164 # @retval True Successfully find a alignment statement\r
2165 # @retval False Not able to find a alignment statement\r
2166 #\r
2167 def __GetFvAlignment(self, Obj):\r
2168\r
2169 if not self.__IsKeyword( "FvAlignment"):\r
2170 return False\r
2171\r
2172 if not self.__IsToken( "="):\r
2173 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2174\r
2175 if not self.__GetNextToken():\r
2176 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)\r
2177\r
2178 if self.__Token.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \\r
2179 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \\r
2180 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \\r
2181 "1G", "2G"):\r
2182 raise Warning("Unknown alignment value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
2183 Obj.FvAlignment = self.__Token\r
2184 return True\r
4234283c
LG
2185 \r
2186 ## __GetFvBaseAddress() method\r
2187 #\r
2188 # Get BaseAddress for FV\r
2189 #\r
2190 # @param self The object pointer\r
2191 # @param Obj for whom FvBaseAddress is got\r
2192 # @retval True Successfully find a FvBaseAddress statement\r
2193 # @retval False Not able to find a FvBaseAddress statement\r
2194 #\r
2195 def __GetFvBaseAddress(self, Obj):\r
2196\r
2197 if not self.__IsKeyword("FvBaseAddress"):\r
2198 return False\r
2199\r
2200 if not self.__IsToken( "="):\r
2201 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2202\r
2203 if not self.__GetNextToken():\r
2204 raise Warning("expected FV base address value", self.FileName, self.CurrentLineNumber)\r
2205\r
2206 IsValidBaseAddrValue = re.compile('^0[x|X][0-9a-fA-F]+')\r
2207\r
2208 if not IsValidBaseAddrValue.match(self.__Token.upper()):\r
79b74a03 2209 raise Warning("Unknown FV base address value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
4234283c 2210 Obj.FvBaseAddress = self.__Token\r
0d2711a6
LG
2211 return True \r
2212 \r
79b74a03
LG
2213 ## __GetFvForceRebase() method\r
2214 #\r
2215 # Get FvForceRebase for FV\r
2216 #\r
2217 # @param self The object pointer\r
2218 # @param Obj for whom FvForceRebase is got\r
2219 # @retval True Successfully find a FvForceRebase statement\r
2220 # @retval False Not able to find a FvForceRebase statement\r
2221 #\r
2222 def __GetFvForceRebase(self, Obj):\r
2223\r
2224 if not self.__IsKeyword("FvForceRebase"):\r
2225 return False\r
2226\r
2227 if not self.__IsToken( "="):\r
2228 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2229\r
2230 if not self.__GetNextToken():\r
2231 raise Warning("expected FvForceRebase value", self.FileName, self.CurrentLineNumber)\r
30fdf114 2232\r
79b74a03
LG
2233 if self.__Token.upper() not in ["TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"]:\r
2234 raise Warning("Unknown FvForceRebase value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
2235 \r
2236 if self.__Token.upper() in ["TRUE", "1", "0X1", "0X01"]:\r
2237 Obj.FvForceRebase = True\r
2238 elif self.__Token.upper() in ["FALSE", "0", "0X0", "0X00"]:\r
2239 Obj.FvForceRebase = False\r
2240 else:\r
2241 Obj.FvForceRebase = None\r
2242 \r
2243 return True\r
0d2711a6
LG
2244\r
2245\r
30fdf114
LG
2246 ## __GetFvAttributes() method\r
2247 #\r
2248 # Get attributes for FV\r
2249 #\r
2250 # @param self The object pointer\r
2251 # @param Obj for whom attribute is got\r
2252 # @retval None\r
2253 #\r
2254 def __GetFvAttributes(self, FvObj):\r
2bc3256c 2255 IsWordToken = False\r
30fdf114 2256 while self.__GetNextWord():\r
2bc3256c 2257 IsWordToken = True\r
30fdf114
LG
2258 name = self.__Token\r
2259 if name not in ("ERASE_POLARITY", "MEMORY_MAPPED", \\r
2260 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \\r
2261 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \\r
2262 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \\r
2263 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \\r
e8a47801 2264 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT"):\r
30fdf114 2265 self.__UndoToken()\r
e8a47801 2266 return False\r
30fdf114
LG
2267\r
2268 if not self.__IsToken( "="):\r
2269 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2270\r
2271 if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):\r
2272 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)\r
2273\r
2274 FvObj.FvAttributeDict[name] = self.__Token\r
2275\r
2bc3256c 2276 return IsWordToken\r
30fdf114
LG
2277 \r
2278 ## __GetFvNameGuid() method\r
2279 #\r
2280 # Get FV GUID for FV\r
2281 #\r
2282 # @param self The object pointer\r
2283 # @param Obj for whom GUID is got\r
2284 # @retval None\r
2285 #\r
2286 def __GetFvNameGuid(self, FvObj):\r
2287\r
2288 if not self.__IsKeyword( "FvNameGuid"):\r
e8a47801 2289 return False\r
30fdf114
LG
2290\r
2291 if not self.__IsToken( "="):\r
2292 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2293\r
2294 if not self.__GetNextGuid():\r
2295 raise Warning("expected FV GUID value", self.FileName, self.CurrentLineNumber)\r
2296\r
2297 FvObj.FvNameGuid = self.__Token\r
2298\r
e8a47801 2299 return True\r
30fdf114 2300\r
aaf8aa7b
YL
2301 def __GetFvNameString(self, FvObj):\r
2302\r
2303 if not self.__IsKeyword( "FvNameString"):\r
2304 return False\r
2305\r
2306 if not self.__IsToken( "="):\r
2307 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2308\r
2309 if not self.__GetNextToken() or self.__Token not in ('TRUE', 'FALSE'):\r
2310 raise Warning("expected TRUE or FALSE for FvNameString", self.FileName, self.CurrentLineNumber)\r
2311\r
2312 FvObj.FvNameString = self.__Token\r
2313\r
2314 return True\r
2315\r
b303ea72
LG
2316 def __GetFvExtEntryStatement(self, FvObj):\r
2317\r
2318 if not self.__IsKeyword( "FV_EXT_ENTRY"):\r
2319 return False\r
2320\r
2321 if not self.__IsKeyword ("TYPE"):\r
2322 raise Warning("expected 'TYPE'", self.FileName, self.CurrentLineNumber)\r
2323 \r
2324 if not self.__IsToken( "="):\r
2325 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2326\r
2327 if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():\r
2328 raise Warning("expected Hex FV extension entry type value At Line ", self.FileName, self.CurrentLineNumber)\r
2329\r
2330 FvObj.FvExtEntryTypeValue += [self.__Token]\r
2331\r
2332 if not self.__IsToken( "{"):\r
2333 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2334\r
2335 if not self.__IsKeyword ("FILE") and not self.__IsKeyword ("DATA"):\r
2336 raise Warning("expected 'FILE' or 'DATA'", self.FileName, self.CurrentLineNumber)\r
2337\r
2338 FvObj.FvExtEntryType += [self.__Token]\r
2339\r
2340 if self.__Token == 'DATA':\r
2341\r
2342 if not self.__IsToken( "="):\r
2343 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2344 \r
2345 if not self.__IsToken( "{"):\r
2346 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2347\r
2348 if not self.__GetNextHexNumber():\r
2349 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)\r
2350\r
2351 if len(self.__Token) > 4:\r
2352 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
2353\r
2354 DataString = self.__Token\r
2355 DataString += ","\r
2356\r
2357 while self.__IsToken(","):\r
2358 if not self.__GetNextHexNumber():\r
2359 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)\r
2360 if len(self.__Token) > 4:\r
2361 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
2362 DataString += self.__Token\r
2363 DataString += ","\r
2364\r
2365 if not self.__IsToken( "}"):\r
2366 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2367\r
2368 if not self.__IsToken( "}"):\r
2369 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2370\r
2371 DataString = DataString.rstrip(",")\r
2372 FvObj.FvExtEntryData += [DataString]\r
2373\r
2374 if self.__Token == 'FILE':\r
2375 \r
2376 if not self.__IsToken( "="):\r
2377 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2378 \r
2379 if not self.__GetNextToken():\r
2380 raise Warning("expected FV Extension Entry file path At Line ", self.FileName, self.CurrentLineNumber)\r
2381 \r
2382 FvObj.FvExtEntryData += [self.__Token]\r
2383\r
2384 if not self.__IsToken( "}"):\r
2385 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2386\r
2387 return True\r
2388\r
30fdf114
LG
2389 ## __GetAprioriSection() method\r
2390 #\r
2391 # Get token statements\r
2392 #\r
2393 # @param self The object pointer\r
2394 # @param FvObj for whom apriori is got\r
2395 # @param MacroDict dictionary used to replace macro\r
2396 # @retval True Successfully find apriori statement\r
2397 # @retval False Not able to find apriori statement\r
2398 #\r
2399 def __GetAprioriSection(self, FvObj, MacroDict = {}):\r
2400\r
2401 if not self.__IsKeyword( "APRIORI"):\r
2402 return False\r
2403\r
2404 if not self.__IsKeyword("PEI") and not self.__IsKeyword("DXE"):\r
2405 raise Warning("expected Apriori file type", self.FileName, self.CurrentLineNumber)\r
2406 AprType = self.__Token\r
2407\r
2408 if not self.__IsToken( "{"):\r
2409 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2410\r
2411 AprSectionObj = AprioriSection.AprioriSection()\r
2412 AprSectionObj.AprioriType = AprType\r
2413\r
2414 self.__GetDefineStatements(AprSectionObj)\r
2415 MacroDict.update(AprSectionObj.DefineVarDict)\r
2416\r
2417 while True:\r
2418 IsInf = self.__GetInfStatement( AprSectionObj, MacroDict = MacroDict)\r
2419 IsFile = self.__GetFileStatement( AprSectionObj)\r
2420 if not IsInf and not IsFile:\r
2421 break\r
2422\r
2423 if not self.__IsToken( "}"):\r
2424 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2425\r
2426 FvObj.AprioriSectionList.append(AprSectionObj)\r
2427 return True\r
2428\r
2429 ## __GetInfStatement() method\r
2430 #\r
2431 # Get INF statements\r
2432 #\r
2433 # @param self The object pointer\r
2434 # @param Obj for whom inf statement is got\r
2435 # @param MacroDict dictionary used to replace macro\r
2436 # @retval True Successfully find inf statement\r
2437 # @retval False Not able to find inf statement\r
2438 #\r
2439 def __GetInfStatement(self, Obj, ForCapsule = False, MacroDict = {}):\r
2440\r
2441 if not self.__IsKeyword( "INF"):\r
2442 return False\r
2443\r
2444 ffsInf = FfsInfStatement.FfsInfStatement()\r
2445 self.__GetInfOptions( ffsInf)\r
2446\r
2447 if not self.__GetNextToken():\r
2448 raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)\r
2449 ffsInf.InfFileName = self.__Token\r
64b2609f
LG
2450\r
2451 ffsInf.CurrentLineNum = self.CurrentLineNumber\r
2452 ffsInf.CurrentLineContent = self.__CurrentLine()\r
2453\r
97fa0ee9
YL
2454 #Replace $(SAPCE) with real space\r
2455 ffsInf.InfFileName = ffsInf.InfFileName.replace('$(SPACE)', ' ')\r
2456\r
14c48571 2457 if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:\r
2458 #do case sensitive check for file path\r
2459 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
2460 if ErrorCode != 0:\r
2461 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114 2462\r
30fdf114
LG
2463 if not ffsInf.InfFileName in self.Profile.InfList:\r
2464 self.Profile.InfList.append(ffsInf.InfFileName)\r
d0acc87a
LG
2465 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2466 self.Profile.InfFileLineList.append(FileLineTuple)\r
30fdf114
LG
2467\r
2468 if self.__IsToken('|'):\r
2469 if self.__IsKeyword('RELOCS_STRIPPED'):\r
2470 ffsInf.KeepReloc = False\r
2471 elif self.__IsKeyword('RELOCS_RETAINED'):\r
2472 ffsInf.KeepReloc = True\r
2473 else:\r
2474 raise Warning("Unknown reloc strip flag '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
79b74a03 2475 \r
30fdf114
LG
2476 if ForCapsule:\r
2477 capsuleFfs = CapsuleData.CapsuleFfs()\r
2478 capsuleFfs.Ffs = ffsInf\r
2479 Obj.CapsuleDataList.append(capsuleFfs)\r
2480 else:\r
2481 Obj.FfsList.append(ffsInf)\r
2482 return True\r
2483\r
2484 ## __GetInfOptions() method\r
2485 #\r
2486 # Get options for INF\r
2487 #\r
2488 # @param self The object pointer\r
2489 # @param FfsInfObj for whom option is got\r
2490 #\r
2491 def __GetInfOptions(self, FfsInfObj):\r
97fa0ee9
YL
2492 if self.__IsKeyword("FILE_GUID"):\r
2493 if not self.__IsToken("="):\r
2494 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2495 if not self.__GetNextGuid():\r
2496 raise Warning("expected GUID value", self.FileName, self.CurrentLineNumber)\r
2497 FfsInfObj.OverrideGuid = self.__Token\r
30fdf114
LG
2498\r
2499 if self.__IsKeyword( "RuleOverride"):\r
2500 if not self.__IsToken( "="):\r
2501 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2502 if not self.__GetNextToken():\r
2503 raise Warning("expected Rule name", self.FileName, self.CurrentLineNumber)\r
2504 FfsInfObj.Rule = self.__Token\r
2505\r
2506 if self.__IsKeyword( "VERSION"):\r
2507 if not self.__IsToken( "="):\r
2508 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2509 if not self.__GetNextToken():\r
2510 raise Warning("expected Version", self.FileName, self.CurrentLineNumber)\r
2511\r
2512 if self.__GetStringData():\r
2513 FfsInfObj.Version = self.__Token\r
2514\r
2515 if self.__IsKeyword( "UI"):\r
2516 if not self.__IsToken( "="):\r
2517 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2518 if not self.__GetNextToken():\r
2519 raise Warning("expected UI name", self.FileName, self.CurrentLineNumber)\r
2520\r
2521 if self.__GetStringData():\r
2522 FfsInfObj.Ui = self.__Token\r
2523\r
2524 if self.__IsKeyword( "USE"):\r
2525 if not self.__IsToken( "="):\r
2526 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2527 if not self.__GetNextToken():\r
2528 raise Warning("expected ARCH name", self.FileName, self.CurrentLineNumber)\r
2529 FfsInfObj.UseArch = self.__Token\r
2530\r
2531 \r
2532 if self.__GetNextToken():\r
97fa0ee9
YL
2533 p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')\r
2534 if p.match(self.__Token) and p.match(self.__Token).span()[1] == len(self.__Token):\r
30fdf114
LG
2535 FfsInfObj.KeyStringList.append(self.__Token)\r
2536 if not self.__IsToken(","):\r
2537 return\r
2538 else:\r
2539 self.__UndoToken()\r
2540 return\r
2541\r
2542 while self.__GetNextToken():\r
2543 if not p.match(self.__Token):\r
2544 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
2545 FfsInfObj.KeyStringList.append(self.__Token)\r
2546\r
2547 if not self.__IsToken(","):\r
2548 break\r
2549\r
2550 ## __GetFileStatement() method\r
2551 #\r
2552 # Get FILE statements\r
2553 #\r
2554 # @param self The object pointer\r
2555 # @param Obj for whom FILE statement is got\r
2556 # @param MacroDict dictionary used to replace macro\r
2557 # @retval True Successfully find FILE statement\r
2558 # @retval False Not able to find FILE statement\r
2559 #\r
2560 def __GetFileStatement(self, Obj, ForCapsule = False, MacroDict = {}):\r
2561\r
2562 if not self.__IsKeyword( "FILE"):\r
2563 return False\r
2564\r
30fdf114
LG
2565 if not self.__GetNextWord():\r
2566 raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)\r
b36d134f
LG
2567\r
2568 if ForCapsule and self.__Token == 'DATA':\r
2569 self.__UndoToken()\r
2570 self.__UndoToken()\r
2571 return False\r
2572 \r
2573 FfsFileObj = FfsFileStatement.FileStatement()\r
30fdf114
LG
2574 FfsFileObj.FvFileType = self.__Token\r
2575\r
2576 if not self.__IsToken( "="):\r
2577 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2578\r
2579 if not self.__GetNextGuid():\r
2580 if not self.__GetNextWord():\r
2581 raise Warning("expected File GUID", self.FileName, self.CurrentLineNumber)\r
2582 if self.__Token == 'PCD':\r
2583 if not self.__IsToken( "("):\r
2584 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)\r
2585 PcdPair = self.__GetNextPcdName()\r
2586 if not self.__IsToken( ")"):\r
2587 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)\r
2588 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'\r
2589 \r
2590 FfsFileObj.NameGuid = self.__Token\r
79b74a03 2591 \r
30fdf114
LG
2592 self.__GetFilePart( FfsFileObj, MacroDict.copy())\r
2593\r
2594 if ForCapsule:\r
2595 capsuleFfs = CapsuleData.CapsuleFfs()\r
2596 capsuleFfs.Ffs = FfsFileObj\r
2597 Obj.CapsuleDataList.append(capsuleFfs)\r
2598 else:\r
2599 Obj.FfsList.append(FfsFileObj)\r
2600\r
2601 return True\r
2602\r
2603 ## __FileCouldHaveRelocFlag() method\r
2604 #\r
2605 # Check whether reloc strip flag can be set for a file type.\r
2606 #\r
2607 # @param self The object pointer\r
2608 # @param FileType The file type to check with\r
2609 # @retval True This type could have relocation strip flag\r
2610 # @retval False No way to have it\r
2611 #\r
2612\r
2613 def __FileCouldHaveRelocFlag (self, FileType):\r
2614 if FileType in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'):\r
2615 return True\r
2616 else:\r
2617 return False\r
2618\r
2619 ## __SectionCouldHaveRelocFlag() method\r
2620 #\r
2621 # Check whether reloc strip flag can be set for a section type.\r
2622 #\r
2623 # @param self The object pointer\r
2624 # @param SectionType The section type to check with\r
2625 # @retval True This type could have relocation strip flag\r
2626 # @retval False No way to have it\r
2627 #\r
2628\r
2629 def __SectionCouldHaveRelocFlag (self, SectionType):\r
2630 if SectionType in ('TE', 'PE32'):\r
2631 return True\r
2632 else:\r
2633 return False\r
2634\r
2635 ## __GetFilePart() method\r
2636 #\r
2637 # Get components for FILE statement\r
2638 #\r
2639 # @param self The object pointer\r
2640 # @param FfsFileObj for whom component is got\r
2641 # @param MacroDict dictionary used to replace macro\r
2642 #\r
2643 def __GetFilePart(self, FfsFileObj, MacroDict = {}):\r
2644\r
2645 self.__GetFileOpts( FfsFileObj)\r
2646\r
2647 if not self.__IsToken("{"):\r
4afd3d04
LG
2648 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):\r
2649 if self.__FileCouldHaveRelocFlag(FfsFileObj.FvFileType):\r
2650 if self.__Token == 'RELOCS_STRIPPED':\r
2651 FfsFileObj.KeepReloc = False\r
2652 else:\r
2653 FfsFileObj.KeepReloc = True\r
2654 else:\r
2655 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
2656\r
2657 if not self.__IsToken("{"):\r
30fdf114
LG
2658 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2659\r
2660 if not self.__GetNextToken():\r
2661 raise Warning("expected File name or section data", self.FileName, self.CurrentLineNumber)\r
2662\r
2663 if self.__Token == "FV":\r
2664 if not self.__IsToken( "="):\r
2665 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2666 if not self.__GetNextToken():\r
2667 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)\r
2668 FfsFileObj.FvName = self.__Token\r
2669\r
2670 elif self.__Token == "FD":\r
2671 if not self.__IsToken( "="):\r
2672 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2673 if not self.__GetNextToken():\r
2674 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)\r
2675 FfsFileObj.FdName = self.__Token\r
2676\r
2677 elif self.__Token in ("DEFINE", "APRIORI", "SECTION"):\r
2678 self.__UndoToken()\r
2679 self.__GetSectionData( FfsFileObj, MacroDict)\r
2680 else:\r
64b2609f
LG
2681 FfsFileObj.CurrentLineNum = self.CurrentLineNumber\r
2682 FfsFileObj.CurrentLineContent = self.__CurrentLine()\r
97fa0ee9 2683 FfsFileObj.FileName = self.__Token.replace('$(SPACE)', ' ')\r
2bc3256c 2684 self.__VerifyFile(FfsFileObj.FileName)\r
0d2711a6 2685\r
30fdf114
LG
2686 if not self.__IsToken( "}"):\r
2687 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2688\r
2689 ## __GetFileOpts() method\r
2690 #\r
2691 # Get options for FILE statement\r
2692 #\r
2693 # @param self The object pointer\r
2694 # @param FfsFileObj for whom options is got\r
2695 #\r
2696 def __GetFileOpts(self, FfsFileObj):\r
2697\r
2698 if self.__GetNextToken():\r
2699 Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')\r
2700 if Pattern.match(self.__Token):\r
2701 FfsFileObj.KeyStringList.append(self.__Token)\r
2702 if self.__IsToken(","):\r
2703 while self.__GetNextToken():\r
2704 if not Pattern.match(self.__Token):\r
2705 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
2706 FfsFileObj.KeyStringList.append(self.__Token)\r
2707\r
2708 if not self.__IsToken(","):\r
2709 break\r
2710\r
2711 else:\r
2712 self.__UndoToken()\r
2713\r
2714 if self.__IsKeyword( "FIXED", True):\r
2715 FfsFileObj.Fixed = True\r
2716\r
2717 if self.__IsKeyword( "CHECKSUM", True):\r
2718 FfsFileObj.CheckSum = True\r
2719\r
2720 if self.__GetAlignment():\r
9053bc51 2721 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):\r
2722 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
2723 #For FFS, Auto is default option same to ""\r
2724 if not self.__Token == "Auto":\r
2725 FfsFileObj.Alignment = self.__Token\r
30fdf114
LG
2726\r
2727 ## __GetAlignment() method\r
2728 #\r
2729 # Return the alignment value\r
2730 #\r
2731 # @param self The object pointer\r
2732 # @retval True Successfully find alignment\r
2733 # @retval False Not able to find alignment\r
2734 #\r
2735 def __GetAlignment(self):\r
2736 if self.__IsKeyword( "Align", True):\r
2737 if not self.__IsToken( "="):\r
2738 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2739\r
2740 if not self.__GetNextToken():\r
2741 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)\r
2742 return True\r
2743\r
2744 return False\r
2745\r
2746 ## __GetFilePart() method\r
2747 #\r
2748 # Get section data for FILE statement\r
2749 #\r
2750 # @param self The object pointer\r
2751 # @param FfsFileObj for whom section is got\r
2752 # @param MacroDict dictionary used to replace macro\r
2753 #\r
2754 def __GetSectionData(self, FfsFileObj, MacroDict = {}):\r
2755 Dict = {}\r
2756 Dict.update(MacroDict)\r
2757\r
2758 self.__GetDefineStatements(FfsFileObj)\r
2759\r
2760 Dict.update(FfsFileObj.DefineVarDict)\r
2761 self.__GetAprioriSection(FfsFileObj, Dict.copy())\r
2762 self.__GetAprioriSection(FfsFileObj, Dict.copy())\r
2763\r
2764 while True:\r
2765 IsLeafSection = self.__GetLeafSection(FfsFileObj, Dict)\r
2766 IsEncapSection = self.__GetEncapsulationSec(FfsFileObj)\r
2767 if not IsLeafSection and not IsEncapSection:\r
2768 break\r
2769\r
2770 ## __GetLeafSection() method\r
2771 #\r
2772 # Get leaf section for Obj\r
2773 #\r
2774 # @param self The object pointer\r
2775 # @param Obj for whom leaf section is got\r
2776 # @param MacroDict dictionary used to replace macro\r
2777 # @retval True Successfully find section statement\r
2778 # @retval False Not able to find section statement\r
2779 #\r
2780 def __GetLeafSection(self, Obj, MacroDict = {}):\r
2781\r
2782 OldPos = self.GetFileBufferPos()\r
2783\r
2784 if not self.__IsKeyword( "SECTION"):\r
2785 if len(Obj.SectionList) == 0:\r
2786 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)\r
2787 else:\r
2788 return False\r
2789\r
2790 AlignValue = None\r
2791 if self.__GetAlignment():\r
52302d4d
LG
2792 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):\r
2793 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2794 AlignValue = self.__Token\r
2795\r
2796 BuildNum = None\r
2797 if self.__IsKeyword( "BUILD_NUM"):\r
2798 if not self.__IsToken( "="):\r
2799 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2800\r
2801 if not self.__GetNextToken():\r
2802 raise Warning("expected Build number value", self.FileName, self.CurrentLineNumber)\r
2803\r
2804 BuildNum = self.__Token\r
2805\r
2806 if self.__IsKeyword( "VERSION"):\r
52302d4d
LG
2807 if AlignValue == 'Auto':\r
2808 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2809 if not self.__IsToken( "="):\r
2810 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2811 if not self.__GetNextToken():\r
2812 raise Warning("expected version", self.FileName, self.CurrentLineNumber)\r
2813 VerSectionObj = VerSection.VerSection()\r
2814 VerSectionObj.Alignment = AlignValue\r
2815 VerSectionObj.BuildNum = BuildNum\r
2816 if self.__GetStringData():\r
2817 VerSectionObj.StringData = self.__Token\r
2818 else:\r
2819 VerSectionObj.FileName = self.__Token\r
2820 Obj.SectionList.append(VerSectionObj)\r
52302d4d 2821 \r
30fdf114 2822 elif self.__IsKeyword( "UI"):\r
52302d4d
LG
2823 if AlignValue == 'Auto':\r
2824 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2825 if not self.__IsToken( "="):\r
2826 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2827 if not self.__GetNextToken():\r
2828 raise Warning("expected UI", self.FileName, self.CurrentLineNumber)\r
2829 UiSectionObj = UiSection.UiSection()\r
2830 UiSectionObj.Alignment = AlignValue\r
2831 if self.__GetStringData():\r
2832 UiSectionObj.StringData = self.__Token\r
2833 else:\r
2834 UiSectionObj.FileName = self.__Token\r
2835 Obj.SectionList.append(UiSectionObj)\r
2836\r
2837 elif self.__IsKeyword( "FV_IMAGE"):\r
52302d4d
LG
2838 if AlignValue == 'Auto':\r
2839 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2840 if not self.__IsToken( "="):\r
2841 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2842 if not self.__GetNextToken():\r
2843 raise Warning("expected FV name or FV file path", self.FileName, self.CurrentLineNumber)\r
2844\r
2845 FvName = self.__Token\r
2846 FvObj = None\r
2847\r
2848 if self.__IsToken( "{"):\r
2849 FvObj = Fv.FV()\r
2850 FvObj.UiFvName = FvName.upper()\r
2851 self.__GetDefineStatements(FvObj)\r
2852 MacroDict.update(FvObj.DefineVarDict)\r
2853 self.__GetBlockStatement(FvObj)\r
2854 self.__GetSetStatements(FvObj)\r
2855 self.__GetFvAlignment(FvObj)\r
2856 self.__GetFvAttributes(FvObj)\r
2857 self.__GetAprioriSection(FvObj, MacroDict.copy())\r
2858 self.__GetAprioriSection(FvObj, MacroDict.copy())\r
2859\r
2860 while True:\r
2861 IsInf = self.__GetInfStatement(FvObj, MacroDict.copy())\r
2862 IsFile = self.__GetFileStatement(FvObj, MacroDict.copy())\r
2863 if not IsInf and not IsFile:\r
2864 break\r
2865\r
2866 if not self.__IsToken( "}"):\r
2867 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2868\r
2869 FvImageSectionObj = FvImageSection.FvImageSection()\r
2870 FvImageSectionObj.Alignment = AlignValue\r
2871 if FvObj != None:\r
2872 FvImageSectionObj.Fv = FvObj\r
2873 FvImageSectionObj.FvName = None\r
2874 else:\r
2875 FvImageSectionObj.FvName = FvName.upper()\r
2876 FvImageSectionObj.FvFileName = FvName\r
2877\r
2878 Obj.SectionList.append(FvImageSectionObj)\r
2879\r
2880 elif self.__IsKeyword("PEI_DEPEX_EXP") or self.__IsKeyword("DXE_DEPEX_EXP") or self.__IsKeyword("SMM_DEPEX_EXP"):\r
52302d4d
LG
2881 if AlignValue == 'Auto':\r
2882 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2883 DepexSectionObj = DepexSection.DepexSection()\r
2884 DepexSectionObj.Alignment = AlignValue\r
2885 DepexSectionObj.DepexType = self.__Token\r
2886\r
2887 if not self.__IsToken( "="):\r
2888 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2889 if not self.__IsToken( "{"):\r
2890 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2891 if not self.__SkipToToken( "}"):\r
2892 raise Warning("expected Depex expression ending '}'", self.FileName, self.CurrentLineNumber)\r
2893\r
2894 DepexSectionObj.Expression = self.__SkippedChars.rstrip('}')\r
2895 Obj.SectionList.append(DepexSectionObj)\r
2896\r
2897 else:\r
30fdf114
LG
2898 if not self.__GetNextWord():\r
2899 raise Warning("expected section type", self.FileName, self.CurrentLineNumber)\r
2900\r
2901 # Encapsulation section appear, UndoToken and return\r
2902 if self.__Token == "COMPRESS" or self.__Token == "GUIDED":\r
2903 self.SetFileBufferPos(OldPos)\r
2904 return False\r
2905\r
2906 if self.__Token not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\\r
2907 "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"):\r
2908 raise Warning("Unknown section type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
52302d4d
LG
2909 if AlignValue == 'Auto'and (not self.__Token == 'PE32') and (not self.__Token == 'TE'):\r
2910 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
2911\r
30fdf114
LG
2912 # DataSection\r
2913 DataSectionObj = DataSection.DataSection()\r
2914 DataSectionObj.Alignment = AlignValue\r
2915 DataSectionObj.SecType = self.__Token\r
2916\r
2917 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):\r
2918 if self.__FileCouldHaveRelocFlag(Obj.FvFileType) and self.__SectionCouldHaveRelocFlag(DataSectionObj.SecType):\r
2919 if self.__Token == 'RELOCS_STRIPPED':\r
2920 DataSectionObj.KeepReloc = False\r
2921 else:\r
2922 DataSectionObj.KeepReloc = True\r
2923 else:\r
2924 raise Warning("File type %s, section type %s, could not have reloc strip flag%d" % (Obj.FvFileType, DataSectionObj.SecType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
2925\r
2926 if self.__IsToken("="):\r
2927 if not self.__GetNextToken():\r
2928 raise Warning("expected section file path", self.FileName, self.CurrentLineNumber)\r
2929 DataSectionObj.SectFileName = self.__Token\r
2bc3256c 2930 self.__VerifyFile(DataSectionObj.SectFileName)\r
30fdf114
LG
2931 else:\r
2932 if not self.__GetCglSection(DataSectionObj):\r
2933 return False\r
2934\r
2935 Obj.SectionList.append(DataSectionObj)\r
2936\r
2937 return True\r
2938\r
2bc3256c
LG
2939 ## __VerifyFile\r
2940 #\r
2941 # Check if file exists or not:\r
2942 # If current phase if GenFds, the file must exist;\r
2943 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist\r
2944 # @param FileName: File path to be verified.\r
2945 #\r
2946 def __VerifyFile(self, FileName):\r
2947 if FileName.replace('$(WORKSPACE)', '').find('$') != -1:\r
2948 return\r
2949 if not GlobalData.gAutoGenPhase or not self.__GetMacroValue("OUTPUT_DIRECTORY") in FileName:\r
2950 ErrorCode, ErrorInfo = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
2951 if ErrorCode != 0:\r
2952 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
2953\r
30fdf114
LG
2954 ## __GetCglSection() method\r
2955 #\r
2956 # Get compressed or GUIDed section for Obj\r
2957 #\r
2958 # @param self The object pointer\r
2959 # @param Obj for whom leaf section is got\r
2960 # @param AlignValue alignment value for complex section\r
2961 # @retval True Successfully find section statement\r
2962 # @retval False Not able to find section statement\r
2963 #\r
2964 def __GetCglSection(self, Obj, AlignValue = None):\r
2965\r
2966 if self.__IsKeyword( "COMPRESS"):\r
2967 type = "PI_STD"\r
2968 if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):\r
2969 type = self.__Token\r
2970\r
2971 if not self.__IsToken("{"):\r
2972 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2973\r
2974 CompressSectionObj = CompressSection.CompressSection()\r
2975 CompressSectionObj.Alignment = AlignValue\r
2976 CompressSectionObj.CompType = type\r
2977 # Recursive sections...\r
2978 while True:\r
2979 IsLeafSection = self.__GetLeafSection(CompressSectionObj)\r
2980 IsEncapSection = self.__GetEncapsulationSec(CompressSectionObj)\r
2981 if not IsLeafSection and not IsEncapSection:\r
2982 break\r
2983\r
2984\r
2985 if not self.__IsToken( "}"):\r
2986 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2987 Obj.SectionList.append(CompressSectionObj)\r
2988\r
2989# else:\r
2990# raise Warning("Compress type not known")\r
2991\r
2992 return True\r
2993\r
2994 elif self.__IsKeyword( "GUIDED"):\r
2995 GuidValue = None\r
2996 if self.__GetNextGuid():\r
2997 GuidValue = self.__Token\r
2998\r
2999 AttribDict = self.__GetGuidAttrib()\r
3000 if not self.__IsToken("{"):\r
3001 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
3002 GuidSectionObj = GuidSection.GuidSection()\r
3003 GuidSectionObj.Alignment = AlignValue\r
3004 GuidSectionObj.NameGuid = GuidValue\r
3005 GuidSectionObj.SectionType = "GUIDED"\r
3006 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]\r
3007 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]\r
25918452 3008 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]\r
30fdf114
LG
3009 # Recursive sections...\r
3010 while True:\r
3011 IsLeafSection = self.__GetLeafSection(GuidSectionObj)\r
3012 IsEncapSection = self.__GetEncapsulationSec(GuidSectionObj)\r
3013 if not IsLeafSection and not IsEncapSection:\r
3014 break\r
3015\r
3016 if not self.__IsToken( "}"):\r
3017 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
3018 Obj.SectionList.append(GuidSectionObj)\r
3019\r
3020 return True\r
3021\r
3022 return False\r
3023\r
3024 ## __GetGuidAttri() method\r
3025 #\r
3026 # Get attributes for GUID section\r
3027 #\r
3028 # @param self The object pointer\r
3029 # @retval AttribDict Dictionary of key-value pair of section attributes\r
3030 #\r
3031 def __GetGuidAttrib(self):\r
3032\r
3033 AttribDict = {}\r
14c48571 3034 AttribDict["PROCESSING_REQUIRED"] = "NONE"\r
3035 AttribDict["AUTH_STATUS_VALID"] = "NONE"\r
25918452
LG
3036 AttribDict["EXTRA_HEADER_SIZE"] = -1\r
3037 while self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID") \\r
3038 or self.__IsKeyword("EXTRA_HEADER_SIZE"):\r
30fdf114
LG
3039 AttribKey = self.__Token\r
3040\r
3041 if not self.__IsToken("="):\r
3042 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3043\r
25918452
LG
3044 if not self.__GetNextToken():\r
3045 raise Warning("expected TRUE(1)/FALSE(0)/Number", self.FileName, self.CurrentLineNumber)\r
3046 elif AttribKey == "EXTRA_HEADER_SIZE":\r
3047 Base = 10\r
3048 if self.__Token[0:2].upper() == "0X":\r
3049 Base = 16\r
3050 try:\r
3051 AttribDict[AttribKey] = int(self.__Token, Base)\r
3052 continue\r
3053 except ValueError:\r
3054 raise Warning("expected Number", self.FileName, self.CurrentLineNumber)\r
3055 elif self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):\r
30fdf114
LG
3056 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)\r
3057 AttribDict[AttribKey] = self.__Token\r
3058\r
3059 return AttribDict\r
3060\r
3061 ## __GetEncapsulationSec() method\r
3062 #\r
3063 # Get encapsulation section for FILE\r
3064 #\r
3065 # @param self The object pointer\r
3066 # @param FfsFile for whom section is got\r
3067 # @retval True Successfully find section statement\r
3068 # @retval False Not able to find section statement\r
3069 #\r
3070 def __GetEncapsulationSec(self, FfsFileObj):\r
3071\r
3072 OldPos = self.GetFileBufferPos()\r
3073 if not self.__IsKeyword( "SECTION"):\r
3074 if len(FfsFileObj.SectionList) == 0:\r
3075 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)\r
3076 else:\r
3077 return False\r
3078\r
3079 AlignValue = None\r
3080 if self.__GetAlignment():\r
52302d4d
LG
3081 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):\r
3082 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3083 AlignValue = self.__Token\r
3084\r
3085 if not self.__GetCglSection(FfsFileObj, AlignValue):\r
3086 self.SetFileBufferPos(OldPos)\r
3087 return False\r
3088 else:\r
3089 return True\r
3090\r
a3251d84
YL
3091 def __GetFmp(self):\r
3092 if not self.__GetNextToken():\r
3093 return False\r
3094 S = self.__Token.upper()\r
3095 if not S.startswith("[FMPPAYLOAD."):\r
3096 if not S.startswith("[CAPSULE.") and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):\r
3097 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [FmpPayload.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)\r
3098 self.__UndoToken()\r
3099 return False\r
3100\r
3101 self.__UndoToken()\r
3102 self.__SkipToToken("[FMPPAYLOAD.", True)\r
3103 FmpUiName = self.__GetUiName().upper()\r
3104 if FmpUiName in self.Profile.FmpPayloadDict:\r
3105 raise Warning("Duplicated FMP UI name found: %s" % FmpUiName, self.FileName, self.CurrentLineNumber)\r
3106\r
3107 FmpData = CapsuleData.CapsulePayload()\r
3108 FmpData.UiName = FmpUiName\r
3109\r
3110 if not self.__IsToken( "]"):\r
3111 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
3112\r
3113 if not self.__GetNextToken():\r
3114 raise Warning("The FMP payload section is empty!", self.FileName, self.CurrentLineNumber)\r
3115 FmpKeyList = ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE']\r
3116 while self.__Token in FmpKeyList:\r
3117 Name = self.__Token\r
3118 FmpKeyList.remove(Name)\r
3119 if not self.__IsToken("="):\r
3120 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3121 if Name == 'IMAGE_TYPE_ID':\r
3122 if not self.__GetNextGuid():\r
3123 raise Warning("expected GUID value for IMAGE_TYPE_ID", self.FileName, self.CurrentLineNumber)\r
3124 FmpData.ImageTypeId = self.__Token\r
3125 else:\r
3126 if not self.__GetNextToken():\r
3127 raise Warning("expected value of %s" % Name, self.FileName, self.CurrentLineNumber)\r
3128 Value = self.__Token\r
3129 if Name == 'IMAGE_HEADER_INIT_VERSION':\r
3130 FmpData.Version = Value\r
3131 elif Name == 'IMAGE_INDEX':\r
3132 FmpData.ImageIndex = Value\r
3133 elif Name == 'HARDWARE_INSTANCE':\r
3134 FmpData.HardwareInstance = Value\r
3135 if not self.__GetNextToken():\r
3136 break\r
3137 else:\r
3138 self.__UndoToken()\r
3139\r
3140 if FmpKeyList:\r
3141 raise Warning("Missing keywords %s in FMP payload section" % ', '.join(FmpKeyList), self.FileName, self.CurrentLineNumber)\r
3142 ImageFile = self.__ParseRawFileStatement()\r
3143 if not ImageFile:\r
3144 raise Warning("Missing image file in FMP payload section", self.FileName, self.CurrentLineNumber)\r
3145 FmpData.ImageFile = ImageFile\r
3146 VendorCodeFile = self.__ParseRawFileStatement()\r
3147 if VendorCodeFile:\r
3148 FmpData.VendorCodeFile = VendorCodeFile\r
3149 self.Profile.FmpPayloadDict[FmpUiName] = FmpData\r
3150 return True\r
3151\r
30fdf114
LG
3152 ## __GetCapsule() method\r
3153 #\r
3154 # Get capsule section contents and store its data into capsule list of self.Profile\r
3155 #\r
3156 # @param self The object pointer\r
3157 # @retval True Successfully find a capsule\r
3158 # @retval False Not able to find a capsule\r
3159 #\r
3160 def __GetCapsule(self):\r
3161\r
3162 if not self.__GetNextToken():\r
3163 return False\r
3164\r
3165 S = self.__Token.upper()\r
3166 if S.startswith("[") and not S.startswith("[CAPSULE."):\r
3167 if not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):\r
3168 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
3169 self.__UndoToken()\r
3170 return False\r
3171\r
3172 self.__UndoToken()\r
3173 if not self.__IsToken("[CAPSULE.", True):\r
3174 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
3175 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
3176 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
3177 raise Warning("expected [Capsule.]", self.FileName, self.CurrentLineNumber)\r
3178\r
3179 CapsuleObj = Capsule.Capsule()\r
3180\r
3181 CapsuleName = self.__GetUiName()\r
3182 if not CapsuleName:\r
3183 raise Warning("expected capsule name", self.FileName, self.CurrentLineNumber)\r
3184\r
3185 CapsuleObj.UiCapsuleName = CapsuleName.upper()\r
3186\r
3187 if not self.__IsToken( "]"):\r
3188 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
3189\r
3190 if self.__IsKeyword("CREATE_FILE"):\r
3191 if not self.__IsToken( "="):\r
3192 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3193\r
3194 if not self.__GetNextToken():\r
3195 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)\r
3196\r
3197 CapsuleObj.CreateFile = self.__Token\r
3198\r
3199 self.__GetCapsuleStatements(CapsuleObj)\r
fd171542 3200 self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj\r
30fdf114
LG
3201 return True\r
3202\r
3203 ## __GetCapsuleStatements() method\r
3204 #\r
3205 # Get statements for capsule\r
3206 #\r
3207 # @param self The object pointer\r
3208 # @param Obj for whom statements are got\r
3209 #\r
3210 def __GetCapsuleStatements(self, Obj):\r
3211 self.__GetCapsuleTokens(Obj)\r
3212 self.__GetDefineStatements(Obj)\r
3213 self.__GetSetStatements(Obj)\r
30fdf114
LG
3214 self.__GetCapsuleData(Obj)\r
3215\r
fd171542 3216 ## __GetCapsuleTokens() method\r
30fdf114
LG
3217 #\r
3218 # Get token statements for capsule\r
3219 #\r
3220 # @param self The object pointer\r
3221 # @param Obj for whom token statements are got\r
3222 #\r
3223 def __GetCapsuleTokens(self, Obj):\r
b303ea72
LG
3224 if not self.__GetNextToken():\r
3225 return False\r
a3251d84 3226 while self.__Token in ("CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"):\r
b303ea72
LG
3227 Name = self.__Token.strip()\r
3228 if not self.__IsToken("="):\r
3229 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3230 if not self.__GetNextToken():\r
3231 raise Warning("expected value", self.FileName, self.CurrentLineNumber)\r
3232 if Name == 'CAPSULE_FLAGS':\r
3233 if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):\r
3234 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)\r
3235 Value = self.__Token.strip()\r
3236 while self.__IsToken(","):\r
3237 Value += ','\r
3238 if not self.__GetNextToken():\r
3239 raise Warning("expected value", self.FileName, self.CurrentLineNumber)\r
3240 if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):\r
3241 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)\r
3242 Value += self.__Token.strip()\r
e8a47801
LG
3243 elif Name == 'OEM_CAPSULE_FLAGS':\r
3244 Value = self.__Token.strip()\r
2bc3256c
LG
3245 if not Value.upper().startswith('0X'):\r
3246 raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)\r
e8a47801
LG
3247 try:\r
3248 Value = int(Value, 0)\r
3249 except ValueError:\r
2bc3256c 3250 raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)\r
e8a47801 3251 if not 0x0000 <= Value <= 0xFFFF:\r
2bc3256c 3252 raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)\r
e8a47801 3253 Value = self.__Token.strip()\r
b303ea72
LG
3254 else:\r
3255 Value = self.__Token.strip()\r
3256 Obj.TokensDict[Name] = Value \r
3257 if not self.__GetNextToken():\r
3258 return False\r
3259 self.__UndoToken()\r
30fdf114
LG
3260\r
3261 ## __GetCapsuleData() method\r
3262 #\r
3263 # Get capsule data for capsule\r
3264 #\r
3265 # @param self The object pointer\r
3266 # @param Obj for whom capsule data are got\r
3267 #\r
3268 def __GetCapsuleData(self, Obj):\r
3269\r
3270 while True:\r
3271 IsInf = self.__GetInfStatement(Obj, True)\r
3272 IsFile = self.__GetFileStatement(Obj, True)\r
3273 IsFv = self.__GetFvStatement(Obj)\r
b36d134f
LG
3274 IsFd = self.__GetFdStatement(Obj)\r
3275 IsAnyFile = self.__GetAnyFileStatement(Obj)\r
2bc3256c 3276 IsAfile = self.__GetAfileStatement(Obj)\r
a3251d84
YL
3277 IsFmp = self.__GetFmpStatement(Obj)\r
3278 if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile or IsAfile or IsFmp):\r
30fdf114
LG
3279 break\r
3280\r
3281 ## __GetFvStatement() method\r
3282 #\r
3283 # Get FV for capsule\r
3284 #\r
3285 # @param self The object pointer\r
3286 # @param CapsuleObj for whom FV is got\r
3287 # @retval True Successfully find a FV statement\r
3288 # @retval False Not able to find a FV statement\r
3289 #\r
3290 def __GetFvStatement(self, CapsuleObj):\r
3291\r
3292 if not self.__IsKeyword("FV"):\r
3293 return False\r
3294\r
3295 if not self.__IsToken("="):\r
3296 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3297\r
3298 if not self.__GetNextToken():\r
3299 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)\r
3300\r
2bcc713e
LG
3301 if self.__Token.upper() not in self.Profile.FvDict.keys():\r
3302 raise Warning("FV name does not exist", self.FileName, self.CurrentLineNumber)\r
3303\r
30fdf114
LG
3304 CapsuleFv = CapsuleData.CapsuleFv()\r
3305 CapsuleFv.FvName = self.__Token\r
3306 CapsuleObj.CapsuleDataList.append(CapsuleFv)\r
3307 return True\r
3308\r
b36d134f
LG
3309 ## __GetFdStatement() method\r
3310 #\r
3311 # Get FD for capsule\r
3312 #\r
3313 # @param self The object pointer\r
3314 # @param CapsuleObj for whom FD is got\r
3315 # @retval True Successfully find a FD statement\r
3316 # @retval False Not able to find a FD statement\r
3317 #\r
3318 def __GetFdStatement(self, CapsuleObj):\r
3319\r
3320 if not self.__IsKeyword("FD"):\r
3321 return False\r
3322\r
3323 if not self.__IsToken("="):\r
3324 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3325\r
3326 if not self.__GetNextToken():\r
3327 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)\r
3328\r
2bcc713e
LG
3329 if self.__Token.upper() not in self.Profile.FdDict.keys():\r
3330 raise Warning("FD name does not exist", self.FileName, self.CurrentLineNumber)\r
3331\r
b36d134f
LG
3332 CapsuleFd = CapsuleData.CapsuleFd()\r
3333 CapsuleFd.FdName = self.__Token\r
3334 CapsuleObj.CapsuleDataList.append(CapsuleFd)\r
3335 return True\r
3336\r
a3251d84
YL
3337 def __GetFmpStatement(self, CapsuleObj):\r
3338 if not self.__IsKeyword("FMP"):\r
3339 return False\r
b36d134f 3340\r
a3251d84
YL
3341 if not self.__IsKeyword("PAYLOAD"):\r
3342 self.__UndoToken()\r
b36d134f
LG
3343 return False\r
3344\r
a3251d84
YL
3345 if not self.__IsToken("="):\r
3346 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3347\r
3348 if not self.__GetNextToken():\r
3349 raise Warning("expected payload name after FMP PAYLOAD =", self.FileName, self.CurrentLineNumber)\r
3350 Payload = self.__Token.upper()\r
3351 if Payload not in self.Profile.FmpPayloadDict:\r
3352 raise Warning("This FMP Payload does not exist: %s" % self.__Token, self.FileName, self.CurrentLineNumber)\r
3353 CapsuleObj.FmpPayloadList.append(self.Profile.FmpPayloadDict[Payload])\r
3354 return True\r
3355\r
3356 def __ParseRawFileStatement(self):\r
3357 if not self.__IsKeyword("FILE"):\r
3358 return None\r
3359\r
b36d134f
LG
3360 if not self.__IsKeyword("DATA"):\r
3361 self.__UndoToken()\r
a3251d84 3362 return None\r
b36d134f
LG
3363\r
3364 if not self.__IsToken("="):\r
3365 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3366\r
3367 if not self.__GetNextToken():\r
3368 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)\r
3369 \r
3370 AnyFileName = self.__Token\r
3371 AnyFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AnyFileName)\r
3372 if not os.path.exists(AnyFileName):\r
3373 raise Warning("File %s not exists"%AnyFileName, self.FileName, self.CurrentLineNumber)\r
a3251d84
YL
3374 return AnyFileName\r
3375\r
3376 ## __GetAnyFileStatement() method\r
3377 #\r
3378 # Get AnyFile for capsule\r
3379 #\r
3380 # @param self The object pointer\r
3381 # @param CapsuleObj for whom AnyFile is got\r
3382 # @retval True Successfully find a Anyfile statement\r
3383 # @retval False Not able to find a AnyFile statement\r
3384 #\r
3385 def __GetAnyFileStatement(self, CapsuleObj):\r
3386 AnyFileName = self.__ParseRawFileStatement()\r
3387 if not AnyFileName:\r
3388 return False\r
b36d134f
LG
3389\r
3390 CapsuleAnyFile = CapsuleData.CapsuleAnyFile()\r
3391 CapsuleAnyFile.FileName = AnyFileName\r
3392 CapsuleObj.CapsuleDataList.append(CapsuleAnyFile)\r
3393 return True\r
2bc3256c
LG
3394 \r
3395 ## __GetAfileStatement() method\r
3396 #\r
3397 # Get Afile for capsule\r
3398 #\r
3399 # @param self The object pointer\r
3400 # @param CapsuleObj for whom Afile is got\r
3401 # @retval True Successfully find a Afile statement\r
3402 # @retval False Not able to find a Afile statement\r
3403 #\r
3404 def __GetAfileStatement(self, CapsuleObj):\r
3405\r
3406 if not self.__IsKeyword("APPEND"):\r
3407 return False\r
3408\r
3409 if not self.__IsToken("="):\r
3410 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3411\r
3412 if not self.__GetNextToken():\r
3413 raise Warning("expected Afile name", self.FileName, self.CurrentLineNumber)\r
3414 \r
3415 AfileName = self.__Token\r
3416 AfileBaseName = os.path.basename(AfileName)\r
3417 \r
3418 if os.path.splitext(AfileBaseName)[1] not in [".bin",".BIN",".Bin",".dat",".DAT",".Dat",".data",".DATA",".Data"]:\r
3419 raise Warning('invalid binary file type, should be one of "bin","BIN","Bin","dat","DAT","Dat","data","DATA","Data"', \\r
3420 self.FileName, self.CurrentLineNumber)\r
3421 \r
3422 if not os.path.isabs(AfileName):\r
3423 AfileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AfileName)\r
3424 self.__VerifyFile(AfileName)\r
3425 else:\r
3426 if not os.path.exists(AfileName):\r
3427 raise Warning('%s does not exist' % AfileName, self.FileName, self.CurrentLineNumber)\r
3428 else:\r
3429 pass\r
3430\r
3431 CapsuleAfile = CapsuleData.CapsuleAfile()\r
3432 CapsuleAfile.FileName = AfileName\r
3433 CapsuleObj.CapsuleDataList.append(CapsuleAfile)\r
3434 return True\r
b36d134f 3435\r
30fdf114
LG
3436 ## __GetRule() method\r
3437 #\r
3438 # Get Rule section contents and store its data into rule list of self.Profile\r
3439 #\r
3440 # @param self The object pointer\r
3441 # @retval True Successfully find a Rule\r
3442 # @retval False Not able to find a Rule\r
3443 #\r
3444 def __GetRule(self):\r
3445\r
3446 if not self.__GetNextToken():\r
3447 return False\r
3448\r
3449 S = self.__Token.upper()\r
3450 if S.startswith("[") and not S.startswith("[RULE."):\r
3451 if not S.startswith("[OPTIONROM."):\r
3452 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
3453 self.__UndoToken()\r
3454 return False\r
3455 self.__UndoToken()\r
3456 if not self.__IsToken("[Rule.", True):\r
3457 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
3458 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
3459 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
3460 raise Warning("expected [Rule.]", self.FileName, self.CurrentLineNumber)\r
3461\r
3462 if not self.__SkipToToken("."):\r
3463 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)\r
3464\r
3465 Arch = self.__SkippedChars.rstrip(".")\r
4afd3d04 3466 if Arch.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "AARCH64", "COMMON"):\r
30fdf114
LG
3467 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)\r
3468\r
3469 ModuleType = self.__GetModuleType()\r
3470\r
3471 TemplateName = ""\r
3472 if self.__IsToken("."):\r
3473 if not self.__GetNextWord():\r
3474 raise Warning("expected template name", self.FileName, self.CurrentLineNumber)\r
3475 TemplateName = self.__Token\r
3476\r
3477 if not self.__IsToken( "]"):\r
3478 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
3479\r
3480 RuleObj = self.__GetRuleFileStatements()\r
3481 RuleObj.Arch = Arch.upper()\r
3482 RuleObj.ModuleType = ModuleType\r
3483 RuleObj.TemplateName = TemplateName\r
3484 if TemplateName == '' :\r
3485 self.Profile.RuleDict['RULE' + \\r
3486 '.' + \\r
3487 Arch.upper() + \\r
3488 '.' + \\r
3489 ModuleType.upper() ] = RuleObj\r
3490 else :\r
3491 self.Profile.RuleDict['RULE' + \\r
3492 '.' + \\r
3493 Arch.upper() + \\r
3494 '.' + \\r
3495 ModuleType.upper() + \\r
3496 '.' + \\r
3497 TemplateName.upper() ] = RuleObj\r
3498# self.Profile.RuleList.append(rule)\r
3499 return True\r
3500\r
3501 ## __GetModuleType() method\r
3502 #\r
3503 # Return the module type\r
3504 #\r
3505 # @param self The object pointer\r
3506 # @retval string module type\r
3507 #\r
3508 def __GetModuleType(self):\r
3509\r
3510 if not self.__GetNextWord():\r
3511 raise Warning("expected Module type", self.FileName, self.CurrentLineNumber)\r
3512 if self.__Token.upper() not in ("SEC", "PEI_CORE", "PEIM", "DXE_CORE", \\r
3513 "DXE_DRIVER", "DXE_SAL_DRIVER", \\r
3514 "DXE_SMM_DRIVER", "DXE_RUNTIME_DRIVER", \\r
3515 "UEFI_DRIVER", "UEFI_APPLICATION", "USER_DEFINED", "DEFAULT", "BASE", \\r
3516 "SECURITY_CORE", "COMBINED_PEIM_DRIVER", "PIC_PEIM", "RELOCATABLE_PEIM", \\r
b303ea72 3517 "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION", "ACPITABLE", "SMM_CORE"):\r
30fdf114
LG
3518 raise Warning("Unknown Module type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
3519 return self.__Token\r
3520\r
3521 ## __GetFileExtension() method\r
3522 #\r
3523 # Return the file extension\r
3524 #\r
3525 # @param self The object pointer\r
3526 # @retval string file name extension\r
3527 #\r
3528 def __GetFileExtension(self):\r
3529 if not self.__IsToken("."):\r
3530 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)\r
3531\r
3532 Ext = ""\r
3533 if self.__GetNextToken():\r
3534 Pattern = re.compile(r'([a-zA-Z][a-zA-Z0-9]*)')\r
3535 if Pattern.match(self.__Token):\r
3536 Ext = self.__Token\r
3537 return '.' + Ext\r
3538 else:\r
3539 raise Warning("Unknown file extension '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
3540\r
3541 else:\r
3542 raise Warning("expected file extension", self.FileName, self.CurrentLineNumber)\r
3543\r
3544 ## __GetRuleFileStatement() method\r
3545 #\r
3546 # Get rule contents\r
3547 #\r
3548 # @param self The object pointer\r
3549 # @retval Rule Rule object\r
3550 #\r
3551 def __GetRuleFileStatements(self):\r
3552\r
3553 if not self.__IsKeyword("FILE"):\r
3554 raise Warning("expected FILE", self.FileName, self.CurrentLineNumber)\r
3555\r
3556 if not self.__GetNextWord():\r
3557 raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)\r
3558\r
3559 Type = self.__Token.strip().upper()\r
3560 if Type not in ("RAW", "FREEFORM", "SEC", "PEI_CORE", "PEIM",\\r
b303ea72 3561 "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE", "SMM", "SMM_CORE"):\r
30fdf114
LG
3562 raise Warning("Unknown FV type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
3563\r
3564 if not self.__IsToken("="):\r
3565 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3566\r
3567 if not self.__IsKeyword("$(NAMED_GUID)"):\r
3568 if not self.__GetNextWord():\r
3569 raise Warning("expected $(NAMED_GUID)", self.FileName, self.CurrentLineNumber)\r
3570 if self.__Token == 'PCD':\r
3571 if not self.__IsToken( "("):\r
3572 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)\r
3573 PcdPair = self.__GetNextPcdName()\r
3574 if not self.__IsToken( ")"):\r
3575 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)\r
3576 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'\r
3577 \r
3578 NameGuid = self.__Token\r
3579\r
3580 KeepReloc = None\r
3581 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):\r
3582 if self.__FileCouldHaveRelocFlag(Type):\r
3583 if self.__Token == 'RELOCS_STRIPPED':\r
3584 KeepReloc = False\r
3585 else:\r
3586 KeepReloc = True\r
3587 else:\r
3588 raise Warning("File type %s could not have reloc strip flag%d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3589\r
3590 KeyStringList = []\r
3591 if self.__GetNextToken():\r
3592 Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')\r
3593 if Pattern.match(self.__Token):\r
3594 KeyStringList.append(self.__Token)\r
3595 if self.__IsToken(","):\r
3596 while self.__GetNextToken():\r
3597 if not Pattern.match(self.__Token):\r
3598 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
3599 KeyStringList.append(self.__Token)\r
3600\r
3601 if not self.__IsToken(","):\r
3602 break\r
3603\r
3604 else:\r
3605 self.__UndoToken()\r
3606\r
3607\r
3608 Fixed = False\r
3609 if self.__IsKeyword("Fixed", True):\r
3610 Fixed = True\r
3611\r
3612 CheckSum = False\r
3613 if self.__IsKeyword("CheckSum", True):\r
3614 CheckSum = True\r
3615\r
3616 AlignValue = ""\r
3617 if self.__GetAlignment():\r
52302d4d 3618 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):\r
30fdf114 3619 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
52302d4d
LG
3620 #For FFS, Auto is default option same to ""\r
3621 if not self.__Token == "Auto":\r
3622 AlignValue = self.__Token\r
30fdf114
LG
3623\r
3624 if self.__IsToken("{"):\r
3625 # Complex file rule expected\r
3626 Rule = RuleComplexFile.RuleComplexFile()\r
3627 Rule.FvFileType = Type\r
3628 Rule.NameGuid = NameGuid\r
3629 Rule.Alignment = AlignValue\r
3630 Rule.CheckSum = CheckSum\r
3631 Rule.Fixed = Fixed\r
3632 Rule.KeyStringList = KeyStringList\r
3633 if KeepReloc != None:\r
3634 Rule.KeepReloc = KeepReloc\r
3635\r
3636 while True:\r
3637 IsEncapsulate = self.__GetRuleEncapsulationSection(Rule)\r
3638 IsLeaf = self.__GetEfiSection(Rule)\r
3639 if not IsEncapsulate and not IsLeaf:\r
3640 break\r
3641\r
3642 if not self.__IsToken("}"):\r
3643 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
3644\r
3645 return Rule\r
3646\r
30fdf114
LG
3647 else:\r
3648 # Simple file rule expected\r
3649 if not self.__GetNextWord():\r
3650 raise Warning("expected leaf section type", self.FileName, self.CurrentLineNumber)\r
3651\r
3652 SectionName = self.__Token\r
3653\r
3654 if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\\r
3655 "UI", "PEI_DEPEX", "VERSION", "SUBTYPE_GUID", "SMM_DEPEX"):\r
3656 raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber)\r
3657\r
3658\r
3659 if self.__IsKeyword("Fixed", True):\r
3660 Fixed = True\r
3661\r
3662 if self.__IsKeyword("CheckSum", True):\r
3663 CheckSum = True\r
3664\r
52302d4d 3665 SectAlignment = ""\r
30fdf114 3666 if self.__GetAlignment():\r
52302d4d 3667 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):\r
30fdf114 3668 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
52302d4d
LG
3669 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):\r
3670 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
3671 SectAlignment = self.__Token\r
3672\r
3673 Ext = None\r
3674 if self.__IsToken('|'):\r
3675 Ext = self.__GetFileExtension()\r
3676 elif not self.__GetNextToken():\r
30fdf114
LG
3677 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)\r
3678\r
3679 Rule = RuleSimpleFile.RuleSimpleFile()\r
3680 Rule.SectionType = SectionName\r
3681 Rule.FvFileType = Type\r
3682 Rule.NameGuid = NameGuid\r
3683 Rule.Alignment = AlignValue\r
52302d4d 3684 Rule.SectAlignment = SectAlignment\r
30fdf114
LG
3685 Rule.CheckSum = CheckSum\r
3686 Rule.Fixed = Fixed\r
30fdf114
LG
3687 Rule.KeyStringList = KeyStringList\r
3688 if KeepReloc != None:\r
3689 Rule.KeepReloc = KeepReloc\r
52302d4d
LG
3690 Rule.FileExtension = Ext\r
3691 Rule.FileName = self.__Token\r
30fdf114
LG
3692 return Rule\r
3693\r
3694 ## __GetEfiSection() method\r
3695 #\r
3696 # Get section list for Rule\r
3697 #\r
3698 # @param self The object pointer\r
3699 # @param Obj for whom section is got\r
3700 # @retval True Successfully find section statement\r
3701 # @retval False Not able to find section statement\r
3702 #\r
3703 def __GetEfiSection(self, Obj):\r
3704\r
3705 OldPos = self.GetFileBufferPos()\r
3706 if not self.__GetNextWord():\r
3707 return False\r
3708 SectionName = self.__Token\r
3709\r
3710 if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\\r
3711 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):\r
3712 self.__UndoToken()\r
3713 return False\r
3714\r
3715 if SectionName == "FV_IMAGE":\r
3716 FvImageSectionObj = FvImageSection.FvImageSection()\r
3717 if self.__IsKeyword("FV_IMAGE"):\r
3718 pass\r
3719 if self.__IsToken( "{"):\r
3720 FvObj = Fv.FV()\r
3721 self.__GetDefineStatements(FvObj)\r
3722 self.__GetBlockStatement(FvObj)\r
3723 self.__GetSetStatements(FvObj)\r
3724 self.__GetFvAlignment(FvObj)\r
3725 self.__GetFvAttributes(FvObj)\r
3726 self.__GetAprioriSection(FvObj)\r
3727 self.__GetAprioriSection(FvObj)\r
3728\r
3729 while True:\r
3730 IsInf = self.__GetInfStatement(FvObj)\r
3731 IsFile = self.__GetFileStatement(FvObj)\r
3732 if not IsInf and not IsFile:\r
3733 break\r
3734\r
3735 if not self.__IsToken( "}"):\r
3736 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
3737 FvImageSectionObj.Fv = FvObj\r
3738 FvImageSectionObj.FvName = None\r
3739\r
3740 else:\r
3741 if not self.__IsKeyword("FV"):\r
3742 raise Warning("expected 'FV'", self.FileName, self.CurrentLineNumber)\r
3743 FvImageSectionObj.FvFileType = self.__Token\r
3744\r
30fdf114
LG
3745 if self.__GetAlignment():\r
3746 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):\r
3747 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
3748 FvImageSectionObj.Alignment = self.__Token\r
3749\r
3750 if self.__IsToken('|'):\r
3751 FvImageSectionObj.FvFileExtension = self.__GetFileExtension()\r
3752 elif self.__GetNextToken():\r
3753 if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\\r
3754 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):\r
3755 FvImageSectionObj.FvFileName = self.__Token\r
3756 else:\r
3757 self.__UndoToken()\r
3758 else:\r
3759 raise Warning("expected FV file name", self.FileName, self.CurrentLineNumber)\r
3760\r
3761 Obj.SectionList.append(FvImageSectionObj)\r
3762 return True\r
3763\r
3764 EfiSectionObj = EfiSection.EfiSection()\r
3765 EfiSectionObj.SectionType = SectionName\r
3766\r
3767 if not self.__GetNextToken():\r
3768 raise Warning("expected file type", self.FileName, self.CurrentLineNumber)\r
3769\r
3770 if self.__Token == "STRING":\r
3771 if not self.__RuleSectionCouldHaveString(EfiSectionObj.SectionType):\r
3772 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3773\r
3774 if not self.__IsToken('='):\r
3775 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3776\r
3777 if not self.__GetNextToken():\r
3778 raise Warning("expected Quoted String", self.FileName, self.CurrentLineNumber)\r
3779\r
3780 if self.__GetStringData():\r
3781 EfiSectionObj.StringData = self.__Token\r
3782\r
3783 if self.__IsKeyword("BUILD_NUM"):\r
3784 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):\r
3785 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3786\r
3787 if not self.__IsToken("="):\r
3788 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3789 if not self.__GetNextToken():\r
3790 raise Warning("expected Build number", self.FileName, self.CurrentLineNumber)\r
3791 EfiSectionObj.BuildNum = self.__Token\r
3792\r
3793 else:\r
3794 EfiSectionObj.FileType = self.__Token\r
3795 self.__CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType)\r
3796\r
3797 if self.__IsKeyword("Optional"):\r
3798 if not self.__RuleSectionCouldBeOptional(EfiSectionObj.SectionType):\r
3799 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3800 EfiSectionObj.Optional = True\r
3801\r
3802 if self.__IsKeyword("BUILD_NUM"):\r
3803 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):\r
3804 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3805\r
3806 if not self.__IsToken("="):\r
3807 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3808 if not self.__GetNextToken():\r
3809 raise Warning("expected Build number", self.FileName, self.CurrentLineNumber)\r
3810 EfiSectionObj.BuildNum = self.__Token\r
3811\r
3812 if self.__GetAlignment():\r
52302d4d
LG
3813 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):\r
3814 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
3815 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):\r
3816 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3817 EfiSectionObj.Alignment = self.__Token\r
3818\r
3819 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):\r
3820 if self.__SectionCouldHaveRelocFlag(EfiSectionObj.SectionType):\r
3821 if self.__Token == 'RELOCS_STRIPPED':\r
3822 EfiSectionObj.KeepReloc = False\r
3823 else:\r
3824 EfiSectionObj.KeepReloc = True\r
3825 if Obj.KeepReloc != None and Obj.KeepReloc != EfiSectionObj.KeepReloc:\r
3826 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)\r
3827 else:\r
3828 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)\r
3829\r
3830\r
3831 if self.__IsToken('|'):\r
3832 EfiSectionObj.FileExtension = self.__GetFileExtension()\r
3833 elif self.__GetNextToken():\r
3834 if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\\r
3835 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):\r
3836 \r
3837 if self.__Token.startswith('PCD'):\r
3838 self.__UndoToken()\r
3839 self.__GetNextWord()\r
3840 \r
3841 if self.__Token == 'PCD':\r
3842 if not self.__IsToken( "("):\r
3843 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)\r
3844 PcdPair = self.__GetNextPcdName()\r
3845 if not self.__IsToken( ")"):\r
3846 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)\r
3847 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'\r
3848 \r
3849 EfiSectionObj.FileName = self.__Token \r
3850 \r
3851 else:\r
3852 self.__UndoToken()\r
3853 else:\r
3854 raise Warning("expected section file name", self.FileName, self.CurrentLineNumber)\r
3855\r
3856 Obj.SectionList.append(EfiSectionObj)\r
3857 return True\r
3858\r
3859 ## __RuleSectionCouldBeOptional() method\r
3860 #\r
3861 # Get whether a section could be optional\r
3862 #\r
3863 # @param self The object pointer\r
3864 # @param SectionType The section type to check\r
3865 # @retval True section could be optional\r
3866 # @retval False section never optional\r
3867 #\r
3868 def __RuleSectionCouldBeOptional(self, SectionType):\r
3869 if SectionType in ("DXE_DEPEX", "UI", "VERSION", "PEI_DEPEX", "RAW", "SMM_DEPEX"):\r
3870 return True\r
3871 else:\r
3872 return False\r
3873\r
3874 ## __RuleSectionCouldHaveBuildNum() method\r
3875 #\r
3876 # Get whether a section could have build number information\r
3877 #\r
3878 # @param self The object pointer\r
3879 # @param SectionType The section type to check\r
3880 # @retval True section could have build number information\r
3881 # @retval False section never have build number information\r
3882 #\r
3883 def __RuleSectionCouldHaveBuildNum(self, SectionType):\r
3884 if SectionType in ("VERSION"):\r
3885 return True\r
3886 else:\r
3887 return False\r
3888\r
3889 ## __RuleSectionCouldHaveString() method\r
3890 #\r
3891 # Get whether a section could have string\r
3892 #\r
3893 # @param self The object pointer\r
3894 # @param SectionType The section type to check\r
3895 # @retval True section could have string\r
3896 # @retval False section never have string\r
3897 #\r
3898 def __RuleSectionCouldHaveString(self, SectionType):\r
3899 if SectionType in ("UI", "VERSION"):\r
3900 return True\r
3901 else:\r
3902 return False\r
3903\r
3904 ## __CheckRuleSectionFileType() method\r
3905 #\r
3906 # Get whether a section matches a file type\r
3907 #\r
3908 # @param self The object pointer\r
3909 # @param SectionType The section type to check\r
3910 # @param FileType The file type to check\r
3911 #\r
3912 def __CheckRuleSectionFileType(self, SectionType, FileType):\r
3913 if SectionType == "COMPAT16":\r
3914 if FileType not in ("COMPAT16", "SEC_COMPAT16"):\r
3915 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
3916 elif SectionType == "PE32":\r
3917 if FileType not in ("PE32", "SEC_PE32"):\r
3918 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
3919 elif SectionType == "PIC":\r
3920 if FileType not in ("PIC", "PIC"):\r
3921 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
3922 elif SectionType == "TE":\r
3923 if FileType not in ("TE", "SEC_TE"):\r
3924 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
3925 elif SectionType == "RAW":\r
3926 if FileType not in ("BIN", "SEC_BIN", "RAW", "ASL", "ACPI"):\r
3927 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
b303ea72
LG
3928 elif SectionType == "DXE_DEPEX" or SectionType == "SMM_DEPEX":\r
3929 if FileType not in ("DXE_DEPEX", "SEC_DXE_DEPEX", "SMM_DEPEX"):\r
30fdf114
LG
3930 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
3931 elif SectionType == "UI":\r
3932 if FileType not in ("UI", "SEC_UI"):\r
3933 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
3934 elif SectionType == "VERSION":\r
3935 if FileType not in ("VERSION", "SEC_VERSION"):\r
3936 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
3937 elif SectionType == "PEI_DEPEX":\r
3938 if FileType not in ("PEI_DEPEX", "SEC_PEI_DEPEX"):\r
3939 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
3940 elif SectionType == "GUID":\r
3941 if FileType not in ("PE32", "SEC_GUID"):\r
3942 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
3943\r
3944 ## __GetRuleEncapsulationSection() method\r
3945 #\r
3946 # Get encapsulation section for Rule\r
3947 #\r
3948 # @param self The object pointer\r
3949 # @param Rule for whom section is got\r
3950 # @retval True Successfully find section statement\r
3951 # @retval False Not able to find section statement\r
3952 #\r
3953 def __GetRuleEncapsulationSection(self, Rule):\r
3954\r
3955 if self.__IsKeyword( "COMPRESS"):\r
3956 Type = "PI_STD"\r
3957 if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):\r
3958 Type = self.__Token\r
3959\r
3960 if not self.__IsToken("{"):\r
3961 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
3962\r
3963 CompressSectionObj = CompressSection.CompressSection()\r
3964\r
3965 CompressSectionObj.CompType = Type\r
3966 # Recursive sections...\r
3967 while True:\r
3968 IsEncapsulate = self.__GetRuleEncapsulationSection(CompressSectionObj)\r
3969 IsLeaf = self.__GetEfiSection(CompressSectionObj)\r
3970 if not IsEncapsulate and not IsLeaf:\r
3971 break\r
3972\r
3973 if not self.__IsToken( "}"):\r
3974 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
3975 Rule.SectionList.append(CompressSectionObj)\r
3976\r
3977 return True\r
3978\r
3979 elif self.__IsKeyword( "GUIDED"):\r
3980 GuidValue = None\r
3981 if self.__GetNextGuid():\r
3982 GuidValue = self.__Token\r
3983\r
3984 if self.__IsKeyword( "$(NAMED_GUID)"):\r
3985 GuidValue = self.__Token\r
3986\r
3987 AttribDict = self.__GetGuidAttrib()\r
3988\r
3989 if not self.__IsToken("{"):\r
3990 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
3991 GuidSectionObj = GuidSection.GuidSection()\r
3992 GuidSectionObj.NameGuid = GuidValue\r
3993 GuidSectionObj.SectionType = "GUIDED"\r
3994 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]\r
3995 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]\r
25918452 3996 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]\r
30fdf114
LG
3997\r
3998 # Efi sections...\r
3999 while True:\r
4000 IsEncapsulate = self.__GetRuleEncapsulationSection(GuidSectionObj)\r
4001 IsLeaf = self.__GetEfiSection(GuidSectionObj)\r
4002 if not IsEncapsulate and not IsLeaf:\r
4003 break\r
4004\r
4005 if not self.__IsToken( "}"):\r
4006 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
4007 Rule.SectionList.append(GuidSectionObj)\r
4008\r
4009 return True\r
4010\r
4011 return False\r
4012\r
4013 ## __GetVtf() method\r
4014 #\r
4015 # Get VTF section contents and store its data into VTF list of self.Profile\r
4016 #\r
4017 # @param self The object pointer\r
4018 # @retval True Successfully find a VTF\r
4019 # @retval False Not able to find a VTF\r
4020 #\r
4021 def __GetVtf(self):\r
4022\r
4023 if not self.__GetNextToken():\r
4024 return False\r
4025\r
4026 S = self.__Token.upper()\r
4027 if S.startswith("[") and not S.startswith("[VTF."):\r
4028 if not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):\r
4029 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
4030 self.__UndoToken()\r
4031 return False\r
4032\r
4033 self.__UndoToken()\r
4034 if not self.__IsToken("[VTF.", True):\r
4035 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
4036 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
4037 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
4038 raise Warning("expected [VTF.]", self.FileName, self.CurrentLineNumber)\r
4039\r
4040 if not self.__SkipToToken("."):\r
4041 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)\r
4042\r
4043 Arch = self.__SkippedChars.rstrip(".").upper()\r
4afd3d04 4044 if Arch not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):\r
30fdf114
LG
4045 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)\r
4046\r
4047 if not self.__GetNextWord():\r
4048 raise Warning("expected VTF name", self.FileName, self.CurrentLineNumber)\r
4049 Name = self.__Token.upper()\r
4050\r
4051 VtfObj = Vtf.Vtf()\r
4052 VtfObj.UiName = Name\r
4053 VtfObj.KeyArch = Arch\r
4054\r
4055 if self.__IsToken(","):\r
4056 if not self.__GetNextWord():\r
4057 raise Warning("expected Arch list", self.FileName, self.CurrentLineNumber)\r
4afd3d04 4058 if self.__Token.upper() not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):\r
30fdf114
LG
4059 raise Warning("Unknown Arch '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
4060 VtfObj.ArchList = self.__Token.upper()\r
4061\r
4062 if not self.__IsToken( "]"):\r
4063 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
4064\r
4065 if self.__IsKeyword("IA32_RST_BIN"):\r
4066 if not self.__IsToken("="):\r
4067 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4068\r
4069 if not self.__GetNextToken():\r
4070 raise Warning("expected Reset file", self.FileName, self.CurrentLineNumber)\r
4071\r
4072 VtfObj.ResetBin = self.__Token\r
6310ffd7 4073 if VtfObj.ResetBin.replace('$(WORKSPACE)', '').find('$') == -1:\r
4074 #check for file path\r
4075 ErrorCode, ErrorInfo = PathClass(NormPath(VtfObj.ResetBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4076 if ErrorCode != 0:\r
4077 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114
LG
4078\r
4079 while self.__GetComponentStatement(VtfObj):\r
4080 pass\r
4081\r
4082 self.Profile.VtfList.append(VtfObj)\r
4083 return True\r
4084\r
4085 ## __GetComponentStatement() method\r
4086 #\r
4087 # Get components in VTF\r
4088 #\r
4089 # @param self The object pointer\r
4090 # @param VtfObj for whom component is got\r
4091 # @retval True Successfully find a component\r
4092 # @retval False Not able to find a component\r
4093 #\r
4094 def __GetComponentStatement(self, VtfObj):\r
4095\r
4096 if not self.__IsKeyword("COMP_NAME"):\r
4097 return False\r
4098\r
4099 if not self.__IsToken("="):\r
4100 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4101\r
4102 if not self.__GetNextWord():\r
4103 raise Warning("expected Component Name", self.FileName, self.CurrentLineNumber)\r
4104\r
4105 CompStatementObj = ComponentStatement.ComponentStatement()\r
4106 CompStatementObj.CompName = self.__Token\r
4107\r
4108 if not self.__IsKeyword("COMP_LOC"):\r
4109 raise Warning("expected COMP_LOC", self.FileName, self.CurrentLineNumber)\r
4110\r
4111 if not self.__IsToken("="):\r
4112 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4113\r
4114 CompStatementObj.CompLoc = ""\r
4115 if self.__GetNextWord():\r
4116 CompStatementObj.CompLoc = self.__Token\r
4117 if self.__IsToken('|'):\r
4118 if not self.__GetNextWord():\r
4119 raise Warning("Expected Region Name", self.FileName, self.CurrentLineNumber)\r
4120\r
4121 if self.__Token not in ("F", "N", "S"): #, "H", "L", "PH", "PL"): not support\r
4122 raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
4123\r
4124 CompStatementObj.FilePos = self.__Token\r
4125 else:\r
4126 self.CurrentLineNumber += 1\r
4127 self.CurrentOffsetWithinLine = 0\r
4128\r
4129 if not self.__IsKeyword("COMP_TYPE"):\r
4130 raise Warning("expected COMP_TYPE", self.FileName, self.CurrentLineNumber)\r
4131\r
4132 if not self.__IsToken("="):\r
4133 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4134\r
4135 if not self.__GetNextToken():\r
4136 raise Warning("expected Component type", self.FileName, self.CurrentLineNumber)\r
4137 if self.__Token not in ("FIT", "PAL_B", "PAL_A", "OEM"):\r
4138 if not self.__Token.startswith("0x") or len(self.__Token) < 3 or len(self.__Token) > 4 or \\r
4139 not self.__HexDigit(self.__Token[2]) or not self.__HexDigit(self.__Token[-1]):\r
4140 raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
4141 CompStatementObj.CompType = self.__Token\r
4142\r
4143 if not self.__IsKeyword("COMP_VER"):\r
4144 raise Warning("expected COMP_VER", self.FileName, self.CurrentLineNumber)\r
4145\r
4146 if not self.__IsToken("="):\r
4147 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4148\r
4149 if not self.__GetNextToken():\r
4150 raise Warning("expected Component version", self.FileName, self.CurrentLineNumber)\r
4151\r
9fd2164e 4152 Pattern = re.compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', re.DOTALL)\r
30fdf114
LG
4153 if Pattern.match(self.__Token) == None:\r
4154 raise Warning("Unknown version format '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
4155 CompStatementObj.CompVer = self.__Token\r
4156\r
4157 if not self.__IsKeyword("COMP_CS"):\r
4158 raise Warning("expected COMP_CS", self.FileName, self.CurrentLineNumber)\r
4159\r
4160 if not self.__IsToken("="):\r
4161 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4162\r
4163 if not self.__GetNextToken():\r
4164 raise Warning("expected Component CS", self.FileName, self.CurrentLineNumber)\r
4165 if self.__Token not in ("1", "0"):\r
4166 raise Warning("Unknown Component CS '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
4167 CompStatementObj.CompCs = self.__Token\r
4168\r
4169\r
4170 if not self.__IsKeyword("COMP_BIN"):\r
4171 raise Warning("expected COMP_BIN", self.FileName, self.CurrentLineNumber)\r
4172\r
4173 if not self.__IsToken("="):\r
4174 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4175\r
4176 if not self.__GetNextToken():\r
4177 raise Warning("expected Component file", self.FileName, self.CurrentLineNumber)\r
4178\r
4179 CompStatementObj.CompBin = self.__Token\r
6310ffd7 4180 if CompStatementObj.CompBin != '-' and CompStatementObj.CompBin.replace('$(WORKSPACE)', '').find('$') == -1:\r
4181 #check for file path\r
4182 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4183 if ErrorCode != 0:\r
4184 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114
LG
4185\r
4186 if not self.__IsKeyword("COMP_SYM"):\r
4187 raise Warning("expected COMP_SYM", self.FileName, self.CurrentLineNumber)\r
4188\r
4189 if not self.__IsToken("="):\r
4190 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4191\r
4192 if not self.__GetNextToken():\r
4193 raise Warning("expected Component symbol file", self.FileName, self.CurrentLineNumber)\r
4194\r
4195 CompStatementObj.CompSym = self.__Token\r
6310ffd7 4196 if CompStatementObj.CompSym != '-' and CompStatementObj.CompSym.replace('$(WORKSPACE)', '').find('$') == -1:\r
4197 #check for file path\r
4198 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompSym), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4199 if ErrorCode != 0:\r
4200 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114
LG
4201\r
4202 if not self.__IsKeyword("COMP_SIZE"):\r
4203 raise Warning("expected COMP_SIZE", self.FileName, self.CurrentLineNumber)\r
4204\r
4205 if not self.__IsToken("="):\r
4206 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4207\r
4208 if self.__IsToken("-"):\r
4209 CompStatementObj.CompSize = self.__Token\r
4210 elif self.__GetNextDecimalNumber():\r
4211 CompStatementObj.CompSize = self.__Token\r
4212 elif self.__GetNextHexNumber():\r
4213 CompStatementObj.CompSize = self.__Token\r
4214 else:\r
4215 raise Warning("Unknown size '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
4216\r
4217 VtfObj.ComponentStatementList.append(CompStatementObj)\r
4218 return True\r
4219\r
4220 ## __GetOptionRom() method\r
4221 #\r
4222 # Get OptionROM section contents and store its data into OptionROM list of self.Profile\r
4223 #\r
4224 # @param self The object pointer\r
4225 # @retval True Successfully find a OptionROM\r
4226 # @retval False Not able to find a OptionROM\r
4227 #\r
4228 def __GetOptionRom(self):\r
4229\r
4230 if not self.__GetNextToken():\r
4231 return False\r
4232\r
4233 S = self.__Token.upper()\r
4234 if S.startswith("[") and not S.startswith("[OPTIONROM."):\r
4235 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
4236 \r
4237 self.__UndoToken()\r
4238 if not self.__IsToken("[OptionRom.", True):\r
4239 raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
4240\r
4241 OptRomName = self.__GetUiName()\r
4242\r
4243 if not self.__IsToken( "]"):\r
4244 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
4245\r
4246 OptRomObj = OptionRom.OPTIONROM()\r
4247 OptRomObj.DriverName = OptRomName\r
4248 self.Profile.OptRomDict[OptRomName] = OptRomObj\r
4249\r
4250 while True:\r
4251 isInf = self.__GetOptRomInfStatement(OptRomObj)\r
4252 isFile = self.__GetOptRomFileStatement(OptRomObj)\r
4253 if not isInf and not isFile:\r
4254 break\r
4255 \r
4256 return True\r
4257\r
4258 ## __GetOptRomInfStatement() method\r
4259 #\r
4260 # Get INF statements\r
4261 #\r
4262 # @param self The object pointer\r
4263 # @param Obj for whom inf statement is got\r
4264 # @retval True Successfully find inf statement\r
4265 # @retval False Not able to find inf statement\r
4266 #\r
4267 def __GetOptRomInfStatement(self, Obj):\r
4268\r
4269 if not self.__IsKeyword( "INF"):\r
4270 return False\r
4271\r
4272 ffsInf = OptRomInfStatement.OptRomInfStatement()\r
4273 self.__GetInfOptions( ffsInf)\r
4274\r
4275 if not self.__GetNextToken():\r
4276 raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)\r
4277 ffsInf.InfFileName = self.__Token\r
6310ffd7 4278 if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:\r
4279 #check for file path\r
4280 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4281 if ErrorCode != 0:\r
4282 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114
LG
4283\r
4284 if not ffsInf.InfFileName in self.Profile.InfList:\r
4285 self.Profile.InfList.append(ffsInf.InfFileName)\r
d0acc87a
LG
4286 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
4287 self.Profile.InfFileLineList.append(FileLineTuple)\r
30fdf114
LG
4288\r
4289 \r
4290 self.__GetOptRomOverrides (ffsInf)\r
4291 \r
4292 Obj.FfsList.append(ffsInf)\r
4293 return True\r
4294\r
4295 ## __GetOptRomOverrides() method\r
4296 #\r
4297 # Get overrides for OptROM INF & FILE\r
4298 #\r
4299 # @param self The object pointer\r
4300 # @param FfsInfObj for whom overrides is got\r
4301 #\r
4302 def __GetOptRomOverrides(self, Obj):\r
4303 if self.__IsToken('{'):\r
4304 Overrides = OptionRom.OverrideAttribs()\r
fd171542 4305 while True:\r
4306 if self.__IsKeyword( "PCI_VENDOR_ID"):\r
4307 if not self.__IsToken( "="):\r
4308 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4309 if not self.__GetNextHexNumber():\r
4310 raise Warning("expected Hex vendor id", self.FileName, self.CurrentLineNumber)\r
4311 Overrides.PciVendorId = self.__Token\r
4312 continue\r
4313\r
4314 if self.__IsKeyword( "PCI_CLASS_CODE"):\r
4315 if not self.__IsToken( "="):\r
4316 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4317 if not self.__GetNextHexNumber():\r
4318 raise Warning("expected Hex class code", self.FileName, self.CurrentLineNumber)\r
4319 Overrides.PciClassCode = self.__Token\r
4320 continue\r
4321\r
4322 if self.__IsKeyword( "PCI_DEVICE_ID"):\r
4323 if not self.__IsToken( "="):\r
4324 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4325 if not self.__GetNextHexNumber():\r
4326 raise Warning("expected Hex device id", self.FileName, self.CurrentLineNumber)\r
4327\r
4328 Overrides.PciDeviceId = self.__Token\r
4329 continue\r
4330\r
4331 if self.__IsKeyword( "PCI_REVISION"):\r
4332 if not self.__IsToken( "="):\r
4333 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4334 if not self.__GetNextHexNumber():\r
4335 raise Warning("expected Hex revision", self.FileName, self.CurrentLineNumber)\r
4336 Overrides.PciRevision = self.__Token\r
4337 continue\r
4338\r
79b74a03 4339 if self.__IsKeyword( "PCI_COMPRESS"):\r
fd171542 4340 if not self.__IsToken( "="):\r
4341 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4342 if not self.__GetNextToken():\r
4343 raise Warning("expected TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber)\r
4344 Overrides.NeedCompress = self.__Token.upper() == 'TRUE'\r
4345 continue\r
4346\r
4347 if self.__IsToken( "}"):\r
4348 break\r
4349 else:\r
4350 EdkLogger.error("FdfParser", FORMAT_INVALID, File=self.FileName, Line=self.CurrentLineNumber)\r
4351\r
30fdf114
LG
4352 Obj.OverrideAttribs = Overrides\r
4353 \r
4354 ## __GetOptRomFileStatement() method\r
4355 #\r
4356 # Get FILE statements\r
4357 #\r
4358 # @param self The object pointer\r
4359 # @param Obj for whom FILE statement is got\r
4360 # @retval True Successfully find FILE statement\r
4361 # @retval False Not able to find FILE statement\r
4362 #\r
4363 def __GetOptRomFileStatement(self, Obj):\r
4364\r
4365 if not self.__IsKeyword( "FILE"):\r
4366 return False\r
4367\r
4368 FfsFileObj = OptRomFileStatement.OptRomFileStatement()\r
4369\r
4370 if not self.__IsKeyword("EFI") and not self.__IsKeyword("BIN"):\r
4371 raise Warning("expected Binary type (EFI/BIN)", self.FileName, self.CurrentLineNumber)\r
4372 FfsFileObj.FileType = self.__Token\r
4373\r
4374 if not self.__GetNextToken():\r
4375 raise Warning("expected File path", self.FileName, self.CurrentLineNumber)\r
4376 FfsFileObj.FileName = self.__Token\r
6310ffd7 4377 if FfsFileObj.FileName.replace('$(WORKSPACE)', '').find('$') == -1:\r
4378 #check for file path\r
4379 ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4380 if ErrorCode != 0:\r
4381 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114
LG
4382\r
4383 if FfsFileObj.FileType == 'EFI':\r
4384 self.__GetOptRomOverrides(FfsFileObj)\r
4385 \r
4386 Obj.FfsList.append(FfsFileObj)\r
4387\r
4388 return True\r
fd171542 4389\r
4390 ## __GetCapInFd() method\r
4391 #\r
4392 # Get Cap list contained in FD\r
4393 #\r
4394 # @param self The object pointer\r
4395 # @param FdName FD name\r
4396 # @retval CapList List of Capsule in FD\r
4397 #\r
4398 def __GetCapInFd (self, FdName):\r
4399\r
4400 CapList = []\r
4401 if FdName.upper() in self.Profile.FdDict.keys():\r
4402 FdObj = self.Profile.FdDict[FdName.upper()]\r
4403 for elementRegion in FdObj.RegionList:\r
4404 if elementRegion.RegionType == 'CAPSULE':\r
4405 for elementRegionData in elementRegion.RegionDataList:\r
4406 if elementRegionData.endswith(".cap"):\r
4407 continue\r
4408 if elementRegionData != None and elementRegionData.upper() not in CapList:\r
4409 CapList.append(elementRegionData.upper())\r
4410 return CapList\r
4411\r
4412 ## __GetReferencedFdCapTuple() method\r
4413 #\r
4414 # Get FV and FD list referenced by a capsule image\r
4415 #\r
4416 # @param self The object pointer\r
4417 # @param CapObj Capsule section to be searched\r
4418 # @param RefFdList referenced FD by section\r
4419 # @param RefFvList referenced FV by section\r
4420 #\r
4421 def __GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []):\r
4422\r
4423 for CapsuleDataObj in CapObj.CapsuleDataList :\r
b36d134f 4424 if hasattr(CapsuleDataObj, 'FvName') and CapsuleDataObj.FvName != None and CapsuleDataObj.FvName.upper() not in RefFvList:\r
fd171542 4425 RefFvList.append (CapsuleDataObj.FvName.upper())\r
b36d134f
LG
4426 elif hasattr(CapsuleDataObj, 'FdName') and CapsuleDataObj.FdName != None and CapsuleDataObj.FdName.upper() not in RefFdList:\r
4427 RefFdList.append (CapsuleDataObj.FdName.upper()) \r
fd171542 4428 elif CapsuleDataObj.Ffs != None:\r
b36d134f
LG
4429 if isinstance(CapsuleDataObj.Ffs, FfsFileStatement.FileStatement):\r
4430 if CapsuleDataObj.Ffs.FvName != None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList:\r
4431 RefFvList.append(CapsuleDataObj.Ffs.FvName.upper())\r
4432 elif CapsuleDataObj.Ffs.FdName != None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList:\r
4433 RefFdList.append(CapsuleDataObj.Ffs.FdName.upper())\r
4434 else:\r
4435 self.__GetReferencedFdFvTupleFromSection(CapsuleDataObj.Ffs, RefFdList, RefFvList)\r
fd171542 4436\r
30fdf114
LG
4437 ## __GetFvInFd() method\r
4438 #\r
4439 # Get FV list contained in FD\r
4440 #\r
4441 # @param self The object pointer\r
4442 # @param FdName FD name\r
4443 # @retval FvList list of FV in FD\r
4444 #\r
4445 def __GetFvInFd (self, FdName):\r
4446\r
4447 FvList = []\r
4448 if FdName.upper() in self.Profile.FdDict.keys():\r
4449 FdObj = self.Profile.FdDict[FdName.upper()]\r
4450 for elementRegion in FdObj.RegionList:\r
4451 if elementRegion.RegionType == 'FV':\r
4452 for elementRegionData in elementRegion.RegionDataList:\r
fd171542 4453 if elementRegionData.endswith(".fv"):\r
4454 continue\r
30fdf114
LG
4455 if elementRegionData != None and elementRegionData.upper() not in FvList:\r
4456 FvList.append(elementRegionData.upper())\r
4457 return FvList\r
4458\r
4459 ## __GetReferencedFdFvTuple() method\r
4460 #\r
4461 # Get FD and FV list referenced by a FFS file\r
4462 #\r
4463 # @param self The object pointer\r
4464 # @param FfsFile contains sections to be searched\r
4465 # @param RefFdList referenced FD by section\r
4466 # @param RefFvList referenced FV by section\r
4467 #\r
4468 def __GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []):\r
4469\r
4470 for FfsObj in FvObj.FfsList:\r
4471 if isinstance(FfsObj, FfsFileStatement.FileStatement):\r
4472 if FfsObj.FvName != None and FfsObj.FvName.upper() not in RefFvList:\r
4473 RefFvList.append(FfsObj.FvName.upper())\r
4474 elif FfsObj.FdName != None and FfsObj.FdName.upper() not in RefFdList:\r
4475 RefFdList.append(FfsObj.FdName.upper())\r
4476 else:\r
4477 self.__GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList)\r
4478\r
4479 ## __GetReferencedFdFvTupleFromSection() method\r
4480 #\r
4481 # Get FD and FV list referenced by a FFS section\r
4482 #\r
4483 # @param self The object pointer\r
4484 # @param FfsFile contains sections to be searched\r
4485 # @param FdList referenced FD by section\r
4486 # @param FvList referenced FV by section\r
4487 #\r
4488 def __GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []):\r
4489\r
4490 SectionStack = []\r
4491 SectionStack.extend(FfsFile.SectionList)\r
4492 while SectionStack != []:\r
4493 SectionObj = SectionStack.pop()\r
4494 if isinstance(SectionObj, FvImageSection.FvImageSection):\r
4495 if SectionObj.FvName != None and SectionObj.FvName.upper() not in FvList:\r
4496 FvList.append(SectionObj.FvName.upper())\r
4497 if SectionObj.Fv != None and SectionObj.Fv.UiFvName != None and SectionObj.Fv.UiFvName.upper() not in FvList:\r
4498 FvList.append(SectionObj.Fv.UiFvName.upper())\r
4499 self.__GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList)\r
4500\r
4501 if isinstance(SectionObj, CompressSection.CompressSection) or isinstance(SectionObj, GuidSection.GuidSection):\r
4502 SectionStack.extend(SectionObj.SectionList)\r
4503\r
4504 ## CycleReferenceCheck() method\r
4505 #\r
4506 # Check whether cycle reference exists in FDF\r
4507 #\r
4508 # @param self The object pointer\r
4509 # @retval True cycle reference exists\r
4510 # @retval False Not exists cycle reference\r
4511 #\r
4512 def CycleReferenceCheck(self):\r
fd171542 4513 #\r
4514 # Check the cycle between FV and FD image\r
4515 #\r
4516 MaxLength = len (self.Profile.FvDict)\r
4517 for FvName in self.Profile.FvDict.keys():\r
4518 LogStr = "\nCycle Reference Checking for FV: %s\n" % FvName\r
4519 RefFvStack = []\r
4520 RefFvStack.append(FvName)\r
4521 FdAnalyzedList = []\r
4522 \r
4523 Index = 0\r
4524 while RefFvStack != [] and Index < MaxLength:\r
4525 Index = Index + 1\r
4526 FvNameFromStack = RefFvStack.pop()\r
4527 if FvNameFromStack.upper() in self.Profile.FvDict.keys():\r
4528 FvObj = self.Profile.FvDict[FvNameFromStack.upper()]\r
4529 else:\r
4530 continue\r
30fdf114 4531\r
fd171542 4532 RefFdList = []\r
4533 RefFvList = []\r
4534 self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)\r
30fdf114 4535\r
fd171542 4536 for RefFdName in RefFdList:\r
4537 if RefFdName in FdAnalyzedList:\r
30fdf114
LG
4538 continue\r
4539\r
fd171542 4540 LogStr += "FV %s contains FD %s\n" % (FvNameFromStack, RefFdName)\r
4541 FvInFdList = self.__GetFvInFd(RefFdName)\r
4542 if FvInFdList != []:\r
4543 for FvNameInFd in FvInFdList:\r
4544 LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)\r
4545 if FvNameInFd not in RefFvStack:\r
4546 RefFvStack.append(FvNameInFd)\r
4547\r
4548 if FvName in RefFvStack or FvNameFromStack in RefFvStack:\r
4549 EdkLogger.info(LogStr)\r
4550 return True\r
4551 FdAnalyzedList.append(RefFdName)\r
30fdf114 4552\r
fd171542 4553 for RefFvName in RefFvList:\r
4554 LogStr += "FV %s contains FV %s\n" % (FvNameFromStack, RefFvName)\r
4555 if RefFvName not in RefFvStack:\r
4556 RefFvStack.append(RefFvName)\r
4557\r
4558 if FvName in RefFvStack or FvNameFromStack in RefFvStack:\r
4559 EdkLogger.info(LogStr)\r
4560 return True\r
4561\r
4562 #\r
4563 # Check the cycle between Capsule and FD image\r
4564 #\r
4565 MaxLength = len (self.Profile.CapsuleDict)\r
4566 for CapName in self.Profile.CapsuleDict.keys():\r
4567 #\r
4568 # Capsule image to be checked.\r
4569 #\r
4570 LogStr = "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName\r
4571 RefCapStack = []\r
4572 RefCapStack.append(CapName)\r
4573 FdAnalyzedList = []\r
4574 FvAnalyzedList = []\r
4575 \r
4576 Index = 0\r
4577 while RefCapStack != [] and Index < MaxLength:\r
4578 Index = Index + 1\r
4579 CapNameFromStack = RefCapStack.pop()\r
4580 if CapNameFromStack.upper() in self.Profile.CapsuleDict.keys():\r
4581 CapObj = self.Profile.CapsuleDict[CapNameFromStack.upper()]\r
4582 else:\r
4583 continue\r
4584\r
4585 RefFvList = []\r
4586 RefFdList = []\r
4587 self.__GetReferencedFdCapTuple(CapObj, RefFdList, RefFvList)\r
4588\r
4589 FvListLength = 0\r
4590 FdListLength = 0\r
4591 while FvListLength < len (RefFvList) or FdListLength < len (RefFdList):\r
30fdf114
LG
4592 for RefFdName in RefFdList:\r
4593 if RefFdName in FdAnalyzedList:\r
4594 continue\r
4595\r
fd171542 4596 LogStr += "Capsule %s contains FD %s\n" % (CapNameFromStack, RefFdName)\r
4597 CapInFdList = self.__GetCapInFd(RefFdName)\r
4598 if CapInFdList != []:\r
4599 for CapNameInFd in CapInFdList:\r
4600 LogStr += "FD %s contains Capsule %s\n" % (RefFdName,CapNameInFd)\r
4601 if CapNameInFd not in RefCapStack:\r
4602 RefCapStack.append(CapNameInFd)\r
4603\r
4604 if CapName in RefCapStack or CapNameFromStack in RefCapStack:\r
4605 EdkLogger.info(LogStr)\r
4606 return True\r
4607\r
30fdf114
LG
4608 FvInFdList = self.__GetFvInFd(RefFdName)\r
4609 if FvInFdList != []:\r
fd171542 4610 for FvNameInFd in FvInFdList:\r
4611 LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)\r
4612 if FvNameInFd not in RefFvList:\r
4613 RefFvList.append(FvNameInFd)\r
30fdf114 4614\r
fd171542 4615 FdAnalyzedList.append(RefFdName)\r
4616 #\r
4617 # the number of the parsed FV and FD image\r
4618 #\r
4619 FvListLength = len (RefFvList)\r
4620 FdListLength = len (RefFdList)\r
30fdf114 4621 for RefFvName in RefFvList:\r
fd171542 4622 if RefFvName in FvAnalyzedList:\r
4623 continue\r
4624 LogStr += "Capsule %s contains FV %s\n" % (CapNameFromStack, RefFvName)\r
4625 if RefFvName.upper() in self.Profile.FvDict.keys():\r
4626 FvObj = self.Profile.FvDict[RefFvName.upper()]\r
4627 else:\r
4628 continue\r
4629 self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)\r
4630 FvAnalyzedList.append(RefFvName)\r
30fdf114 4631\r
fd171542 4632 return False\r
30fdf114
LG
4633\r
4634if __name__ == "__main__":\r
b36d134f
LG
4635 import sys\r
4636 try:\r
4637 test_file = sys.argv[1]\r
4638 except IndexError, v:\r
4639 print "Usage: %s filename" % sys.argv[0]\r
4640 sys.exit(1)\r
4641\r
4642 parser = FdfParser(test_file)\r
30fdf114
LG
4643 try:\r
4644 parser.ParseFile()\r
4645 parser.CycleReferenceCheck()\r
4646 except Warning, X:\r
b36d134f 4647 print str(X)\r
30fdf114
LG
4648 else:\r
4649 print "Success!"\r
4650\r