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