]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/FdfParser.py
BaseTools/GenFds: remove MacroDict parameter
[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
5a264f28 73CR_LB_SET = {T_CHAR_CR, TAB_LINE_BREAK}\r
9e47e6f9
CJ
74\r
75RegionSizePattern = compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")\r
76RegionSizeGuidPattern = compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*\|\s*(?P<size>\w+\.\w+[\.\w\[\]]*)\s*")\r
77RegionOffsetPcdPattern = compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*$")\r
78ShortcutPcdPattern = compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")\r
79BaseAddrValuePattern = compile('^0[xX][0-9a-fA-F]+')\r
80FileExtensionPattern = compile(r'([a-zA-Z][a-zA-Z0-9]*)')\r
81TokenFindPattern = compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')\r
118bf096
CS
82AllIncludeFileList = []\r
83\r
84# Get the closest parent\r
85def GetParentAtLine (Line):\r
86 for Profile in AllIncludeFileList:\r
87 if Profile.IsLineInFile(Line):\r
88 return Profile\r
89 return None\r
90\r
91# Check include loop\r
92def IsValidInclude (File, Line):\r
93 for Profile in AllIncludeFileList:\r
94 if Profile.IsLineInFile(Line) and Profile.FileName == File:\r
95 return False\r
96\r
97 return True\r
30fdf114
LG
98\r
99def GetRealFileLine (File, Line):\r
30fdf114 100 InsertedLines = 0\r
118bf096
CS
101 for Profile in AllIncludeFileList:\r
102 if Profile.IsLineInFile(Line):\r
103 return Profile.GetLineInFile(Line)\r
104 elif Line >= Profile.InsertStartLineNumber and Profile.Level == 1:\r
df81077f 105 InsertedLines += Profile.GetTotalLines()\r
30fdf114
LG
106\r
107 return (File, Line - InsertedLines)\r
108\r
109## The exception class that used to report error messages when parsing FDF\r
110#\r
9e47e6f9 111# Currently the "ToolName" is set to be "FdfParser".\r
30fdf114
LG
112#\r
113class Warning (Exception):\r
114 ## The constructor\r
115 #\r
116 # @param self The object pointer\r
117 # @param Str The message to record\r
118 # @param File The FDF name\r
119 # @param Line The Line number that error occurs\r
120 #\r
121 def __init__(self, Str, File = None, Line = None):\r
30fdf114
LG
122 FileLineTuple = GetRealFileLine(File, Line)\r
123 self.FileName = FileLineTuple[0]\r
124 self.LineNumber = FileLineTuple[1]\r
118bf096 125 self.OriginalLineNumber = Line\r
30fdf114
LG
126 self.Message = Str\r
127 self.ToolName = 'FdfParser'\r
128\r
129 def __str__(self):\r
130 return self.Message\r
131\r
30fdf114
LG
132## The Include file content class that used to record file data when parsing include file\r
133#\r
134# May raise Exception when opening file.\r
135#\r
9e47e6f9 136class IncludeFileProfile:\r
30fdf114
LG
137 ## The constructor\r
138 #\r
139 # @param self The object pointer\r
140 # @param FileName The file that to be parsed\r
141 #\r
142 def __init__(self, FileName):\r
143 self.FileName = FileName\r
144 self.FileLinesList = []\r
145 try:\r
9e47e6f9 146 with open(FileName, "rb", 0) as fsock:\r
30fdf114 147 self.FileLinesList = fsock.readlines()\r
47a29bc7 148 for index, line in enumerate(self.FileLinesList):\r
9e47e6f9
CJ
149 if not line.endswith(TAB_LINE_BREAK):\r
150 self.FileLinesList[index] += TAB_LINE_BREAK\r
30fdf114
LG
151 except:\r
152 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)\r
153\r
154 self.InsertStartLineNumber = None\r
155 self.InsertAdjust = 0\r
118bf096
CS
156 self.IncludeFileList = []\r
157 self.Level = 1 # first level include file\r
f7496d71 158\r
118bf096
CS
159 def GetTotalLines(self):\r
160 TotalLines = self.InsertAdjust + len(self.FileLinesList)\r
161\r
162 for Profile in self.IncludeFileList:\r
df81077f 163 TotalLines += Profile.GetTotalLines()\r
118bf096
CS
164\r
165 return TotalLines\r
166\r
167 def IsLineInFile(self, Line):\r
168 if Line >= self.InsertStartLineNumber and Line < self.InsertStartLineNumber + self.GetTotalLines():\r
169 return True\r
170\r
171 return False\r
172\r
173 def GetLineInFile(self, Line):\r
174 if not self.IsLineInFile (Line):\r
175 return (self.FileName, -1)\r
f7496d71 176\r
118bf096
CS
177 InsertedLines = self.InsertStartLineNumber\r
178\r
179 for Profile in self.IncludeFileList:\r
180 if Profile.IsLineInFile(Line):\r
181 return Profile.GetLineInFile(Line)\r
182 elif Line >= Profile.InsertStartLineNumber:\r
183 InsertedLines += Profile.GetTotalLines()\r
184\r
185 return (self.FileName, Line - InsertedLines + 1)\r
186\r
187\r
30fdf114
LG
188\r
189## The FDF content class that used to record file data when parsing FDF\r
190#\r
191# May raise Exception when opening file.\r
192#\r
9e47e6f9 193class FileProfile:\r
30fdf114
LG
194 ## The constructor\r
195 #\r
196 # @param self The object pointer\r
197 # @param FileName The file that to be parsed\r
198 #\r
199 def __init__(self, FileName):\r
200 self.FileLinesList = []\r
201 try:\r
9e47e6f9 202 with open(FileName, "rb", 0) as fsock:\r
30fdf114 203 self.FileLinesList = fsock.readlines()\r
30fdf114
LG
204\r
205 except:\r
206 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)\r
207\r
543f5ac3 208 self.FileName = FileName\r
57ee97c0
B
209 self.PcdDict = OrderedDict()\r
210 self.PcdLocalDict = OrderedDict()\r
30fdf114 211 self.InfList = []\r
2502b735 212 self.InfDict = {'ArchTBD':[]}\r
d0acc87a
LG
213 # ECC will use this Dict and List information\r
214 self.PcdFileLineDict = {}\r
215 self.InfFileLineList = []\r
f7496d71 216\r
30fdf114 217 self.FdDict = {}\r
52302d4d 218 self.FdNameNotSet = False\r
30fdf114 219 self.FvDict = {}\r
fd171542 220 self.CapsuleDict = {}\r
30fdf114
LG
221 self.VtfList = []\r
222 self.RuleDict = {}\r
223 self.OptRomDict = {}\r
a3251d84 224 self.FmpPayloadDict = {}\r
30fdf114
LG
225\r
226## The syntax parser for FDF\r
227#\r
228# PreprocessFile method should be called prior to ParseFile\r
229# CycleReferenceCheck method can detect cycles in FDF contents\r
230#\r
231# GetNext*** procedures mean these procedures will get next token first, then make judgement.\r
232# Get*** procedures mean these procedures will make judgement on current token only.\r
233#\r
234class FdfParser:\r
235 ## The constructor\r
236 #\r
237 # @param self The object pointer\r
238 # @param FileName The file that to be parsed\r
239 #\r
240 def __init__(self, FileName):\r
241 self.Profile = FileProfile(FileName)\r
242 self.FileName = FileName\r
243 self.CurrentLineNumber = 1\r
244 self.CurrentOffsetWithinLine = 0\r
245 self.CurrentFdName = None\r
246 self.CurrentFvName = None\r
9e47e6f9
CJ
247 self._Token = ""\r
248 self._SkippedChars = ""\r
97fa0ee9 249 GlobalData.gFdfParser = self\r
30fdf114 250\r
d0acc87a 251 # Used to section info\r
9e47e6f9 252 self._CurSection = []\r
d0acc87a 253 # Key: [section name, UI name, arch]\r
9e47e6f9
CJ
254 # Value: {MACRO_NAME: MACRO_VALUE}\r
255 self._MacroDict = tdict(True, 3)\r
256 self._PcdDict = OrderedDict()\r
d0acc87a 257\r
9e47e6f9 258 self._WipeOffArea = []\r
14c48571 259 if GenFdsGlobalVariable.WorkSpaceDir == '':\r
260 GenFdsGlobalVariable.WorkSpaceDir = os.getenv("WORKSPACE")\r
30fdf114 261\r
9e47e6f9 262 ## _SkipWhiteSpace() method\r
30fdf114 263 #\r
9e47e6f9 264 # Skip white spaces from current char.\r
30fdf114
LG
265 #\r
266 # @param self The object pointer\r
30fdf114 267 #\r
9e47e6f9
CJ
268 def _SkipWhiteSpace(self):\r
269 while not self._EndOfFile():\r
5a264f28 270 if self._CurrentChar() in {TAB_PRINTCHAR_NUL, T_CHAR_CR, TAB_LINE_BREAK, TAB_SPACE_SPLIT, T_CHAR_TAB}:\r
9e47e6f9
CJ
271 self._SkippedChars += str(self._CurrentChar())\r
272 self._GetOneChar()\r
30fdf114 273 else:\r
9e47e6f9
CJ
274 return\r
275 return\r
30fdf114 276\r
9e47e6f9 277 ## _EndOfFile() method\r
30fdf114
LG
278 #\r
279 # Judge current buffer pos is at file end\r
280 #\r
281 # @param self The object pointer\r
282 # @retval True Current File buffer position is at file end\r
283 # @retval False Current File buffer position is NOT at file end\r
284 #\r
9e47e6f9 285 def _EndOfFile(self):\r
30fdf114
LG
286 NumberOfLines = len(self.Profile.FileLinesList)\r
287 SizeOfLastLine = len(self.Profile.FileLinesList[-1])\r
288 if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1:\r
289 return True\r
9e47e6f9 290 if self.CurrentLineNumber > NumberOfLines:\r
30fdf114 291 return True\r
9e47e6f9 292 return False\r
30fdf114 293\r
9e47e6f9 294 ## _EndOfLine() method\r
30fdf114
LG
295 #\r
296 # Judge current buffer pos is at line end\r
297 #\r
298 # @param self The object pointer\r
299 # @retval True Current File buffer position is at line end\r
300 # @retval False Current File buffer position is NOT at line end\r
301 #\r
9e47e6f9 302 def _EndOfLine(self):\r
30fdf114
LG
303 if self.CurrentLineNumber > len(self.Profile.FileLinesList):\r
304 return True\r
305 SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1])\r
306 if self.CurrentOffsetWithinLine >= SizeOfCurrentLine:\r
307 return True\r
9e47e6f9 308 return False\r
30fdf114
LG
309\r
310 ## Rewind() method\r
311 #\r
312 # Reset file data buffer to the initial state\r
313 #\r
314 # @param self The object pointer\r
118bf096 315 # @param DestLine Optional new destination line number.\r
f7496d71 316 # @param DestOffset Optional new destination offset.\r
30fdf114 317 #\r
f7496d71
LG
318 def Rewind(self, DestLine = 1, DestOffset = 0):\r
319 self.CurrentLineNumber = DestLine\r
320 self.CurrentOffsetWithinLine = DestOffset\r
30fdf114 321\r
9e47e6f9 322 ## _UndoOneChar() method\r
30fdf114
LG
323 #\r
324 # Go back one char in the file buffer\r
325 #\r
326 # @param self The object pointer\r
327 # @retval True Successfully go back one char\r
328 # @retval False Not able to go back one char as file beginning reached\r
329 #\r
9e47e6f9 330 def _UndoOneChar(self):\r
30fdf114
LG
331 if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0:\r
332 return False\r
333 elif self.CurrentOffsetWithinLine == 0:\r
334 self.CurrentLineNumber -= 1\r
9e47e6f9 335 self.CurrentOffsetWithinLine = len(self._CurrentLine()) - 1\r
30fdf114
LG
336 else:\r
337 self.CurrentOffsetWithinLine -= 1\r
338 return True\r
339\r
9e47e6f9 340 ## _GetOneChar() method\r
30fdf114
LG
341 #\r
342 # Move forward one char in the file buffer\r
343 #\r
344 # @param self The object pointer\r
345 #\r
9e47e6f9 346 def _GetOneChar(self):\r
30fdf114 347 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:\r
0d2711a6
LG
348 self.CurrentLineNumber += 1\r
349 self.CurrentOffsetWithinLine = 0\r
30fdf114 350 else:\r
0d2711a6 351 self.CurrentOffsetWithinLine += 1\r
30fdf114 352\r
9e47e6f9 353 ## _CurrentChar() method\r
30fdf114
LG
354 #\r
355 # Get the char pointed to by the file buffer pointer\r
356 #\r
357 # @param self The object pointer\r
358 # @retval Char Current char\r
359 #\r
9e47e6f9 360 def _CurrentChar(self):\r
30fdf114
LG
361 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine]\r
362\r
9e47e6f9 363 ## _NextChar() method\r
30fdf114
LG
364 #\r
365 # Get the one char pass the char pointed to by the file buffer pointer\r
366 #\r
367 # @param self The object pointer\r
368 # @retval Char Next char\r
369 #\r
9e47e6f9 370 def _NextChar(self):\r
30fdf114
LG
371 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:\r
372 return self.Profile.FileLinesList[self.CurrentLineNumber][0]\r
9e47e6f9 373 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1]\r
30fdf114 374\r
9e47e6f9 375 ## _SetCurrentCharValue() method\r
30fdf114
LG
376 #\r
377 # Modify the value of current char\r
378 #\r
379 # @param self The object pointer\r
380 # @param Value The new value of current char\r
381 #\r
9e47e6f9 382 def _SetCurrentCharValue(self, Value):\r
30fdf114
LG
383 self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value\r
384\r
9e47e6f9 385 ## _CurrentLine() method\r
30fdf114
LG
386 #\r
387 # Get the list that contains current line contents\r
388 #\r
389 # @param self The object pointer\r
390 # @retval List current line contents\r
391 #\r
9e47e6f9 392 def _CurrentLine(self):\r
30fdf114
LG
393 return self.Profile.FileLinesList[self.CurrentLineNumber - 1]\r
394\r
9e47e6f9 395 def _StringToList(self):\r
30fdf114 396 self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList]\r
3b46dd93
YF
397 if not self.Profile.FileLinesList:\r
398 EdkLogger.error('FdfParser', FILE_READ_FAILURE, 'The file is empty!', File=self.FileName)\r
30fdf114
LG
399 self.Profile.FileLinesList[-1].append(' ')\r
400\r
9e47e6f9 401 def _ReplaceFragment(self, StartPos, EndPos, Value = ' '):\r
30fdf114
LG
402 if StartPos[0] == EndPos[0]:\r
403 Offset = StartPos[1]\r
404 while Offset <= EndPos[1]:\r
405 self.Profile.FileLinesList[StartPos[0]][Offset] = Value\r
406 Offset += 1\r
407 return\r
408\r
409 Offset = StartPos[1]\r
5a264f28 410 while self.Profile.FileLinesList[StartPos[0]][Offset] not in CR_LB_SET:\r
30fdf114
LG
411 self.Profile.FileLinesList[StartPos[0]][Offset] = Value\r
412 Offset += 1\r
413\r
414 Line = StartPos[0]\r
415 while Line < EndPos[0]:\r
416 Offset = 0\r
5a264f28 417 while self.Profile.FileLinesList[Line][Offset] not in CR_LB_SET:\r
30fdf114
LG
418 self.Profile.FileLinesList[Line][Offset] = Value\r
419 Offset += 1\r
420 Line += 1\r
421\r
422 Offset = 0\r
423 while Offset <= EndPos[1]:\r
424 self.Profile.FileLinesList[EndPos[0]][Offset] = Value\r
425 Offset += 1\r
426\r
9e47e6f9
CJ
427 def _SetMacroValue(self, Macro, Value):\r
428 if not self._CurSection:\r
d0acc87a
LG
429 return\r
430\r
431 MacroDict = {}\r
9e47e6f9
CJ
432 if not self._MacroDict[self._CurSection[0], self._CurSection[1], self._CurSection[2]]:\r
433 self._MacroDict[self._CurSection[0], self._CurSection[1], self._CurSection[2]] = MacroDict\r
d0acc87a 434 else:\r
9e47e6f9 435 MacroDict = self._MacroDict[self._CurSection[0], self._CurSection[1], self._CurSection[2]]\r
d0acc87a
LG
436 MacroDict[Macro] = Value\r
437\r
9e47e6f9 438 def _GetMacroValue(self, Macro):\r
d0acc87a
LG
439 # Highest priority\r
440 if Macro in GlobalData.gCommandLineDefines:\r
441 return GlobalData.gCommandLineDefines[Macro]\r
442 if Macro in GlobalData.gGlobalDefines:\r
443 return GlobalData.gGlobalDefines[Macro]\r
444\r
9e47e6f9
CJ
445 if self._CurSection:\r
446 MacroDict = self._MacroDict[\r
447 self._CurSection[0],\r
448 self._CurSection[1],\r
449 self._CurSection[2]\r
d0acc87a
LG
450 ]\r
451 if MacroDict and Macro in MacroDict:\r
452 return MacroDict[Macro]\r
453\r
454 # Lowest priority\r
455 if Macro in GlobalData.gPlatformDefines:\r
456 return GlobalData.gPlatformDefines[Macro]\r
457 return None\r
458\r
9e47e6f9 459 def _SectionHeaderParser(self, Section):\r
d0acc87a
LG
460 # [Defines]\r
461 # [FD.UiName]: use dummy instead if UI name is optional\r
462 # [FV.UiName]\r
463 # [Capsule.UiName]\r
464 # [Rule]: don't take rule section into account, macro is not allowed in this section\r
465 # [VTF.arch.UiName, arch]\r
466 # [OptionRom.DriverName]\r
9e47e6f9
CJ
467 self._CurSection = []\r
468 Section = Section.strip()[1:-1].upper().replace(' ', '').strip(TAB_SPLIT)\r
469 ItemList = Section.split(TAB_SPLIT)\r
d0acc87a
LG
470 Item = ItemList[0]\r
471 if Item == '' or Item == 'RULE':\r
472 return\r
473\r
55c84777 474 if Item == TAB_COMMON_DEFINES.upper():\r
9e47e6f9 475 self._CurSection = [TAB_COMMON, TAB_COMMON, TAB_COMMON]\r
d0acc87a
LG
476 elif Item == 'VTF' and len(ItemList) == 3:\r
477 UiName = ItemList[2]\r
9e47e6f9 478 Pos = UiName.find(TAB_COMMA_SPLIT)\r
d0acc87a
LG
479 if Pos != -1:\r
480 UiName = UiName[:Pos]\r
9e47e6f9 481 self._CurSection = ['VTF', UiName, ItemList[1]]\r
d0acc87a 482 elif len(ItemList) > 1:\r
9e47e6f9 483 self._CurSection = [ItemList[0], ItemList[1], TAB_COMMON]\r
d0acc87a 484 elif len(ItemList) > 0:\r
9e47e6f9 485 self._CurSection = [ItemList[0], 'DUMMY', TAB_COMMON]\r
d0acc87a 486\r
30fdf114
LG
487 ## PreprocessFile() method\r
488 #\r
489 # Preprocess file contents, replace comments with spaces.\r
490 # In the end, rewind the file buffer pointer to the beginning\r
491 # BUGBUG: No !include statement processing contained in this procedure\r
492 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]\r
493 #\r
494 # @param self The object pointer\r
495 #\r
496 def PreprocessFile(self):\r
30fdf114
LG
497 self.Rewind()\r
498 InComment = False\r
499 DoubleSlashComment = False\r
500 HashComment = False\r
501 # HashComment in quoted string " " is ignored.\r
502 InString = False\r
503\r
9e47e6f9 504 while not self._EndOfFile():\r
30fdf114 505\r
9e47e6f9 506 if self._CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment:\r
30fdf114
LG
507 InString = not InString\r
508 # meet new line, then no longer in a comment for // and '#'\r
9e47e6f9 509 if self._CurrentChar() == TAB_LINE_BREAK:\r
30fdf114
LG
510 self.CurrentLineNumber += 1\r
511 self.CurrentOffsetWithinLine = 0\r
512 if InComment and DoubleSlashComment:\r
513 InComment = False\r
514 DoubleSlashComment = False\r
515 if InComment and HashComment:\r
516 InComment = False\r
517 HashComment = False\r
518 # check for */ comment end\r
9e47e6f9
CJ
519 elif InComment and not DoubleSlashComment and not HashComment and self._CurrentChar() == T_CHAR_STAR and self._NextChar() == TAB_BACK_SLASH:\r
520 self._SetCurrentCharValue(TAB_SPACE_SPLIT)\r
521 self._GetOneChar()\r
522 self._SetCurrentCharValue(TAB_SPACE_SPLIT)\r
523 self._GetOneChar()\r
30fdf114
LG
524 InComment = False\r
525 # set comments to spaces\r
526 elif InComment:\r
9e47e6f9
CJ
527 self._SetCurrentCharValue(TAB_SPACE_SPLIT)\r
528 self._GetOneChar()\r
30fdf114 529 # check for // comment\r
9e47e6f9 530 elif self._CurrentChar() == TAB_BACK_SLASH and self._NextChar() == TAB_BACK_SLASH and not self._EndOfLine():\r
30fdf114
LG
531 InComment = True\r
532 DoubleSlashComment = True\r
533 # check for '#' comment\r
9e47e6f9 534 elif self._CurrentChar() == TAB_COMMENT_SPLIT and not self._EndOfLine() and not InString:\r
30fdf114
LG
535 InComment = True\r
536 HashComment = True\r
537 # check for /* comment start\r
9e47e6f9
CJ
538 elif self._CurrentChar() == TAB_BACK_SLASH and self._NextChar() == T_CHAR_STAR:\r
539 self._SetCurrentCharValue(TAB_SPACE_SPLIT)\r
540 self._GetOneChar()\r
541 self._SetCurrentCharValue(TAB_SPACE_SPLIT)\r
542 self._GetOneChar()\r
30fdf114
LG
543 InComment = True\r
544 else:\r
9e47e6f9 545 self._GetOneChar()\r
30fdf114
LG
546\r
547 # restore from ListOfList to ListOfString\r
548 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]\r
549 self.Rewind()\r
550\r
551 ## PreprocessIncludeFile() method\r
552 #\r
553 # Preprocess file contents, replace !include statements with file contents.\r
554 # In the end, rewind the file buffer pointer to the beginning\r
555 #\r
556 # @param self The object pointer\r
557 #\r
558 def PreprocessIncludeFile(self):\r
f7496d71 559 # nested include support\r
118bf096 560 Processed = False\r
0fdfe274 561 MacroDict = {}\r
9e47e6f9 562 while self._GetNextToken():\r
30fdf114 563\r
9e47e6f9
CJ
564 if self._Token == TAB_DEFINE:\r
565 if not self._GetNextToken():\r
0fdfe274 566 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
567 Macro = self._Token\r
568 if not self._IsToken(TAB_EQUAL_SPLIT):\r
0fdfe274 569 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 570 Value = self._GetExpression()\r
0fdfe274
YZ
571 MacroDict[Macro] = Value\r
572\r
9e47e6f9 573 elif self._Token == TAB_INCLUDE:\r
118bf096 574 Processed = True\r
30fdf114 575 IncludeLine = self.CurrentLineNumber\r
9e47e6f9
CJ
576 IncludeOffset = self.CurrentOffsetWithinLine - len(TAB_INCLUDE)\r
577 if not self._GetNextToken():\r
30fdf114 578 raise Warning("expected include file name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 579 IncFileName = self._Token\r
0fdfe274
YZ
580 PreIndex = 0\r
581 StartPos = IncFileName.find('$(', PreIndex)\r
582 EndPos = IncFileName.find(')', StartPos+2)\r
583 while StartPos != -1 and EndPos != -1:\r
9e47e6f9
CJ
584 Macro = IncFileName[StartPos+2: EndPos]\r
585 MacroVal = self._GetMacroValue(Macro)\r
0fdfe274
YZ
586 if not MacroVal:\r
587 if Macro in MacroDict:\r
588 MacroVal = MacroDict[Macro]\r
4231a819 589 if MacroVal is not None:\r
0fdfe274
YZ
590 IncFileName = IncFileName.replace('$(' + Macro + ')', MacroVal, 1)\r
591 if MacroVal.find('$(') != -1:\r
592 PreIndex = StartPos\r
593 else:\r
594 PreIndex = StartPos + len(MacroVal)\r
595 else:\r
596 raise Warning("The Macro %s is not defined" %Macro, self.FileName, self.CurrentLineNumber)\r
597 StartPos = IncFileName.find('$(', PreIndex)\r
598 EndPos = IncFileName.find(')', StartPos+2)\r
599\r
600 IncludedFile = NormPath(IncFileName)\r
2bcc713e
LG
601 #\r
602 # First search the include file under the same directory as FDF file\r
603 #\r
604 IncludedFile1 = PathClass(IncludedFile, os.path.dirname(self.FileName))\r
605 ErrorCode = IncludedFile1.Validate()[0]\r
606 if ErrorCode != 0:\r
607 #\r
608 # Then search the include file under the same directory as DSC file\r
609 #\r
d0acc87a
LG
610 PlatformDir = ''\r
611 if GenFdsGlobalVariable.ActivePlatform:\r
612 PlatformDir = GenFdsGlobalVariable.ActivePlatform.Dir\r
613 elif GlobalData.gActivePlatform:\r
614 PlatformDir = GlobalData.gActivePlatform.MetaFile.Dir\r
615 IncludedFile1 = PathClass(IncludedFile, PlatformDir)\r
2bcc713e
LG
616 ErrorCode = IncludedFile1.Validate()[0]\r
617 if ErrorCode != 0:\r
618 #\r
619 # Also search file under the WORKSPACE directory\r
620 #\r
621 IncludedFile1 = PathClass(IncludedFile, GlobalData.gWorkspace)\r
622 ErrorCode = IncludedFile1.Validate()[0]\r
623 if ErrorCode != 0:\r
f7496d71 624 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 625 self.FileName, self.CurrentLineNumber)\r
30fdf114 626\r
118bf096
CS
627 if not IsValidInclude (IncludedFile1.Path, self.CurrentLineNumber):\r
628 raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1.Path), self.FileName, self.CurrentLineNumber)\r
629\r
2bcc713e 630 IncFileProfile = IncludeFileProfile(IncludedFile1.Path)\r
30fdf114
LG
631\r
632 CurrentLine = self.CurrentLineNumber\r
633 CurrentOffset = self.CurrentOffsetWithinLine\r
634 # list index of the insertion, note that line number is 'CurrentLine + 1'\r
635 InsertAtLine = CurrentLine\r
118bf096 636 ParentProfile = GetParentAtLine (CurrentLine)\r
4231a819 637 if ParentProfile is not None:\r
118bf096
CS
638 ParentProfile.IncludeFileList.insert(0, IncFileProfile)\r
639 IncFileProfile.Level = ParentProfile.Level + 1\r
30fdf114
LG
640 IncFileProfile.InsertStartLineNumber = InsertAtLine + 1\r
641 # deal with remaining portions after "!include filename", if exists.\r
9e47e6f9 642 if self._GetNextToken():\r
30fdf114 643 if self.CurrentLineNumber == CurrentLine:\r
9e47e6f9 644 RemainingLine = self._CurrentLine()[CurrentOffset:]\r
30fdf114
LG
645 self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine)\r
646 IncFileProfile.InsertAdjust += 1\r
647 self.CurrentLineNumber += 1\r
648 self.CurrentOffsetWithinLine = 0\r
649\r
650 for Line in IncFileProfile.FileLinesList:\r
651 self.Profile.FileLinesList.insert(InsertAtLine, Line)\r
652 self.CurrentLineNumber += 1\r
653 InsertAtLine += 1\r
654\r
118bf096
CS
655 # reversely sorted to better determine error in file\r
656 AllIncludeFileList.insert(0, IncFileProfile)\r
30fdf114
LG
657\r
658 # comment out the processed include file statement\r
659 TempList = list(self.Profile.FileLinesList[IncludeLine - 1])\r
9e47e6f9 660 TempList.insert(IncludeOffset, TAB_COMMENT_SPLIT)\r
30fdf114 661 self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList)\r
118bf096
CS
662 if Processed: # Nested and back-to-back support\r
663 self.Rewind(DestLine = IncFileProfile.InsertStartLineNumber - 1)\r
664 Processed = False\r
665 # Preprocess done.\r
30fdf114 666 self.Rewind()\r
f7496d71 667\r
5bcf1d56 668 @staticmethod\r
9e47e6f9 669 def _GetIfListCurrentItemStat(IfList):\r
da92f276
LG
670 if len(IfList) == 0:\r
671 return True\r
f7496d71 672\r
da92f276
LG
673 for Item in IfList:\r
674 if Item[1] == False:\r
675 return False\r
f7496d71 676\r
da92f276 677 return True\r
f7496d71 678\r
6780eef1 679 ## PreprocessConditionalStatement() method\r
30fdf114 680 #\r
6780eef1 681 # Preprocess conditional statement.\r
30fdf114
LG
682 # In the end, rewind the file buffer pointer to the beginning\r
683 #\r
684 # @param self The object pointer\r
685 #\r
686 def PreprocessConditionalStatement(self):\r
687 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]\r
688 IfList = []\r
0d2711a6 689 RegionLayoutLine = 0\r
d0acc87a 690 ReplacedLine = -1\r
9e47e6f9 691 while self._GetNextToken():\r
d0acc87a 692 # Determine section name and the location dependent macro\r
9e47e6f9
CJ
693 if self._GetIfListCurrentItemStat(IfList):\r
694 if self._Token.startswith(TAB_SECTION_START):\r
695 Header = self._Token\r
696 if not self._Token.endswith(TAB_SECTION_END):\r
697 self._SkipToToken(TAB_SECTION_END)\r
698 Header += self._SkippedChars\r
d0acc87a
LG
699 if Header.find('$(') != -1:\r
700 raise Warning("macro cannot be used in section header", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 701 self._SectionHeaderParser(Header)\r
d0acc87a
LG
702 continue\r
703 # Replace macros except in RULE section or out of section\r
9e47e6f9 704 elif self._CurSection and ReplacedLine != self.CurrentLineNumber:\r
d0acc87a 705 ReplacedLine = self.CurrentLineNumber\r
9e47e6f9 706 self._UndoToken()\r
d0acc87a
LG
707 CurLine = self.Profile.FileLinesList[ReplacedLine - 1]\r
708 PreIndex = 0\r
709 StartPos = CurLine.find('$(', PreIndex)\r
710 EndPos = CurLine.find(')', StartPos+2)\r
5a264f28 711 while StartPos != -1 and EndPos != -1 and self._Token not in {TAB_IF_DEF, TAB_IF_N_DEF, TAB_IF, TAB_ELSE_IF}:\r
9e47e6f9
CJ
712 MacroName = CurLine[StartPos+2: EndPos]\r
713 MacorValue = self._GetMacroValue(MacroName)\r
4231a819 714 if MacorValue is not None:\r
d0acc87a
LG
715 CurLine = CurLine.replace('$(' + MacroName + ')', MacorValue, 1)\r
716 if MacorValue.find('$(') != -1:\r
717 PreIndex = StartPos\r
718 else:\r
719 PreIndex = StartPos + len(MacorValue)\r
720 else:\r
721 PreIndex = EndPos + 1\r
722 StartPos = CurLine.find('$(', PreIndex)\r
723 EndPos = CurLine.find(')', StartPos+2)\r
724 self.Profile.FileLinesList[ReplacedLine - 1] = CurLine\r
725 continue\r
726\r
9e47e6f9
CJ
727 if self._Token == TAB_DEFINE:\r
728 if self._GetIfListCurrentItemStat(IfList):\r
729 if not self._CurSection:\r
d0acc87a 730 raise Warning("macro cannot be defined in Rule section or out of section", self.FileName, self.CurrentLineNumber)\r
da92f276 731 DefineLine = self.CurrentLineNumber - 1\r
9e47e6f9
CJ
732 DefineOffset = self.CurrentOffsetWithinLine - len(TAB_DEFINE)\r
733 if not self._GetNextToken():\r
da92f276 734 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
735 Macro = self._Token\r
736 if not self._IsToken(TAB_EQUAL_SPLIT):\r
da92f276 737 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
f7496d71 738\r
9e47e6f9
CJ
739 Value = self._GetExpression()\r
740 self._SetMacroValue(Macro, Value)\r
741 self._WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
742 elif self._Token == 'SET':\r
743 if not self._GetIfListCurrentItemStat(IfList):\r
2f04e527 744 continue\r
64b2609f
LG
745 SetLine = self.CurrentLineNumber - 1\r
746 SetOffset = self.CurrentOffsetWithinLine - len('SET')\r
9e47e6f9 747 PcdPair = self._GetNextPcdSettings()\r
0d2711a6 748 PcdName = "%s.%s" % (PcdPair[1], PcdPair[0])\r
9e47e6f9 749 if not self._IsToken(TAB_EQUAL_SPLIT):\r
0d2711a6
LG
750 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
751\r
9e47e6f9
CJ
752 Value = self._GetExpression()\r
753 Value = self._EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)\r
30fdf114 754\r
9e47e6f9 755 self._PcdDict[PcdName] = Value\r
64b2609f
LG
756\r
757 self.Profile.PcdDict[PcdPair] = Value\r
543f5ac3 758 self.SetPcdLocalation(PcdPair)\r
64b2609f
LG
759 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
760 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple\r
761\r
9e47e6f9 762 self._WipeOffArea.append(((SetLine, SetOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
5a264f28 763 elif self._Token in {TAB_IF_DEF, TAB_IF_N_DEF, TAB_IF}:\r
9e47e6f9 764 IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self._Token))\r
30fdf114 765 IfList.append([IfStartPos, None, None])\r
0d2711a6 766\r
9e47e6f9
CJ
767 CondLabel = self._Token\r
768 Expression = self._GetExpression()\r
f7496d71 769\r
9e47e6f9
CJ
770 if CondLabel == TAB_IF:\r
771 ConditionSatisfied = self._EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')\r
30fdf114 772 else:\r
9e47e6f9
CJ
773 ConditionSatisfied = self._EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'in')\r
774 if CondLabel == TAB_IF_N_DEF:\r
30fdf114 775 ConditionSatisfied = not ConditionSatisfied\r
30fdf114 776\r
0d2711a6
LG
777 BranchDetermined = ConditionSatisfied\r
778 IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]\r
779 if ConditionSatisfied:\r
9e47e6f9 780 self._WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
5a264f28 781 elif self._Token in {TAB_ELSE_IF, TAB_ELSE}:\r
9e47e6f9 782 ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self._Token))\r
30fdf114
LG
783 if len(IfList) <= 0:\r
784 raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)\r
0d2711a6 785\r
30fdf114
LG
786 if IfList[-1][1]:\r
787 IfList[-1] = [ElseStartPos, False, True]\r
9e47e6f9 788 self._WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
30fdf114 789 else:\r
9e47e6f9 790 self._WipeOffArea.append((IfList[-1][0], ElseStartPos))\r
30fdf114 791 IfList[-1] = [ElseStartPos, True, IfList[-1][2]]\r
9e47e6f9
CJ
792 if self._Token == TAB_ELSE_IF:\r
793 Expression = self._GetExpression()\r
794 ConditionSatisfied = self._EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')\r
30fdf114
LG
795 IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]]\r
796\r
797 if IfList[-1][1]:\r
798 if IfList[-1][2]:\r
799 IfList[-1][1] = False\r
800 else:\r
801 IfList[-1][2] = True\r
9e47e6f9
CJ
802 self._WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
803 elif self._Token == '!endif':\r
d0acc87a
LG
804 if len(IfList) <= 0:\r
805 raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)\r
30fdf114 806 if IfList[-1][1]:\r
9e47e6f9 807 self._WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
30fdf114 808 else:\r
9e47e6f9 809 self._WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
30fdf114
LG
810\r
811 IfList.pop()\r
0d2711a6
LG
812 elif not IfList: # Don't use PCDs inside conditional directive\r
813 if self.CurrentLineNumber <= RegionLayoutLine:\r
814 # Don't try the same line twice\r
815 continue\r
64b2609f
LG
816 SetPcd = ShortcutPcdPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])\r
817 if SetPcd:\r
9e47e6f9 818 self._PcdDict[SetPcd.group('name')] = SetPcd.group('value')\r
64b2609f
LG
819 RegionLayoutLine = self.CurrentLineNumber\r
820 continue\r
0d2711a6
LG
821 RegionSize = RegionSizePattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])\r
822 if not RegionSize:\r
823 RegionLayoutLine = self.CurrentLineNumber\r
824 continue\r
825 RegionSizeGuid = RegionSizeGuidPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber])\r
826 if not RegionSizeGuid:\r
827 RegionLayoutLine = self.CurrentLineNumber + 1\r
828 continue\r
9e47e6f9
CJ
829 self._PcdDict[RegionSizeGuid.group('base')] = RegionSize.group('base')\r
830 self._PcdDict[RegionSizeGuid.group('size')] = RegionSize.group('size')\r
0d2711a6
LG
831 RegionLayoutLine = self.CurrentLineNumber + 1\r
832\r
833 if IfList:\r
30fdf114
LG
834 raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber)\r
835 self.Rewind()\r
836\r
9e47e6f9 837 def _CollectMacroPcd(self):\r
d0acc87a
LG
838 MacroDict = {}\r
839\r
840 # PCD macro\r
64b2609f 841 MacroDict.update(GlobalData.gPlatformPcds)\r
9e47e6f9 842 MacroDict.update(self._PcdDict)\r
d0acc87a
LG
843\r
844 # Lowest priority\r
845 MacroDict.update(GlobalData.gPlatformDefines)\r
846\r
9e47e6f9 847 if self._CurSection:\r
d0acc87a 848 # Defines macro\r
9e47e6f9 849 ScopeMacro = self._MacroDict[TAB_COMMON, TAB_COMMON, TAB_COMMON]\r
d0acc87a
LG
850 if ScopeMacro:\r
851 MacroDict.update(ScopeMacro)\r
f7496d71 852\r
d0acc87a 853 # Section macro\r
9e47e6f9
CJ
854 ScopeMacro = self._MacroDict[\r
855 self._CurSection[0],\r
856 self._CurSection[1],\r
857 self._CurSection[2]\r
d0acc87a
LG
858 ]\r
859 if ScopeMacro:\r
860 MacroDict.update(ScopeMacro)\r
861\r
862 MacroDict.update(GlobalData.gGlobalDefines)\r
863 MacroDict.update(GlobalData.gCommandLineDefines)\r
5a264f28
CJ
864 for Item in GlobalData.BuildOptionPcd:\r
865 if isinstance(Item, tuple):\r
866 continue\r
867 PcdName, TmpValue = Item.split(TAB_EQUAL_SPLIT)\r
868 TmpValue = BuildOptionValue(TmpValue, {})\r
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
5a264f28 970 while Line[Index] in CR_LB_SET:\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 1068 self._Token = self.Profile.FileLinesList[StartLine-1][StartPos: EndPos]\r
5a264f28 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
9e47e6f9 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
5a264f28 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
9ffaaac2 2093 FvObj = FV(Name=self.CurrentFvName)\r
30fdf114
LG
2094 self.Profile.FvDict[self.CurrentFvName] = FvObj\r
2095\r
9e47e6f9 2096 Status = self._GetCreateFile(FvObj)\r
30fdf114
LG
2097 if not Status:\r
2098 raise Warning("FV name error", self.FileName, self.CurrentLineNumber)\r
2099\r
9e47e6f9 2100 self._GetDefineStatements(FvObj)\r
30fdf114 2101\r
9e47e6f9 2102 self._GetAddressStatements(FvObj)\r
30fdf114 2103\r
b303ea72 2104 while True:\r
9e47e6f9 2105 self._GetSetStatements(FvObj)\r
e8a47801 2106\r
9e47e6f9
CJ
2107 if not (self._GetBlockStatement(FvObj) or self._GetFvBaseAddress(FvObj) or\r
2108 self._GetFvForceRebase(FvObj) or self._GetFvAlignment(FvObj) or\r
2109 self._GetFvAttributes(FvObj) or self._GetFvNameGuid(FvObj) or\r
2110 self._GetFvExtEntryStatement(FvObj) or self._GetFvNameString(FvObj)):\r
b303ea72
LG
2111 break\r
2112\r
aaf8aa7b
YL
2113 if FvObj.FvNameString == 'TRUE' and not FvObj.FvNameGuid:\r
2114 raise Warning("FvNameString found but FvNameGuid was not found", self.FileName, self.CurrentLineNumber)\r
2115\r
5a6a268d
JC
2116 self._GetAprioriSection(FvObj)\r
2117 self._GetAprioriSection(FvObj)\r
30fdf114
LG
2118\r
2119 while True:\r
9e47e6f9 2120 isInf = self._GetInfStatement(FvObj)\r
5a6a268d 2121 isFile = self._GetFileStatement(FvObj)\r
30fdf114
LG
2122 if not isInf and not isFile:\r
2123 break\r
2124\r
2125 return True\r
2126\r
9e47e6f9 2127 ## _GetFvAlignment() method\r
30fdf114
LG
2128 #\r
2129 # Get alignment for FV\r
2130 #\r
2131 # @param self The object pointer\r
2132 # @param Obj for whom alignment is got\r
2133 # @retval True Successfully find a alignment statement\r
2134 # @retval False Not able to find a alignment statement\r
2135 #\r
9e47e6f9
CJ
2136 def _GetFvAlignment(self, Obj):\r
2137 if not self._IsKeyword("FvAlignment"):\r
30fdf114
LG
2138 return False\r
2139\r
9e47e6f9 2140 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
2141 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2142\r
9e47e6f9 2143 if not self._GetNextToken():\r
30fdf114
LG
2144 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)\r
2145\r
5a264f28 2146 if self._Token.upper() not in {"1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \\r
30fdf114
LG
2147 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \\r
2148 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \\r
5a264f28 2149 "1G", "2G"}:\r
9e47e6f9
CJ
2150 raise Warning("Unknown alignment value '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
2151 Obj.FvAlignment = self._Token\r
30fdf114 2152 return True\r
f7496d71 2153\r
9e47e6f9 2154 ## _GetFvBaseAddress() method\r
4234283c
LG
2155 #\r
2156 # Get BaseAddress for FV\r
2157 #\r
2158 # @param self The object pointer\r
2159 # @param Obj for whom FvBaseAddress is got\r
2160 # @retval True Successfully find a FvBaseAddress statement\r
2161 # @retval False Not able to find a FvBaseAddress statement\r
2162 #\r
9e47e6f9
CJ
2163 def _GetFvBaseAddress(self, Obj):\r
2164 if not self._IsKeyword("FvBaseAddress"):\r
4234283c
LG
2165 return False\r
2166\r
9e47e6f9 2167 if not self._IsToken(TAB_EQUAL_SPLIT):\r
4234283c
LG
2168 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2169\r
9e47e6f9 2170 if not self._GetNextToken():\r
4234283c
LG
2171 raise Warning("expected FV base address value", self.FileName, self.CurrentLineNumber)\r
2172\r
9e47e6f9
CJ
2173 if not BaseAddrValuePattern.match(self._Token.upper()):\r
2174 raise Warning("Unknown FV base address value '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
2175 Obj.FvBaseAddress = self._Token\r
f7496d71
LG
2176 return True\r
2177\r
9e47e6f9 2178 ## _GetFvForceRebase() method\r
79b74a03
LG
2179 #\r
2180 # Get FvForceRebase for FV\r
2181 #\r
2182 # @param self The object pointer\r
2183 # @param Obj for whom FvForceRebase is got\r
2184 # @retval True Successfully find a FvForceRebase statement\r
2185 # @retval False Not able to find a FvForceRebase statement\r
2186 #\r
9e47e6f9
CJ
2187 def _GetFvForceRebase(self, Obj):\r
2188 if not self._IsKeyword("FvForceRebase"):\r
79b74a03
LG
2189 return False\r
2190\r
9e47e6f9 2191 if not self._IsToken(TAB_EQUAL_SPLIT):\r
79b74a03
LG
2192 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2193\r
9e47e6f9 2194 if not self._GetNextToken():\r
79b74a03 2195 raise Warning("expected FvForceRebase value", self.FileName, self.CurrentLineNumber)\r
30fdf114 2196\r
5a264f28 2197 if self._Token.upper() not in {"TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"}:\r
9e47e6f9 2198 raise Warning("Unknown FvForceRebase value '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
f7496d71 2199\r
5a264f28 2200 if self._Token.upper() in {"TRUE", "1", "0X1", "0X01"}:\r
79b74a03 2201 Obj.FvForceRebase = True\r
5a264f28 2202 elif self._Token.upper() in {"FALSE", "0", "0X0", "0X00"}:\r
79b74a03
LG
2203 Obj.FvForceRebase = False\r
2204 else:\r
2205 Obj.FvForceRebase = None\r
f7496d71 2206\r
79b74a03 2207 return True\r
0d2711a6
LG
2208\r
2209\r
9e47e6f9 2210 ## _GetFvAttributes() method\r
30fdf114
LG
2211 #\r
2212 # Get attributes for FV\r
2213 #\r
2214 # @param self The object pointer\r
2215 # @param Obj for whom attribute is got\r
2216 # @retval None\r
2217 #\r
9e47e6f9 2218 def _GetFvAttributes(self, FvObj):\r
2bc3256c 2219 IsWordToken = False\r
9e47e6f9 2220 while self._GetNextWord():\r
2bc3256c 2221 IsWordToken = True\r
9e47e6f9 2222 name = self._Token\r
5a264f28 2223 if name not in {"ERASE_POLARITY", "MEMORY_MAPPED", \\r
30fdf114
LG
2224 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \\r
2225 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \\r
2226 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \\r
2227 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \\r
5a264f28 2228 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"}:\r
9e47e6f9 2229 self._UndoToken()\r
e8a47801 2230 return False\r
30fdf114 2231\r
9e47e6f9 2232 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
2233 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2234\r
5a264f28 2235 if not self._GetNextToken() or self._Token.upper() not in {"TRUE", "FALSE", "1", "0"}:\r
30fdf114
LG
2236 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)\r
2237\r
9e47e6f9 2238 FvObj.FvAttributeDict[name] = self._Token\r
30fdf114 2239\r
2bc3256c 2240 return IsWordToken\r
f7496d71 2241\r
9e47e6f9 2242 ## _GetFvNameGuid() method\r
30fdf114
LG
2243 #\r
2244 # Get FV GUID for FV\r
2245 #\r
2246 # @param self The object pointer\r
2247 # @param Obj for whom GUID is got\r
2248 # @retval None\r
2249 #\r
9e47e6f9
CJ
2250 def _GetFvNameGuid(self, FvObj):\r
2251 if not self._IsKeyword("FvNameGuid"):\r
e8a47801 2252 return False\r
30fdf114 2253\r
9e47e6f9 2254 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
2255 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2256\r
9e47e6f9 2257 if not self._GetNextGuid():\r
30fdf114
LG
2258 raise Warning("expected FV GUID value", self.FileName, self.CurrentLineNumber)\r
2259\r
9e47e6f9 2260 FvObj.FvNameGuid = self._Token\r
30fdf114 2261\r
e8a47801 2262 return True\r
30fdf114 2263\r
9e47e6f9
CJ
2264 def _GetFvNameString(self, FvObj):\r
2265 if not self._IsKeyword("FvNameString"):\r
aaf8aa7b
YL
2266 return False\r
2267\r
9e47e6f9 2268 if not self._IsToken(TAB_EQUAL_SPLIT):\r
aaf8aa7b
YL
2269 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2270\r
5a264f28 2271 if not self._GetNextToken() or self._Token not in {'TRUE', 'FALSE'}:\r
aaf8aa7b
YL
2272 raise Warning("expected TRUE or FALSE for FvNameString", self.FileName, self.CurrentLineNumber)\r
2273\r
9e47e6f9 2274 FvObj.FvNameString = self._Token\r
aaf8aa7b
YL
2275\r
2276 return True\r
2277\r
9e47e6f9
CJ
2278 def _GetFvExtEntryStatement(self, FvObj):\r
2279 if not (self._IsKeyword("FV_EXT_ENTRY") or self._IsKeyword("FV_EXT_ENTRY_TYPE")):\r
b303ea72
LG
2280 return False\r
2281\r
9e47e6f9 2282 if not self._IsKeyword ("TYPE"):\r
b303ea72 2283 raise Warning("expected 'TYPE'", self.FileName, self.CurrentLineNumber)\r
f7496d71 2284\r
9e47e6f9 2285 if not self._IsToken(TAB_EQUAL_SPLIT):\r
b303ea72
LG
2286 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2287\r
9e47e6f9 2288 if not self._GetNextHexNumber() and not self._GetNextDecimalNumber():\r
b303ea72
LG
2289 raise Warning("expected Hex FV extension entry type value At Line ", self.FileName, self.CurrentLineNumber)\r
2290\r
9e47e6f9 2291 FvObj.FvExtEntryTypeValue.append(self._Token)\r
b303ea72 2292\r
9e47e6f9 2293 if not self._IsToken("{"):\r
b303ea72
LG
2294 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2295\r
9e47e6f9 2296 if not self._IsKeyword ("FILE") and not self._IsKeyword ("DATA"):\r
b303ea72
LG
2297 raise Warning("expected 'FILE' or 'DATA'", self.FileName, self.CurrentLineNumber)\r
2298\r
9e47e6f9 2299 FvObj.FvExtEntryType.append(self._Token)\r
b303ea72 2300\r
9e47e6f9 2301 if self._Token == 'DATA':\r
b303ea72 2302\r
9e47e6f9 2303 if not self._IsToken(TAB_EQUAL_SPLIT):\r
b303ea72 2304 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
f7496d71 2305\r
9e47e6f9 2306 if not self._IsToken("{"):\r
b303ea72
LG
2307 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2308\r
9e47e6f9 2309 if not self._GetNextHexNumber():\r
b303ea72
LG
2310 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)\r
2311\r
9e47e6f9 2312 if len(self._Token) > 4:\r
b303ea72
LG
2313 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
2314\r
9e47e6f9
CJ
2315 DataString = self._Token\r
2316 DataString += TAB_COMMA_SPLIT\r
b303ea72 2317\r
9e47e6f9
CJ
2318 while self._IsToken(TAB_COMMA_SPLIT):\r
2319 if not self._GetNextHexNumber():\r
b303ea72 2320 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2321 if len(self._Token) > 4:\r
b303ea72 2322 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
2323 DataString += self._Token\r
2324 DataString += TAB_COMMA_SPLIT\r
b303ea72 2325\r
9e47e6f9 2326 if not self._IsToken("}"):\r
b303ea72
LG
2327 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2328\r
9e47e6f9 2329 if not self._IsToken("}"):\r
b303ea72
LG
2330 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2331\r
9e47e6f9 2332 DataString = DataString.rstrip(TAB_COMMA_SPLIT)\r
caf74495 2333 FvObj.FvExtEntryData.append(DataString)\r
b303ea72 2334\r
9e47e6f9 2335 if self._Token == 'FILE':\r
f7496d71 2336\r
9e47e6f9 2337 if not self._IsToken(TAB_EQUAL_SPLIT):\r
b303ea72 2338 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
f7496d71 2339\r
9e47e6f9 2340 if not self._GetNextToken():\r
b303ea72 2341 raise Warning("expected FV Extension Entry file path At Line ", self.FileName, self.CurrentLineNumber)\r
f7496d71 2342\r
9e47e6f9 2343 FvObj.FvExtEntryData.append(self._Token)\r
b303ea72 2344\r
9e47e6f9 2345 if not self._IsToken("}"):\r
b303ea72
LG
2346 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2347\r
2348 return True\r
2349\r
9e47e6f9 2350 ## _GetAprioriSection() method\r
30fdf114
LG
2351 #\r
2352 # Get token statements\r
2353 #\r
2354 # @param self The object pointer\r
2355 # @param FvObj for whom apriori is got\r
30fdf114
LG
2356 # @retval True Successfully find apriori statement\r
2357 # @retval False Not able to find apriori statement\r
2358 #\r
5a6a268d 2359 def _GetAprioriSection(self, FvObj):\r
9e47e6f9 2360 if not self._IsKeyword("APRIORI"):\r
30fdf114
LG
2361 return False\r
2362\r
9e47e6f9 2363 if not self._IsKeyword("PEI") and not self._IsKeyword("DXE"):\r
30fdf114 2364 raise Warning("expected Apriori file type", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2365 AprType = self._Token\r
30fdf114 2366\r
9e47e6f9 2367 if not self._IsToken("{"):\r
30fdf114
LG
2368 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2369\r
9e47e6f9 2370 AprSectionObj = AprioriSection()\r
30fdf114
LG
2371 AprSectionObj.AprioriType = AprType\r
2372\r
9e47e6f9 2373 self._GetDefineStatements(AprSectionObj)\r
30fdf114
LG
2374\r
2375 while True:\r
9e47e6f9
CJ
2376 IsInf = self._GetInfStatement(AprSectionObj)\r
2377 IsFile = self._GetFileStatement(AprSectionObj)\r
30fdf114
LG
2378 if not IsInf and not IsFile:\r
2379 break\r
2380\r
9e47e6f9 2381 if not self._IsToken("}"):\r
30fdf114
LG
2382 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2383\r
2384 FvObj.AprioriSectionList.append(AprSectionObj)\r
2385 return True\r
2386\r
9e47e6f9
CJ
2387 def _ParseInfStatement(self):\r
2388 if not self._IsKeyword("INF"):\r
b21a13fb 2389 return None\r
30fdf114 2390\r
9e47e6f9
CJ
2391 ffsInf = FfsInfStatement()\r
2392 self._GetInfOptions(ffsInf)\r
30fdf114 2393\r
9e47e6f9 2394 if not self._GetNextToken():\r
30fdf114 2395 raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2396 ffsInf.InfFileName = self._Token\r
a87e79d9
YZ
2397 if not ffsInf.InfFileName.endswith('.inf'):\r
2398 raise Warning("expected .inf file path", self.FileName, self.CurrentLineNumber)\r
64b2609f
LG
2399\r
2400 ffsInf.CurrentLineNum = self.CurrentLineNumber\r
9e47e6f9 2401 ffsInf.CurrentLineContent = self._CurrentLine()\r
64b2609f 2402\r
97fa0ee9
YL
2403 #Replace $(SAPCE) with real space\r
2404 ffsInf.InfFileName = ffsInf.InfFileName.replace('$(SPACE)', ' ')\r
2405\r
9e47e6f9 2406 if ffsInf.InfFileName.replace(TAB_WORKSPACE, '').find('$') == -1:\r
14c48571 2407 #do case sensitive check for file path\r
2408 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
2409 if ErrorCode != 0:\r
2410 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114 2411\r
30fdf114
LG
2412 if not ffsInf.InfFileName in self.Profile.InfList:\r
2413 self.Profile.InfList.append(ffsInf.InfFileName)\r
d0acc87a
LG
2414 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2415 self.Profile.InfFileLineList.append(FileLineTuple)\r
2502b735
YZ
2416 if ffsInf.UseArch:\r
2417 if ffsInf.UseArch not in self.Profile.InfDict:\r
2418 self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]\r
2419 else:\r
2420 self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)\r
2421 else:\r
2422 self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)\r
30fdf114 2423\r
9e47e6f9
CJ
2424 if self._IsToken(TAB_VALUE_SPLIT):\r
2425 if self._IsKeyword('RELOCS_STRIPPED'):\r
30fdf114 2426 ffsInf.KeepReloc = False\r
9e47e6f9 2427 elif self._IsKeyword('RELOCS_RETAINED'):\r
30fdf114
LG
2428 ffsInf.KeepReloc = True\r
2429 else:\r
9e47e6f9 2430 raise Warning("Unknown reloc strip flag '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
b21a13fb
YZ
2431 return ffsInf\r
2432\r
9e47e6f9 2433 ## _GetInfStatement() method\r
b21a13fb
YZ
2434 #\r
2435 # Get INF statements\r
2436 #\r
2437 # @param self The object pointer\r
2438 # @param Obj for whom inf statement is got\r
b21a13fb
YZ
2439 # @retval True Successfully find inf statement\r
2440 # @retval False Not able to find inf statement\r
2441 #\r
9e47e6f9
CJ
2442 def _GetInfStatement(self, Obj, ForCapsule=False):\r
2443 ffsInf = self._ParseInfStatement()\r
b21a13fb
YZ
2444 if not ffsInf:\r
2445 return False\r
2446\r
30fdf114 2447 if ForCapsule:\r
9e47e6f9
CJ
2448 myCapsuleFfs = CapsuleFfs()\r
2449 myCapsuleFfs.Ffs = ffsInf\r
2450 Obj.CapsuleDataList.append(myCapsuleFfs)\r
30fdf114
LG
2451 else:\r
2452 Obj.FfsList.append(ffsInf)\r
2453 return True\r
2454\r
9e47e6f9 2455 ## _GetInfOptions() method\r
30fdf114
LG
2456 #\r
2457 # Get options for INF\r
2458 #\r
2459 # @param self The object pointer\r
2460 # @param FfsInfObj for whom option is got\r
2461 #\r
9e47e6f9
CJ
2462 def _GetInfOptions(self, FfsInfObj):\r
2463 if self._IsKeyword("FILE_GUID"):\r
2464 if not self._IsToken(TAB_EQUAL_SPLIT):\r
97fa0ee9 2465 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2466 if not self._GetNextGuid():\r
97fa0ee9 2467 raise Warning("expected GUID value", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2468 FfsInfObj.OverrideGuid = self._Token\r
30fdf114 2469\r
9e47e6f9
CJ
2470 if self._IsKeyword("RuleOverride"):\r
2471 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114 2472 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2473 if not self._GetNextToken():\r
30fdf114 2474 raise Warning("expected Rule name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2475 FfsInfObj.Rule = self._Token\r
30fdf114 2476\r
9e47e6f9
CJ
2477 if self._IsKeyword("VERSION"):\r
2478 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114 2479 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2480 if not self._GetNextToken():\r
30fdf114
LG
2481 raise Warning("expected Version", self.FileName, self.CurrentLineNumber)\r
2482\r
9e47e6f9
CJ
2483 if self._GetStringData():\r
2484 FfsInfObj.Version = self._Token\r
30fdf114 2485\r
9e47e6f9
CJ
2486 if self._IsKeyword(BINARY_FILE_TYPE_UI):\r
2487 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114 2488 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2489 if not self._GetNextToken():\r
30fdf114
LG
2490 raise Warning("expected UI name", self.FileName, self.CurrentLineNumber)\r
2491\r
9e47e6f9
CJ
2492 if self._GetStringData():\r
2493 FfsInfObj.Ui = self._Token\r
30fdf114 2494\r
9e47e6f9
CJ
2495 if self._IsKeyword("USE"):\r
2496 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114 2497 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2498 if not self._GetNextToken():\r
30fdf114 2499 raise Warning("expected ARCH name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2500 FfsInfObj.UseArch = self._Token\r
30fdf114 2501\r
f7496d71 2502\r
9e47e6f9
CJ
2503 if self._GetNextToken():\r
2504 p = compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')\r
2505 if p.match(self._Token) and p.match(self._Token).span()[1] == len(self._Token):\r
2506 FfsInfObj.KeyStringList.append(self._Token)\r
2507 if not self._IsToken(TAB_COMMA_SPLIT):\r
30fdf114
LG
2508 return\r
2509 else:\r
9e47e6f9 2510 self._UndoToken()\r
30fdf114
LG
2511 return\r
2512\r
9e47e6f9
CJ
2513 while self._GetNextToken():\r
2514 if not p.match(self._Token):\r
30fdf114 2515 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2516 FfsInfObj.KeyStringList.append(self._Token)\r
30fdf114 2517\r
9e47e6f9 2518 if not self._IsToken(TAB_COMMA_SPLIT):\r
30fdf114
LG
2519 break\r
2520\r
9e47e6f9 2521 ## _GetFileStatement() method\r
30fdf114
LG
2522 #\r
2523 # Get FILE statements\r
2524 #\r
2525 # @param self The object pointer\r
2526 # @param Obj for whom FILE statement is got\r
30fdf114
LG
2527 # @retval True Successfully find FILE statement\r
2528 # @retval False Not able to find FILE statement\r
2529 #\r
5a6a268d 2530 def _GetFileStatement(self, Obj, ForCapsule = False):\r
9e47e6f9 2531 if not self._IsKeyword("FILE"):\r
30fdf114
LG
2532 return False\r
2533\r
9e47e6f9 2534 if not self._GetNextWord():\r
30fdf114 2535 raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)\r
b36d134f 2536\r
9e47e6f9
CJ
2537 if ForCapsule and self._Token == 'DATA':\r
2538 self._UndoToken()\r
2539 self._UndoToken()\r
b36d134f 2540 return False\r
f7496d71 2541\r
9e47e6f9
CJ
2542 FfsFileObj = FileStatement()\r
2543 FfsFileObj.FvFileType = self._Token\r
30fdf114 2544\r
9e47e6f9 2545 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
2546 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2547\r
9e47e6f9
CJ
2548 if not self._GetNextGuid():\r
2549 if not self._GetNextWord():\r
30fdf114 2550 raise Warning("expected File GUID", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
2551 if self._Token == 'PCD':\r
2552 if not self._IsToken("("):\r
30fdf114 2553 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
2554 PcdPair = self._GetNextPcdSettings()\r
2555 if not self._IsToken(")"):\r
30fdf114 2556 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2557 self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'\r
f7496d71 2558\r
9e47e6f9 2559 FfsFileObj.NameGuid = self._Token\r
f7496d71 2560\r
5a6a268d 2561 self._GetFilePart(FfsFileObj)\r
30fdf114
LG
2562\r
2563 if ForCapsule:\r
9e47e6f9 2564 capsuleFfs = CapsuleFfs()\r
30fdf114
LG
2565 capsuleFfs.Ffs = FfsFileObj\r
2566 Obj.CapsuleDataList.append(capsuleFfs)\r
2567 else:\r
2568 Obj.FfsList.append(FfsFileObj)\r
2569\r
2570 return True\r
2571\r
9e47e6f9 2572 ## _FileCouldHaveRelocFlag() method\r
30fdf114
LG
2573 #\r
2574 # Check whether reloc strip flag can be set for a file type.\r
2575 #\r
30fdf114
LG
2576 # @param FileType The file type to check with\r
2577 # @retval True This type could have relocation strip flag\r
2578 # @retval False No way to have it\r
2579 #\r
5bcf1d56 2580 @staticmethod\r
9e47e6f9 2581 def _FileCouldHaveRelocFlag (FileType):\r
5a264f28 2582 if FileType in {SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, 'PEI_DXE_COMBO'}:\r
30fdf114
LG
2583 return True\r
2584 else:\r
2585 return False\r
2586\r
9e47e6f9 2587 ## _SectionCouldHaveRelocFlag() method\r
30fdf114
LG
2588 #\r
2589 # Check whether reloc strip flag can be set for a section type.\r
2590 #\r
30fdf114
LG
2591 # @param SectionType The section type to check with\r
2592 # @retval True This type could have relocation strip flag\r
2593 # @retval False No way to have it\r
2594 #\r
5bcf1d56 2595 @staticmethod\r
9e47e6f9 2596 def _SectionCouldHaveRelocFlag (SectionType):\r
5a264f28 2597 if SectionType in {BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32}:\r
30fdf114
LG
2598 return True\r
2599 else:\r
2600 return False\r
2601\r
9e47e6f9 2602 ## _GetFilePart() method\r
30fdf114
LG
2603 #\r
2604 # Get components for FILE statement\r
2605 #\r
2606 # @param self The object pointer\r
2607 # @param FfsFileObj for whom component is got\r
30fdf114 2608 #\r
5a6a268d 2609 def _GetFilePart(self, FfsFileObj):\r
9e47e6f9 2610 self._GetFileOpts(FfsFileObj)\r
30fdf114 2611\r
9e47e6f9
CJ
2612 if not self._IsToken("{"):\r
2613 if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):\r
2614 if self._FileCouldHaveRelocFlag(FfsFileObj.FvFileType):\r
2615 if self._Token == 'RELOCS_STRIPPED':\r
4afd3d04
LG
2616 FfsFileObj.KeepReloc = False\r
2617 else:\r
2618 FfsFileObj.KeepReloc = True\r
2619 else:\r
2620 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
2621\r
9e47e6f9 2622 if not self._IsToken("{"):\r
30fdf114
LG
2623 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2624\r
9e47e6f9 2625 if not self._GetNextToken():\r
30fdf114
LG
2626 raise Warning("expected File name or section data", self.FileName, self.CurrentLineNumber)\r
2627\r
9e47e6f9
CJ
2628 if self._Token == BINARY_FILE_TYPE_FV:\r
2629 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114 2630 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2631 if not self._GetNextToken():\r
30fdf114 2632 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2633 FfsFileObj.FvName = self._Token\r
30fdf114 2634\r
9e47e6f9
CJ
2635 elif self._Token == "FD":\r
2636 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114 2637 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2638 if not self._GetNextToken():\r
30fdf114 2639 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2640 FfsFileObj.FdName = self._Token\r
30fdf114 2641\r
5a264f28 2642 elif self._Token in {TAB_DEFINE, "APRIORI", "SECTION"}:\r
9e47e6f9 2643 self._UndoToken()\r
5a6a268d 2644 self._GetSectionData(FfsFileObj)\r
860992ed
YZ
2645\r
2646 elif hasattr(FfsFileObj, 'FvFileType') and FfsFileObj.FvFileType == 'RAW':\r
9e47e6f9 2647 self._UndoToken()\r
5a6a268d 2648 self._GetRAWData(FfsFileObj)\r
860992ed 2649\r
30fdf114 2650 else:\r
64b2609f 2651 FfsFileObj.CurrentLineNum = self.CurrentLineNumber\r
9e47e6f9
CJ
2652 FfsFileObj.CurrentLineContent = self._CurrentLine()\r
2653 FfsFileObj.FileName = self._Token.replace('$(SPACE)', ' ')\r
2654 self._VerifyFile(FfsFileObj.FileName)\r
0d2711a6 2655\r
9e47e6f9 2656 if not self._IsToken("}"):\r
30fdf114
LG
2657 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2658\r
9e47e6f9 2659 ## _GetRAWData() method\r
860992ed
YZ
2660 #\r
2661 # Get RAW data for FILE statement\r
2662 #\r
2663 # @param self The object pointer\r
2664 # @param FfsFileObj for whom section is got\r
860992ed 2665 #\r
5a6a268d 2666 def _GetRAWData(self, FfsFileObj):\r
860992ed 2667 FfsFileObj.FileName = []\r
cfaaf99b 2668 FfsFileObj.SubAlignment = []\r
860992ed
YZ
2669 while True:\r
2670 AlignValue = None\r
9e47e6f9
CJ
2671 if self._GetAlignment():\r
2672 if self._Token not in ALIGNMENTS:\r
2673 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
f475f1e2 2674 #For FFS, Auto is default option same to ""\r
9e47e6f9
CJ
2675 if not self._Token == "Auto":\r
2676 AlignValue = self._Token\r
2677 if not self._GetNextToken():\r
860992ed
YZ
2678 raise Warning("expected Filename value", self.FileName, self.CurrentLineNumber)\r
2679\r
9e47e6f9 2680 FileName = self._Token.replace('$(SPACE)', ' ')\r
860992ed 2681 if FileName == '}':\r
9e47e6f9 2682 self._UndoToken()\r
860992ed 2683 raise Warning("expected Filename value", self.FileName, self.CurrentLineNumber)\r
860992ed 2684\r
9e47e6f9 2685 self._VerifyFile(FileName)\r
860992ed
YZ
2686 File = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir)\r
2687 FfsFileObj.FileName.append(File.Path)\r
cfaaf99b 2688 FfsFileObj.SubAlignment.append(AlignValue)\r
860992ed 2689\r
9e47e6f9
CJ
2690 if self._IsToken("}"):\r
2691 self._UndoToken()\r
860992ed
YZ
2692 break\r
2693\r
cfaaf99b
YZ
2694 if len(FfsFileObj.SubAlignment) == 1:\r
2695 FfsFileObj.SubAlignment = FfsFileObj.SubAlignment[0]\r
860992ed
YZ
2696 if len(FfsFileObj.FileName) == 1:\r
2697 FfsFileObj.FileName = FfsFileObj.FileName[0]\r
2698\r
9e47e6f9 2699 ## _GetFileOpts() method\r
30fdf114
LG
2700 #\r
2701 # Get options for FILE statement\r
2702 #\r
2703 # @param self The object pointer\r
2704 # @param FfsFileObj for whom options is got\r
2705 #\r
9e47e6f9
CJ
2706 def _GetFileOpts(self, FfsFileObj):\r
2707 if self._GetNextToken():\r
2708 if TokenFindPattern.match(self._Token):\r
2709 FfsFileObj.KeyStringList.append(self._Token)\r
2710 if self._IsToken(TAB_COMMA_SPLIT):\r
2711 while self._GetNextToken():\r
2712 if not TokenFindPattern.match(self._Token):\r
30fdf114 2713 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2714 FfsFileObj.KeyStringList.append(self._Token)\r
30fdf114 2715\r
9e47e6f9 2716 if not self._IsToken(TAB_COMMA_SPLIT):\r
30fdf114
LG
2717 break\r
2718\r
2719 else:\r
9e47e6f9 2720 self._UndoToken()\r
30fdf114 2721\r
9e47e6f9 2722 if self._IsKeyword("FIXED", True):\r
30fdf114
LG
2723 FfsFileObj.Fixed = True\r
2724\r
9e47e6f9 2725 if self._IsKeyword("CHECKSUM", True):\r
30fdf114
LG
2726 FfsFileObj.CheckSum = True\r
2727\r
9e47e6f9
CJ
2728 if self._GetAlignment():\r
2729 if self._Token not in ALIGNMENTS:\r
2730 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
9053bc51 2731 #For FFS, Auto is default option same to ""\r
9e47e6f9
CJ
2732 if not self._Token == "Auto":\r
2733 FfsFileObj.Alignment = self._Token\r
30fdf114 2734\r
9e47e6f9 2735 ## _GetAlignment() method\r
30fdf114
LG
2736 #\r
2737 # Return the alignment value\r
2738 #\r
2739 # @param self The object pointer\r
2740 # @retval True Successfully find alignment\r
2741 # @retval False Not able to find alignment\r
2742 #\r
9e47e6f9
CJ
2743 def _GetAlignment(self):\r
2744 if self._IsKeyword("Align", True):\r
2745 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
2746 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2747\r
9e47e6f9 2748 if not self._GetNextToken():\r
30fdf114
LG
2749 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)\r
2750 return True\r
2751\r
2752 return False\r
2753\r
5a6a268d 2754 ## _GetSectionData() method\r
30fdf114
LG
2755 #\r
2756 # Get section data for FILE statement\r
2757 #\r
2758 # @param self The object pointer\r
2759 # @param FfsFileObj for whom section is got\r
30fdf114 2760 #\r
5a6a268d 2761 def _GetSectionData(self, FfsFileObj):\r
9e47e6f9 2762 self._GetDefineStatements(FfsFileObj)\r
30fdf114 2763\r
30fdf114 2764 while True:\r
5a6a268d 2765 IsLeafSection = self._GetLeafSection(FfsFileObj)\r
9e47e6f9 2766 IsEncapSection = self._GetEncapsulationSec(FfsFileObj)\r
30fdf114
LG
2767 if not IsLeafSection and not IsEncapSection:\r
2768 break\r
2769\r
9e47e6f9 2770 ## _GetLeafSection() method\r
30fdf114
LG
2771 #\r
2772 # Get leaf section for Obj\r
2773 #\r
2774 # @param self The object pointer\r
2775 # @param Obj for whom leaf section is got\r
30fdf114
LG
2776 # @retval True Successfully find section statement\r
2777 # @retval False Not able to find section statement\r
2778 #\r
5a6a268d 2779 def _GetLeafSection(self, Obj):\r
30fdf114
LG
2780 OldPos = self.GetFileBufferPos()\r
2781\r
9e47e6f9 2782 if not self._IsKeyword("SECTION"):\r
30fdf114
LG
2783 if len(Obj.SectionList) == 0:\r
2784 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)\r
2785 else:\r
2786 return False\r
2787\r
2788 AlignValue = None\r
9e47e6f9
CJ
2789 if self._GetAlignment():\r
2790 if self._Token not in ALIGNMENTS:\r
2791 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
2792 AlignValue = self._Token\r
30fdf114
LG
2793\r
2794 BuildNum = None\r
9e47e6f9
CJ
2795 if self._IsKeyword("BUILD_NUM"):\r
2796 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
2797 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
2798\r
9e47e6f9 2799 if not self._GetNextToken():\r
30fdf114
LG
2800 raise Warning("expected Build number value", self.FileName, self.CurrentLineNumber)\r
2801\r
9e47e6f9 2802 BuildNum = self._Token\r
30fdf114 2803\r
9e47e6f9 2804 if self._IsKeyword("VERSION"):\r
52302d4d
LG
2805 if AlignValue == 'Auto':\r
2806 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2807 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114 2808 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2809 if not self._GetNextToken():\r
30fdf114 2810 raise Warning("expected version", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2811 VerSectionObj = VerSection()\r
30fdf114
LG
2812 VerSectionObj.Alignment = AlignValue\r
2813 VerSectionObj.BuildNum = BuildNum\r
9e47e6f9
CJ
2814 if self._GetStringData():\r
2815 VerSectionObj.StringData = self._Token\r
30fdf114 2816 else:\r
9e47e6f9 2817 VerSectionObj.FileName = self._Token\r
30fdf114 2818 Obj.SectionList.append(VerSectionObj)\r
f7496d71 2819\r
9e47e6f9 2820 elif self._IsKeyword(BINARY_FILE_TYPE_UI):\r
52302d4d
LG
2821 if AlignValue == 'Auto':\r
2822 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2823 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114 2824 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2825 if not self._GetNextToken():\r
30fdf114 2826 raise Warning("expected UI", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2827 UiSectionObj = UiSection()\r
30fdf114 2828 UiSectionObj.Alignment = AlignValue\r
9e47e6f9
CJ
2829 if self._GetStringData():\r
2830 UiSectionObj.StringData = self._Token\r
30fdf114 2831 else:\r
9e47e6f9 2832 UiSectionObj.FileName = self._Token\r
30fdf114
LG
2833 Obj.SectionList.append(UiSectionObj)\r
2834\r
9e47e6f9 2835 elif self._IsKeyword("FV_IMAGE"):\r
52302d4d
LG
2836 if AlignValue == 'Auto':\r
2837 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2838 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114 2839 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2840 if not self._GetNextToken():\r
30fdf114
LG
2841 raise Warning("expected FV name or FV file path", self.FileName, self.CurrentLineNumber)\r
2842\r
9e47e6f9 2843 FvName = self._Token\r
30fdf114
LG
2844 FvObj = None\r
2845\r
9e47e6f9
CJ
2846 if self._IsToken("{"):\r
2847 FvObj = FV()\r
30fdf114 2848 FvObj.UiFvName = FvName.upper()\r
9e47e6f9 2849 self._GetDefineStatements(FvObj)\r
5a6a268d 2850\r
9e47e6f9
CJ
2851 self._GetBlockStatement(FvObj)\r
2852 self._GetSetStatements(FvObj)\r
2853 self._GetFvAlignment(FvObj)\r
2854 self._GetFvAttributes(FvObj)\r
30fdf114
LG
2855\r
2856 while True:\r
9e47e6f9 2857 IsInf = self._GetInfStatement(FvObj)\r
5a6a268d 2858 IsFile = self._GetFileStatement(FvObj)\r
30fdf114
LG
2859 if not IsInf and not IsFile:\r
2860 break\r
2861\r
9e47e6f9 2862 if not self._IsToken("}"):\r
30fdf114
LG
2863 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2864\r
9e47e6f9 2865 FvImageSectionObj = FvImageSection()\r
30fdf114 2866 FvImageSectionObj.Alignment = AlignValue\r
4231a819 2867 if FvObj is not None:\r
30fdf114
LG
2868 FvImageSectionObj.Fv = FvObj\r
2869 FvImageSectionObj.FvName = None\r
2870 else:\r
2871 FvImageSectionObj.FvName = FvName.upper()\r
2872 FvImageSectionObj.FvFileName = FvName\r
2873\r
2874 Obj.SectionList.append(FvImageSectionObj)\r
2875\r
9e47e6f9 2876 elif self._IsKeyword("PEI_DEPEX_EXP") or self._IsKeyword("DXE_DEPEX_EXP") or self._IsKeyword("SMM_DEPEX_EXP"):\r
52302d4d
LG
2877 if AlignValue == 'Auto':\r
2878 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2879 DepexSectionObj = DepexSection()\r
30fdf114 2880 DepexSectionObj.Alignment = AlignValue\r
9e47e6f9 2881 DepexSectionObj.DepexType = self._Token\r
30fdf114 2882\r
9e47e6f9 2883 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114 2884 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2885 if not self._IsToken("{"):\r
30fdf114 2886 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2887 if not self._SkipToToken("}"):\r
30fdf114
LG
2888 raise Warning("expected Depex expression ending '}'", self.FileName, self.CurrentLineNumber)\r
2889\r
9e47e6f9 2890 DepexSectionObj.Expression = self._SkippedChars.rstrip('}')\r
30fdf114
LG
2891 Obj.SectionList.append(DepexSectionObj)\r
2892\r
2893 else:\r
9e47e6f9 2894 if not self._GetNextWord():\r
30fdf114
LG
2895 raise Warning("expected section type", self.FileName, self.CurrentLineNumber)\r
2896\r
2897 # Encapsulation section appear, UndoToken and return\r
9e47e6f9 2898 if self._Token == "COMPRESS" or self._Token == "GUIDED":\r
30fdf114
LG
2899 self.SetFileBufferPos(OldPos)\r
2900 return False\r
2901\r
5a264f28
CJ
2902 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
2903 BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX}:\r
9e47e6f9
CJ
2904 raise Warning("Unknown section type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
2905 if AlignValue == 'Auto'and (not self._Token == BINARY_FILE_TYPE_PE32) and (not self._Token == BINARY_FILE_TYPE_TE):\r
52302d4d
LG
2906 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
2907\r
30fdf114 2908 # DataSection\r
9e47e6f9 2909 DataSectionObj = DataSection()\r
30fdf114 2910 DataSectionObj.Alignment = AlignValue\r
9e47e6f9 2911 DataSectionObj.SecType = self._Token\r
30fdf114 2912\r
9e47e6f9
CJ
2913 if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):\r
2914 if self._FileCouldHaveRelocFlag(Obj.FvFileType) and self._SectionCouldHaveRelocFlag(DataSectionObj.SecType):\r
2915 if self._Token == 'RELOCS_STRIPPED':\r
30fdf114
LG
2916 DataSectionObj.KeepReloc = False\r
2917 else:\r
2918 DataSectionObj.KeepReloc = True\r
2919 else:\r
2920 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
2921\r
9e47e6f9
CJ
2922 if self._IsToken(TAB_EQUAL_SPLIT):\r
2923 if not self._GetNextToken():\r
30fdf114 2924 raise Warning("expected section file path", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
2925 DataSectionObj.SectFileName = self._Token\r
2926 self._VerifyFile(DataSectionObj.SectFileName)\r
30fdf114 2927 else:\r
9e47e6f9 2928 if not self._GetCglSection(DataSectionObj):\r
30fdf114
LG
2929 return False\r
2930\r
2931 Obj.SectionList.append(DataSectionObj)\r
2932\r
2933 return True\r
2934\r
9e47e6f9 2935 ## _VerifyFile\r
2bc3256c
LG
2936 #\r
2937 # Check if file exists or not:\r
2938 # If current phase if GenFds, the file must exist;\r
2939 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist\r
2940 # @param FileName: File path to be verified.\r
2941 #\r
9e47e6f9
CJ
2942 def _VerifyFile(self, FileName):\r
2943 if FileName.replace(TAB_WORKSPACE, '').find('$') != -1:\r
2bc3256c 2944 return\r
9e47e6f9 2945 if not GlobalData.gAutoGenPhase or not self._GetMacroValue(TAB_DSC_DEFINES_OUTPUT_DIRECTORY) in FileName:\r
2bc3256c
LG
2946 ErrorCode, ErrorInfo = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
2947 if ErrorCode != 0:\r
2948 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
2949\r
9e47e6f9 2950 ## _GetCglSection() method\r
30fdf114
LG
2951 #\r
2952 # Get compressed or GUIDed section for Obj\r
2953 #\r
2954 # @param self The object pointer\r
2955 # @param Obj for whom leaf section is got\r
2956 # @param AlignValue alignment value for complex section\r
2957 # @retval True Successfully find section statement\r
2958 # @retval False Not able to find section statement\r
2959 #\r
9e47e6f9 2960 def _GetCglSection(self, Obj, AlignValue = None):\r
30fdf114 2961\r
9e47e6f9 2962 if self._IsKeyword("COMPRESS"):\r
30fdf114 2963 type = "PI_STD"\r
9e47e6f9
CJ
2964 if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE"):\r
2965 type = self._Token\r
30fdf114 2966\r
9e47e6f9 2967 if not self._IsToken("{"):\r
30fdf114
LG
2968 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
2969\r
9e47e6f9 2970 CompressSectionObj = CompressSection()\r
30fdf114
LG
2971 CompressSectionObj.Alignment = AlignValue\r
2972 CompressSectionObj.CompType = type\r
2973 # Recursive sections...\r
2974 while True:\r
9e47e6f9
CJ
2975 IsLeafSection = self._GetLeafSection(CompressSectionObj)\r
2976 IsEncapSection = self._GetEncapsulationSec(CompressSectionObj)\r
30fdf114
LG
2977 if not IsLeafSection and not IsEncapSection:\r
2978 break\r
2979\r
2980\r
9e47e6f9 2981 if not self._IsToken("}"):\r
30fdf114
LG
2982 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
2983 Obj.SectionList.append(CompressSectionObj)\r
2984\r
2985# else:\r
2986# raise Warning("Compress type not known")\r
2987\r
2988 return True\r
2989\r
9e47e6f9 2990 elif self._IsKeyword("GUIDED"):\r
30fdf114 2991 GuidValue = None\r
9e47e6f9
CJ
2992 if self._GetNextGuid():\r
2993 GuidValue = self._Token\r
30fdf114 2994\r
9e47e6f9
CJ
2995 AttribDict = self._GetGuidAttrib()\r
2996 if not self._IsToken("{"):\r
30fdf114 2997 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2998 GuidSectionObj = GuidSection()\r
30fdf114
LG
2999 GuidSectionObj.Alignment = AlignValue\r
3000 GuidSectionObj.NameGuid = GuidValue\r
3001 GuidSectionObj.SectionType = "GUIDED"\r
3002 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]\r
3003 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]\r
25918452 3004 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]\r
30fdf114
LG
3005 # Recursive sections...\r
3006 while True:\r
9e47e6f9
CJ
3007 IsLeafSection = self._GetLeafSection(GuidSectionObj)\r
3008 IsEncapSection = self._GetEncapsulationSec(GuidSectionObj)\r
30fdf114
LG
3009 if not IsLeafSection and not IsEncapSection:\r
3010 break\r
3011\r
9e47e6f9 3012 if not self._IsToken("}"):\r
30fdf114
LG
3013 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
3014 Obj.SectionList.append(GuidSectionObj)\r
3015\r
3016 return True\r
3017\r
3018 return False\r
3019\r
9e47e6f9 3020 ## _GetGuidAttri() method\r
30fdf114
LG
3021 #\r
3022 # Get attributes for GUID section\r
3023 #\r
3024 # @param self The object pointer\r
3025 # @retval AttribDict Dictionary of key-value pair of section attributes\r
3026 #\r
9e47e6f9 3027 def _GetGuidAttrib(self):\r
30fdf114 3028 AttribDict = {}\r
14c48571 3029 AttribDict["PROCESSING_REQUIRED"] = "NONE"\r
3030 AttribDict["AUTH_STATUS_VALID"] = "NONE"\r
25918452 3031 AttribDict["EXTRA_HEADER_SIZE"] = -1\r
9e47e6f9
CJ
3032 while self._IsKeyword("PROCESSING_REQUIRED") or self._IsKeyword("AUTH_STATUS_VALID") \\r
3033 or self._IsKeyword("EXTRA_HEADER_SIZE"):\r
3034 AttribKey = self._Token\r
30fdf114 3035\r
9e47e6f9 3036 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
3037 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3038\r
9e47e6f9 3039 if not self._GetNextToken():\r
25918452
LG
3040 raise Warning("expected TRUE(1)/FALSE(0)/Number", self.FileName, self.CurrentLineNumber)\r
3041 elif AttribKey == "EXTRA_HEADER_SIZE":\r
3042 Base = 10\r
9e47e6f9 3043 if self._Token[0:2].upper() == "0X":\r
25918452
LG
3044 Base = 16\r
3045 try:\r
9e47e6f9 3046 AttribDict[AttribKey] = int(self._Token, Base)\r
25918452
LG
3047 continue\r
3048 except ValueError:\r
3049 raise Warning("expected Number", self.FileName, self.CurrentLineNumber)\r
5a264f28 3050 elif self._Token.upper() not in {"TRUE", "FALSE", "1", "0"}:\r
30fdf114 3051 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3052 AttribDict[AttribKey] = self._Token\r
30fdf114
LG
3053\r
3054 return AttribDict\r
3055\r
9e47e6f9 3056 ## _GetEncapsulationSec() method\r
30fdf114
LG
3057 #\r
3058 # Get encapsulation section for FILE\r
3059 #\r
3060 # @param self The object pointer\r
3061 # @param FfsFile for whom section is got\r
3062 # @retval True Successfully find section statement\r
3063 # @retval False Not able to find section statement\r
3064 #\r
9e47e6f9 3065 def _GetEncapsulationSec(self, FfsFileObj):\r
30fdf114 3066 OldPos = self.GetFileBufferPos()\r
9e47e6f9 3067 if not self._IsKeyword("SECTION"):\r
30fdf114
LG
3068 if len(FfsFileObj.SectionList) == 0:\r
3069 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)\r
3070 else:\r
3071 return False\r
3072\r
3073 AlignValue = None\r
9e47e6f9
CJ
3074 if self._GetAlignment():\r
3075 if self._Token not in ALIGNMENT_NOAUTO:\r
3076 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
3077 AlignValue = self._Token\r
30fdf114 3078\r
9e47e6f9 3079 if not self._GetCglSection(FfsFileObj, AlignValue):\r
30fdf114
LG
3080 self.SetFileBufferPos(OldPos)\r
3081 return False\r
3082 else:\r
3083 return True\r
3084\r
9e47e6f9
CJ
3085 def _GetFmp(self):\r
3086 if not self._GetNextToken():\r
a3251d84 3087 return False\r
9e47e6f9
CJ
3088 S = self._Token.upper()\r
3089 if S.startswith(TAB_SECTION_START) and not S.startswith("[FMPPAYLOAD."):\r
df81077f 3090 self.SectionParser(S)\r
9e47e6f9 3091 self._UndoToken()\r
a3251d84
YL
3092 return False\r
3093\r
9e47e6f9
CJ
3094 self._UndoToken()\r
3095 self._SkipToToken("[FMPPAYLOAD.", True)\r
3096 FmpUiName = self._GetUiName().upper()\r
a3251d84
YL
3097 if FmpUiName in self.Profile.FmpPayloadDict:\r
3098 raise Warning("Duplicated FMP UI name found: %s" % FmpUiName, self.FileName, self.CurrentLineNumber)\r
3099\r
9e47e6f9 3100 FmpData = CapsulePayload()\r
a3251d84
YL
3101 FmpData.UiName = FmpUiName\r
3102\r
9e47e6f9 3103 if not self._IsToken(TAB_SECTION_END):\r
a3251d84
YL
3104 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
3105\r
9e47e6f9 3106 if not self._GetNextToken():\r
a3251d84 3107 raise Warning("The FMP payload section is empty!", self.FileName, self.CurrentLineNumber)\r
91ae2988 3108 FmpKeyList = ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']\r
9e47e6f9
CJ
3109 while self._Token in FmpKeyList:\r
3110 Name = self._Token\r
a3251d84 3111 FmpKeyList.remove(Name)\r
9e47e6f9 3112 if not self._IsToken(TAB_EQUAL_SPLIT):\r
a3251d84
YL
3113 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3114 if Name == 'IMAGE_TYPE_ID':\r
9e47e6f9 3115 if not self._GetNextGuid():\r
91ae2988 3116 raise Warning("expected GUID value for IMAGE_TYPE_ID.", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3117 FmpData.ImageTypeId = self._Token\r
91ae2988 3118 elif Name == 'CERTIFICATE_GUID':\r
9e47e6f9 3119 if not self._GetNextGuid():\r
91ae2988 3120 raise Warning("expected GUID value for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3121 FmpData.Certificate_Guid = self._Token\r
3122 if UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_RSA2048_SHA256_GUID and UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_PKCS7_GUID:\r
91ae2988 3123 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 3124 else:\r
9e47e6f9 3125 if not self._GetNextToken():\r
a3251d84 3126 raise Warning("expected value of %s" % Name, self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3127 Value = self._Token\r
a3251d84 3128 if Name == 'IMAGE_HEADER_INIT_VERSION':\r
9e47e6f9 3129 if FdfParser._Verify(Name, Value, 'UINT8'):\r
91ae2988 3130 FmpData.Version = Value\r
a3251d84 3131 elif Name == 'IMAGE_INDEX':\r
9e47e6f9 3132 if FdfParser._Verify(Name, Value, 'UINT8'):\r
91ae2988 3133 FmpData.ImageIndex = Value\r
a3251d84 3134 elif Name == 'HARDWARE_INSTANCE':\r
9e47e6f9 3135 if FdfParser._Verify(Name, Value, 'UINT8'):\r
91ae2988
YZ
3136 FmpData.HardwareInstance = Value\r
3137 elif Name == 'MONOTONIC_COUNT':\r
9e47e6f9 3138 if FdfParser._Verify(Name, Value, 'UINT64'):\r
91ae2988
YZ
3139 FmpData.MonotonicCount = Value\r
3140 if FmpData.MonotonicCount.upper().startswith('0X'):\r
1ccc4d89 3141 FmpData.MonotonicCount = (long)(FmpData.MonotonicCount, 16)\r
91ae2988 3142 else:\r
1ccc4d89 3143 FmpData.MonotonicCount = (long)(FmpData.MonotonicCount)\r
9e47e6f9 3144 if not self._GetNextToken():\r
a3251d84
YL
3145 break\r
3146 else:\r
9e47e6f9 3147 self._UndoToken()\r
a3251d84 3148\r
91ae2988
YZ
3149 if (FmpData.MonotonicCount and not FmpData.Certificate_Guid) or (not FmpData.MonotonicCount and FmpData.Certificate_Guid):\r
3150 EdkLogger.error("FdfParser", FORMAT_INVALID, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")\r
9ce9bf53
YZ
3151\r
3152 # Only the IMAGE_TYPE_ID is required item\r
3153 if FmpKeyList and 'IMAGE_TYPE_ID' in FmpKeyList:\r
3154 raise Warning("Missing keywords IMAGE_TYPE_ID in FMP payload section.", self.FileName, self.CurrentLineNumber)\r
19e3aa7a 3155 # get the Image file and Vendor code file\r
9e47e6f9 3156 self._GetFMPCapsuleData(FmpData)\r
19e3aa7a 3157 if not FmpData.ImageFile:\r
91ae2988 3158 raise Warning("Missing image file in FMP payload section.", self.FileName, self.CurrentLineNumber)\r
19e3aa7a
YZ
3159 # check whether more than one Vendor code file\r
3160 if len(FmpData.VendorCodeFile) > 1:\r
91ae2988 3161 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
3162 self.Profile.FmpPayloadDict[FmpUiName] = FmpData\r
3163 return True\r
3164\r
9e47e6f9 3165 ## _GetCapsule() method\r
30fdf114
LG
3166 #\r
3167 # Get capsule section contents and store its data into capsule list of self.Profile\r
3168 #\r
3169 # @param self The object pointer\r
3170 # @retval True Successfully find a capsule\r
3171 # @retval False Not able to find a capsule\r
3172 #\r
9e47e6f9
CJ
3173 def _GetCapsule(self):\r
3174 if not self._GetNextToken():\r
30fdf114
LG
3175 return False\r
3176\r
9e47e6f9
CJ
3177 S = self._Token.upper()\r
3178 if S.startswith(TAB_SECTION_START) and not S.startswith("[CAPSULE."):\r
df81077f 3179 self.SectionParser(S)\r
9e47e6f9 3180 self._UndoToken()\r
30fdf114
LG
3181 return False\r
3182\r
9e47e6f9
CJ
3183 self._UndoToken()\r
3184 if not self._IsToken("[CAPSULE.", True):\r
30fdf114
LG
3185 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
3186 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
9e47e6f9 3187 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
30fdf114
LG
3188 raise Warning("expected [Capsule.]", self.FileName, self.CurrentLineNumber)\r
3189\r
9e47e6f9 3190 CapsuleObj = Capsule()\r
30fdf114 3191\r
9e47e6f9 3192 CapsuleName = self._GetUiName()\r
30fdf114
LG
3193 if not CapsuleName:\r
3194 raise Warning("expected capsule name", self.FileName, self.CurrentLineNumber)\r
3195\r
3196 CapsuleObj.UiCapsuleName = CapsuleName.upper()\r
3197\r
9e47e6f9 3198 if not self._IsToken(TAB_SECTION_END):\r
30fdf114
LG
3199 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
3200\r
9e47e6f9
CJ
3201 if self._IsKeyword("CREATE_FILE"):\r
3202 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
3203 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3204\r
9e47e6f9 3205 if not self._GetNextToken():\r
30fdf114
LG
3206 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)\r
3207\r
9e47e6f9 3208 CapsuleObj.CreateFile = self._Token\r
30fdf114 3209\r
9e47e6f9 3210 self._GetCapsuleStatements(CapsuleObj)\r
fd171542 3211 self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj\r
30fdf114
LG
3212 return True\r
3213\r
9e47e6f9 3214 ## _GetCapsuleStatements() method\r
30fdf114
LG
3215 #\r
3216 # Get statements for capsule\r
3217 #\r
3218 # @param self The object pointer\r
3219 # @param Obj for whom statements are got\r
3220 #\r
9e47e6f9
CJ
3221 def _GetCapsuleStatements(self, Obj):\r
3222 self._GetCapsuleTokens(Obj)\r
3223 self._GetDefineStatements(Obj)\r
3224 self._GetSetStatements(Obj)\r
3225 self._GetCapsuleData(Obj)\r
30fdf114 3226\r
9e47e6f9 3227 ## _GetCapsuleTokens() method\r
30fdf114
LG
3228 #\r
3229 # Get token statements for capsule\r
3230 #\r
3231 # @param self The object pointer\r
3232 # @param Obj for whom token statements are got\r
3233 #\r
9e47e6f9
CJ
3234 def _GetCapsuleTokens(self, Obj):\r
3235 if not self._GetNextToken():\r
b303ea72 3236 return False\r
5a264f28 3237 while self._Token in {"CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"}:\r
9e47e6f9
CJ
3238 Name = self._Token.strip()\r
3239 if not self._IsToken(TAB_EQUAL_SPLIT):\r
b303ea72 3240 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3241 if not self._GetNextToken():\r
b303ea72
LG
3242 raise Warning("expected value", self.FileName, self.CurrentLineNumber)\r
3243 if Name == 'CAPSULE_FLAGS':\r
5a264f28 3244 if not self._Token in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:\r
b303ea72 3245 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3246 Value = self._Token.strip()\r
3247 while self._IsToken(TAB_COMMA_SPLIT):\r
3248 Value += TAB_COMMA_SPLIT\r
3249 if not self._GetNextToken():\r
b303ea72 3250 raise Warning("expected value", self.FileName, self.CurrentLineNumber)\r
5a264f28 3251 if not self._Token in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:\r
b303ea72 3252 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3253 Value += self._Token.strip()\r
e8a47801 3254 elif Name == 'OEM_CAPSULE_FLAGS':\r
9e47e6f9 3255 Value = self._Token.strip()\r
2bc3256c
LG
3256 if not Value.upper().startswith('0X'):\r
3257 raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)\r
e8a47801
LG
3258 try:\r
3259 Value = int(Value, 0)\r
3260 except ValueError:\r
2bc3256c 3261 raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)\r
e8a47801 3262 if not 0x0000 <= Value <= 0xFFFF:\r
2bc3256c 3263 raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3264 Value = self._Token.strip()\r
b303ea72 3265 else:\r
9e47e6f9 3266 Value = self._Token.strip()\r
f7496d71 3267 Obj.TokensDict[Name] = Value\r
9e47e6f9 3268 if not self._GetNextToken():\r
b303ea72 3269 return False\r
9e47e6f9 3270 self._UndoToken()\r
30fdf114 3271\r
9e47e6f9 3272 ## _GetCapsuleData() method\r
30fdf114
LG
3273 #\r
3274 # Get capsule data for capsule\r
3275 #\r
3276 # @param self The object pointer\r
3277 # @param Obj for whom capsule data are got\r
3278 #\r
9e47e6f9 3279 def _GetCapsuleData(self, Obj):\r
30fdf114 3280 while True:\r
9e47e6f9
CJ
3281 IsInf = self._GetInfStatement(Obj, True)\r
3282 IsFile = self._GetFileStatement(Obj, True)\r
3283 IsFv = self._GetFvStatement(Obj)\r
3284 IsFd = self._GetFdStatement(Obj)\r
3285 IsAnyFile = self._GetAnyFileStatement(Obj)\r
3286 IsAfile = self._GetAfileStatement(Obj)\r
3287 IsFmp = self._GetFmpStatement(Obj)\r
a3251d84 3288 if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile or IsAfile or IsFmp):\r
30fdf114
LG
3289 break\r
3290\r
9e47e6f9 3291 ## _GetFMPCapsuleData() method\r
19e3aa7a
YZ
3292 #\r
3293 # Get capsule data for FMP capsule\r
3294 #\r
3295 # @param self The object pointer\r
3296 # @param Obj for whom capsule data are got\r
3297 #\r
9e47e6f9 3298 def _GetFMPCapsuleData(self, Obj):\r
19e3aa7a 3299 while True:\r
9e47e6f9
CJ
3300 IsFv = self._GetFvStatement(Obj, True)\r
3301 IsFd = self._GetFdStatement(Obj, True)\r
3302 IsAnyFile = self._GetAnyFileStatement(Obj, True)\r
19e3aa7a
YZ
3303 if not (IsFv or IsFd or IsAnyFile):\r
3304 break\r
3305\r
9e47e6f9 3306 ## _GetFvStatement() method\r
30fdf114
LG
3307 #\r
3308 # Get FV for capsule\r
3309 #\r
3310 # @param self The object pointer\r
3311 # @param CapsuleObj for whom FV is got\r
3312 # @retval True Successfully find a FV statement\r
3313 # @retval False Not able to find a FV statement\r
3314 #\r
9e47e6f9
CJ
3315 def _GetFvStatement(self, CapsuleObj, FMPCapsule = False):\r
3316 if not self._IsKeyword(BINARY_FILE_TYPE_FV):\r
30fdf114
LG
3317 return False\r
3318\r
9e47e6f9 3319 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
3320 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3321\r
9e47e6f9 3322 if not self._GetNextToken():\r
30fdf114
LG
3323 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)\r
3324\r
9e47e6f9 3325 if self._Token.upper() not in self.Profile.FvDict:\r
2bcc713e
LG
3326 raise Warning("FV name does not exist", self.FileName, self.CurrentLineNumber)\r
3327\r
9e47e6f9
CJ
3328 myCapsuleFv = CapsuleFv()\r
3329 myCapsuleFv.FvName = self._Token\r
19e3aa7a
YZ
3330 if FMPCapsule:\r
3331 if not CapsuleObj.ImageFile:\r
9e47e6f9 3332 CapsuleObj.ImageFile.append(myCapsuleFv)\r
19e3aa7a 3333 else:\r
9e47e6f9 3334 CapsuleObj.VendorCodeFile.append(myCapsuleFv)\r
19e3aa7a 3335 else:\r
9e47e6f9 3336 CapsuleObj.CapsuleDataList.append(myCapsuleFv)\r
30fdf114
LG
3337 return True\r
3338\r
9e47e6f9 3339 ## _GetFdStatement() method\r
b36d134f
LG
3340 #\r
3341 # Get FD for capsule\r
3342 #\r
3343 # @param self The object pointer\r
3344 # @param CapsuleObj for whom FD is got\r
3345 # @retval True Successfully find a FD statement\r
3346 # @retval False Not able to find a FD statement\r
3347 #\r
9e47e6f9
CJ
3348 def _GetFdStatement(self, CapsuleObj, FMPCapsule = False):\r
3349 if not self._IsKeyword("FD"):\r
b36d134f
LG
3350 return False\r
3351\r
9e47e6f9 3352 if not self._IsToken(TAB_EQUAL_SPLIT):\r
b36d134f
LG
3353 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3354\r
9e47e6f9 3355 if not self._GetNextToken():\r
b36d134f
LG
3356 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)\r
3357\r
9e47e6f9 3358 if self._Token.upper() not in self.Profile.FdDict:\r
2bcc713e
LG
3359 raise Warning("FD name does not exist", self.FileName, self.CurrentLineNumber)\r
3360\r
9e47e6f9
CJ
3361 myCapsuleFd = CapsuleFd()\r
3362 myCapsuleFd.FdName = self._Token\r
19e3aa7a
YZ
3363 if FMPCapsule:\r
3364 if not CapsuleObj.ImageFile:\r
9e47e6f9 3365 CapsuleObj.ImageFile.append(myCapsuleFd)\r
19e3aa7a 3366 else:\r
9e47e6f9 3367 CapsuleObj.VendorCodeFile.append(myCapsuleFd)\r
19e3aa7a 3368 else:\r
9e47e6f9 3369 CapsuleObj.CapsuleDataList.append(myCapsuleFd)\r
b36d134f
LG
3370 return True\r
3371\r
9e47e6f9
CJ
3372 def _GetFmpStatement(self, CapsuleObj):\r
3373 if not self._IsKeyword("FMP_PAYLOAD"):\r
3374 if not self._IsKeyword("FMP"):\r
df81077f 3375 return False\r
b36d134f 3376\r
9e47e6f9
CJ
3377 if not self._IsKeyword("PAYLOAD"):\r
3378 self._UndoToken()\r
df81077f 3379 return False\r
b36d134f 3380\r
9e47e6f9 3381 if not self._IsToken(TAB_EQUAL_SPLIT):\r
a3251d84
YL
3382 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3383\r
9e47e6f9 3384 if not self._GetNextToken():\r
df81077f 3385 raise Warning("expected payload name after FMP_PAYLOAD =", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3386 Payload = self._Token.upper()\r
a3251d84 3387 if Payload not in self.Profile.FmpPayloadDict:\r
9e47e6f9 3388 raise Warning("This FMP Payload does not exist: %s" % self._Token, self.FileName, self.CurrentLineNumber)\r
a3251d84
YL
3389 CapsuleObj.FmpPayloadList.append(self.Profile.FmpPayloadDict[Payload])\r
3390 return True\r
3391\r
9e47e6f9
CJ
3392 def _ParseRawFileStatement(self):\r
3393 if not self._IsKeyword("FILE"):\r
a3251d84
YL
3394 return None\r
3395\r
9e47e6f9
CJ
3396 if not self._IsKeyword("DATA"):\r
3397 self._UndoToken()\r
a3251d84 3398 return None\r
b36d134f 3399\r
9e47e6f9 3400 if not self._IsToken(TAB_EQUAL_SPLIT):\r
b36d134f
LG
3401 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3402\r
9e47e6f9 3403 if not self._GetNextToken():\r
b36d134f 3404 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)\r
f7496d71 3405\r
9e47e6f9
CJ
3406 AnyFileName = self._Token\r
3407 self._VerifyFile(AnyFileName)\r
35217a33 3408\r
94e4bcbb
YZ
3409 if not os.path.isabs(AnyFileName):\r
3410 AnyFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, AnyFileName)\r
3411\r
a3251d84
YL
3412 return AnyFileName\r
3413\r
9e47e6f9 3414 ## _GetAnyFileStatement() method\r
a3251d84
YL
3415 #\r
3416 # Get AnyFile for capsule\r
3417 #\r
3418 # @param self The object pointer\r
3419 # @param CapsuleObj for whom AnyFile is got\r
3420 # @retval True Successfully find a Anyfile statement\r
3421 # @retval False Not able to find a AnyFile statement\r
3422 #\r
9e47e6f9
CJ
3423 def _GetAnyFileStatement(self, CapsuleObj, FMPCapsule = False):\r
3424 AnyFileName = self._ParseRawFileStatement()\r
a3251d84
YL
3425 if not AnyFileName:\r
3426 return False\r
b36d134f 3427\r
9e47e6f9
CJ
3428 myCapsuleAnyFile = CapsuleAnyFile()\r
3429 myCapsuleAnyFile.FileName = AnyFileName\r
19e3aa7a
YZ
3430 if FMPCapsule:\r
3431 if not CapsuleObj.ImageFile:\r
9e47e6f9 3432 CapsuleObj.ImageFile.append(myCapsuleAnyFile)\r
19e3aa7a 3433 else:\r
9e47e6f9 3434 CapsuleObj.VendorCodeFile.append(myCapsuleAnyFile)\r
19e3aa7a 3435 else:\r
9e47e6f9 3436 CapsuleObj.CapsuleDataList.append(myCapsuleAnyFile)\r
b36d134f 3437 return True\r
f7496d71 3438\r
9e47e6f9 3439 ## _GetAfileStatement() method\r
2bc3256c
LG
3440 #\r
3441 # Get Afile for capsule\r
3442 #\r
3443 # @param self The object pointer\r
3444 # @param CapsuleObj for whom Afile is got\r
3445 # @retval True Successfully find a Afile statement\r
3446 # @retval False Not able to find a Afile statement\r
3447 #\r
9e47e6f9
CJ
3448 def _GetAfileStatement(self, CapsuleObj):\r
3449 if not self._IsKeyword("APPEND"):\r
2bc3256c
LG
3450 return False\r
3451\r
9e47e6f9 3452 if not self._IsToken(TAB_EQUAL_SPLIT):\r
2bc3256c
LG
3453 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3454\r
9e47e6f9 3455 if not self._GetNextToken():\r
2bc3256c 3456 raise Warning("expected Afile name", self.FileName, self.CurrentLineNumber)\r
f7496d71 3457\r
9e47e6f9 3458 AfileName = self._Token\r
2bc3256c 3459 AfileBaseName = os.path.basename(AfileName)\r
f7496d71 3460\r
5a264f28 3461 if os.path.splitext(AfileBaseName)[1] not in {".bin", ".BIN", ".Bin", ".dat", ".DAT", ".Dat", ".data", ".DATA", ".Data"}:\r
91fa33ee 3462 raise Warning('invalid binary file type, should be one of "bin",BINARY_FILE_TYPE_BIN,"Bin","dat","DAT","Dat","data","DATA","Data"', \\r
2bc3256c 3463 self.FileName, self.CurrentLineNumber)\r
f7496d71 3464\r
2bc3256c
LG
3465 if not os.path.isabs(AfileName):\r
3466 AfileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AfileName)\r
9e47e6f9 3467 self._VerifyFile(AfileName)\r
2bc3256c
LG
3468 else:\r
3469 if not os.path.exists(AfileName):\r
3470 raise Warning('%s does not exist' % AfileName, self.FileName, self.CurrentLineNumber)\r
3471 else:\r
3472 pass\r
3473\r
9e47e6f9
CJ
3474 myCapsuleAfile = CapsuleAfile()\r
3475 myCapsuleAfile.FileName = AfileName\r
3476 CapsuleObj.CapsuleDataList.append(myCapsuleAfile)\r
2bc3256c 3477 return True\r
b36d134f 3478\r
9e47e6f9 3479 ## _GetRule() method\r
30fdf114
LG
3480 #\r
3481 # Get Rule section contents and store its data into rule list of self.Profile\r
3482 #\r
3483 # @param self The object pointer\r
3484 # @retval True Successfully find a Rule\r
3485 # @retval False Not able to find a Rule\r
3486 #\r
9e47e6f9
CJ
3487 def _GetRule(self):\r
3488 if not self._GetNextToken():\r
30fdf114
LG
3489 return False\r
3490\r
9e47e6f9
CJ
3491 S = self._Token.upper()\r
3492 if S.startswith(TAB_SECTION_START) and not S.startswith("[RULE."):\r
df81077f 3493 self.SectionParser(S)\r
9e47e6f9 3494 self._UndoToken()\r
30fdf114 3495 return False\r
9e47e6f9
CJ
3496 self._UndoToken()\r
3497 if not self._IsToken("[Rule.", True):\r
30fdf114
LG
3498 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
3499 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
9e47e6f9 3500 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
30fdf114
LG
3501 raise Warning("expected [Rule.]", self.FileName, self.CurrentLineNumber)\r
3502\r
9e47e6f9 3503 if not self._SkipToToken(TAB_SPLIT):\r
30fdf114
LG
3504 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)\r
3505\r
9e47e6f9 3506 Arch = self._SkippedChars.rstrip(TAB_SPLIT)\r
eece4292 3507 if Arch.upper() not in ARCH_SET_FULL:\r
30fdf114
LG
3508 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)\r
3509\r
9e47e6f9 3510 ModuleType = self._GetModuleType()\r
30fdf114
LG
3511\r
3512 TemplateName = ""\r
9e47e6f9
CJ
3513 if self._IsToken(TAB_SPLIT):\r
3514 if not self._GetNextWord():\r
30fdf114 3515 raise Warning("expected template name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3516 TemplateName = self._Token\r
30fdf114 3517\r
9e47e6f9 3518 if not self._IsToken(TAB_SECTION_END):\r
30fdf114
LG
3519 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
3520\r
9e47e6f9 3521 RuleObj = self._GetRuleFileStatements()\r
30fdf114
LG
3522 RuleObj.Arch = Arch.upper()\r
3523 RuleObj.ModuleType = ModuleType\r
3524 RuleObj.TemplateName = TemplateName\r
9e47e6f9 3525 if TemplateName == '':\r
30fdf114 3526 self.Profile.RuleDict['RULE' + \\r
9e47e6f9 3527 TAB_SPLIT + \\r
30fdf114 3528 Arch.upper() + \\r
9e47e6f9 3529 TAB_SPLIT + \\r
30fdf114 3530 ModuleType.upper() ] = RuleObj\r
9e47e6f9 3531 else:\r
30fdf114 3532 self.Profile.RuleDict['RULE' + \\r
9e47e6f9 3533 TAB_SPLIT + \\r
30fdf114 3534 Arch.upper() + \\r
9e47e6f9 3535 TAB_SPLIT + \\r
30fdf114 3536 ModuleType.upper() + \\r
9e47e6f9 3537 TAB_SPLIT + \\r
30fdf114 3538 TemplateName.upper() ] = RuleObj\r
30fdf114
LG
3539 return True\r
3540\r
9e47e6f9 3541 ## _GetModuleType() method\r
30fdf114
LG
3542 #\r
3543 # Return the module type\r
3544 #\r
3545 # @param self The object pointer\r
3546 # @retval string module type\r
3547 #\r
9e47e6f9
CJ
3548 def _GetModuleType(self):\r
3549 if not self._GetNextWord():\r
30fdf114 3550 raise Warning("expected Module type", self.FileName, self.CurrentLineNumber)\r
5a264f28
CJ
3551 if self._Token.upper() not in {\r
3552 SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM,\r
3553 SUP_MODULE_DXE_CORE, SUP_MODULE_DXE_DRIVER,\r
3554 SUP_MODULE_DXE_SAL_DRIVER, SUP_MODULE_DXE_SMM_DRIVER,\r
3555 SUP_MODULE_DXE_RUNTIME_DRIVER, SUP_MODULE_UEFI_DRIVER,\r
3556 SUP_MODULE_UEFI_APPLICATION, SUP_MODULE_USER_DEFINED,\r
3557 TAB_DEFAULT, SUP_MODULE_BASE,\r
3558 EDK_COMPONENT_TYPE_SECURITY_CORE,\r
3559 EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER,\r
3560 EDK_COMPONENT_TYPE_PIC_PEIM,\r
3561 EDK_COMPONENT_TYPE_RELOCATABLE_PEIM, "PE32_PEIM",\r
3562 EDK_COMPONENT_TYPE_BS_DRIVER, EDK_COMPONENT_TYPE_RT_DRIVER,\r
3563 EDK_COMPONENT_TYPE_SAL_RT_DRIVER,\r
3564 EDK_COMPONENT_TYPE_APPLICATION, "ACPITABLE",\r
3565 SUP_MODULE_SMM_CORE, SUP_MODULE_MM_STANDALONE,\r
3566 SUP_MODULE_MM_CORE_STANDALONE}:\r
9e47e6f9
CJ
3567 raise Warning("Unknown Module type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
3568 return self._Token\r
30fdf114 3569\r
9e47e6f9 3570 ## _GetFileExtension() method\r
30fdf114
LG
3571 #\r
3572 # Return the file extension\r
3573 #\r
3574 # @param self The object pointer\r
3575 # @retval string file name extension\r
3576 #\r
9e47e6f9
CJ
3577 def _GetFileExtension(self):\r
3578 if not self._IsToken(TAB_SPLIT):\r
df81077f 3579 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3580\r
3581 Ext = ""\r
9e47e6f9
CJ
3582 if self._GetNextToken():\r
3583 if FileExtensionPattern.match(self._Token):\r
3584 Ext = self._Token\r
3585 return TAB_SPLIT + Ext\r
30fdf114 3586 else:\r
9e47e6f9 3587 raise Warning("Unknown file extension '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3588\r
3589 else:\r
3590 raise Warning("expected file extension", self.FileName, self.CurrentLineNumber)\r
3591\r
9e47e6f9 3592 ## _GetRuleFileStatement() method\r
30fdf114
LG
3593 #\r
3594 # Get rule contents\r
3595 #\r
3596 # @param self The object pointer\r
3597 # @retval Rule Rule object\r
3598 #\r
9e47e6f9
CJ
3599 def _GetRuleFileStatements(self):\r
3600 if not self._IsKeyword("FILE"):\r
30fdf114
LG
3601 raise Warning("expected FILE", self.FileName, self.CurrentLineNumber)\r
3602\r
9e47e6f9 3603 if not self._GetNextWord():\r
30fdf114
LG
3604 raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)\r
3605\r
9e47e6f9 3606 Type = self._Token.strip().upper()\r
5a264f28
CJ
3607 if Type not in {"RAW", "FREEFORM", SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM,\r
3608 "PEI_DXE_COMBO", "DRIVER", SUP_MODULE_DXE_CORE, EDK_COMPONENT_TYPE_APPLICATION,\r
3609 "FV_IMAGE", "SMM", SUP_MODULE_SMM_CORE, SUP_MODULE_MM_STANDALONE,\r
3610 SUP_MODULE_MM_CORE_STANDALONE}:\r
9e47e6f9 3611 raise Warning("Unknown FV type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114 3612\r
9e47e6f9 3613 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
3614 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3615\r
9e47e6f9
CJ
3616 if not self._IsKeyword("$(NAMED_GUID)"):\r
3617 if not self._GetNextWord():\r
30fdf114 3618 raise Warning("expected $(NAMED_GUID)", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3619 if self._Token == 'PCD':\r
3620 if not self._IsToken("("):\r
30fdf114 3621 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3622 PcdPair = self._GetNextPcdSettings()\r
3623 if not self._IsToken(")"):\r
30fdf114 3624 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3625 self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'\r
f7496d71 3626\r
9e47e6f9 3627 NameGuid = self._Token\r
30fdf114
LG
3628\r
3629 KeepReloc = None\r
9e47e6f9
CJ
3630 if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):\r
3631 if self._FileCouldHaveRelocFlag(Type):\r
3632 if self._Token == 'RELOCS_STRIPPED':\r
30fdf114
LG
3633 KeepReloc = False\r
3634 else:\r
3635 KeepReloc = True\r
3636 else:\r
3637 raise Warning("File type %s could not have reloc strip flag%d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3638\r
3639 KeyStringList = []\r
9e47e6f9
CJ
3640 if self._GetNextToken():\r
3641 if TokenFindPattern.match(self._Token):\r
3642 KeyStringList.append(self._Token)\r
3643 if self._IsToken(TAB_COMMA_SPLIT):\r
3644 while self._GetNextToken():\r
3645 if not TokenFindPattern.match(self._Token):\r
30fdf114 3646 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3647 KeyStringList.append(self._Token)\r
30fdf114 3648\r
9e47e6f9 3649 if not self._IsToken(TAB_COMMA_SPLIT):\r
30fdf114
LG
3650 break\r
3651\r
3652 else:\r
9e47e6f9 3653 self._UndoToken()\r
30fdf114
LG
3654\r
3655\r
3656 Fixed = False\r
9e47e6f9 3657 if self._IsKeyword("Fixed", True):\r
30fdf114
LG
3658 Fixed = True\r
3659\r
3660 CheckSum = False\r
9e47e6f9 3661 if self._IsKeyword("CheckSum", True):\r
30fdf114
LG
3662 CheckSum = True\r
3663\r
3664 AlignValue = ""\r
9e47e6f9
CJ
3665 if self._GetAlignment():\r
3666 if self._Token not in ALIGNMENTS:\r
3667 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
52302d4d 3668 #For FFS, Auto is default option same to ""\r
9e47e6f9
CJ
3669 if not self._Token == "Auto":\r
3670 AlignValue = self._Token\r
30fdf114 3671\r
9e47e6f9 3672 if self._IsToken("{"):\r
30fdf114 3673 # Complex file rule expected\r
9e47e6f9
CJ
3674 NewRule = RuleComplexFile()\r
3675 NewRule.FvFileType = Type\r
3676 NewRule.NameGuid = NameGuid\r
3677 NewRule.Alignment = AlignValue\r
3678 NewRule.CheckSum = CheckSum\r
3679 NewRule.Fixed = Fixed\r
3680 NewRule.KeyStringList = KeyStringList\r
4231a819 3681 if KeepReloc is not None:\r
9e47e6f9 3682 NewRule.KeepReloc = KeepReloc\r
30fdf114
LG
3683\r
3684 while True:\r
9e47e6f9
CJ
3685 IsEncapsulate = self._GetRuleEncapsulationSection(NewRule)\r
3686 IsLeaf = self._GetEfiSection(NewRule)\r
30fdf114
LG
3687 if not IsEncapsulate and not IsLeaf:\r
3688 break\r
3689\r
9e47e6f9 3690 if not self._IsToken("}"):\r
30fdf114
LG
3691 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
3692\r
9e47e6f9 3693 return NewRule\r
30fdf114 3694\r
30fdf114
LG
3695 else:\r
3696 # Simple file rule expected\r
9e47e6f9 3697 if not self._GetNextWord():\r
30fdf114
LG
3698 raise Warning("expected leaf section type", self.FileName, self.CurrentLineNumber)\r
3699\r
9e47e6f9 3700 SectionName = self._Token\r
30fdf114 3701\r
5a264f28
CJ
3702 if SectionName not in {\r
3703 "COMPAT16", BINARY_FILE_TYPE_PE32,\r
3704 BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE",\r
3705 "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI,\r
3706 BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID",\r
3707 BINARY_FILE_TYPE_SMM_DEPEX}:\r
30fdf114
LG
3708 raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber)\r
3709\r
3710\r
9e47e6f9 3711 if self._IsKeyword("Fixed", True):\r
30fdf114
LG
3712 Fixed = True\r
3713\r
9e47e6f9 3714 if self._IsKeyword("CheckSum", True):\r
30fdf114
LG
3715 CheckSum = True\r
3716\r
52302d4d 3717 SectAlignment = ""\r
9e47e6f9
CJ
3718 if self._GetAlignment():\r
3719 if self._Token not in ALIGNMENTS:\r
3720 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
3721 if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_TE):\r
52302d4d 3722 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3723 SectAlignment = self._Token\r
52302d4d
LG
3724\r
3725 Ext = None\r
9e47e6f9
CJ
3726 if self._IsToken(TAB_VALUE_SPLIT):\r
3727 Ext = self._GetFileExtension()\r
3728 elif not self._GetNextToken():\r
30fdf114
LG
3729 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)\r
3730\r
9e47e6f9
CJ
3731 NewRule = RuleSimpleFile()\r
3732 NewRule.SectionType = SectionName\r
3733 NewRule.FvFileType = Type\r
3734 NewRule.NameGuid = NameGuid\r
3735 NewRule.Alignment = AlignValue\r
3736 NewRule.SectAlignment = SectAlignment\r
3737 NewRule.CheckSum = CheckSum\r
3738 NewRule.Fixed = Fixed\r
3739 NewRule.KeyStringList = KeyStringList\r
4231a819 3740 if KeepReloc is not None:\r
9e47e6f9
CJ
3741 NewRule.KeepReloc = KeepReloc\r
3742 NewRule.FileExtension = Ext\r
3743 NewRule.FileName = self._Token\r
3744 return NewRule\r
30fdf114 3745\r
9e47e6f9 3746 ## _GetEfiSection() method\r
30fdf114
LG
3747 #\r
3748 # Get section list for Rule\r
3749 #\r
3750 # @param self The object pointer\r
3751 # @param Obj for whom section is got\r
3752 # @retval True Successfully find section statement\r
3753 # @retval False Not able to find section statement\r
3754 #\r
9e47e6f9 3755 def _GetEfiSection(self, Obj):\r
30fdf114 3756 OldPos = self.GetFileBufferPos()\r
9e47e6f9 3757 if not self._GetNextWord():\r
30fdf114 3758 return False\r
9e47e6f9 3759 SectionName = self._Token\r
30fdf114 3760\r
5a264f28
CJ
3761 if SectionName not in {\r
3762 "COMPAT16", BINARY_FILE_TYPE_PE32,\r
3763 BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE",\r
3764 "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI,\r
3765 BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID",\r
3766 BINARY_FILE_TYPE_SMM_DEPEX, BINARY_FILE_TYPE_GUID}:\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
5a264f28
CJ
3808 if self._Token not in {\r
3809 "}", "COMPAT16", BINARY_FILE_TYPE_PE32,\r
3810 BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE,\r
3811 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,\r
3812 BINARY_FILE_TYPE_UI, "VERSION",\r
3813 BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID,\r
3814 BINARY_FILE_TYPE_SMM_DEPEX}:\r
9e47e6f9 3815 FvImageSectionObj.FvFileName = self._Token\r
30fdf114 3816 else:\r
9e47e6f9 3817 self._UndoToken()\r
30fdf114
LG
3818 else:\r
3819 raise Warning("expected FV file name", self.FileName, self.CurrentLineNumber)\r
3820\r
3821 Obj.SectionList.append(FvImageSectionObj)\r
3822 return True\r
3823\r
9e47e6f9 3824 EfiSectionObj = EfiSection()\r
30fdf114
LG
3825 EfiSectionObj.SectionType = SectionName\r
3826\r
9e47e6f9 3827 if not self._GetNextToken():\r
30fdf114
LG
3828 raise Warning("expected file type", self.FileName, self.CurrentLineNumber)\r
3829\r
9e47e6f9
CJ
3830 if self._Token == "STRING":\r
3831 if not self._RuleSectionCouldHaveString(EfiSectionObj.SectionType):\r
30fdf114
LG
3832 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3833\r
9e47e6f9 3834 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
3835 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
3836\r
9e47e6f9 3837 if not self._GetNextToken():\r
30fdf114
LG
3838 raise Warning("expected Quoted String", self.FileName, self.CurrentLineNumber)\r
3839\r
9e47e6f9
CJ
3840 if self._GetStringData():\r
3841 EfiSectionObj.StringData = self._Token\r
30fdf114 3842\r
9e47e6f9
CJ
3843 if self._IsKeyword("BUILD_NUM"):\r
3844 if not self._RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):\r
30fdf114
LG
3845 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3846\r
9e47e6f9 3847 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114 3848 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3849 if not self._GetNextToken():\r
30fdf114 3850 raise Warning("expected Build number", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3851 EfiSectionObj.BuildNum = self._Token\r
30fdf114
LG
3852\r
3853 else:\r
9e47e6f9
CJ
3854 EfiSectionObj.FileType = self._Token\r
3855 self._CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType)\r
30fdf114 3856\r
9e47e6f9
CJ
3857 if self._IsKeyword("Optional"):\r
3858 if not self._RuleSectionCouldBeOptional(EfiSectionObj.SectionType):\r
30fdf114
LG
3859 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3860 EfiSectionObj.Optional = True\r
3861\r
9e47e6f9
CJ
3862 if self._IsKeyword("BUILD_NUM"):\r
3863 if not self._RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):\r
30fdf114
LG
3864 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3865\r
9e47e6f9 3866 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114 3867 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3868 if not self._GetNextToken():\r
30fdf114 3869 raise Warning("expected Build number", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3870 EfiSectionObj.BuildNum = self._Token\r
30fdf114 3871\r
9e47e6f9
CJ
3872 if self._GetAlignment():\r
3873 if self._Token not in ALIGNMENTS:\r
3874 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
3875 if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_TE):\r
52302d4d 3876 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3877 EfiSectionObj.Alignment = self._Token\r
30fdf114 3878\r
9e47e6f9
CJ
3879 if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):\r
3880 if self._SectionCouldHaveRelocFlag(EfiSectionObj.SectionType):\r
3881 if self._Token == 'RELOCS_STRIPPED':\r
30fdf114
LG
3882 EfiSectionObj.KeepReloc = False\r
3883 else:\r
3884 EfiSectionObj.KeepReloc = True\r
4231a819 3885 if Obj.KeepReloc is not None and Obj.KeepReloc != EfiSectionObj.KeepReloc:\r
30fdf114
LG
3886 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)\r
3887 else:\r
3888 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)\r
3889\r
3890\r
9e47e6f9
CJ
3891 if self._IsToken(TAB_VALUE_SPLIT):\r
3892 EfiSectionObj.FileExtension = self._GetFileExtension()\r
3893 elif self._GetNextToken():\r
5a264f28
CJ
3894 if self._Token not in {\r
3895 "}", "COMPAT16", BINARY_FILE_TYPE_PE32,\r
3896 BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE,\r
3897 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,\r
3898 BINARY_FILE_TYPE_UI, "VERSION",\r
3899 BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID,\r
3900 BINARY_FILE_TYPE_SMM_DEPEX}:\r
f7496d71 3901\r
9e47e6f9
CJ
3902 if self._Token.startswith('PCD'):\r
3903 self._UndoToken()\r
3904 self._GetNextWord()\r
f7496d71 3905\r
9e47e6f9
CJ
3906 if self._Token == 'PCD':\r
3907 if not self._IsToken("("):\r
30fdf114 3908 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3909 PcdPair = self._GetNextPcdSettings()\r
3910 if not self._IsToken(")"):\r
30fdf114 3911 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3912 self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'\r
f7496d71 3913\r
9e47e6f9 3914 EfiSectionObj.FileName = self._Token\r
f7496d71 3915\r
30fdf114 3916 else:\r
9e47e6f9 3917 self._UndoToken()\r
30fdf114
LG
3918 else:\r
3919 raise Warning("expected section file name", self.FileName, self.CurrentLineNumber)\r
3920\r
3921 Obj.SectionList.append(EfiSectionObj)\r
3922 return True\r
3923\r
9e47e6f9 3924 ## _RuleSectionCouldBeOptional() method\r
30fdf114
LG
3925 #\r
3926 # Get whether a section could be optional\r
3927 #\r
30fdf114
LG
3928 # @param SectionType The section type to check\r
3929 # @retval True section could be optional\r
3930 # @retval False section never optional\r
3931 #\r
5bcf1d56 3932 @staticmethod\r
9e47e6f9 3933 def _RuleSectionCouldBeOptional(SectionType):\r
5a264f28 3934 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
3935 return True\r
3936 else:\r
3937 return False\r
3938\r
9e47e6f9 3939 ## _RuleSectionCouldHaveBuildNum() method\r
30fdf114
LG
3940 #\r
3941 # Get whether a section could have build number information\r
3942 #\r
30fdf114
LG
3943 # @param SectionType The section type to check\r
3944 # @retval True section could have build number information\r
3945 # @retval False section never have build number information\r
3946 #\r
5bcf1d56 3947 @staticmethod\r
9e47e6f9 3948 def _RuleSectionCouldHaveBuildNum(SectionType):\r
5a264f28 3949 if SectionType == "VERSION":\r
30fdf114
LG
3950 return True\r
3951 else:\r
3952 return False\r
3953\r
9e47e6f9 3954 ## _RuleSectionCouldHaveString() method\r
30fdf114
LG
3955 #\r
3956 # Get whether a section could have string\r
3957 #\r
30fdf114
LG
3958 # @param SectionType The section type to check\r
3959 # @retval True section could have string\r
3960 # @retval False section never have string\r
3961 #\r
5bcf1d56 3962 @staticmethod\r
9e47e6f9 3963 def _RuleSectionCouldHaveString(SectionType):\r
5a264f28 3964 if SectionType in {BINARY_FILE_TYPE_UI, "VERSION"}:\r
30fdf114
LG
3965 return True\r
3966 else:\r
3967 return False\r
3968\r
9e47e6f9 3969 ## _CheckRuleSectionFileType() method\r
30fdf114
LG
3970 #\r
3971 # Get whether a section matches a file type\r
3972 #\r
3973 # @param self The object pointer\r
3974 # @param SectionType The section type to check\r
3975 # @param FileType The file type to check\r
3976 #\r
9e47e6f9 3977 def _CheckRuleSectionFileType(self, SectionType, FileType):\r
30fdf114 3978 if SectionType == "COMPAT16":\r
5a264f28 3979 if FileType not in {"COMPAT16", "SEC_COMPAT16"}:\r
30fdf114 3980 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 3981 elif SectionType == BINARY_FILE_TYPE_PE32:\r
5a264f28 3982 if FileType not in {BINARY_FILE_TYPE_PE32, "SEC_PE32"}:\r
30fdf114 3983 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 3984 elif SectionType == BINARY_FILE_TYPE_PIC:\r
5a264f28 3985 if FileType not in {BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_PIC}:\r
30fdf114 3986 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 3987 elif SectionType == BINARY_FILE_TYPE_TE:\r
5a264f28 3988 if FileType not in {BINARY_FILE_TYPE_TE, "SEC_TE"}:\r
30fdf114
LG
3989 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
3990 elif SectionType == "RAW":\r
5a264f28 3991 if FileType not in {BINARY_FILE_TYPE_BIN, "SEC_BIN", "RAW", "ASL", "ACPI"}:\r
30fdf114 3992 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 3993 elif SectionType == BINARY_FILE_TYPE_DXE_DEPEX or SectionType == BINARY_FILE_TYPE_SMM_DEPEX:\r
5a264f28 3994 if FileType not in {BINARY_FILE_TYPE_DXE_DEPEX, "SEC_DXE_DEPEX", BINARY_FILE_TYPE_SMM_DEPEX}:\r
30fdf114 3995 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 3996 elif SectionType == BINARY_FILE_TYPE_UI:\r
5a264f28 3997 if FileType not in {BINARY_FILE_TYPE_UI, "SEC_UI"}:\r
30fdf114
LG
3998 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
3999 elif SectionType == "VERSION":\r
5a264f28 4000 if FileType not in {"VERSION", "SEC_VERSION"}:\r
30fdf114 4001 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 4002 elif SectionType == BINARY_FILE_TYPE_PEI_DEPEX:\r
5a264f28 4003 if FileType not in {BINARY_FILE_TYPE_PEI_DEPEX, "SEC_PEI_DEPEX"}:\r
30fdf114 4004 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 4005 elif SectionType == BINARY_FILE_TYPE_GUID:\r
5a264f28 4006 if FileType not in {BINARY_FILE_TYPE_PE32, "SEC_GUID"}:\r
30fdf114
LG
4007 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)\r
4008\r
9e47e6f9 4009 ## _GetRuleEncapsulationSection() method\r
30fdf114
LG
4010 #\r
4011 # Get encapsulation section for Rule\r
4012 #\r
4013 # @param self The object pointer\r
9e47e6f9 4014 # @param theRule for whom section is got\r
30fdf114
LG
4015 # @retval True Successfully find section statement\r
4016 # @retval False Not able to find section statement\r
4017 #\r
9e47e6f9
CJ
4018 def _GetRuleEncapsulationSection(self, theRule):\r
4019 if self._IsKeyword("COMPRESS"):\r
30fdf114 4020 Type = "PI_STD"\r
9e47e6f9
CJ
4021 if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE"):\r
4022 Type = self._Token\r
30fdf114 4023\r
9e47e6f9 4024 if not self._IsToken("{"):\r
30fdf114
LG
4025 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
4026\r
9e47e6f9 4027 CompressSectionObj = CompressSection()\r
30fdf114
LG
4028\r
4029 CompressSectionObj.CompType = Type\r
4030 # Recursive sections...\r
4031 while True:\r
9e47e6f9
CJ
4032 IsEncapsulate = self._GetRuleEncapsulationSection(CompressSectionObj)\r
4033 IsLeaf = self._GetEfiSection(CompressSectionObj)\r
30fdf114
LG
4034 if not IsEncapsulate and not IsLeaf:\r
4035 break\r
4036\r
9e47e6f9 4037 if not self._IsToken("}"):\r
30fdf114 4038 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4039 theRule.SectionList.append(CompressSectionObj)\r
30fdf114
LG
4040\r
4041 return True\r
4042\r
9e47e6f9 4043 elif self._IsKeyword("GUIDED"):\r
30fdf114 4044 GuidValue = None\r
9e47e6f9
CJ
4045 if self._GetNextGuid():\r
4046 GuidValue = self._Token\r
30fdf114 4047\r
9e47e6f9
CJ
4048 if self._IsKeyword("$(NAMED_GUID)"):\r
4049 GuidValue = self._Token\r
30fdf114 4050\r
9e47e6f9 4051 AttribDict = self._GetGuidAttrib()\r
30fdf114 4052\r
9e47e6f9 4053 if not self._IsToken("{"):\r
30fdf114 4054 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4055 GuidSectionObj = GuidSection()\r
30fdf114
LG
4056 GuidSectionObj.NameGuid = GuidValue\r
4057 GuidSectionObj.SectionType = "GUIDED"\r
4058 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]\r
4059 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]\r
25918452 4060 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]\r
30fdf114
LG
4061\r
4062 # Efi sections...\r
4063 while True:\r
9e47e6f9
CJ
4064 IsEncapsulate = self._GetRuleEncapsulationSection(GuidSectionObj)\r
4065 IsLeaf = self._GetEfiSection(GuidSectionObj)\r
30fdf114
LG
4066 if not IsEncapsulate and not IsLeaf:\r
4067 break\r
4068\r
9e47e6f9 4069 if not self._IsToken("}"):\r
30fdf114 4070 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4071 theRule.SectionList.append(GuidSectionObj)\r
30fdf114
LG
4072\r
4073 return True\r
4074\r
4075 return False\r
4076\r
9e47e6f9 4077 ## _GetVtf() method\r
30fdf114
LG
4078 #\r
4079 # Get VTF section contents and store its data into VTF list of self.Profile\r
4080 #\r
4081 # @param self The object pointer\r
4082 # @retval True Successfully find a VTF\r
4083 # @retval False Not able to find a VTF\r
4084 #\r
9e47e6f9 4085 def _GetVtf(self):\r
5a264f28 4086 HW_ARCH_SET = {TAB_ARCH_IA32, TAB_ARCH_X64, TAB_ARCH_IPF, TAB_ARCH_ARM, TAB_ARCH_AARCH64}\r
9e47e6f9 4087 if not self._GetNextToken():\r
30fdf114
LG
4088 return False\r
4089\r
9e47e6f9
CJ
4090 S = self._Token.upper()\r
4091 if S.startswith(TAB_SECTION_START) and not S.startswith("[VTF."):\r
df81077f 4092 self.SectionParser(S)\r
9e47e6f9 4093 self._UndoToken()\r
30fdf114
LG
4094 return False\r
4095\r
9e47e6f9
CJ
4096 self._UndoToken()\r
4097 if not self._IsToken("[VTF.", True):\r
30fdf114
LG
4098 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
4099 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
9e47e6f9 4100 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
30fdf114
LG
4101 raise Warning("expected [VTF.]", self.FileName, self.CurrentLineNumber)\r
4102\r
9e47e6f9 4103 if not self._SkipToToken(TAB_SPLIT):\r
30fdf114
LG
4104 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)\r
4105\r
9e47e6f9 4106 Arch = self._SkippedChars.rstrip(TAB_SPLIT).upper()\r
5a264f28 4107 if Arch not in HW_ARCH_SET:\r
30fdf114
LG
4108 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)\r
4109\r
9e47e6f9 4110 if not self._GetNextWord():\r
30fdf114 4111 raise Warning("expected VTF name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4112 Name = self._Token.upper()\r
30fdf114 4113\r
9e47e6f9 4114 VtfObj = Vtf()\r
30fdf114
LG
4115 VtfObj.UiName = Name\r
4116 VtfObj.KeyArch = Arch\r
4117\r
9e47e6f9
CJ
4118 if self._IsToken(TAB_COMMA_SPLIT):\r
4119 if not self._GetNextWord():\r
30fdf114 4120 raise Warning("expected Arch list", self.FileName, self.CurrentLineNumber)\r
5a264f28 4121 if self._Token.upper() not in HW_ARCH_SET:\r
9e47e6f9
CJ
4122 raise Warning("Unknown Arch '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
4123 VtfObj.ArchList = self._Token.upper()\r
30fdf114 4124\r
9e47e6f9 4125 if not self._IsToken(TAB_SECTION_END):\r
30fdf114
LG
4126 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
4127\r
9e47e6f9
CJ
4128 if self._IsKeyword("IA32_RST_BIN"):\r
4129 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
4130 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4131\r
9e47e6f9 4132 if not self._GetNextToken():\r
30fdf114
LG
4133 raise Warning("expected Reset file", self.FileName, self.CurrentLineNumber)\r
4134\r
9e47e6f9
CJ
4135 VtfObj.ResetBin = self._Token\r
4136 if VtfObj.ResetBin.replace(TAB_WORKSPACE, '').find('$') == -1:\r
6310ffd7 4137 #check for file path\r
4138 ErrorCode, ErrorInfo = PathClass(NormPath(VtfObj.ResetBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4139 if ErrorCode != 0:\r
4140 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114 4141\r
9e47e6f9 4142 while self._GetComponentStatement(VtfObj):\r
30fdf114
LG
4143 pass\r
4144\r
4145 self.Profile.VtfList.append(VtfObj)\r
4146 return True\r
4147\r
9e47e6f9 4148 ## _GetComponentStatement() method\r
30fdf114
LG
4149 #\r
4150 # Get components in VTF\r
4151 #\r
4152 # @param self The object pointer\r
4153 # @param VtfObj for whom component is got\r
4154 # @retval True Successfully find a component\r
4155 # @retval False Not able to find a component\r
4156 #\r
9e47e6f9
CJ
4157 def _GetComponentStatement(self, VtfObj):\r
4158 if not self._IsKeyword("COMP_NAME"):\r
30fdf114
LG
4159 return False\r
4160\r
9e47e6f9 4161 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
4162 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4163\r
9e47e6f9 4164 if not self._GetNextWord():\r
30fdf114
LG
4165 raise Warning("expected Component Name", self.FileName, self.CurrentLineNumber)\r
4166\r
9e47e6f9
CJ
4167 CompStatementObj = ComponentStatement()\r
4168 CompStatementObj.CompName = self._Token\r
30fdf114 4169\r
9e47e6f9 4170 if not self._IsKeyword("COMP_LOC"):\r
30fdf114
LG
4171 raise Warning("expected COMP_LOC", self.FileName, self.CurrentLineNumber)\r
4172\r
9e47e6f9 4173 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
4174 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4175\r
4176 CompStatementObj.CompLoc = ""\r
9e47e6f9
CJ
4177 if self._GetNextWord():\r
4178 CompStatementObj.CompLoc = self._Token\r
4179 if self._IsToken(TAB_VALUE_SPLIT):\r
4180 if not self._GetNextWord():\r
30fdf114
LG
4181 raise Warning("Expected Region Name", self.FileName, self.CurrentLineNumber)\r
4182\r
5a264f28 4183 if self._Token not in {"F", "N", "S"}: #, "H", "L", "PH", "PL"): not support\r
9e47e6f9 4184 raise Warning("Unknown location type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114 4185\r
9e47e6f9 4186 CompStatementObj.FilePos = self._Token\r
30fdf114
LG
4187 else:\r
4188 self.CurrentLineNumber += 1\r
4189 self.CurrentOffsetWithinLine = 0\r
4190\r
9e47e6f9 4191 if not self._IsKeyword("COMP_TYPE"):\r
30fdf114
LG
4192 raise Warning("expected COMP_TYPE", self.FileName, self.CurrentLineNumber)\r
4193\r
9e47e6f9 4194 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
4195 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4196\r
9e47e6f9 4197 if not self._GetNextToken():\r
30fdf114 4198 raise Warning("expected Component type", self.FileName, self.CurrentLineNumber)\r
5a264f28 4199 if self._Token not in {"FIT", "PAL_B", "PAL_A", "OEM"}:\r
9e47e6f9
CJ
4200 if not self._Token.startswith("0x") or len(self._Token) < 3 or len(self._Token) > 4 or \\r
4201 not self._Token[2] in hexdigits or not self._Token[-1] in hexdigits:\r
4202 raise Warning("Unknown location type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
4203 CompStatementObj.CompType = self._Token\r
30fdf114 4204\r
9e47e6f9 4205 if not self._IsKeyword("COMP_VER"):\r
30fdf114
LG
4206 raise Warning("expected COMP_VER", self.FileName, self.CurrentLineNumber)\r
4207\r
9e47e6f9 4208 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
4209 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4210\r
9e47e6f9 4211 if not self._GetNextToken():\r
30fdf114
LG
4212 raise Warning("expected Component version", self.FileName, self.CurrentLineNumber)\r
4213\r
9e47e6f9
CJ
4214 Pattern = compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', DOTALL)\r
4215 if Pattern.match(self._Token) is None:\r
4216 raise Warning("Unknown version format '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
4217 CompStatementObj.CompVer = self._Token\r
30fdf114 4218\r
9e47e6f9 4219 if not self._IsKeyword("COMP_CS"):\r
30fdf114
LG
4220 raise Warning("expected COMP_CS", self.FileName, self.CurrentLineNumber)\r
4221\r
9e47e6f9 4222 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
4223 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4224\r
9e47e6f9 4225 if not self._GetNextToken():\r
30fdf114 4226 raise Warning("expected Component CS", self.FileName, self.CurrentLineNumber)\r
5a264f28 4227 if self._Token not in {"1", "0"}:\r
9e47e6f9
CJ
4228 raise Warning("Unknown Component CS '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
4229 CompStatementObj.CompCs = self._Token\r
30fdf114
LG
4230\r
4231\r
9e47e6f9 4232 if not self._IsKeyword("COMP_BIN"):\r
30fdf114
LG
4233 raise Warning("expected COMP_BIN", self.FileName, self.CurrentLineNumber)\r
4234\r
9e47e6f9 4235 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
4236 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4237\r
9e47e6f9 4238 if not self._GetNextToken():\r
30fdf114
LG
4239 raise Warning("expected Component file", self.FileName, self.CurrentLineNumber)\r
4240\r
9e47e6f9
CJ
4241 CompStatementObj.CompBin = self._Token\r
4242 if CompStatementObj.CompBin != '-' and CompStatementObj.CompBin.replace(TAB_WORKSPACE, '').find('$') == -1:\r
6310ffd7 4243 #check for file path\r
4244 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4245 if ErrorCode != 0:\r
4246 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114 4247\r
9e47e6f9 4248 if not self._IsKeyword("COMP_SYM"):\r
30fdf114
LG
4249 raise Warning("expected COMP_SYM", self.FileName, self.CurrentLineNumber)\r
4250\r
9e47e6f9 4251 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
4252 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4253\r
9e47e6f9 4254 if not self._GetNextToken():\r
30fdf114
LG
4255 raise Warning("expected Component symbol file", self.FileName, self.CurrentLineNumber)\r
4256\r
9e47e6f9
CJ
4257 CompStatementObj.CompSym = self._Token\r
4258 if CompStatementObj.CompSym != '-' and CompStatementObj.CompSym.replace(TAB_WORKSPACE, '').find('$') == -1:\r
6310ffd7 4259 #check for file path\r
4260 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompSym), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4261 if ErrorCode != 0:\r
4262 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114 4263\r
9e47e6f9 4264 if not self._IsKeyword("COMP_SIZE"):\r
30fdf114
LG
4265 raise Warning("expected COMP_SIZE", self.FileName, self.CurrentLineNumber)\r
4266\r
9e47e6f9 4267 if not self._IsToken(TAB_EQUAL_SPLIT):\r
30fdf114
LG
4268 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
4269\r
9e47e6f9
CJ
4270 if self._IsToken("-"):\r
4271 CompStatementObj.CompSize = self._Token\r
4272 elif self._GetNextDecimalNumber():\r
4273 CompStatementObj.CompSize = self._Token\r
4274 elif self._GetNextHexNumber():\r
4275 CompStatementObj.CompSize = self._Token\r
30fdf114 4276 else:\r
9e47e6f9 4277 raise Warning("Unknown size '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
4278\r
4279 VtfObj.ComponentStatementList.append(CompStatementObj)\r
4280 return True\r
4281\r
9e47e6f9 4282 ## _GetOptionRom() method\r
30fdf114
LG
4283 #\r
4284 # Get OptionROM section contents and store its data into OptionROM list of self.Profile\r
4285 #\r
4286 # @param self The object pointer\r
4287 # @retval True Successfully find a OptionROM\r
4288 # @retval False Not able to find a OptionROM\r
4289 #\r
9e47e6f9
CJ
4290 def _GetOptionRom(self):\r
4291 if not self._GetNextToken():\r
30fdf114
LG
4292 return False\r
4293\r
9e47e6f9
CJ
4294 S = self._Token.upper()\r
4295 if S.startswith(TAB_SECTION_START) and not S.startswith("[OPTIONROM."):\r
df81077f 4296 self.SectionParser(S)\r
9e47e6f9 4297 self._UndoToken()\r
df81077f 4298 return False\r
f7496d71 4299\r
9e47e6f9
CJ
4300 self._UndoToken()\r
4301 if not self._IsToken("[OptionRom.", True):\r
4302 raise Warning("Unknown Keyword '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114 4303\r
9e47e6f9 4304 OptRomName = self._GetUiName()\r
30fdf114 4305\r
9e47e6f9 4306 if not self._IsToken(TAB_SECTION_END):\r
30fdf114
LG
4307 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
4308\r
9e47e6f9 4309 OptRomObj = OPTIONROM(OptRomName)\r
30fdf114
LG
4310 self.Profile.OptRomDict[OptRomName] = OptRomObj\r
4311\r
4312 while True:\r
9e47e6f9
CJ
4313 isInf = self._GetOptRomInfStatement(OptRomObj)\r
4314 isFile = self._GetOptRomFileStatement(OptRomObj)\r
30fdf114
LG
4315 if not isInf and not isFile:\r
4316 break\r
f7496d71 4317\r
30fdf114
LG
4318 return True\r
4319\r
9e47e6f9 4320 ## _GetOptRomInfStatement() method\r
30fdf114
LG
4321 #\r
4322 # Get INF statements\r
4323 #\r
4324 # @param self The object pointer\r
4325 # @param Obj for whom inf statement is got\r
4326 # @retval True Successfully find inf statement\r
4327 # @retval False Not able to find inf statement\r
4328 #\r
9e47e6f9
CJ
4329 def _GetOptRomInfStatement(self, Obj):\r
4330 if not self._IsKeyword("INF"):\r
30fdf114
LG
4331 return False\r
4332\r
9e47e6f9
CJ
4333 ffsInf = OptRomInfStatement()\r
4334 self._GetInfOptions(ffsInf)\r
30fdf114 4335\r
9e47e6f9 4336 if not self._GetNextToken():\r
30fdf114 4337 raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
4338 ffsInf.InfFileName = self._Token\r
4339 if ffsInf.InfFileName.replace(TAB_WORKSPACE, '').find('$') == -1:\r
6310ffd7 4340 #check for file path\r
4341 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4342 if ErrorCode != 0:\r
4343 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114
LG
4344\r
4345 if not ffsInf.InfFileName in self.Profile.InfList:\r
4346 self.Profile.InfList.append(ffsInf.InfFileName)\r
d0acc87a
LG
4347 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
4348 self.Profile.InfFileLineList.append(FileLineTuple)\r
2502b735
YZ
4349 if ffsInf.UseArch:\r
4350 if ffsInf.UseArch not in self.Profile.InfDict:\r
4351 self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]\r
4352 else:\r
4353 self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)\r
4354 else:\r
4355 self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)\r
30fdf114 4356\r
f7496d71 4357\r
9e47e6f9 4358 self._GetOptRomOverrides (ffsInf)\r
f7496d71 4359\r
30fdf114
LG
4360 Obj.FfsList.append(ffsInf)\r
4361 return True\r
4362\r
9e47e6f9 4363 ## _GetOptRomOverrides() method\r
30fdf114
LG
4364 #\r
4365 # Get overrides for OptROM INF & FILE\r
4366 #\r
4367 # @param self The object pointer\r
4368 # @param FfsInfObj for whom overrides is got\r
4369 #\r
9e47e6f9
CJ
4370 def _GetOptRomOverrides(self, Obj):\r
4371 if self._IsToken('{'):\r
4372 Overrides = OverrideAttribs()\r
fd171542 4373 while True:\r
9e47e6f9
CJ
4374 if self._IsKeyword("PCI_VENDOR_ID"):\r
4375 if not self._IsToken(TAB_EQUAL_SPLIT):\r
fd171542 4376 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4377 if not self._GetNextHexNumber():\r
fd171542 4378 raise Warning("expected Hex vendor id", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4379 Overrides.PciVendorId = self._Token\r
fd171542 4380 continue\r
4381\r
9e47e6f9
CJ
4382 if self._IsKeyword("PCI_CLASS_CODE"):\r
4383 if not self._IsToken(TAB_EQUAL_SPLIT):\r
fd171542 4384 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4385 if not self._GetNextHexNumber():\r
fd171542 4386 raise Warning("expected Hex class code", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4387 Overrides.PciClassCode = self._Token\r
fd171542 4388 continue\r
4389\r
9e47e6f9
CJ
4390 if self._IsKeyword("PCI_DEVICE_ID"):\r
4391 if not self._IsToken(TAB_EQUAL_SPLIT):\r
fd171542 4392 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4393 if not self._GetNextHexNumber():\r
fd171542 4394 raise Warning("expected Hex device id", self.FileName, self.CurrentLineNumber)\r
4395\r
9e47e6f9 4396 Overrides.PciDeviceId = self._Token\r
fd171542 4397 continue\r
4398\r
9e47e6f9
CJ
4399 if self._IsKeyword("PCI_REVISION"):\r
4400 if not self._IsToken(TAB_EQUAL_SPLIT):\r
fd171542 4401 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4402 if not self._GetNextHexNumber():\r
fd171542 4403 raise Warning("expected Hex revision", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4404 Overrides.PciRevision = self._Token\r
fd171542 4405 continue\r
4406\r
9e47e6f9
CJ
4407 if self._IsKeyword("PCI_COMPRESS"):\r
4408 if not self._IsToken(TAB_EQUAL_SPLIT):\r
fd171542 4409 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4410 if not self._GetNextToken():\r
fd171542 4411 raise Warning("expected TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4412 Overrides.NeedCompress = self._Token.upper() == 'TRUE'\r
fd171542 4413 continue\r
4414\r
9e47e6f9 4415 if self._IsToken("}"):\r
fd171542 4416 break\r
4417 else:\r
4418 EdkLogger.error("FdfParser", FORMAT_INVALID, File=self.FileName, Line=self.CurrentLineNumber)\r
4419\r
30fdf114 4420 Obj.OverrideAttribs = Overrides\r
f7496d71 4421\r
9e47e6f9 4422 ## _GetOptRomFileStatement() method\r
30fdf114
LG
4423 #\r
4424 # Get FILE statements\r
4425 #\r
4426 # @param self The object pointer\r
4427 # @param Obj for whom FILE statement is got\r
4428 # @retval True Successfully find FILE statement\r
4429 # @retval False Not able to find FILE statement\r
4430 #\r
9e47e6f9
CJ
4431 def _GetOptRomFileStatement(self, Obj):\r
4432 if not self._IsKeyword("FILE"):\r
30fdf114
LG
4433 return False\r
4434\r
9e47e6f9 4435 FfsFileObj = OptRomFileStatement()\r
30fdf114 4436\r
9e47e6f9 4437 if not self._IsKeyword("EFI") and not self._IsKeyword(BINARY_FILE_TYPE_BIN):\r
30fdf114 4438 raise Warning("expected Binary type (EFI/BIN)", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4439 FfsFileObj.FileType = self._Token\r
30fdf114 4440\r
9e47e6f9 4441 if not self._GetNextToken():\r
30fdf114 4442 raise Warning("expected File path", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
4443 FfsFileObj.FileName = self._Token\r
4444 if FfsFileObj.FileName.replace(TAB_WORKSPACE, '').find('$') == -1:\r
6310ffd7 4445 #check for file path\r
4446 ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4447 if ErrorCode != 0:\r
4448 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114
LG
4449\r
4450 if FfsFileObj.FileType == 'EFI':\r
9e47e6f9 4451 self._GetOptRomOverrides(FfsFileObj)\r
f7496d71 4452\r
30fdf114
LG
4453 Obj.FfsList.append(FfsFileObj)\r
4454\r
4455 return True\r
fd171542 4456\r
9e47e6f9 4457 ## _GetCapInFd() method\r
fd171542 4458 #\r
4459 # Get Cap list contained in FD\r
4460 #\r
4461 # @param self The object pointer\r
4462 # @param FdName FD name\r
4463 # @retval CapList List of Capsule in FD\r
4464 #\r
9e47e6f9 4465 def _GetCapInFd (self, FdName):\r
fd171542 4466 CapList = []\r
9eb87141 4467 if FdName.upper() in self.Profile.FdDict:\r
fd171542 4468 FdObj = self.Profile.FdDict[FdName.upper()]\r
4469 for elementRegion in FdObj.RegionList:\r
4470 if elementRegion.RegionType == 'CAPSULE':\r
4471 for elementRegionData in elementRegion.RegionDataList:\r
4472 if elementRegionData.endswith(".cap"):\r
4473 continue\r
4231a819 4474 if elementRegionData is not None and elementRegionData.upper() not in CapList:\r
fd171542 4475 CapList.append(elementRegionData.upper())\r
4476 return CapList\r
4477\r
9e47e6f9 4478 ## _GetReferencedFdCapTuple() method\r
fd171542 4479 #\r
4480 # Get FV and FD list referenced by a capsule image\r
4481 #\r
4482 # @param self The object pointer\r
4483 # @param CapObj Capsule section to be searched\r
4484 # @param RefFdList referenced FD by section\r
4485 # @param RefFvList referenced FV by section\r
4486 #\r
9e47e6f9
CJ
4487 def _GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []):\r
4488 for CapsuleDataObj in CapObj.CapsuleDataList:\r
4231a819 4489 if hasattr(CapsuleDataObj, 'FvName') and CapsuleDataObj.FvName is not None and CapsuleDataObj.FvName.upper() not in RefFvList:\r
fd171542 4490 RefFvList.append (CapsuleDataObj.FvName.upper())\r
4231a819 4491 elif hasattr(CapsuleDataObj, 'FdName') and CapsuleDataObj.FdName is not None and CapsuleDataObj.FdName.upper() not in RefFdList:\r
f7496d71 4492 RefFdList.append (CapsuleDataObj.FdName.upper())\r
4231a819 4493 elif CapsuleDataObj.Ffs is not None:\r
9e47e6f9 4494 if isinstance(CapsuleDataObj.Ffs, FileStatement):\r
4231a819 4495 if CapsuleDataObj.Ffs.FvName is not None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList:\r
b36d134f 4496 RefFvList.append(CapsuleDataObj.Ffs.FvName.upper())\r
4231a819 4497 elif CapsuleDataObj.Ffs.FdName is not None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList:\r
b36d134f
LG
4498 RefFdList.append(CapsuleDataObj.Ffs.FdName.upper())\r
4499 else:\r
9e47e6f9 4500 self._GetReferencedFdFvTupleFromSection(CapsuleDataObj.Ffs, RefFdList, RefFvList)\r
fd171542 4501\r
9e47e6f9 4502 ## _GetFvInFd() method\r
30fdf114
LG
4503 #\r
4504 # Get FV list contained in FD\r
4505 #\r
4506 # @param self The object pointer\r
4507 # @param FdName FD name\r
4508 # @retval FvList list of FV in FD\r
4509 #\r
9e47e6f9 4510 def _GetFvInFd (self, FdName):\r
30fdf114 4511 FvList = []\r
9eb87141 4512 if FdName.upper() in self.Profile.FdDict:\r
30fdf114
LG
4513 FdObj = self.Profile.FdDict[FdName.upper()]\r
4514 for elementRegion in FdObj.RegionList:\r
91fa33ee 4515 if elementRegion.RegionType == BINARY_FILE_TYPE_FV:\r
30fdf114 4516 for elementRegionData in elementRegion.RegionDataList:\r
fd171542 4517 if elementRegionData.endswith(".fv"):\r
4518 continue\r
4231a819 4519 if elementRegionData is not None and elementRegionData.upper() not in FvList:\r
30fdf114
LG
4520 FvList.append(elementRegionData.upper())\r
4521 return FvList\r
4522\r
9e47e6f9 4523 ## _GetReferencedFdFvTuple() method\r
30fdf114
LG
4524 #\r
4525 # Get FD and FV list referenced by a FFS file\r
4526 #\r
4527 # @param self The object pointer\r
4528 # @param FfsFile contains sections to be searched\r
4529 # @param RefFdList referenced FD by section\r
4530 # @param RefFvList referenced FV by section\r
4531 #\r
9e47e6f9 4532 def _GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []):\r
30fdf114 4533 for FfsObj in FvObj.FfsList:\r
9e47e6f9 4534 if isinstance(FfsObj, FileStatement):\r
4231a819 4535 if FfsObj.FvName is not None and FfsObj.FvName.upper() not in RefFvList:\r
30fdf114 4536 RefFvList.append(FfsObj.FvName.upper())\r
4231a819 4537 elif FfsObj.FdName is not None and FfsObj.FdName.upper() not in RefFdList:\r
30fdf114
LG
4538 RefFdList.append(FfsObj.FdName.upper())\r
4539 else:\r
9e47e6f9 4540 self._GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList)\r
30fdf114 4541\r
9e47e6f9 4542 ## _GetReferencedFdFvTupleFromSection() method\r
30fdf114
LG
4543 #\r
4544 # Get FD and FV list referenced by a FFS section\r
4545 #\r
4546 # @param self The object pointer\r
4547 # @param FfsFile contains sections to be searched\r
4548 # @param FdList referenced FD by section\r
4549 # @param FvList referenced FV by section\r
4550 #\r
9e47e6f9 4551 def _GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []):\r
5a264f28 4552 SectionStack = list(FfsFile.SectionList)\r
30fdf114
LG
4553 while SectionStack != []:\r
4554 SectionObj = SectionStack.pop()\r
9e47e6f9 4555 if isinstance(SectionObj, FvImageSection):\r
4231a819 4556 if SectionObj.FvName is not None and SectionObj.FvName.upper() not in FvList:\r
30fdf114 4557 FvList.append(SectionObj.FvName.upper())\r
4231a819 4558 if SectionObj.Fv is not None and SectionObj.Fv.UiFvName is not None and SectionObj.Fv.UiFvName.upper() not in FvList:\r
30fdf114 4559 FvList.append(SectionObj.Fv.UiFvName.upper())\r
9e47e6f9 4560 self._GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList)\r
30fdf114 4561\r
9e47e6f9 4562 if isinstance(SectionObj, CompressSection) or isinstance(SectionObj, GuidSection):\r
30fdf114
LG
4563 SectionStack.extend(SectionObj.SectionList)\r
4564\r
4565 ## CycleReferenceCheck() method\r
4566 #\r
4567 # Check whether cycle reference exists in FDF\r
4568 #\r
4569 # @param self The object pointer\r
4570 # @retval True cycle reference exists\r
4571 # @retval False Not exists cycle reference\r
4572 #\r
4573 def CycleReferenceCheck(self):\r
fd171542 4574 #\r
4575 # Check the cycle between FV and FD image\r
4576 #\r
4577 MaxLength = len (self.Profile.FvDict)\r
9eb87141 4578 for FvName in self.Profile.FvDict:\r
fd171542 4579 LogStr = "\nCycle Reference Checking for FV: %s\n" % FvName\r
5a264f28
CJ
4580 RefFvStack = set(FvName)\r
4581 FdAnalyzedList = set()\r
f7496d71 4582\r
fd171542 4583 Index = 0\r
9e47e6f9 4584 while RefFvStack and Index < MaxLength:\r
fd171542 4585 Index = Index + 1\r
4586 FvNameFromStack = RefFvStack.pop()\r
9eb87141 4587 if FvNameFromStack.upper() in self.Profile.FvDict:\r
fd171542 4588 FvObj = self.Profile.FvDict[FvNameFromStack.upper()]\r
4589 else:\r
4590 continue\r
30fdf114 4591\r
fd171542 4592 RefFdList = []\r
4593 RefFvList = []\r
9e47e6f9 4594 self._GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)\r
30fdf114 4595\r
fd171542 4596 for RefFdName in RefFdList:\r
4597 if RefFdName in FdAnalyzedList:\r
30fdf114
LG
4598 continue\r
4599\r
fd171542 4600 LogStr += "FV %s contains FD %s\n" % (FvNameFromStack, RefFdName)\r
9e47e6f9 4601 FvInFdList = self._GetFvInFd(RefFdName)\r
fd171542 4602 if FvInFdList != []:\r
4603 for FvNameInFd in FvInFdList:\r
ccaa7754 4604 LogStr += "FD %s contains FV %s\n" % (RefFdName, FvNameInFd)\r
fd171542 4605 if FvNameInFd not in RefFvStack:\r
5a264f28 4606 RefFvStack.add(FvNameInFd)\r
fd171542 4607\r
4608 if FvName in RefFvStack or FvNameFromStack in RefFvStack:\r
4609 EdkLogger.info(LogStr)\r
4610 return True\r
5a264f28 4611 FdAnalyzedList.add(RefFdName)\r
30fdf114 4612\r
fd171542 4613 for RefFvName in RefFvList:\r
4614 LogStr += "FV %s contains FV %s\n" % (FvNameFromStack, RefFvName)\r
4615 if RefFvName not in RefFvStack:\r
5a264f28 4616 RefFvStack.add(RefFvName)\r
fd171542 4617\r
4618 if FvName in RefFvStack or FvNameFromStack in RefFvStack:\r
4619 EdkLogger.info(LogStr)\r
4620 return True\r
4621\r
4622 #\r
4623 # Check the cycle between Capsule and FD image\r
4624 #\r
4625 MaxLength = len (self.Profile.CapsuleDict)\r
9eb87141 4626 for CapName in self.Profile.CapsuleDict:\r
fd171542 4627 #\r
4628 # Capsule image to be checked.\r
4629 #\r
4630 LogStr = "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName\r
5a264f28
CJ
4631 RefCapStack = {CapName}\r
4632 FdAnalyzedList = set()\r
4633 FvAnalyzedList = set()\r
f7496d71 4634\r
fd171542 4635 Index = 0\r
5a264f28 4636 while RefCapStack and Index < MaxLength:\r
fd171542 4637 Index = Index + 1\r
4638 CapNameFromStack = RefCapStack.pop()\r
9eb87141 4639 if CapNameFromStack.upper() in self.Profile.CapsuleDict:\r
fd171542 4640 CapObj = self.Profile.CapsuleDict[CapNameFromStack.upper()]\r
4641 else:\r
4642 continue\r
4643\r
4644 RefFvList = []\r
4645 RefFdList = []\r
9e47e6f9 4646 self._GetReferencedFdCapTuple(CapObj, RefFdList, RefFvList)\r
fd171542 4647\r
4648 FvListLength = 0\r
4649 FdListLength = 0\r
4650 while FvListLength < len (RefFvList) or FdListLength < len (RefFdList):\r
30fdf114
LG
4651 for RefFdName in RefFdList:\r
4652 if RefFdName in FdAnalyzedList:\r
4653 continue\r
4654\r
fd171542 4655 LogStr += "Capsule %s contains FD %s\n" % (CapNameFromStack, RefFdName)\r
5a264f28
CJ
4656 for CapNameInFd in self._GetCapInFd(RefFdName):\r
4657 LogStr += "FD %s contains Capsule %s\n" % (RefFdName, CapNameInFd)\r
4658 if CapNameInFd not in RefCapStack:\r
4659 RefCapStack.append(CapNameInFd)\r
4660\r
4661 if CapName in RefCapStack or CapNameFromStack in RefCapStack:\r
4662 EdkLogger.info(LogStr)\r
4663 return True\r
4664\r
4665 for FvNameInFd in self._GetFvInFd(RefFdName):\r
4666 LogStr += "FD %s contains FV %s\n" % (RefFdName, FvNameInFd)\r
4667 if FvNameInFd not in RefFvList:\r
4668 RefFvList.append(FvNameInFd)\r
4669\r
4670 FdAnalyzedList.add(RefFdName)\r
fd171542 4671 #\r
4672 # the number of the parsed FV and FD image\r
4673 #\r
4674 FvListLength = len (RefFvList)\r
4675 FdListLength = len (RefFdList)\r
30fdf114 4676 for RefFvName in RefFvList:\r
fd171542 4677 if RefFvName in FvAnalyzedList:\r
4678 continue\r
4679 LogStr += "Capsule %s contains FV %s\n" % (CapNameFromStack, RefFvName)\r
9eb87141 4680 if RefFvName.upper() in self.Profile.FvDict:\r
fd171542 4681 FvObj = self.Profile.FvDict[RefFvName.upper()]\r
4682 else:\r
4683 continue\r
9e47e6f9 4684 self._GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)\r
5a264f28 4685 FvAnalyzedList.add(RefFvName)\r
30fdf114 4686\r
fd171542 4687 return False\r
30fdf114 4688\r
c17956e0
DL
4689 def GetAllIncludedFile (self):\r
4690 global AllIncludeFileList\r
4691 return AllIncludeFileList\r
4692\r
30fdf114 4693if __name__ == "__main__":\r
b36d134f
LG
4694 import sys\r
4695 try:\r
4696 test_file = sys.argv[1]\r
5b0671c1 4697 except IndexError as v:\r
72443dd2 4698 print("Usage: %s filename" % sys.argv[0])\r
b36d134f
LG
4699 sys.exit(1)\r
4700\r
4701 parser = FdfParser(test_file)\r
30fdf114
LG
4702 try:\r
4703 parser.ParseFile()\r
4704 parser.CycleReferenceCheck()\r
5b0671c1 4705 except Warning as X:\r
72443dd2 4706 print(str(X))\r
30fdf114 4707 else:\r
72443dd2 4708 print("Success!")\r
30fdf114 4709\r