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