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