]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/FdfParser.py
BaseTools: fix imports
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FdfParser.py
CommitLineData
30fdf114
LG
1## @file\r
2# parse FDF file\r
3#\r
a87e79d9 4# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
118bf096 5# Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>\r
30fdf114 6#\r
40d841f6 7# This program and the accompanying materials\r
30fdf114
LG
8# are licensed and made available under the terms and conditions of the BSD License\r
9# which accompanies this distribution. The full text of the license may be found at\r
10# http://opensource.org/licenses/bsd-license.php\r
11#\r
12# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14#\r
15\r
16##\r
17# Import Modules\r
18#\r
1ccc4d89
LG
19from __future__ import print_function\r
20from __future__ import absolute_import\r
9e47e6f9
CJ
21from re import compile, DOTALL\r
22from string import hexdigits\r
23from uuid import UUID\r
30fdf114
LG
24\r
25from Common.BuildToolError import *\r
26from Common import EdkLogger\r
3d3416e8 27from Common.Misc import PathClass, tdict, ProcessDuplicatedInf\r
9e47e6f9 28from Common.StringUtils import NormPath, ReplaceMacro\r
df692f02 29from Common import GlobalData\r
9e47e6f9 30from Common.Expression import *\r
55c84777 31from Common.DataType import *\r
94e4bcbb 32from Common.MultipleWorkspace import MultipleWorkspace as mws\r
1be2ed90
HC
33import Common.LongFilePathOs as os\r
34from Common.LongFilePathSupport import OpenLongFilePath as open\r
2eb370ff 35from Common.RangeExpression import RangeExpression\r
57ee97c0 36from collections import OrderedDict\r
30fdf114 37\r
9e47e6f9
CJ
38from .Fd import FD\r
39from .Region import Region\r
40from .Fv import FV\r
41from .AprioriSection import AprioriSection\r
42from .FfsInfStatement import FfsInfStatement\r
43from .FfsFileStatement import FileStatement\r
44from .VerSection import VerSection\r
45from .UiSection import UiSection\r
46from .FvImageSection import FvImageSection\r
47from .DataSection import DataSection\r
48from .DepexSection import DepexSection\r
49from .CompressSection import CompressSection\r
50from .GuidSection import GuidSection\r
51from .Capsule import EFI_CERT_TYPE_PKCS7_GUID, EFI_CERT_TYPE_RSA2048_SHA256_GUID, Capsule\r
52from .CapsuleData import CapsuleFfs, CapsulePayload, CapsuleFv, CapsuleFd, CapsuleAnyFile, CapsuleAfile\r
53from .RuleComplexFile import RuleComplexFile\r
54from .RuleSimpleFile import RuleSimpleFile\r
55from .EfiSection import EfiSection\r
56from .Vtf import Vtf\r
57from .ComponentStatement import ComponentStatement\r
58from .OptionRom import OPTIONROM\r
59from .OptRomInfStatement import OptRomInfStatement, OverrideAttribs\r
60from .OptRomFileStatement import OptRomFileStatement\r
61from .GenFdsGlobalVariable import GenFdsGlobalVariable\r
62\r
63T_CHAR_CR = '\r'\r
64T_CHAR_TAB = '\t'\r
65T_CHAR_DOUBLE_QUOTE = '\"'\r
66T_CHAR_SINGLE_QUOTE = '\''\r
ea98a825 67T_CHAR_BRACE_R = '}'\r
9e47e6f9 68\r
ea98a825 69SEPARATORS = {TAB_EQUAL_SPLIT, TAB_VALUE_SPLIT, TAB_COMMA_SPLIT, '{', T_CHAR_BRACE_R}\r
9e47e6f9
CJ
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
bc39c5cb 535 elif InComment and not DoubleSlashComment and not HashComment and self._CurrentChar() == TAB_STAR and self._NextChar() == TAB_BACK_SLASH:\r
9e47e6f9
CJ
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
bc39c5cb 554 elif self._CurrentChar() == TAB_BACK_SLASH and self._NextChar() == TAB_STAR:\r
9e47e6f9
CJ
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
938cf4c3 1104 if GlobalData.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
938cf4c3 1172 if GlobalData.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
ea98a825 2024 if not self._IsToken(T_CHAR_BRACE_R):\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
ea98a825 2064 if not self._IsToken(T_CHAR_BRACE_R):\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
ea98a825 2333 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2334 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
b303ea72 2335\r
ea98a825 2336 if not self._IsToken(T_CHAR_BRACE_R):\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
ea98a825 2351 if not self._IsToken(T_CHAR_BRACE_R):\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
ea98a825 2387 if not self._IsToken(T_CHAR_BRACE_R):\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
3d3416e8
FB
2418 NewFileName = ffsInf.InfFileName\r
2419 if ffsInf.OverrideGuid:\r
2420 NewFileName = ProcessDuplicatedInf(PathClass(ffsInf.InfFileName,GenFdsGlobalVariable.WorkSpaceDir), ffsInf.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir).Path\r
2421\r
2422 if not NewFileName in self.Profile.InfList:\r
2423 self.Profile.InfList.append(NewFileName)\r
d0acc87a
LG
2424 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2425 self.Profile.InfFileLineList.append(FileLineTuple)\r
2502b735
YZ
2426 if ffsInf.UseArch:\r
2427 if ffsInf.UseArch not in self.Profile.InfDict:\r
2428 self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]\r
2429 else:\r
2430 self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)\r
2431 else:\r
2432 self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)\r
30fdf114 2433\r
9e47e6f9
CJ
2434 if self._IsToken(TAB_VALUE_SPLIT):\r
2435 if self._IsKeyword('RELOCS_STRIPPED'):\r
30fdf114 2436 ffsInf.KeepReloc = False\r
9e47e6f9 2437 elif self._IsKeyword('RELOCS_RETAINED'):\r
30fdf114
LG
2438 ffsInf.KeepReloc = True\r
2439 else:\r
9e47e6f9 2440 raise Warning("Unknown reloc strip flag '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
b21a13fb
YZ
2441 return ffsInf\r
2442\r
9e47e6f9 2443 ## _GetInfStatement() method\r
b21a13fb
YZ
2444 #\r
2445 # Get INF statements\r
2446 #\r
2447 # @param self The object pointer\r
2448 # @param Obj for whom inf statement is got\r
b21a13fb
YZ
2449 # @retval True Successfully find inf statement\r
2450 # @retval False Not able to find inf statement\r
2451 #\r
9e47e6f9
CJ
2452 def _GetInfStatement(self, Obj, ForCapsule=False):\r
2453 ffsInf = self._ParseInfStatement()\r
b21a13fb
YZ
2454 if not ffsInf:\r
2455 return False\r
2456\r
30fdf114 2457 if ForCapsule:\r
9e47e6f9
CJ
2458 myCapsuleFfs = CapsuleFfs()\r
2459 myCapsuleFfs.Ffs = ffsInf\r
2460 Obj.CapsuleDataList.append(myCapsuleFfs)\r
30fdf114
LG
2461 else:\r
2462 Obj.FfsList.append(ffsInf)\r
2463 return True\r
2464\r
9e47e6f9 2465 ## _GetInfOptions() method\r
30fdf114
LG
2466 #\r
2467 # Get options for INF\r
2468 #\r
2469 # @param self The object pointer\r
2470 # @param FfsInfObj for whom option is got\r
2471 #\r
9e47e6f9
CJ
2472 def _GetInfOptions(self, FfsInfObj):\r
2473 if self._IsKeyword("FILE_GUID"):\r
2474 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2475 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2476 if not self._GetNextGuid():\r
ca957eb5 2477 raise Warning.Expected("GUID value", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2478 FfsInfObj.OverrideGuid = self._Token\r
30fdf114 2479\r
9e47e6f9
CJ
2480 if self._IsKeyword("RuleOverride"):\r
2481 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2482 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2483 if not self._GetNextToken():\r
ca957eb5 2484 raise Warning.Expected("Rule name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2485 FfsInfObj.Rule = self._Token\r
30fdf114 2486\r
9e47e6f9
CJ
2487 if self._IsKeyword("VERSION"):\r
2488 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2489 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2490 if not self._GetNextToken():\r
ca957eb5 2491 raise Warning.Expected("Version", self.FileName, self.CurrentLineNumber)\r
30fdf114 2492\r
9e47e6f9
CJ
2493 if self._GetStringData():\r
2494 FfsInfObj.Version = self._Token\r
30fdf114 2495\r
9e47e6f9
CJ
2496 if self._IsKeyword(BINARY_FILE_TYPE_UI):\r
2497 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2498 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2499 if not self._GetNextToken():\r
ca957eb5 2500 raise Warning.Expected("UI name", self.FileName, self.CurrentLineNumber)\r
30fdf114 2501\r
9e47e6f9
CJ
2502 if self._GetStringData():\r
2503 FfsInfObj.Ui = self._Token\r
30fdf114 2504\r
9e47e6f9
CJ
2505 if self._IsKeyword("USE"):\r
2506 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2507 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2508 if not self._GetNextToken():\r
ca957eb5 2509 raise Warning.Expected("ARCH name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2510 FfsInfObj.UseArch = self._Token\r
30fdf114 2511\r
f7496d71 2512\r
9e47e6f9
CJ
2513 if self._GetNextToken():\r
2514 p = compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')\r
2515 if p.match(self._Token) and p.match(self._Token).span()[1] == len(self._Token):\r
2516 FfsInfObj.KeyStringList.append(self._Token)\r
2517 if not self._IsToken(TAB_COMMA_SPLIT):\r
30fdf114
LG
2518 return\r
2519 else:\r
9e47e6f9 2520 self._UndoToken()\r
30fdf114
LG
2521 return\r
2522\r
9e47e6f9
CJ
2523 while self._GetNextToken():\r
2524 if not p.match(self._Token):\r
ca957eb5 2525 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2526 FfsInfObj.KeyStringList.append(self._Token)\r
30fdf114 2527\r
9e47e6f9 2528 if not self._IsToken(TAB_COMMA_SPLIT):\r
30fdf114
LG
2529 break\r
2530\r
9e47e6f9 2531 ## _GetFileStatement() method\r
30fdf114
LG
2532 #\r
2533 # Get FILE statements\r
2534 #\r
2535 # @param self The object pointer\r
2536 # @param Obj for whom FILE statement is got\r
30fdf114
LG
2537 # @retval True Successfully find FILE statement\r
2538 # @retval False Not able to find FILE statement\r
2539 #\r
5a6a268d 2540 def _GetFileStatement(self, Obj, ForCapsule = False):\r
9e47e6f9 2541 if not self._IsKeyword("FILE"):\r
30fdf114
LG
2542 return False\r
2543\r
9e47e6f9 2544 if not self._GetNextWord():\r
ca957eb5 2545 raise Warning.Expected("FFS type", self.FileName, self.CurrentLineNumber)\r
b36d134f 2546\r
9e47e6f9
CJ
2547 if ForCapsule and self._Token == 'DATA':\r
2548 self._UndoToken()\r
2549 self._UndoToken()\r
b36d134f 2550 return False\r
f7496d71 2551\r
9e47e6f9
CJ
2552 FfsFileObj = FileStatement()\r
2553 FfsFileObj.FvFileType = self._Token\r
30fdf114 2554\r
9e47e6f9 2555 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2556 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 2557\r
9e47e6f9
CJ
2558 if not self._GetNextGuid():\r
2559 if not self._GetNextWord():\r
ca957eb5 2560 raise Warning.Expected("File GUID", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
2561 if self._Token == 'PCD':\r
2562 if not self._IsToken("("):\r
ca957eb5 2563 raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
2564 PcdPair = self._GetNextPcdSettings()\r
2565 if not self._IsToken(")"):\r
ca957eb5 2566 raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2567 self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'\r
f7496d71 2568\r
9e47e6f9 2569 FfsFileObj.NameGuid = self._Token\r
f7496d71 2570\r
5a6a268d 2571 self._GetFilePart(FfsFileObj)\r
30fdf114
LG
2572\r
2573 if ForCapsule:\r
9e47e6f9 2574 capsuleFfs = CapsuleFfs()\r
30fdf114
LG
2575 capsuleFfs.Ffs = FfsFileObj\r
2576 Obj.CapsuleDataList.append(capsuleFfs)\r
2577 else:\r
2578 Obj.FfsList.append(FfsFileObj)\r
2579\r
2580 return True\r
2581\r
9e47e6f9 2582 ## _FileCouldHaveRelocFlag() method\r
30fdf114
LG
2583 #\r
2584 # Check whether reloc strip flag can be set for a file type.\r
2585 #\r
30fdf114
LG
2586 # @param FileType The file type to check with\r
2587 # @retval True This type could have relocation strip flag\r
2588 # @retval False No way to have it\r
2589 #\r
5bcf1d56 2590 @staticmethod\r
9e47e6f9 2591 def _FileCouldHaveRelocFlag (FileType):\r
8ef653aa 2592 if FileType in {SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_MM_CORE_STANDALONE, 'PEI_DXE_COMBO'}:\r
30fdf114
LG
2593 return True\r
2594 else:\r
2595 return False\r
2596\r
9e47e6f9 2597 ## _SectionCouldHaveRelocFlag() method\r
30fdf114
LG
2598 #\r
2599 # Check whether reloc strip flag can be set for a section type.\r
2600 #\r
30fdf114
LG
2601 # @param SectionType The section type to check with\r
2602 # @retval True This type could have relocation strip flag\r
2603 # @retval False No way to have it\r
2604 #\r
5bcf1d56 2605 @staticmethod\r
9e47e6f9 2606 def _SectionCouldHaveRelocFlag (SectionType):\r
5a264f28 2607 if SectionType in {BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32}:\r
30fdf114
LG
2608 return True\r
2609 else:\r
2610 return False\r
2611\r
9e47e6f9 2612 ## _GetFilePart() method\r
30fdf114
LG
2613 #\r
2614 # Get components for FILE statement\r
2615 #\r
2616 # @param self The object pointer\r
2617 # @param FfsFileObj for whom component is got\r
30fdf114 2618 #\r
5a6a268d 2619 def _GetFilePart(self, FfsFileObj):\r
9e47e6f9 2620 self._GetFileOpts(FfsFileObj)\r
30fdf114 2621\r
9e47e6f9
CJ
2622 if not self._IsToken("{"):\r
2623 if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):\r
2624 if self._FileCouldHaveRelocFlag(FfsFileObj.FvFileType):\r
2625 if self._Token == 'RELOCS_STRIPPED':\r
4afd3d04
LG
2626 FfsFileObj.KeepReloc = False\r
2627 else:\r
2628 FfsFileObj.KeepReloc = True\r
2629 else:\r
2630 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
2631\r
9e47e6f9 2632 if not self._IsToken("{"):\r
ca957eb5 2633 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
30fdf114 2634\r
9e47e6f9 2635 if not self._GetNextToken():\r
ca957eb5 2636 raise Warning.Expected("File name or section data", self.FileName, self.CurrentLineNumber)\r
30fdf114 2637\r
9e47e6f9
CJ
2638 if self._Token == BINARY_FILE_TYPE_FV:\r
2639 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2640 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2641 if not self._GetNextToken():\r
ca957eb5 2642 raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2643 FfsFileObj.FvName = self._Token\r
30fdf114 2644\r
9e47e6f9
CJ
2645 elif self._Token == "FD":\r
2646 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2647 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2648 if not self._GetNextToken():\r
ca957eb5 2649 raise Warning.Expected("FD name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2650 FfsFileObj.FdName = self._Token\r
30fdf114 2651\r
5a264f28 2652 elif self._Token in {TAB_DEFINE, "APRIORI", "SECTION"}:\r
9e47e6f9 2653 self._UndoToken()\r
5a6a268d 2654 self._GetSectionData(FfsFileObj)\r
860992ed
YZ
2655\r
2656 elif hasattr(FfsFileObj, 'FvFileType') and FfsFileObj.FvFileType == 'RAW':\r
9e47e6f9 2657 self._UndoToken()\r
5a6a268d 2658 self._GetRAWData(FfsFileObj)\r
860992ed 2659\r
30fdf114 2660 else:\r
64b2609f 2661 FfsFileObj.CurrentLineNum = self.CurrentLineNumber\r
9e47e6f9
CJ
2662 FfsFileObj.CurrentLineContent = self._CurrentLine()\r
2663 FfsFileObj.FileName = self._Token.replace('$(SPACE)', ' ')\r
2664 self._VerifyFile(FfsFileObj.FileName)\r
0d2711a6 2665\r
ea98a825 2666 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2667 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 2668\r
9e47e6f9 2669 ## _GetRAWData() method\r
860992ed
YZ
2670 #\r
2671 # Get RAW data for FILE statement\r
2672 #\r
2673 # @param self The object pointer\r
2674 # @param FfsFileObj for whom section is got\r
860992ed 2675 #\r
5a6a268d 2676 def _GetRAWData(self, FfsFileObj):\r
860992ed 2677 FfsFileObj.FileName = []\r
cfaaf99b 2678 FfsFileObj.SubAlignment = []\r
860992ed
YZ
2679 while True:\r
2680 AlignValue = None\r
9e47e6f9
CJ
2681 if self._GetAlignment():\r
2682 if self._Token not in ALIGNMENTS:\r
2683 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
f475f1e2 2684 #For FFS, Auto is default option same to ""\r
9e47e6f9
CJ
2685 if not self._Token == "Auto":\r
2686 AlignValue = self._Token\r
2687 if not self._GetNextToken():\r
ca957eb5 2688 raise Warning.Expected("Filename value", self.FileName, self.CurrentLineNumber)\r
860992ed 2689\r
9e47e6f9 2690 FileName = self._Token.replace('$(SPACE)', ' ')\r
ea98a825 2691 if FileName == T_CHAR_BRACE_R:\r
9e47e6f9 2692 self._UndoToken()\r
ca957eb5 2693 raise Warning.Expected("Filename value", self.FileName, self.CurrentLineNumber)\r
860992ed 2694\r
9e47e6f9 2695 self._VerifyFile(FileName)\r
860992ed
YZ
2696 File = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir)\r
2697 FfsFileObj.FileName.append(File.Path)\r
cfaaf99b 2698 FfsFileObj.SubAlignment.append(AlignValue)\r
860992ed 2699\r
ea98a825 2700 if self._IsToken(T_CHAR_BRACE_R):\r
9e47e6f9 2701 self._UndoToken()\r
860992ed
YZ
2702 break\r
2703\r
cfaaf99b
YZ
2704 if len(FfsFileObj.SubAlignment) == 1:\r
2705 FfsFileObj.SubAlignment = FfsFileObj.SubAlignment[0]\r
860992ed
YZ
2706 if len(FfsFileObj.FileName) == 1:\r
2707 FfsFileObj.FileName = FfsFileObj.FileName[0]\r
2708\r
9e47e6f9 2709 ## _GetFileOpts() method\r
30fdf114
LG
2710 #\r
2711 # Get options for FILE statement\r
2712 #\r
2713 # @param self The object pointer\r
2714 # @param FfsFileObj for whom options is got\r
2715 #\r
9e47e6f9
CJ
2716 def _GetFileOpts(self, FfsFileObj):\r
2717 if self._GetNextToken():\r
2718 if TokenFindPattern.match(self._Token):\r
2719 FfsFileObj.KeyStringList.append(self._Token)\r
2720 if self._IsToken(TAB_COMMA_SPLIT):\r
2721 while self._GetNextToken():\r
2722 if not TokenFindPattern.match(self._Token):\r
ca957eb5 2723 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2724 FfsFileObj.KeyStringList.append(self._Token)\r
30fdf114 2725\r
9e47e6f9 2726 if not self._IsToken(TAB_COMMA_SPLIT):\r
30fdf114
LG
2727 break\r
2728\r
2729 else:\r
9e47e6f9 2730 self._UndoToken()\r
30fdf114 2731\r
9e47e6f9 2732 if self._IsKeyword("FIXED", True):\r
30fdf114
LG
2733 FfsFileObj.Fixed = True\r
2734\r
9e47e6f9 2735 if self._IsKeyword("CHECKSUM", True):\r
30fdf114
LG
2736 FfsFileObj.CheckSum = True\r
2737\r
9e47e6f9
CJ
2738 if self._GetAlignment():\r
2739 if self._Token not in ALIGNMENTS:\r
2740 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
9053bc51 2741 #For FFS, Auto is default option same to ""\r
9e47e6f9
CJ
2742 if not self._Token == "Auto":\r
2743 FfsFileObj.Alignment = self._Token\r
30fdf114 2744\r
9e47e6f9 2745 ## _GetAlignment() method\r
30fdf114
LG
2746 #\r
2747 # Return the alignment value\r
2748 #\r
2749 # @param self The object pointer\r
2750 # @retval True Successfully find alignment\r
2751 # @retval False Not able to find alignment\r
2752 #\r
9e47e6f9
CJ
2753 def _GetAlignment(self):\r
2754 if self._IsKeyword("Align", True):\r
2755 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2756 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 2757\r
9e47e6f9 2758 if not self._GetNextToken():\r
ca957eb5 2759 raise Warning.Expected("alignment value", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2760 return True\r
2761\r
2762 return False\r
2763\r
5a6a268d 2764 ## _GetSectionData() method\r
30fdf114
LG
2765 #\r
2766 # Get section data for FILE statement\r
2767 #\r
2768 # @param self The object pointer\r
2769 # @param FfsFileObj for whom section is got\r
30fdf114 2770 #\r
5a6a268d 2771 def _GetSectionData(self, FfsFileObj):\r
9e47e6f9 2772 self._GetDefineStatements(FfsFileObj)\r
30fdf114 2773\r
30fdf114 2774 while True:\r
5a6a268d 2775 IsLeafSection = self._GetLeafSection(FfsFileObj)\r
9e47e6f9 2776 IsEncapSection = self._GetEncapsulationSec(FfsFileObj)\r
30fdf114
LG
2777 if not IsLeafSection and not IsEncapSection:\r
2778 break\r
2779\r
9e47e6f9 2780 ## _GetLeafSection() method\r
30fdf114
LG
2781 #\r
2782 # Get leaf section for Obj\r
2783 #\r
2784 # @param self The object pointer\r
2785 # @param Obj for whom leaf section is got\r
30fdf114
LG
2786 # @retval True Successfully find section statement\r
2787 # @retval False Not able to find section statement\r
2788 #\r
5a6a268d 2789 def _GetLeafSection(self, Obj):\r
30fdf114
LG
2790 OldPos = self.GetFileBufferPos()\r
2791\r
9e47e6f9 2792 if not self._IsKeyword("SECTION"):\r
30fdf114 2793 if len(Obj.SectionList) == 0:\r
ca957eb5 2794 raise Warning.Expected("SECTION", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2795 else:\r
2796 return False\r
2797\r
2798 AlignValue = None\r
9e47e6f9
CJ
2799 if self._GetAlignment():\r
2800 if self._Token not in ALIGNMENTS:\r
2801 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
2802 AlignValue = self._Token\r
30fdf114
LG
2803\r
2804 BuildNum = None\r
9e47e6f9
CJ
2805 if self._IsKeyword("BUILD_NUM"):\r
2806 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2807 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 2808\r
9e47e6f9 2809 if not self._GetNextToken():\r
ca957eb5 2810 raise Warning.Expected("Build number value", self.FileName, self.CurrentLineNumber)\r
30fdf114 2811\r
9e47e6f9 2812 BuildNum = self._Token\r
30fdf114 2813\r
9e47e6f9 2814 if self._IsKeyword("VERSION"):\r
52302d4d
LG
2815 if AlignValue == 'Auto':\r
2816 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2817 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2818 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2819 if not self._GetNextToken():\r
ca957eb5 2820 raise Warning.Expected("version", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2821 VerSectionObj = VerSection()\r
30fdf114
LG
2822 VerSectionObj.Alignment = AlignValue\r
2823 VerSectionObj.BuildNum = BuildNum\r
9e47e6f9
CJ
2824 if self._GetStringData():\r
2825 VerSectionObj.StringData = self._Token\r
30fdf114 2826 else:\r
9e47e6f9 2827 VerSectionObj.FileName = self._Token\r
30fdf114 2828 Obj.SectionList.append(VerSectionObj)\r
f7496d71 2829\r
9e47e6f9 2830 elif self._IsKeyword(BINARY_FILE_TYPE_UI):\r
52302d4d
LG
2831 if AlignValue == 'Auto':\r
2832 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2833 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2834 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2835 if not self._GetNextToken():\r
ca957eb5 2836 raise Warning.Expected("UI", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2837 UiSectionObj = UiSection()\r
30fdf114 2838 UiSectionObj.Alignment = AlignValue\r
9e47e6f9
CJ
2839 if self._GetStringData():\r
2840 UiSectionObj.StringData = self._Token\r
30fdf114 2841 else:\r
9e47e6f9 2842 UiSectionObj.FileName = self._Token\r
30fdf114
LG
2843 Obj.SectionList.append(UiSectionObj)\r
2844\r
9e47e6f9 2845 elif self._IsKeyword("FV_IMAGE"):\r
52302d4d
LG
2846 if AlignValue == 'Auto':\r
2847 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2848 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2849 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2850 if not self._GetNextToken():\r
ca957eb5 2851 raise Warning.Expected("FV name or FV file path", self.FileName, self.CurrentLineNumber)\r
30fdf114 2852\r
9e47e6f9 2853 FvName = self._Token\r
30fdf114
LG
2854 FvObj = None\r
2855\r
9e47e6f9
CJ
2856 if self._IsToken("{"):\r
2857 FvObj = FV()\r
30fdf114 2858 FvObj.UiFvName = FvName.upper()\r
9e47e6f9 2859 self._GetDefineStatements(FvObj)\r
5a6a268d 2860\r
9e47e6f9
CJ
2861 self._GetBlockStatement(FvObj)\r
2862 self._GetSetStatements(FvObj)\r
2863 self._GetFvAlignment(FvObj)\r
2864 self._GetFvAttributes(FvObj)\r
30fdf114
LG
2865\r
2866 while True:\r
9e47e6f9 2867 IsInf = self._GetInfStatement(FvObj)\r
5a6a268d 2868 IsFile = self._GetFileStatement(FvObj)\r
30fdf114
LG
2869 if not IsInf and not IsFile:\r
2870 break\r
2871\r
ea98a825 2872 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2873 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 2874\r
9e47e6f9 2875 FvImageSectionObj = FvImageSection()\r
30fdf114 2876 FvImageSectionObj.Alignment = AlignValue\r
4231a819 2877 if FvObj is not None:\r
30fdf114
LG
2878 FvImageSectionObj.Fv = FvObj\r
2879 FvImageSectionObj.FvName = None\r
2880 else:\r
2881 FvImageSectionObj.FvName = FvName.upper()\r
2882 FvImageSectionObj.FvFileName = FvName\r
2883\r
2884 Obj.SectionList.append(FvImageSectionObj)\r
2885\r
9e47e6f9 2886 elif self._IsKeyword("PEI_DEPEX_EXP") or self._IsKeyword("DXE_DEPEX_EXP") or self._IsKeyword("SMM_DEPEX_EXP"):\r
52302d4d
LG
2887 if AlignValue == 'Auto':\r
2888 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2889 DepexSectionObj = DepexSection()\r
30fdf114 2890 DepexSectionObj.Alignment = AlignValue\r
9e47e6f9 2891 DepexSectionObj.DepexType = self._Token\r
30fdf114 2892\r
9e47e6f9 2893 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2894 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2895 if not self._IsToken("{"):\r
ca957eb5 2896 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
ea98a825 2897 if not self._SkipToToken(T_CHAR_BRACE_R):\r
ca957eb5 2898 raise Warning.Expected("Depex expression ending '}'", self.FileName, self.CurrentLineNumber)\r
30fdf114 2899\r
ea98a825 2900 DepexSectionObj.Expression = self._SkippedChars.rstrip(T_CHAR_BRACE_R)\r
30fdf114
LG
2901 Obj.SectionList.append(DepexSectionObj)\r
2902\r
2903 else:\r
9e47e6f9 2904 if not self._GetNextWord():\r
ca957eb5 2905 raise Warning.Expected("section type", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2906\r
2907 # Encapsulation section appear, UndoToken and return\r
9e47e6f9 2908 if self._Token == "COMPRESS" or self._Token == "GUIDED":\r
30fdf114
LG
2909 self.SetFileBufferPos(OldPos)\r
2910 return False\r
2911\r
5a264f28
CJ
2912 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
2913 BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX}:\r
9e47e6f9
CJ
2914 raise Warning("Unknown section type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
2915 if AlignValue == 'Auto'and (not self._Token == BINARY_FILE_TYPE_PE32) and (not self._Token == BINARY_FILE_TYPE_TE):\r
52302d4d
LG
2916 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
2917\r
30fdf114 2918 # DataSection\r
9e47e6f9 2919 DataSectionObj = DataSection()\r
30fdf114 2920 DataSectionObj.Alignment = AlignValue\r
9e47e6f9 2921 DataSectionObj.SecType = self._Token\r
30fdf114 2922\r
9e47e6f9
CJ
2923 if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):\r
2924 if self._FileCouldHaveRelocFlag(Obj.FvFileType) and self._SectionCouldHaveRelocFlag(DataSectionObj.SecType):\r
2925 if self._Token == 'RELOCS_STRIPPED':\r
30fdf114
LG
2926 DataSectionObj.KeepReloc = False\r
2927 else:\r
2928 DataSectionObj.KeepReloc = True\r
2929 else:\r
2930 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
2931\r
9e47e6f9
CJ
2932 if self._IsToken(TAB_EQUAL_SPLIT):\r
2933 if not self._GetNextToken():\r
ca957eb5 2934 raise Warning.Expected("section file path", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
2935 DataSectionObj.SectFileName = self._Token\r
2936 self._VerifyFile(DataSectionObj.SectFileName)\r
30fdf114 2937 else:\r
9e47e6f9 2938 if not self._GetCglSection(DataSectionObj):\r
30fdf114
LG
2939 return False\r
2940\r
2941 Obj.SectionList.append(DataSectionObj)\r
2942\r
2943 return True\r
2944\r
9e47e6f9 2945 ## _VerifyFile\r
2bc3256c
LG
2946 #\r
2947 # Check if file exists or not:\r
2948 # If current phase if GenFds, the file must exist;\r
2949 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist\r
2950 # @param FileName: File path to be verified.\r
2951 #\r
9e47e6f9
CJ
2952 def _VerifyFile(self, FileName):\r
2953 if FileName.replace(TAB_WORKSPACE, '').find('$') != -1:\r
2bc3256c 2954 return\r
9e47e6f9 2955 if not GlobalData.gAutoGenPhase or not self._GetMacroValue(TAB_DSC_DEFINES_OUTPUT_DIRECTORY) in FileName:\r
2bc3256c
LG
2956 ErrorCode, ErrorInfo = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
2957 if ErrorCode != 0:\r
2958 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
2959\r
9e47e6f9 2960 ## _GetCglSection() method\r
30fdf114
LG
2961 #\r
2962 # Get compressed or GUIDed section for Obj\r
2963 #\r
2964 # @param self The object pointer\r
2965 # @param Obj for whom leaf section is got\r
2966 # @param AlignValue alignment value for complex section\r
2967 # @retval True Successfully find section statement\r
2968 # @retval False Not able to find section statement\r
2969 #\r
9e47e6f9 2970 def _GetCglSection(self, Obj, AlignValue = None):\r
30fdf114 2971\r
9e47e6f9 2972 if self._IsKeyword("COMPRESS"):\r
30fdf114 2973 type = "PI_STD"\r
9e47e6f9
CJ
2974 if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE"):\r
2975 type = self._Token\r
30fdf114 2976\r
9e47e6f9 2977 if not self._IsToken("{"):\r
ca957eb5 2978 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
30fdf114 2979\r
9e47e6f9 2980 CompressSectionObj = CompressSection()\r
30fdf114
LG
2981 CompressSectionObj.Alignment = AlignValue\r
2982 CompressSectionObj.CompType = type\r
2983 # Recursive sections...\r
2984 while True:\r
9e47e6f9
CJ
2985 IsLeafSection = self._GetLeafSection(CompressSectionObj)\r
2986 IsEncapSection = self._GetEncapsulationSec(CompressSectionObj)\r
30fdf114
LG
2987 if not IsLeafSection and not IsEncapSection:\r
2988 break\r
2989\r
2990\r
ea98a825 2991 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2992 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 2993 Obj.SectionList.append(CompressSectionObj)\r
30fdf114
LG
2994 return True\r
2995\r
9e47e6f9 2996 elif self._IsKeyword("GUIDED"):\r
30fdf114 2997 GuidValue = None\r
9e47e6f9
CJ
2998 if self._GetNextGuid():\r
2999 GuidValue = self._Token\r
30fdf114 3000\r
9e47e6f9
CJ
3001 AttribDict = self._GetGuidAttrib()\r
3002 if not self._IsToken("{"):\r
ca957eb5 3003 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3004 GuidSectionObj = GuidSection()\r
30fdf114
LG
3005 GuidSectionObj.Alignment = AlignValue\r
3006 GuidSectionObj.NameGuid = GuidValue\r
3007 GuidSectionObj.SectionType = "GUIDED"\r
3008 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]\r
3009 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]\r
25918452 3010 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]\r
30fdf114
LG
3011 # Recursive sections...\r
3012 while True:\r
9e47e6f9
CJ
3013 IsLeafSection = self._GetLeafSection(GuidSectionObj)\r
3014 IsEncapSection = self._GetEncapsulationSec(GuidSectionObj)\r
30fdf114
LG
3015 if not IsLeafSection and not IsEncapSection:\r
3016 break\r
3017\r
ea98a825 3018 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 3019 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3020 Obj.SectionList.append(GuidSectionObj)\r
3021\r
3022 return True\r
3023\r
3024 return False\r
3025\r
9e47e6f9 3026 ## _GetGuidAttri() method\r
30fdf114
LG
3027 #\r
3028 # Get attributes for GUID section\r
3029 #\r
3030 # @param self The object pointer\r
3031 # @retval AttribDict Dictionary of key-value pair of section attributes\r
3032 #\r
9e47e6f9 3033 def _GetGuidAttrib(self):\r
30fdf114 3034 AttribDict = {}\r
14c48571 3035 AttribDict["PROCESSING_REQUIRED"] = "NONE"\r
3036 AttribDict["AUTH_STATUS_VALID"] = "NONE"\r
25918452 3037 AttribDict["EXTRA_HEADER_SIZE"] = -1\r
9e47e6f9
CJ
3038 while self._IsKeyword("PROCESSING_REQUIRED") or self._IsKeyword("AUTH_STATUS_VALID") \\r
3039 or self._IsKeyword("EXTRA_HEADER_SIZE"):\r
3040 AttribKey = self._Token\r
30fdf114 3041\r
9e47e6f9 3042 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3043 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 3044\r
9e47e6f9 3045 if not self._GetNextToken():\r
ca957eb5 3046 raise Warning.Expected("TRUE(1)/FALSE(0)/Number", self.FileName, self.CurrentLineNumber)\r
25918452
LG
3047 elif AttribKey == "EXTRA_HEADER_SIZE":\r
3048 Base = 10\r
9e47e6f9 3049 if self._Token[0:2].upper() == "0X":\r
25918452
LG
3050 Base = 16\r
3051 try:\r
9e47e6f9 3052 AttribDict[AttribKey] = int(self._Token, Base)\r
25918452
LG
3053 continue\r
3054 except ValueError:\r
ca957eb5 3055 raise Warning.Expected("Number", self.FileName, self.CurrentLineNumber)\r
5a264f28 3056 elif self._Token.upper() not in {"TRUE", "FALSE", "1", "0"}:\r
ca957eb5 3057 raise Warning.Expected("TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3058 AttribDict[AttribKey] = self._Token\r
30fdf114
LG
3059\r
3060 return AttribDict\r
3061\r
9e47e6f9 3062 ## _GetEncapsulationSec() method\r
30fdf114
LG
3063 #\r
3064 # Get encapsulation section for FILE\r
3065 #\r
3066 # @param self The object pointer\r
3067 # @param FfsFile for whom section is got\r
3068 # @retval True Successfully find section statement\r
3069 # @retval False Not able to find section statement\r
3070 #\r
9e47e6f9 3071 def _GetEncapsulationSec(self, FfsFileObj):\r
30fdf114 3072 OldPos = self.GetFileBufferPos()\r
9e47e6f9 3073 if not self._IsKeyword("SECTION"):\r
30fdf114 3074 if len(FfsFileObj.SectionList) == 0:\r
ca957eb5 3075 raise Warning.Expected("SECTION", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3076 else:\r
3077 return False\r
3078\r
3079 AlignValue = None\r
9e47e6f9
CJ
3080 if self._GetAlignment():\r
3081 if self._Token not in ALIGNMENT_NOAUTO:\r
3082 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
3083 AlignValue = self._Token\r
30fdf114 3084\r
9e47e6f9 3085 if not self._GetCglSection(FfsFileObj, AlignValue):\r
30fdf114
LG
3086 self.SetFileBufferPos(OldPos)\r
3087 return False\r
3088 else:\r
3089 return True\r
3090\r
9e47e6f9
CJ
3091 def _GetFmp(self):\r
3092 if not self._GetNextToken():\r
a3251d84 3093 return False\r
9e47e6f9
CJ
3094 S = self._Token.upper()\r
3095 if S.startswith(TAB_SECTION_START) and not S.startswith("[FMPPAYLOAD."):\r
df81077f 3096 self.SectionParser(S)\r
9e47e6f9 3097 self._UndoToken()\r
a3251d84
YL
3098 return False\r
3099\r
9e47e6f9
CJ
3100 self._UndoToken()\r
3101 self._SkipToToken("[FMPPAYLOAD.", True)\r
3102 FmpUiName = self._GetUiName().upper()\r
a3251d84
YL
3103 if FmpUiName in self.Profile.FmpPayloadDict:\r
3104 raise Warning("Duplicated FMP UI name found: %s" % FmpUiName, self.FileName, self.CurrentLineNumber)\r
3105\r
9e47e6f9 3106 FmpData = CapsulePayload()\r
a3251d84
YL
3107 FmpData.UiName = FmpUiName\r
3108\r
9e47e6f9 3109 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 3110 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
a3251d84 3111\r
9e47e6f9 3112 if not self._GetNextToken():\r
a3251d84 3113 raise Warning("The FMP payload section is empty!", self.FileName, self.CurrentLineNumber)\r
91ae2988 3114 FmpKeyList = ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']\r
9e47e6f9
CJ
3115 while self._Token in FmpKeyList:\r
3116 Name = self._Token\r
a3251d84 3117 FmpKeyList.remove(Name)\r
9e47e6f9 3118 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3119 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
a3251d84 3120 if Name == 'IMAGE_TYPE_ID':\r
9e47e6f9 3121 if not self._GetNextGuid():\r
ca957eb5 3122 raise Warning.Expected("GUID value for IMAGE_TYPE_ID.", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3123 FmpData.ImageTypeId = self._Token\r
91ae2988 3124 elif Name == 'CERTIFICATE_GUID':\r
9e47e6f9 3125 if not self._GetNextGuid():\r
ca957eb5 3126 raise Warning.Expected("GUID value for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3127 FmpData.Certificate_Guid = self._Token\r
3128 if UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_RSA2048_SHA256_GUID and UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_PKCS7_GUID:\r
91ae2988 3129 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 3130 else:\r
9e47e6f9 3131 if not self._GetNextToken():\r
ca957eb5 3132 raise Warning.Expected("value of %s" % Name, self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3133 Value = self._Token\r
a3251d84 3134 if Name == 'IMAGE_HEADER_INIT_VERSION':\r
9e47e6f9 3135 if FdfParser._Verify(Name, Value, 'UINT8'):\r
91ae2988 3136 FmpData.Version = Value\r
a3251d84 3137 elif Name == 'IMAGE_INDEX':\r
9e47e6f9 3138 if FdfParser._Verify(Name, Value, 'UINT8'):\r
91ae2988 3139 FmpData.ImageIndex = Value\r
a3251d84 3140 elif Name == 'HARDWARE_INSTANCE':\r
9e47e6f9 3141 if FdfParser._Verify(Name, Value, 'UINT8'):\r
91ae2988
YZ
3142 FmpData.HardwareInstance = Value\r
3143 elif Name == 'MONOTONIC_COUNT':\r
9e47e6f9 3144 if FdfParser._Verify(Name, Value, 'UINT64'):\r
91ae2988
YZ
3145 FmpData.MonotonicCount = Value\r
3146 if FmpData.MonotonicCount.upper().startswith('0X'):\r
1ccc4d89 3147 FmpData.MonotonicCount = (long)(FmpData.MonotonicCount, 16)\r
91ae2988 3148 else:\r
1ccc4d89 3149 FmpData.MonotonicCount = (long)(FmpData.MonotonicCount)\r
9e47e6f9 3150 if not self._GetNextToken():\r
a3251d84
YL
3151 break\r
3152 else:\r
9e47e6f9 3153 self._UndoToken()\r
a3251d84 3154\r
91ae2988
YZ
3155 if (FmpData.MonotonicCount and not FmpData.Certificate_Guid) or (not FmpData.MonotonicCount and FmpData.Certificate_Guid):\r
3156 EdkLogger.error("FdfParser", FORMAT_INVALID, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")\r
9ce9bf53
YZ
3157\r
3158 # Only the IMAGE_TYPE_ID is required item\r
3159 if FmpKeyList and 'IMAGE_TYPE_ID' in FmpKeyList:\r
ca957eb5 3160 raise Warning("'IMAGE_TYPE_ID' in FMP payload section.", self.FileName, self.CurrentLineNumber)\r
19e3aa7a 3161 # get the Image file and Vendor code file\r
9e47e6f9 3162 self._GetFMPCapsuleData(FmpData)\r
19e3aa7a 3163 if not FmpData.ImageFile:\r
91ae2988 3164 raise Warning("Missing image file in FMP payload section.", self.FileName, self.CurrentLineNumber)\r
19e3aa7a
YZ
3165 # check whether more than one Vendor code file\r
3166 if len(FmpData.VendorCodeFile) > 1:\r
ca957eb5 3167 raise Warning("Vendor code file max of 1 per FMP payload section.", self.FileName, self.CurrentLineNumber)\r
a3251d84
YL
3168 self.Profile.FmpPayloadDict[FmpUiName] = FmpData\r
3169 return True\r
3170\r
9e47e6f9 3171 ## _GetCapsule() method\r
30fdf114
LG
3172 #\r
3173 # Get capsule section contents and store its data into capsule list of self.Profile\r
3174 #\r
3175 # @param self The object pointer\r
3176 # @retval True Successfully find a capsule\r
3177 # @retval False Not able to find a capsule\r
3178 #\r
9e47e6f9
CJ
3179 def _GetCapsule(self):\r
3180 if not self._GetNextToken():\r
30fdf114
LG
3181 return False\r
3182\r
9e47e6f9
CJ
3183 S = self._Token.upper()\r
3184 if S.startswith(TAB_SECTION_START) and not S.startswith("[CAPSULE."):\r
df81077f 3185 self.SectionParser(S)\r
9e47e6f9 3186 self._UndoToken()\r
30fdf114
LG
3187 return False\r
3188\r
9e47e6f9
CJ
3189 self._UndoToken()\r
3190 if not self._IsToken("[CAPSULE.", True):\r
30fdf114
LG
3191 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
3192 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
9e47e6f9 3193 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
ca957eb5 3194 raise Warning.Expected("[Capsule.]", self.FileName, self.CurrentLineNumber)\r
30fdf114 3195\r
9e47e6f9 3196 CapsuleObj = Capsule()\r
30fdf114 3197\r
9e47e6f9 3198 CapsuleName = self._GetUiName()\r
30fdf114 3199 if not CapsuleName:\r
ca957eb5 3200 raise Warning.Expected("capsule name", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3201\r
3202 CapsuleObj.UiCapsuleName = CapsuleName.upper()\r
3203\r
9e47e6f9 3204 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 3205 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 3206\r
9e47e6f9
CJ
3207 if self._IsKeyword("CREATE_FILE"):\r
3208 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3209 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 3210\r
9e47e6f9 3211 if not self._GetNextToken():\r
ca957eb5 3212 raise Warning.Expected("file name", self.FileName, self.CurrentLineNumber)\r
30fdf114 3213\r
9e47e6f9 3214 CapsuleObj.CreateFile = self._Token\r
30fdf114 3215\r
9e47e6f9 3216 self._GetCapsuleStatements(CapsuleObj)\r
fd171542 3217 self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj\r
30fdf114
LG
3218 return True\r
3219\r
9e47e6f9 3220 ## _GetCapsuleStatements() method\r
30fdf114
LG
3221 #\r
3222 # Get statements for capsule\r
3223 #\r
3224 # @param self The object pointer\r
3225 # @param Obj for whom statements are got\r
3226 #\r
9e47e6f9
CJ
3227 def _GetCapsuleStatements(self, Obj):\r
3228 self._GetCapsuleTokens(Obj)\r
3229 self._GetDefineStatements(Obj)\r
3230 self._GetSetStatements(Obj)\r
3231 self._GetCapsuleData(Obj)\r
30fdf114 3232\r
9e47e6f9 3233 ## _GetCapsuleTokens() method\r
30fdf114
LG
3234 #\r
3235 # Get token statements for capsule\r
3236 #\r
3237 # @param self The object pointer\r
3238 # @param Obj for whom token statements are got\r
3239 #\r
9e47e6f9
CJ
3240 def _GetCapsuleTokens(self, Obj):\r
3241 if not self._GetNextToken():\r
b303ea72 3242 return False\r
5a264f28 3243 while self._Token in {"CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"}:\r
9e47e6f9
CJ
3244 Name = self._Token.strip()\r
3245 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3246 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3247 if not self._GetNextToken():\r
ca957eb5 3248 raise Warning.Expected("value", self.FileName, self.CurrentLineNumber)\r
b303ea72 3249 if Name == 'CAPSULE_FLAGS':\r
5a264f28 3250 if not self._Token in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:\r
ca957eb5 3251 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3252 Value = self._Token.strip()\r
3253 while self._IsToken(TAB_COMMA_SPLIT):\r
3254 Value += TAB_COMMA_SPLIT\r
3255 if not self._GetNextToken():\r
ca957eb5 3256 raise Warning.Expected("value", self.FileName, self.CurrentLineNumber)\r
5a264f28 3257 if not self._Token in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:\r
ca957eb5 3258 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3259 Value += self._Token.strip()\r
e8a47801 3260 elif Name == 'OEM_CAPSULE_FLAGS':\r
9e47e6f9 3261 Value = self._Token.strip()\r
2bc3256c 3262 if not Value.upper().startswith('0X'):\r
ca957eb5 3263 raise Warning.Expected("hex value starting with 0x", self.FileName, self.CurrentLineNumber)\r
e8a47801
LG
3264 try:\r
3265 Value = int(Value, 0)\r
3266 except ValueError:\r
ca957eb5 3267 raise Warning.Expected("hex string failed to convert to value", self.FileName, self.CurrentLineNumber)\r
e8a47801 3268 if not 0x0000 <= Value <= 0xFFFF:\r
ca957eb5 3269 raise Warning.Expected("hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3270 Value = self._Token.strip()\r
b303ea72 3271 else:\r
9e47e6f9 3272 Value = self._Token.strip()\r
f7496d71 3273 Obj.TokensDict[Name] = Value\r
9e47e6f9 3274 if not self._GetNextToken():\r
b303ea72 3275 return False\r
9e47e6f9 3276 self._UndoToken()\r
30fdf114 3277\r
9e47e6f9 3278 ## _GetCapsuleData() method\r
30fdf114
LG
3279 #\r
3280 # Get capsule data for capsule\r
3281 #\r
3282 # @param self The object pointer\r
3283 # @param Obj for whom capsule data are got\r
3284 #\r
9e47e6f9 3285 def _GetCapsuleData(self, Obj):\r
30fdf114 3286 while True:\r
9e47e6f9
CJ
3287 IsInf = self._GetInfStatement(Obj, True)\r
3288 IsFile = self._GetFileStatement(Obj, True)\r
3289 IsFv = self._GetFvStatement(Obj)\r
3290 IsFd = self._GetFdStatement(Obj)\r
3291 IsAnyFile = self._GetAnyFileStatement(Obj)\r
3292 IsAfile = self._GetAfileStatement(Obj)\r
3293 IsFmp = self._GetFmpStatement(Obj)\r
a3251d84 3294 if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile or IsAfile or IsFmp):\r
30fdf114
LG
3295 break\r
3296\r
9e47e6f9 3297 ## _GetFMPCapsuleData() method\r
19e3aa7a
YZ
3298 #\r
3299 # Get capsule data for FMP capsule\r
3300 #\r
3301 # @param self The object pointer\r
3302 # @param Obj for whom capsule data are got\r
3303 #\r
9e47e6f9 3304 def _GetFMPCapsuleData(self, Obj):\r
19e3aa7a 3305 while True:\r
9e47e6f9
CJ
3306 IsFv = self._GetFvStatement(Obj, True)\r
3307 IsFd = self._GetFdStatement(Obj, True)\r
3308 IsAnyFile = self._GetAnyFileStatement(Obj, True)\r
19e3aa7a
YZ
3309 if not (IsFv or IsFd or IsAnyFile):\r
3310 break\r
3311\r
9e47e6f9 3312 ## _GetFvStatement() method\r
30fdf114
LG
3313 #\r
3314 # Get FV for capsule\r
3315 #\r
3316 # @param self The object pointer\r
3317 # @param CapsuleObj for whom FV is got\r
3318 # @retval True Successfully find a FV statement\r
3319 # @retval False Not able to find a FV statement\r
3320 #\r
9e47e6f9
CJ
3321 def _GetFvStatement(self, CapsuleObj, FMPCapsule = False):\r
3322 if not self._IsKeyword(BINARY_FILE_TYPE_FV):\r
30fdf114
LG
3323 return False\r
3324\r
9e47e6f9 3325 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3326 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 3327\r
9e47e6f9 3328 if not self._GetNextToken():\r
ca957eb5 3329 raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)\r
30fdf114 3330\r
9e47e6f9 3331 if self._Token.upper() not in self.Profile.FvDict:\r
2bcc713e
LG
3332 raise Warning("FV name does not exist", self.FileName, self.CurrentLineNumber)\r
3333\r
9e47e6f9
CJ
3334 myCapsuleFv = CapsuleFv()\r
3335 myCapsuleFv.FvName = self._Token\r
19e3aa7a
YZ
3336 if FMPCapsule:\r
3337 if not CapsuleObj.ImageFile:\r
9e47e6f9 3338 CapsuleObj.ImageFile.append(myCapsuleFv)\r
19e3aa7a 3339 else:\r
9e47e6f9 3340 CapsuleObj.VendorCodeFile.append(myCapsuleFv)\r
19e3aa7a 3341 else:\r
9e47e6f9 3342 CapsuleObj.CapsuleDataList.append(myCapsuleFv)\r
30fdf114
LG
3343 return True\r
3344\r
9e47e6f9 3345 ## _GetFdStatement() method\r
b36d134f
LG
3346 #\r
3347 # Get FD for capsule\r
3348 #\r
3349 # @param self The object pointer\r
3350 # @param CapsuleObj for whom FD is got\r
3351 # @retval True Successfully find a FD statement\r
3352 # @retval False Not able to find a FD statement\r
3353 #\r
9e47e6f9
CJ
3354 def _GetFdStatement(self, CapsuleObj, FMPCapsule = False):\r
3355 if not self._IsKeyword("FD"):\r
b36d134f
LG
3356 return False\r
3357\r
9e47e6f9 3358 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3359 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
b36d134f 3360\r
9e47e6f9 3361 if not self._GetNextToken():\r
ca957eb5 3362 raise Warning.Expected("FD name", self.FileName, self.CurrentLineNumber)\r
b36d134f 3363\r
9e47e6f9 3364 if self._Token.upper() not in self.Profile.FdDict:\r
2bcc713e
LG
3365 raise Warning("FD name does not exist", self.FileName, self.CurrentLineNumber)\r
3366\r
9e47e6f9
CJ
3367 myCapsuleFd = CapsuleFd()\r
3368 myCapsuleFd.FdName = self._Token\r
19e3aa7a
YZ
3369 if FMPCapsule:\r
3370 if not CapsuleObj.ImageFile:\r
9e47e6f9 3371 CapsuleObj.ImageFile.append(myCapsuleFd)\r
19e3aa7a 3372 else:\r
9e47e6f9 3373 CapsuleObj.VendorCodeFile.append(myCapsuleFd)\r
19e3aa7a 3374 else:\r
9e47e6f9 3375 CapsuleObj.CapsuleDataList.append(myCapsuleFd)\r
b36d134f
LG
3376 return True\r
3377\r
9e47e6f9
CJ
3378 def _GetFmpStatement(self, CapsuleObj):\r
3379 if not self._IsKeyword("FMP_PAYLOAD"):\r
3380 if not self._IsKeyword("FMP"):\r
df81077f 3381 return False\r
b36d134f 3382\r
9e47e6f9
CJ
3383 if not self._IsKeyword("PAYLOAD"):\r
3384 self._UndoToken()\r
df81077f 3385 return False\r
b36d134f 3386\r
9e47e6f9 3387 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3388 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
a3251d84 3389\r
9e47e6f9 3390 if not self._GetNextToken():\r
ca957eb5 3391 raise Warning.Expected("payload name after FMP_PAYLOAD =", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3392 Payload = self._Token.upper()\r
a3251d84 3393 if Payload not in self.Profile.FmpPayloadDict:\r
9e47e6f9 3394 raise Warning("This FMP Payload does not exist: %s" % self._Token, self.FileName, self.CurrentLineNumber)\r
a3251d84
YL
3395 CapsuleObj.FmpPayloadList.append(self.Profile.FmpPayloadDict[Payload])\r
3396 return True\r
3397\r
9e47e6f9
CJ
3398 def _ParseRawFileStatement(self):\r
3399 if not self._IsKeyword("FILE"):\r
a3251d84
YL
3400 return None\r
3401\r
9e47e6f9
CJ
3402 if not self._IsKeyword("DATA"):\r
3403 self._UndoToken()\r
a3251d84 3404 return None\r
b36d134f 3405\r
9e47e6f9 3406 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3407 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
b36d134f 3408\r
9e47e6f9 3409 if not self._GetNextToken():\r
ca957eb5 3410 raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber)\r
f7496d71 3411\r
9e47e6f9
CJ
3412 AnyFileName = self._Token\r
3413 self._VerifyFile(AnyFileName)\r
35217a33 3414\r
94e4bcbb
YZ
3415 if not os.path.isabs(AnyFileName):\r
3416 AnyFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, AnyFileName)\r
3417\r
a3251d84
YL
3418 return AnyFileName\r
3419\r
9e47e6f9 3420 ## _GetAnyFileStatement() method\r
a3251d84
YL
3421 #\r
3422 # Get AnyFile for capsule\r
3423 #\r
3424 # @param self The object pointer\r
3425 # @param CapsuleObj for whom AnyFile is got\r
3426 # @retval True Successfully find a Anyfile statement\r
3427 # @retval False Not able to find a AnyFile statement\r
3428 #\r
9e47e6f9
CJ
3429 def _GetAnyFileStatement(self, CapsuleObj, FMPCapsule = False):\r
3430 AnyFileName = self._ParseRawFileStatement()\r
a3251d84
YL
3431 if not AnyFileName:\r
3432 return False\r
b36d134f 3433\r
9e47e6f9
CJ
3434 myCapsuleAnyFile = CapsuleAnyFile()\r
3435 myCapsuleAnyFile.FileName = AnyFileName\r
19e3aa7a
YZ
3436 if FMPCapsule:\r
3437 if not CapsuleObj.ImageFile:\r
9e47e6f9 3438 CapsuleObj.ImageFile.append(myCapsuleAnyFile)\r
19e3aa7a 3439 else:\r
9e47e6f9 3440 CapsuleObj.VendorCodeFile.append(myCapsuleAnyFile)\r
19e3aa7a 3441 else:\r
9e47e6f9 3442 CapsuleObj.CapsuleDataList.append(myCapsuleAnyFile)\r
b36d134f 3443 return True\r
f7496d71 3444\r
9e47e6f9 3445 ## _GetAfileStatement() method\r
2bc3256c
LG
3446 #\r
3447 # Get Afile for capsule\r
3448 #\r
3449 # @param self The object pointer\r
3450 # @param CapsuleObj for whom Afile is got\r
3451 # @retval True Successfully find a Afile statement\r
3452 # @retval False Not able to find a Afile statement\r
3453 #\r
9e47e6f9
CJ
3454 def _GetAfileStatement(self, CapsuleObj):\r
3455 if not self._IsKeyword("APPEND"):\r
2bc3256c
LG
3456 return False\r
3457\r
9e47e6f9 3458 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3459 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
2bc3256c 3460\r
9e47e6f9 3461 if not self._GetNextToken():\r
ca957eb5 3462 raise Warning.Expected("Afile name", self.FileName, self.CurrentLineNumber)\r
f7496d71 3463\r
9e47e6f9 3464 AfileName = self._Token\r
2bc3256c 3465 AfileBaseName = os.path.basename(AfileName)\r
f7496d71 3466\r
5a264f28 3467 if os.path.splitext(AfileBaseName)[1] not in {".bin", ".BIN", ".Bin", ".dat", ".DAT", ".Dat", ".data", ".DATA", ".Data"}:\r
91fa33ee 3468 raise Warning('invalid binary file type, should be one of "bin",BINARY_FILE_TYPE_BIN,"Bin","dat","DAT","Dat","data","DATA","Data"', \\r
2bc3256c 3469 self.FileName, self.CurrentLineNumber)\r
f7496d71 3470\r
2bc3256c
LG
3471 if not os.path.isabs(AfileName):\r
3472 AfileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AfileName)\r
9e47e6f9 3473 self._VerifyFile(AfileName)\r
2bc3256c
LG
3474 else:\r
3475 if not os.path.exists(AfileName):\r
3476 raise Warning('%s does not exist' % AfileName, self.FileName, self.CurrentLineNumber)\r
3477 else:\r
3478 pass\r
3479\r
9e47e6f9
CJ
3480 myCapsuleAfile = CapsuleAfile()\r
3481 myCapsuleAfile.FileName = AfileName\r
3482 CapsuleObj.CapsuleDataList.append(myCapsuleAfile)\r
2bc3256c 3483 return True\r
b36d134f 3484\r
9e47e6f9 3485 ## _GetRule() method\r
30fdf114
LG
3486 #\r
3487 # Get Rule section contents and store its data into rule list of self.Profile\r
3488 #\r
3489 # @param self The object pointer\r
3490 # @retval True Successfully find a Rule\r
3491 # @retval False Not able to find a Rule\r
3492 #\r
9e47e6f9
CJ
3493 def _GetRule(self):\r
3494 if not self._GetNextToken():\r
30fdf114
LG
3495 return False\r
3496\r
9e47e6f9
CJ
3497 S = self._Token.upper()\r
3498 if S.startswith(TAB_SECTION_START) and not S.startswith("[RULE."):\r
df81077f 3499 self.SectionParser(S)\r
9e47e6f9 3500 self._UndoToken()\r
30fdf114 3501 return False\r
9e47e6f9
CJ
3502 self._UndoToken()\r
3503 if not self._IsToken("[Rule.", True):\r
30fdf114
LG
3504 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
3505 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
9e47e6f9 3506 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
ca957eb5 3507 raise Warning.Expected("[Rule.]", self.FileName, self.CurrentLineNumber)\r
30fdf114 3508\r
9e47e6f9 3509 if not self._SkipToToken(TAB_SPLIT):\r
ca957eb5 3510 raise Warning.Expected("'.'", self.FileName, self.CurrentLineNumber)\r
30fdf114 3511\r
9e47e6f9 3512 Arch = self._SkippedChars.rstrip(TAB_SPLIT)\r
eece4292 3513 if Arch.upper() not in ARCH_SET_FULL:\r
30fdf114
LG
3514 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)\r
3515\r
9e47e6f9 3516 ModuleType = self._GetModuleType()\r
30fdf114
LG
3517\r
3518 TemplateName = ""\r
9e47e6f9
CJ
3519 if self._IsToken(TAB_SPLIT):\r
3520 if not self._GetNextWord():\r
ca957eb5 3521 raise Warning.Expected("template name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3522 TemplateName = self._Token\r
30fdf114 3523\r
9e47e6f9 3524 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 3525 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 3526\r
9e47e6f9 3527 RuleObj = self._GetRuleFileStatements()\r
30fdf114
LG
3528 RuleObj.Arch = Arch.upper()\r
3529 RuleObj.ModuleType = ModuleType\r
3530 RuleObj.TemplateName = TemplateName\r
9e47e6f9 3531 if TemplateName == '':\r
30fdf114 3532 self.Profile.RuleDict['RULE' + \\r
9e47e6f9 3533 TAB_SPLIT + \\r
30fdf114 3534 Arch.upper() + \\r
9e47e6f9 3535 TAB_SPLIT + \\r
30fdf114 3536 ModuleType.upper() ] = RuleObj\r
9e47e6f9 3537 else:\r
30fdf114 3538 self.Profile.RuleDict['RULE' + \\r
9e47e6f9 3539 TAB_SPLIT + \\r
30fdf114 3540 Arch.upper() + \\r
9e47e6f9 3541 TAB_SPLIT + \\r
30fdf114 3542 ModuleType.upper() + \\r
9e47e6f9 3543 TAB_SPLIT + \\r
30fdf114 3544 TemplateName.upper() ] = RuleObj\r
30fdf114
LG
3545 return True\r
3546\r
9e47e6f9 3547 ## _GetModuleType() method\r
30fdf114
LG
3548 #\r
3549 # Return the module type\r
3550 #\r
3551 # @param self The object pointer\r
3552 # @retval string module type\r
3553 #\r
9e47e6f9
CJ
3554 def _GetModuleType(self):\r
3555 if not self._GetNextWord():\r
ca957eb5 3556 raise Warning.Expected("Module type", self.FileName, self.CurrentLineNumber)\r
5a264f28
CJ
3557 if self._Token.upper() not in {\r
3558 SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM,\r
3559 SUP_MODULE_DXE_CORE, SUP_MODULE_DXE_DRIVER,\r
3560 SUP_MODULE_DXE_SAL_DRIVER, SUP_MODULE_DXE_SMM_DRIVER,\r
3561 SUP_MODULE_DXE_RUNTIME_DRIVER, SUP_MODULE_UEFI_DRIVER,\r
3562 SUP_MODULE_UEFI_APPLICATION, SUP_MODULE_USER_DEFINED,\r
3563 TAB_DEFAULT, SUP_MODULE_BASE,\r
3564 EDK_COMPONENT_TYPE_SECURITY_CORE,\r
3565 EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER,\r
3566 EDK_COMPONENT_TYPE_PIC_PEIM,\r
3567 EDK_COMPONENT_TYPE_RELOCATABLE_PEIM, "PE32_PEIM",\r
3568 EDK_COMPONENT_TYPE_BS_DRIVER, EDK_COMPONENT_TYPE_RT_DRIVER,\r
3569 EDK_COMPONENT_TYPE_SAL_RT_DRIVER,\r
3570 EDK_COMPONENT_TYPE_APPLICATION, "ACPITABLE",\r
3571 SUP_MODULE_SMM_CORE, SUP_MODULE_MM_STANDALONE,\r
3572 SUP_MODULE_MM_CORE_STANDALONE}:\r
9e47e6f9
CJ
3573 raise Warning("Unknown Module type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
3574 return self._Token\r
30fdf114 3575\r
9e47e6f9 3576 ## _GetFileExtension() method\r
30fdf114
LG
3577 #\r
3578 # Return the file extension\r
3579 #\r
3580 # @param self The object pointer\r
3581 # @retval string file name extension\r
3582 #\r
9e47e6f9
CJ
3583 def _GetFileExtension(self):\r
3584 if not self._IsToken(TAB_SPLIT):\r
ca957eb5 3585 raise Warning.Expected("'.'", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3586\r
3587 Ext = ""\r
9e47e6f9
CJ
3588 if self._GetNextToken():\r
3589 if FileExtensionPattern.match(self._Token):\r
3590 Ext = self._Token\r
3591 return TAB_SPLIT + Ext\r
30fdf114 3592 else:\r
9e47e6f9 3593 raise Warning("Unknown file extension '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3594\r
3595 else:\r
ca957eb5 3596 raise Warning.Expected("file extension", self.FileName, self.CurrentLineNumber)\r
30fdf114 3597\r
9e47e6f9 3598 ## _GetRuleFileStatement() method\r
30fdf114
LG
3599 #\r
3600 # Get rule contents\r
3601 #\r
3602 # @param self The object pointer\r
3603 # @retval Rule Rule object\r
3604 #\r
9e47e6f9
CJ
3605 def _GetRuleFileStatements(self):\r
3606 if not self._IsKeyword("FILE"):\r
ca957eb5 3607 raise Warning.Expected("FILE", self.FileName, self.CurrentLineNumber)\r
30fdf114 3608\r
9e47e6f9 3609 if not self._GetNextWord():\r
ca957eb5 3610 raise Warning.Expected("FFS type", self.FileName, self.CurrentLineNumber)\r
30fdf114 3611\r
9e47e6f9 3612 Type = self._Token.strip().upper()\r
5a264f28
CJ
3613 if Type not in {"RAW", "FREEFORM", SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM,\r
3614 "PEI_DXE_COMBO", "DRIVER", SUP_MODULE_DXE_CORE, EDK_COMPONENT_TYPE_APPLICATION,\r
3615 "FV_IMAGE", "SMM", SUP_MODULE_SMM_CORE, SUP_MODULE_MM_STANDALONE,\r
3616 SUP_MODULE_MM_CORE_STANDALONE}:\r
9e47e6f9 3617 raise Warning("Unknown FV type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114 3618\r
9e47e6f9 3619 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3620 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 3621\r
9e47e6f9
CJ
3622 if not self._IsKeyword("$(NAMED_GUID)"):\r
3623 if not self._GetNextWord():\r
ca957eb5 3624 raise Warning.Expected("$(NAMED_GUID)", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3625 if self._Token == 'PCD':\r
3626 if not self._IsToken("("):\r
ca957eb5 3627 raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3628 PcdPair = self._GetNextPcdSettings()\r
3629 if not self._IsToken(")"):\r
ca957eb5 3630 raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3631 self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'\r
f7496d71 3632\r
9e47e6f9 3633 NameGuid = self._Token\r
30fdf114
LG
3634\r
3635 KeepReloc = None\r
9e47e6f9
CJ
3636 if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):\r
3637 if self._FileCouldHaveRelocFlag(Type):\r
3638 if self._Token == 'RELOCS_STRIPPED':\r
30fdf114
LG
3639 KeepReloc = False\r
3640 else:\r
3641 KeepReloc = True\r
3642 else:\r
3643 raise Warning("File type %s could not have reloc strip flag%d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3644\r
3645 KeyStringList = []\r
9e47e6f9
CJ
3646 if self._GetNextToken():\r
3647 if TokenFindPattern.match(self._Token):\r
3648 KeyStringList.append(self._Token)\r
3649 if self._IsToken(TAB_COMMA_SPLIT):\r
3650 while self._GetNextToken():\r
3651 if not TokenFindPattern.match(self._Token):\r
ca957eb5 3652 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3653 KeyStringList.append(self._Token)\r
30fdf114 3654\r
9e47e6f9 3655 if not self._IsToken(TAB_COMMA_SPLIT):\r
30fdf114
LG
3656 break\r
3657\r
3658 else:\r
9e47e6f9 3659 self._UndoToken()\r
30fdf114
LG
3660\r
3661\r
3662 Fixed = False\r
9e47e6f9 3663 if self._IsKeyword("Fixed", True):\r
30fdf114
LG
3664 Fixed = True\r
3665\r
3666 CheckSum = False\r
9e47e6f9 3667 if self._IsKeyword("CheckSum", True):\r
30fdf114
LG
3668 CheckSum = True\r
3669\r
3670 AlignValue = ""\r
9e47e6f9
CJ
3671 if self._GetAlignment():\r
3672 if self._Token not in ALIGNMENTS:\r
3673 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
52302d4d 3674 #For FFS, Auto is default option same to ""\r
9e47e6f9
CJ
3675 if not self._Token == "Auto":\r
3676 AlignValue = self._Token\r
30fdf114 3677\r
9e47e6f9 3678 if self._IsToken("{"):\r
30fdf114 3679 # Complex file rule expected\r
9e47e6f9
CJ
3680 NewRule = RuleComplexFile()\r
3681 NewRule.FvFileType = Type\r
3682 NewRule.NameGuid = NameGuid\r
3683 NewRule.Alignment = AlignValue\r
3684 NewRule.CheckSum = CheckSum\r
3685 NewRule.Fixed = Fixed\r
3686 NewRule.KeyStringList = KeyStringList\r
4231a819 3687 if KeepReloc is not None:\r
9e47e6f9 3688 NewRule.KeepReloc = KeepReloc\r
30fdf114
LG
3689\r
3690 while True:\r
9e47e6f9
CJ
3691 IsEncapsulate = self._GetRuleEncapsulationSection(NewRule)\r
3692 IsLeaf = self._GetEfiSection(NewRule)\r
30fdf114
LG
3693 if not IsEncapsulate and not IsLeaf:\r
3694 break\r
3695\r
ea98a825 3696 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 3697 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 3698\r
9e47e6f9 3699 return NewRule\r
30fdf114 3700\r
30fdf114
LG
3701 else:\r
3702 # Simple file rule expected\r
9e47e6f9 3703 if not self._GetNextWord():\r
ca957eb5 3704 raise Warning.Expected("leaf section type", self.FileName, self.CurrentLineNumber)\r
30fdf114 3705\r
9e47e6f9 3706 SectionName = self._Token\r
30fdf114 3707\r
5a264f28
CJ
3708 if SectionName not in {\r
3709 "COMPAT16", BINARY_FILE_TYPE_PE32,\r
3710 BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE",\r
3711 "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI,\r
3712 BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID",\r
3713 BINARY_FILE_TYPE_SMM_DEPEX}:\r
30fdf114
LG
3714 raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber)\r
3715\r
3716\r
9e47e6f9 3717 if self._IsKeyword("Fixed", True):\r
30fdf114
LG
3718 Fixed = True\r
3719\r
9e47e6f9 3720 if self._IsKeyword("CheckSum", True):\r
30fdf114
LG
3721 CheckSum = True\r
3722\r
52302d4d 3723 SectAlignment = ""\r
9e47e6f9
CJ
3724 if self._GetAlignment():\r
3725 if self._Token not in ALIGNMENTS:\r
3726 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
3727 if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_TE):\r
52302d4d 3728 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3729 SectAlignment = self._Token\r
52302d4d
LG
3730\r
3731 Ext = None\r
9e47e6f9
CJ
3732 if self._IsToken(TAB_VALUE_SPLIT):\r
3733 Ext = self._GetFileExtension()\r
3734 elif not self._GetNextToken():\r
ca957eb5 3735 raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber)\r
30fdf114 3736\r
9e47e6f9
CJ
3737 NewRule = RuleSimpleFile()\r
3738 NewRule.SectionType = SectionName\r
3739 NewRule.FvFileType = Type\r
3740 NewRule.NameGuid = NameGuid\r
3741 NewRule.Alignment = AlignValue\r
3742 NewRule.SectAlignment = SectAlignment\r
3743 NewRule.CheckSum = CheckSum\r
3744 NewRule.Fixed = Fixed\r
3745 NewRule.KeyStringList = KeyStringList\r
4231a819 3746 if KeepReloc is not None:\r
9e47e6f9
CJ
3747 NewRule.KeepReloc = KeepReloc\r
3748 NewRule.FileExtension = Ext\r
3749 NewRule.FileName = self._Token\r
3750 return NewRule\r
30fdf114 3751\r
9e47e6f9 3752 ## _GetEfiSection() method\r
30fdf114
LG
3753 #\r
3754 # Get section list for Rule\r
3755 #\r
3756 # @param self The object pointer\r
3757 # @param Obj for whom section is got\r
3758 # @retval True Successfully find section statement\r
3759 # @retval False Not able to find section statement\r
3760 #\r
9e47e6f9 3761 def _GetEfiSection(self, Obj):\r
30fdf114 3762 OldPos = self.GetFileBufferPos()\r
9e47e6f9 3763 if not self._GetNextWord():\r
30fdf114 3764 return False\r
9e47e6f9 3765 SectionName = self._Token\r
30fdf114 3766\r
5a264f28
CJ
3767 if SectionName not in {\r
3768 "COMPAT16", BINARY_FILE_TYPE_PE32,\r
3769 BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE",\r
3770 "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI,\r
3771 BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID",\r
3772 BINARY_FILE_TYPE_SMM_DEPEX, BINARY_FILE_TYPE_GUID}:\r
9e47e6f9 3773 self._UndoToken()\r
30fdf114
LG
3774 return False\r
3775\r
3776 if SectionName == "FV_IMAGE":\r
9e47e6f9
CJ
3777 FvImageSectionObj = FvImageSection()\r
3778 if self._IsKeyword("FV_IMAGE"):\r
30fdf114 3779 pass\r
9e47e6f9
CJ
3780 if self._IsToken("{"):\r
3781 FvObj = FV()\r
3782 self._GetDefineStatements(FvObj)\r
3783 self._GetBlockStatement(FvObj)\r
3784 self._GetSetStatements(FvObj)\r
3785 self._GetFvAlignment(FvObj)\r
3786 self._GetFvAttributes(FvObj)\r
3787 self._GetAprioriSection(FvObj)\r
3788 self._GetAprioriSection(FvObj)\r
30fdf114
LG
3789\r
3790 while True:\r
9e47e6f9
CJ
3791 IsInf = self._GetInfStatement(FvObj)\r
3792 IsFile = self._GetFileStatement(FvObj)\r
30fdf114
LG
3793 if not IsInf and not IsFile:\r
3794 break\r
3795\r
ea98a825 3796 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 3797 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3798 FvImageSectionObj.Fv = FvObj\r
3799 FvImageSectionObj.FvName = None\r
3800\r
3801 else:\r
9e47e6f9 3802 if not self._IsKeyword(BINARY_FILE_TYPE_FV):\r
ca957eb5 3803 raise Warning.Expected("'FV'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3804 FvImageSectionObj.FvFileType = self._Token\r
3805\r
3806 if self._GetAlignment():\r
3807 if self._Token not in ALIGNMENT_NOAUTO:\r
3808 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
3809 FvImageSectionObj.Alignment = self._Token\r
3810\r
3811 if self._IsToken(TAB_VALUE_SPLIT):\r
3812 FvImageSectionObj.FvFileExtension = self._GetFileExtension()\r
3813 elif self._GetNextToken():\r
5a264f28 3814 if self._Token not in {\r
ea98a825 3815 T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32,\r
5a264f28
CJ
3816 BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE,\r
3817 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,\r
3818 BINARY_FILE_TYPE_UI, "VERSION",\r
3819 BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID,\r
3820 BINARY_FILE_TYPE_SMM_DEPEX}:\r
9e47e6f9 3821 FvImageSectionObj.FvFileName = self._Token\r
30fdf114 3822 else:\r
9e47e6f9 3823 self._UndoToken()\r
30fdf114 3824 else:\r
ca957eb5 3825 raise Warning.Expected("FV file name", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3826\r
3827 Obj.SectionList.append(FvImageSectionObj)\r
3828 return True\r
3829\r
9e47e6f9 3830 EfiSectionObj = EfiSection()\r
30fdf114
LG
3831 EfiSectionObj.SectionType = SectionName\r
3832\r
9e47e6f9 3833 if not self._GetNextToken():\r
ca957eb5 3834 raise Warning.Expected("file type", self.FileName, self.CurrentLineNumber)\r
30fdf114 3835\r
9e47e6f9
CJ
3836 if self._Token == "STRING":\r
3837 if not self._RuleSectionCouldHaveString(EfiSectionObj.SectionType):\r
30fdf114
LG
3838 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3839\r
9e47e6f9 3840 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3841 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 3842\r
9e47e6f9 3843 if not self._GetNextToken():\r
ca957eb5 3844 raise Warning.Expected("Quoted String", self.FileName, self.CurrentLineNumber)\r
30fdf114 3845\r
9e47e6f9
CJ
3846 if self._GetStringData():\r
3847 EfiSectionObj.StringData = self._Token\r
30fdf114 3848\r
9e47e6f9
CJ
3849 if self._IsKeyword("BUILD_NUM"):\r
3850 if not self._RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):\r
30fdf114
LG
3851 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3852\r
9e47e6f9 3853 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3854 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3855 if not self._GetNextToken():\r
ca957eb5 3856 raise Warning.Expected("Build number", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3857 EfiSectionObj.BuildNum = self._Token\r
30fdf114
LG
3858\r
3859 else:\r
9e47e6f9
CJ
3860 EfiSectionObj.FileType = self._Token\r
3861 self._CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType)\r
30fdf114 3862\r
9e47e6f9
CJ
3863 if self._IsKeyword("Optional"):\r
3864 if not self._RuleSectionCouldBeOptional(EfiSectionObj.SectionType):\r
30fdf114
LG
3865 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3866 EfiSectionObj.Optional = True\r
3867\r
9e47e6f9
CJ
3868 if self._IsKeyword("BUILD_NUM"):\r
3869 if not self._RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):\r
30fdf114
LG
3870 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3871\r
9e47e6f9 3872 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3873 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3874 if not self._GetNextToken():\r
ca957eb5 3875 raise Warning.Expected("Build number", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3876 EfiSectionObj.BuildNum = self._Token\r
30fdf114 3877\r
9e47e6f9
CJ
3878 if self._GetAlignment():\r
3879 if self._Token not in ALIGNMENTS:\r
3880 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
3881 if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_TE):\r
52302d4d 3882 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3883 EfiSectionObj.Alignment = self._Token\r
30fdf114 3884\r
9e47e6f9
CJ
3885 if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):\r
3886 if self._SectionCouldHaveRelocFlag(EfiSectionObj.SectionType):\r
3887 if self._Token == 'RELOCS_STRIPPED':\r
30fdf114
LG
3888 EfiSectionObj.KeepReloc = False\r
3889 else:\r
3890 EfiSectionObj.KeepReloc = True\r
4231a819 3891 if Obj.KeepReloc is not None and Obj.KeepReloc != EfiSectionObj.KeepReloc:\r
30fdf114
LG
3892 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)\r
3893 else:\r
3894 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)\r
3895\r
3896\r
9e47e6f9
CJ
3897 if self._IsToken(TAB_VALUE_SPLIT):\r
3898 EfiSectionObj.FileExtension = self._GetFileExtension()\r
3899 elif self._GetNextToken():\r
5a264f28 3900 if self._Token not in {\r
ea98a825 3901 T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32,\r
5a264f28
CJ
3902 BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE,\r
3903 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,\r
3904 BINARY_FILE_TYPE_UI, "VERSION",\r
3905 BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID,\r
3906 BINARY_FILE_TYPE_SMM_DEPEX}:\r
f7496d71 3907\r
9e47e6f9
CJ
3908 if self._Token.startswith('PCD'):\r
3909 self._UndoToken()\r
3910 self._GetNextWord()\r
f7496d71 3911\r
9e47e6f9
CJ
3912 if self._Token == 'PCD':\r
3913 if not self._IsToken("("):\r
ca957eb5 3914 raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3915 PcdPair = self._GetNextPcdSettings()\r
3916 if not self._IsToken(")"):\r
ca957eb5 3917 raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3918 self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'\r
f7496d71 3919\r
9e47e6f9 3920 EfiSectionObj.FileName = self._Token\r
f7496d71 3921\r
30fdf114 3922 else:\r
9e47e6f9 3923 self._UndoToken()\r
30fdf114 3924 else:\r
ca957eb5 3925 raise Warning.Expected("section file name", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3926\r
3927 Obj.SectionList.append(EfiSectionObj)\r
3928 return True\r
3929\r
9e47e6f9 3930 ## _RuleSectionCouldBeOptional() method\r
30fdf114
LG
3931 #\r
3932 # Get whether a section could be optional\r
3933 #\r
30fdf114
LG
3934 # @param SectionType The section type to check\r
3935 # @retval True section could be optional\r
3936 # @retval False section never optional\r
3937 #\r
5bcf1d56 3938 @staticmethod\r
9e47e6f9 3939 def _RuleSectionCouldBeOptional(SectionType):\r
5a264f28 3940 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
3941 return True\r
3942 else:\r
3943 return False\r
3944\r
9e47e6f9 3945 ## _RuleSectionCouldHaveBuildNum() method\r
30fdf114
LG
3946 #\r
3947 # Get whether a section could have build number information\r
3948 #\r
30fdf114
LG
3949 # @param SectionType The section type to check\r
3950 # @retval True section could have build number information\r
3951 # @retval False section never have build number information\r
3952 #\r
5bcf1d56 3953 @staticmethod\r
9e47e6f9 3954 def _RuleSectionCouldHaveBuildNum(SectionType):\r
5a264f28 3955 if SectionType == "VERSION":\r
30fdf114
LG
3956 return True\r
3957 else:\r
3958 return False\r
3959\r
9e47e6f9 3960 ## _RuleSectionCouldHaveString() method\r
30fdf114
LG
3961 #\r
3962 # Get whether a section could have string\r
3963 #\r
30fdf114
LG
3964 # @param SectionType The section type to check\r
3965 # @retval True section could have string\r
3966 # @retval False section never have string\r
3967 #\r
5bcf1d56 3968 @staticmethod\r
9e47e6f9 3969 def _RuleSectionCouldHaveString(SectionType):\r
5a264f28 3970 if SectionType in {BINARY_FILE_TYPE_UI, "VERSION"}:\r
30fdf114
LG
3971 return True\r
3972 else:\r
3973 return False\r
3974\r
9e47e6f9 3975 ## _CheckRuleSectionFileType() method\r
30fdf114
LG
3976 #\r
3977 # Get whether a section matches a file type\r
3978 #\r
3979 # @param self The object pointer\r
3980 # @param SectionType The section type to check\r
3981 # @param FileType The file type to check\r
3982 #\r
9e47e6f9 3983 def _CheckRuleSectionFileType(self, SectionType, FileType):\r
ca957eb5 3984 WarningString = "Incorrect section file type '%s'"\r
30fdf114 3985 if SectionType == "COMPAT16":\r
5a264f28 3986 if FileType not in {"COMPAT16", "SEC_COMPAT16"}:\r
ca957eb5 3987 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 3988 elif SectionType == BINARY_FILE_TYPE_PE32:\r
5a264f28 3989 if FileType not in {BINARY_FILE_TYPE_PE32, "SEC_PE32"}:\r
ca957eb5 3990 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 3991 elif SectionType == BINARY_FILE_TYPE_PIC:\r
5a264f28 3992 if FileType not in {BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_PIC}:\r
ca957eb5 3993 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 3994 elif SectionType == BINARY_FILE_TYPE_TE:\r
5a264f28 3995 if FileType not in {BINARY_FILE_TYPE_TE, "SEC_TE"}:\r
ca957eb5 3996 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
30fdf114 3997 elif SectionType == "RAW":\r
5a264f28 3998 if FileType not in {BINARY_FILE_TYPE_BIN, "SEC_BIN", "RAW", "ASL", "ACPI"}:\r
ca957eb5 3999 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 4000 elif SectionType == BINARY_FILE_TYPE_DXE_DEPEX or SectionType == BINARY_FILE_TYPE_SMM_DEPEX:\r
5a264f28 4001 if FileType not in {BINARY_FILE_TYPE_DXE_DEPEX, "SEC_DXE_DEPEX", BINARY_FILE_TYPE_SMM_DEPEX}:\r
ca957eb5 4002 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 4003 elif SectionType == BINARY_FILE_TYPE_UI:\r
5a264f28 4004 if FileType not in {BINARY_FILE_TYPE_UI, "SEC_UI"}:\r
ca957eb5 4005 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
30fdf114 4006 elif SectionType == "VERSION":\r
5a264f28 4007 if FileType not in {"VERSION", "SEC_VERSION"}:\r
ca957eb5 4008 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 4009 elif SectionType == BINARY_FILE_TYPE_PEI_DEPEX:\r
5a264f28 4010 if FileType not in {BINARY_FILE_TYPE_PEI_DEPEX, "SEC_PEI_DEPEX"}:\r
ca957eb5 4011 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 4012 elif SectionType == BINARY_FILE_TYPE_GUID:\r
5a264f28 4013 if FileType not in {BINARY_FILE_TYPE_PE32, "SEC_GUID"}:\r
ca957eb5 4014 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
30fdf114 4015\r
9e47e6f9 4016 ## _GetRuleEncapsulationSection() method\r
30fdf114
LG
4017 #\r
4018 # Get encapsulation section for Rule\r
4019 #\r
4020 # @param self The object pointer\r
9e47e6f9 4021 # @param theRule for whom section is got\r
30fdf114
LG
4022 # @retval True Successfully find section statement\r
4023 # @retval False Not able to find section statement\r
4024 #\r
9e47e6f9
CJ
4025 def _GetRuleEncapsulationSection(self, theRule):\r
4026 if self._IsKeyword("COMPRESS"):\r
30fdf114 4027 Type = "PI_STD"\r
9e47e6f9
CJ
4028 if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE"):\r
4029 Type = self._Token\r
30fdf114 4030\r
9e47e6f9 4031 if not self._IsToken("{"):\r
ca957eb5 4032 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
30fdf114 4033\r
9e47e6f9 4034 CompressSectionObj = CompressSection()\r
30fdf114
LG
4035\r
4036 CompressSectionObj.CompType = Type\r
4037 # Recursive sections...\r
4038 while True:\r
9e47e6f9
CJ
4039 IsEncapsulate = self._GetRuleEncapsulationSection(CompressSectionObj)\r
4040 IsLeaf = self._GetEfiSection(CompressSectionObj)\r
30fdf114
LG
4041 if not IsEncapsulate and not IsLeaf:\r
4042 break\r
4043\r
ea98a825 4044 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 4045 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4046 theRule.SectionList.append(CompressSectionObj)\r
30fdf114
LG
4047\r
4048 return True\r
4049\r
9e47e6f9 4050 elif self._IsKeyword("GUIDED"):\r
30fdf114 4051 GuidValue = None\r
9e47e6f9
CJ
4052 if self._GetNextGuid():\r
4053 GuidValue = self._Token\r
30fdf114 4054\r
9e47e6f9
CJ
4055 if self._IsKeyword("$(NAMED_GUID)"):\r
4056 GuidValue = self._Token\r
30fdf114 4057\r
9e47e6f9 4058 AttribDict = self._GetGuidAttrib()\r
30fdf114 4059\r
9e47e6f9 4060 if not self._IsToken("{"):\r
ca957eb5 4061 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4062 GuidSectionObj = GuidSection()\r
30fdf114
LG
4063 GuidSectionObj.NameGuid = GuidValue\r
4064 GuidSectionObj.SectionType = "GUIDED"\r
4065 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]\r
4066 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]\r
25918452 4067 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]\r
30fdf114
LG
4068\r
4069 # Efi sections...\r
4070 while True:\r
9e47e6f9
CJ
4071 IsEncapsulate = self._GetRuleEncapsulationSection(GuidSectionObj)\r
4072 IsLeaf = self._GetEfiSection(GuidSectionObj)\r
30fdf114
LG
4073 if not IsEncapsulate and not IsLeaf:\r
4074 break\r
4075\r
ea98a825 4076 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 4077 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4078 theRule.SectionList.append(GuidSectionObj)\r
30fdf114
LG
4079\r
4080 return True\r
4081\r
4082 return False\r
4083\r
9e47e6f9 4084 ## _GetVtf() method\r
30fdf114
LG
4085 #\r
4086 # Get VTF section contents and store its data into VTF list of self.Profile\r
4087 #\r
4088 # @param self The object pointer\r
4089 # @retval True Successfully find a VTF\r
4090 # @retval False Not able to find a VTF\r
4091 #\r
9e47e6f9 4092 def _GetVtf(self):\r
5a264f28 4093 HW_ARCH_SET = {TAB_ARCH_IA32, TAB_ARCH_X64, TAB_ARCH_IPF, TAB_ARCH_ARM, TAB_ARCH_AARCH64}\r
9e47e6f9 4094 if not self._GetNextToken():\r
30fdf114
LG
4095 return False\r
4096\r
9e47e6f9
CJ
4097 S = self._Token.upper()\r
4098 if S.startswith(TAB_SECTION_START) and not S.startswith("[VTF."):\r
df81077f 4099 self.SectionParser(S)\r
9e47e6f9 4100 self._UndoToken()\r
30fdf114
LG
4101 return False\r
4102\r
9e47e6f9
CJ
4103 self._UndoToken()\r
4104 if not self._IsToken("[VTF.", True):\r
30fdf114
LG
4105 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
4106 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
9e47e6f9 4107 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
ca957eb5 4108 raise Warning.Expected("[VTF.]", self.FileName, self.CurrentLineNumber)\r
30fdf114 4109\r
9e47e6f9 4110 if not self._SkipToToken(TAB_SPLIT):\r
ca957eb5 4111 raise Warning.Expected("'.'", self.FileName, self.CurrentLineNumber)\r
30fdf114 4112\r
9e47e6f9 4113 Arch = self._SkippedChars.rstrip(TAB_SPLIT).upper()\r
5a264f28 4114 if Arch not in HW_ARCH_SET:\r
30fdf114
LG
4115 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)\r
4116\r
9e47e6f9 4117 if not self._GetNextWord():\r
ca957eb5 4118 raise Warning.Expected("VTF name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4119 Name = self._Token.upper()\r
30fdf114 4120\r
9e47e6f9 4121 VtfObj = Vtf()\r
30fdf114
LG
4122 VtfObj.UiName = Name\r
4123 VtfObj.KeyArch = Arch\r
4124\r
9e47e6f9
CJ
4125 if self._IsToken(TAB_COMMA_SPLIT):\r
4126 if not self._GetNextWord():\r
ca957eb5 4127 raise Warning.Expected("Arch list", self.FileName, self.CurrentLineNumber)\r
5a264f28 4128 if self._Token.upper() not in HW_ARCH_SET:\r
9e47e6f9
CJ
4129 raise Warning("Unknown Arch '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
4130 VtfObj.ArchList = self._Token.upper()\r
30fdf114 4131\r
9e47e6f9 4132 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 4133 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 4134\r
9e47e6f9
CJ
4135 if self._IsKeyword("IA32_RST_BIN"):\r
4136 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4137 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 4138\r
9e47e6f9 4139 if not self._GetNextToken():\r
ca957eb5 4140 raise Warning.Expected("Reset file", self.FileName, self.CurrentLineNumber)\r
30fdf114 4141\r
9e47e6f9
CJ
4142 VtfObj.ResetBin = self._Token\r
4143 if VtfObj.ResetBin.replace(TAB_WORKSPACE, '').find('$') == -1:\r
6310ffd7 4144 #check for file path\r
4145 ErrorCode, ErrorInfo = PathClass(NormPath(VtfObj.ResetBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4146 if ErrorCode != 0:\r
4147 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114 4148\r
9e47e6f9 4149 while self._GetComponentStatement(VtfObj):\r
30fdf114
LG
4150 pass\r
4151\r
4152 self.Profile.VtfList.append(VtfObj)\r
4153 return True\r
4154\r
9e47e6f9 4155 ## _GetComponentStatement() method\r
30fdf114
LG
4156 #\r
4157 # Get components in VTF\r
4158 #\r
4159 # @param self The object pointer\r
4160 # @param VtfObj for whom component is got\r
4161 # @retval True Successfully find a component\r
4162 # @retval False Not able to find a component\r
4163 #\r
9e47e6f9
CJ
4164 def _GetComponentStatement(self, VtfObj):\r
4165 if not self._IsKeyword("COMP_NAME"):\r
30fdf114
LG
4166 return False\r
4167\r
9e47e6f9 4168 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4169 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 4170\r
9e47e6f9 4171 if not self._GetNextWord():\r
ca957eb5 4172 raise Warning.Expected("Component Name", self.FileName, self.CurrentLineNumber)\r
30fdf114 4173\r
9e47e6f9
CJ
4174 CompStatementObj = ComponentStatement()\r
4175 CompStatementObj.CompName = self._Token\r
30fdf114 4176\r
9e47e6f9 4177 if not self._IsKeyword("COMP_LOC"):\r
ca957eb5 4178 raise Warning.Expected("COMP_LOC", self.FileName, self.CurrentLineNumber)\r
30fdf114 4179\r
9e47e6f9 4180 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4181 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
4182\r
4183 CompStatementObj.CompLoc = ""\r
9e47e6f9
CJ
4184 if self._GetNextWord():\r
4185 CompStatementObj.CompLoc = self._Token\r
4186 if self._IsToken(TAB_VALUE_SPLIT):\r
4187 if not self._GetNextWord():\r
ca957eb5 4188 raise Warning.Expected("Region Name", self.FileName, self.CurrentLineNumber)\r
30fdf114 4189\r
5a264f28 4190 if self._Token not in {"F", "N", "S"}: #, "H", "L", "PH", "PL"): not support\r
9e47e6f9 4191 raise Warning("Unknown location type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114 4192\r
9e47e6f9 4193 CompStatementObj.FilePos = self._Token\r
30fdf114
LG
4194 else:\r
4195 self.CurrentLineNumber += 1\r
4196 self.CurrentOffsetWithinLine = 0\r
4197\r
9e47e6f9 4198 if not self._IsKeyword("COMP_TYPE"):\r
ca957eb5 4199 raise Warning.Expected("COMP_TYPE", self.FileName, self.CurrentLineNumber)\r
30fdf114 4200\r
9e47e6f9 4201 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4202 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 4203\r
9e47e6f9 4204 if not self._GetNextToken():\r
ca957eb5 4205 raise Warning.Expected("Component type", self.FileName, self.CurrentLineNumber)\r
5a264f28 4206 if self._Token not in {"FIT", "PAL_B", "PAL_A", "OEM"}:\r
9e47e6f9
CJ
4207 if not self._Token.startswith("0x") or len(self._Token) < 3 or len(self._Token) > 4 or \\r
4208 not self._Token[2] in hexdigits or not self._Token[-1] in hexdigits:\r
4209 raise Warning("Unknown location type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
4210 CompStatementObj.CompType = self._Token\r
30fdf114 4211\r
9e47e6f9 4212 if not self._IsKeyword("COMP_VER"):\r
ca957eb5 4213 raise Warning.Expected("COMP_VER", self.FileName, self.CurrentLineNumber)\r
30fdf114 4214\r
9e47e6f9 4215 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4216 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 4217\r
9e47e6f9 4218 if not self._GetNextToken():\r
ca957eb5 4219 raise Warning.Expected("Component version", self.FileName, self.CurrentLineNumber)\r
30fdf114 4220\r
9e47e6f9
CJ
4221 Pattern = compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', DOTALL)\r
4222 if Pattern.match(self._Token) is None:\r
4223 raise Warning("Unknown version format '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
4224 CompStatementObj.CompVer = self._Token\r
30fdf114 4225\r
9e47e6f9 4226 if not self._IsKeyword("COMP_CS"):\r
ca957eb5 4227 raise Warning.Expected("COMP_CS", self.FileName, self.CurrentLineNumber)\r
30fdf114 4228\r
9e47e6f9 4229 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4230 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 4231\r
9e47e6f9 4232 if not self._GetNextToken():\r
ca957eb5 4233 raise Warning.Expected("Component CS", self.FileName, self.CurrentLineNumber)\r
5a264f28 4234 if self._Token not in {"1", "0"}:\r
ca957eb5 4235 raise Warning("Unknown Component CS '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4236 CompStatementObj.CompCs = self._Token\r
30fdf114
LG
4237\r
4238\r
9e47e6f9 4239 if not self._IsKeyword("COMP_BIN"):\r
ca957eb5 4240 raise Warning.Expected("COMP_BIN", self.FileName, self.CurrentLineNumber)\r
30fdf114 4241\r
9e47e6f9 4242 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4243 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 4244\r
9e47e6f9 4245 if not self._GetNextToken():\r
ca957eb5 4246 raise Warning.Expected("Component file", self.FileName, self.CurrentLineNumber)\r
30fdf114 4247\r
9e47e6f9
CJ
4248 CompStatementObj.CompBin = self._Token\r
4249 if CompStatementObj.CompBin != '-' and CompStatementObj.CompBin.replace(TAB_WORKSPACE, '').find('$') == -1:\r
6310ffd7 4250 #check for file path\r
4251 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4252 if ErrorCode != 0:\r
4253 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114 4254\r
9e47e6f9 4255 if not self._IsKeyword("COMP_SYM"):\r
ca957eb5 4256 raise Warning.Expected("COMP_SYM", self.FileName, self.CurrentLineNumber)\r
30fdf114 4257\r
9e47e6f9 4258 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4259 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 4260\r
9e47e6f9 4261 if not self._GetNextToken():\r
ca957eb5 4262 raise Warning.Expected("Component symbol file", self.FileName, self.CurrentLineNumber)\r
30fdf114 4263\r
9e47e6f9
CJ
4264 CompStatementObj.CompSym = self._Token\r
4265 if CompStatementObj.CompSym != '-' and CompStatementObj.CompSym.replace(TAB_WORKSPACE, '').find('$') == -1:\r
6310ffd7 4266 #check for file path\r
4267 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompSym), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4268 if ErrorCode != 0:\r
4269 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114 4270\r
9e47e6f9 4271 if not self._IsKeyword("COMP_SIZE"):\r
ca957eb5 4272 raise Warning.Expected("COMP_SIZE", self.FileName, self.CurrentLineNumber)\r
30fdf114 4273\r
9e47e6f9 4274 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4275 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 4276\r
9e47e6f9
CJ
4277 if self._IsToken("-"):\r
4278 CompStatementObj.CompSize = self._Token\r
4279 elif self._GetNextDecimalNumber():\r
4280 CompStatementObj.CompSize = self._Token\r
4281 elif self._GetNextHexNumber():\r
4282 CompStatementObj.CompSize = self._Token\r
30fdf114 4283 else:\r
9e47e6f9 4284 raise Warning("Unknown size '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
4285\r
4286 VtfObj.ComponentStatementList.append(CompStatementObj)\r
4287 return True\r
4288\r
9e47e6f9 4289 ## _GetOptionRom() method\r
30fdf114
LG
4290 #\r
4291 # Get OptionROM section contents and store its data into OptionROM list of self.Profile\r
4292 #\r
4293 # @param self The object pointer\r
4294 # @retval True Successfully find a OptionROM\r
4295 # @retval False Not able to find a OptionROM\r
4296 #\r
9e47e6f9
CJ
4297 def _GetOptionRom(self):\r
4298 if not self._GetNextToken():\r
30fdf114
LG
4299 return False\r
4300\r
9e47e6f9
CJ
4301 S = self._Token.upper()\r
4302 if S.startswith(TAB_SECTION_START) and not S.startswith("[OPTIONROM."):\r
df81077f 4303 self.SectionParser(S)\r
9e47e6f9 4304 self._UndoToken()\r
df81077f 4305 return False\r
f7496d71 4306\r
9e47e6f9
CJ
4307 self._UndoToken()\r
4308 if not self._IsToken("[OptionRom.", True):\r
4309 raise Warning("Unknown Keyword '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114 4310\r
9e47e6f9 4311 OptRomName = self._GetUiName()\r
30fdf114 4312\r
9e47e6f9 4313 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 4314 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 4315\r
9e47e6f9 4316 OptRomObj = OPTIONROM(OptRomName)\r
30fdf114
LG
4317 self.Profile.OptRomDict[OptRomName] = OptRomObj\r
4318\r
4319 while True:\r
9e47e6f9
CJ
4320 isInf = self._GetOptRomInfStatement(OptRomObj)\r
4321 isFile = self._GetOptRomFileStatement(OptRomObj)\r
30fdf114
LG
4322 if not isInf and not isFile:\r
4323 break\r
f7496d71 4324\r
30fdf114
LG
4325 return True\r
4326\r
9e47e6f9 4327 ## _GetOptRomInfStatement() method\r
30fdf114
LG
4328 #\r
4329 # Get INF statements\r
4330 #\r
4331 # @param self The object pointer\r
4332 # @param Obj for whom inf statement is got\r
4333 # @retval True Successfully find inf statement\r
4334 # @retval False Not able to find inf statement\r
4335 #\r
9e47e6f9
CJ
4336 def _GetOptRomInfStatement(self, Obj):\r
4337 if not self._IsKeyword("INF"):\r
30fdf114
LG
4338 return False\r
4339\r
9e47e6f9
CJ
4340 ffsInf = OptRomInfStatement()\r
4341 self._GetInfOptions(ffsInf)\r
30fdf114 4342\r
9e47e6f9 4343 if not self._GetNextToken():\r
ca957eb5 4344 raise Warning.Expected("INF file path", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
4345 ffsInf.InfFileName = self._Token\r
4346 if ffsInf.InfFileName.replace(TAB_WORKSPACE, '').find('$') == -1:\r
6310ffd7 4347 #check for file path\r
4348 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4349 if ErrorCode != 0:\r
4350 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114 4351\r
3d3416e8
FB
4352 NewFileName = ffsInf.InfFileName\r
4353 if ffsInf.OverrideGuid:\r
4354 NewFileName = ProcessDuplicatedInf(PathClass(ffsInf.InfFileName,GenFdsGlobalVariable.WorkSpaceDir), ffsInf.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir).Path\r
4355\r
4356 if not NewFileName in self.Profile.InfList:\r
4357 self.Profile.InfList.append(NewFileName)\r
d0acc87a
LG
4358 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
4359 self.Profile.InfFileLineList.append(FileLineTuple)\r
2502b735
YZ
4360 if ffsInf.UseArch:\r
4361 if ffsInf.UseArch not in self.Profile.InfDict:\r
4362 self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]\r
4363 else:\r
4364 self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)\r
4365 else:\r
4366 self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)\r
30fdf114 4367\r
f7496d71 4368\r
9e47e6f9 4369 self._GetOptRomOverrides (ffsInf)\r
f7496d71 4370\r
30fdf114
LG
4371 Obj.FfsList.append(ffsInf)\r
4372 return True\r
4373\r
9e47e6f9 4374 ## _GetOptRomOverrides() method\r
30fdf114
LG
4375 #\r
4376 # Get overrides for OptROM INF & FILE\r
4377 #\r
4378 # @param self The object pointer\r
4379 # @param FfsInfObj for whom overrides is got\r
4380 #\r
9e47e6f9
CJ
4381 def _GetOptRomOverrides(self, Obj):\r
4382 if self._IsToken('{'):\r
4383 Overrides = OverrideAttribs()\r
fd171542 4384 while True:\r
9e47e6f9
CJ
4385 if self._IsKeyword("PCI_VENDOR_ID"):\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 vendor id", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4390 Overrides.PciVendorId = self._Token\r
fd171542 4391 continue\r
4392\r
9e47e6f9
CJ
4393 if self._IsKeyword("PCI_CLASS_CODE"):\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 class code", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4398 Overrides.PciClassCode = self._Token\r
fd171542 4399 continue\r
4400\r
9e47e6f9
CJ
4401 if self._IsKeyword("PCI_DEVICE_ID"):\r
4402 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4403 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
f157f973
TP
4404 # Get a list of PCI IDs\r
4405 Overrides.PciDeviceId = ""\r
5b9639e6
TP
4406 while (self._GetNextHexNumber()):\r
4407 Overrides.PciDeviceId = "{} {}".format(Overrides.PciDeviceId, self._Token)\r
f157f973
TP
4408 if not Overrides.PciDeviceId:\r
4409 raise Warning.Expected("one or more Hex device ids", self.FileName, self.CurrentLineNumber)\r
fd171542 4410 continue\r
4411\r
9e47e6f9
CJ
4412 if self._IsKeyword("PCI_REVISION"):\r
4413 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4414 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4415 if not self._GetNextHexNumber():\r
ca957eb5 4416 raise Warning.Expected("Hex revision", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4417 Overrides.PciRevision = self._Token\r
fd171542 4418 continue\r
4419\r
9e47e6f9
CJ
4420 if self._IsKeyword("PCI_COMPRESS"):\r
4421 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4422 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4423 if not self._GetNextToken():\r
ca957eb5 4424 raise Warning.Expected("TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4425 Overrides.NeedCompress = self._Token.upper() == 'TRUE'\r
fd171542 4426 continue\r
4427\r
ea98a825 4428 if self._IsToken(T_CHAR_BRACE_R):\r
fd171542 4429 break\r
4430 else:\r
4431 EdkLogger.error("FdfParser", FORMAT_INVALID, File=self.FileName, Line=self.CurrentLineNumber)\r
4432\r
30fdf114 4433 Obj.OverrideAttribs = Overrides\r
f7496d71 4434\r
9e47e6f9 4435 ## _GetOptRomFileStatement() method\r
30fdf114
LG
4436 #\r
4437 # Get FILE statements\r
4438 #\r
4439 # @param self The object pointer\r
4440 # @param Obj for whom FILE statement is got\r
4441 # @retval True Successfully find FILE statement\r
4442 # @retval False Not able to find FILE statement\r
4443 #\r
9e47e6f9
CJ
4444 def _GetOptRomFileStatement(self, Obj):\r
4445 if not self._IsKeyword("FILE"):\r
30fdf114
LG
4446 return False\r
4447\r
9e47e6f9 4448 FfsFileObj = OptRomFileStatement()\r
30fdf114 4449\r
9e47e6f9 4450 if not self._IsKeyword("EFI") and not self._IsKeyword(BINARY_FILE_TYPE_BIN):\r
ca957eb5 4451 raise Warning.Expected("Binary type (EFI/BIN)", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4452 FfsFileObj.FileType = self._Token\r
30fdf114 4453\r
9e47e6f9 4454 if not self._GetNextToken():\r
ca957eb5 4455 raise Warning.Expected("File path", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
4456 FfsFileObj.FileName = self._Token\r
4457 if FfsFileObj.FileName.replace(TAB_WORKSPACE, '').find('$') == -1:\r
6310ffd7 4458 #check for file path\r
4459 ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4460 if ErrorCode != 0:\r
4461 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114
LG
4462\r
4463 if FfsFileObj.FileType == 'EFI':\r
9e47e6f9 4464 self._GetOptRomOverrides(FfsFileObj)\r
f7496d71 4465\r
30fdf114
LG
4466 Obj.FfsList.append(FfsFileObj)\r
4467\r
4468 return True\r
fd171542 4469\r
9e47e6f9 4470 ## _GetCapInFd() method\r
fd171542 4471 #\r
4472 # Get Cap list contained in FD\r
4473 #\r
4474 # @param self The object pointer\r
4475 # @param FdName FD name\r
4476 # @retval CapList List of Capsule in FD\r
4477 #\r
9e47e6f9 4478 def _GetCapInFd (self, FdName):\r
fd171542 4479 CapList = []\r
9eb87141 4480 if FdName.upper() in self.Profile.FdDict:\r
fd171542 4481 FdObj = self.Profile.FdDict[FdName.upper()]\r
4482 for elementRegion in FdObj.RegionList:\r
4483 if elementRegion.RegionType == 'CAPSULE':\r
4484 for elementRegionData in elementRegion.RegionDataList:\r
4485 if elementRegionData.endswith(".cap"):\r
4486 continue\r
4231a819 4487 if elementRegionData is not None and elementRegionData.upper() not in CapList:\r
fd171542 4488 CapList.append(elementRegionData.upper())\r
4489 return CapList\r
4490\r
9e47e6f9 4491 ## _GetReferencedFdCapTuple() method\r
fd171542 4492 #\r
4493 # Get FV and FD list referenced by a capsule image\r
4494 #\r
4495 # @param self The object pointer\r
4496 # @param CapObj Capsule section to be searched\r
4497 # @param RefFdList referenced FD by section\r
4498 # @param RefFvList referenced FV by section\r
4499 #\r
9e47e6f9
CJ
4500 def _GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []):\r
4501 for CapsuleDataObj in CapObj.CapsuleDataList:\r
4231a819 4502 if hasattr(CapsuleDataObj, 'FvName') and CapsuleDataObj.FvName is not None and CapsuleDataObj.FvName.upper() not in RefFvList:\r
fd171542 4503 RefFvList.append (CapsuleDataObj.FvName.upper())\r
4231a819 4504 elif hasattr(CapsuleDataObj, 'FdName') and CapsuleDataObj.FdName is not None and CapsuleDataObj.FdName.upper() not in RefFdList:\r
f7496d71 4505 RefFdList.append (CapsuleDataObj.FdName.upper())\r
4231a819 4506 elif CapsuleDataObj.Ffs is not None:\r
9e47e6f9 4507 if isinstance(CapsuleDataObj.Ffs, FileStatement):\r
4231a819 4508 if CapsuleDataObj.Ffs.FvName is not None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList:\r
b36d134f 4509 RefFvList.append(CapsuleDataObj.Ffs.FvName.upper())\r
4231a819 4510 elif CapsuleDataObj.Ffs.FdName is not None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList:\r
b36d134f
LG
4511 RefFdList.append(CapsuleDataObj.Ffs.FdName.upper())\r
4512 else:\r
9e47e6f9 4513 self._GetReferencedFdFvTupleFromSection(CapsuleDataObj.Ffs, RefFdList, RefFvList)\r
fd171542 4514\r
9e47e6f9 4515 ## _GetFvInFd() method\r
30fdf114
LG
4516 #\r
4517 # Get FV list contained in FD\r
4518 #\r
4519 # @param self The object pointer\r
4520 # @param FdName FD name\r
4521 # @retval FvList list of FV in FD\r
4522 #\r
9e47e6f9 4523 def _GetFvInFd (self, FdName):\r
30fdf114 4524 FvList = []\r
9eb87141 4525 if FdName.upper() in self.Profile.FdDict:\r
30fdf114
LG
4526 FdObj = self.Profile.FdDict[FdName.upper()]\r
4527 for elementRegion in FdObj.RegionList:\r
91fa33ee 4528 if elementRegion.RegionType == BINARY_FILE_TYPE_FV:\r
30fdf114 4529 for elementRegionData in elementRegion.RegionDataList:\r
fd171542 4530 if elementRegionData.endswith(".fv"):\r
4531 continue\r
4231a819 4532 if elementRegionData is not None and elementRegionData.upper() not in FvList:\r
30fdf114
LG
4533 FvList.append(elementRegionData.upper())\r
4534 return FvList\r
4535\r
9e47e6f9 4536 ## _GetReferencedFdFvTuple() method\r
30fdf114
LG
4537 #\r
4538 # Get FD and FV list referenced by a FFS file\r
4539 #\r
4540 # @param self The object pointer\r
4541 # @param FfsFile contains sections to be searched\r
4542 # @param RefFdList referenced FD by section\r
4543 # @param RefFvList referenced FV by section\r
4544 #\r
9e47e6f9 4545 def _GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []):\r
30fdf114 4546 for FfsObj in FvObj.FfsList:\r
9e47e6f9 4547 if isinstance(FfsObj, FileStatement):\r
4231a819 4548 if FfsObj.FvName is not None and FfsObj.FvName.upper() not in RefFvList:\r
30fdf114 4549 RefFvList.append(FfsObj.FvName.upper())\r
4231a819 4550 elif FfsObj.FdName is not None and FfsObj.FdName.upper() not in RefFdList:\r
30fdf114
LG
4551 RefFdList.append(FfsObj.FdName.upper())\r
4552 else:\r
9e47e6f9 4553 self._GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList)\r
30fdf114 4554\r
9e47e6f9 4555 ## _GetReferencedFdFvTupleFromSection() method\r
30fdf114
LG
4556 #\r
4557 # Get FD and FV list referenced by a FFS section\r
4558 #\r
4559 # @param self The object pointer\r
4560 # @param FfsFile contains sections to be searched\r
4561 # @param FdList referenced FD by section\r
4562 # @param FvList referenced FV by section\r
4563 #\r
9e47e6f9 4564 def _GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []):\r
5a264f28 4565 SectionStack = list(FfsFile.SectionList)\r
30fdf114
LG
4566 while SectionStack != []:\r
4567 SectionObj = SectionStack.pop()\r
9e47e6f9 4568 if isinstance(SectionObj, FvImageSection):\r
4231a819 4569 if SectionObj.FvName is not None and SectionObj.FvName.upper() not in FvList:\r
30fdf114 4570 FvList.append(SectionObj.FvName.upper())\r
4231a819 4571 if SectionObj.Fv is not None and SectionObj.Fv.UiFvName is not None and SectionObj.Fv.UiFvName.upper() not in FvList:\r
30fdf114 4572 FvList.append(SectionObj.Fv.UiFvName.upper())\r
9e47e6f9 4573 self._GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList)\r
30fdf114 4574\r
9e47e6f9 4575 if isinstance(SectionObj, CompressSection) or isinstance(SectionObj, GuidSection):\r
30fdf114
LG
4576 SectionStack.extend(SectionObj.SectionList)\r
4577\r
4578 ## CycleReferenceCheck() method\r
4579 #\r
4580 # Check whether cycle reference exists in FDF\r
4581 #\r
4582 # @param self The object pointer\r
4583 # @retval True cycle reference exists\r
4584 # @retval False Not exists cycle reference\r
4585 #\r
4586 def CycleReferenceCheck(self):\r
fd171542 4587 #\r
4588 # Check the cycle between FV and FD image\r
4589 #\r
4590 MaxLength = len (self.Profile.FvDict)\r
9eb87141 4591 for FvName in self.Profile.FvDict:\r
fd171542 4592 LogStr = "\nCycle Reference Checking for FV: %s\n" % FvName\r
5a264f28
CJ
4593 RefFvStack = set(FvName)\r
4594 FdAnalyzedList = set()\r
f7496d71 4595\r
fd171542 4596 Index = 0\r
9e47e6f9 4597 while RefFvStack and Index < MaxLength:\r
fd171542 4598 Index = Index + 1\r
4599 FvNameFromStack = RefFvStack.pop()\r
9eb87141 4600 if FvNameFromStack.upper() in self.Profile.FvDict:\r
fd171542 4601 FvObj = self.Profile.FvDict[FvNameFromStack.upper()]\r
4602 else:\r
4603 continue\r
30fdf114 4604\r
fd171542 4605 RefFdList = []\r
4606 RefFvList = []\r
9e47e6f9 4607 self._GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)\r
30fdf114 4608\r
fd171542 4609 for RefFdName in RefFdList:\r
4610 if RefFdName in FdAnalyzedList:\r
30fdf114
LG
4611 continue\r
4612\r
fd171542 4613 LogStr += "FV %s contains FD %s\n" % (FvNameFromStack, RefFdName)\r
9e47e6f9 4614 FvInFdList = self._GetFvInFd(RefFdName)\r
fd171542 4615 if FvInFdList != []:\r
4616 for FvNameInFd in FvInFdList:\r
ccaa7754 4617 LogStr += "FD %s contains FV %s\n" % (RefFdName, FvNameInFd)\r
fd171542 4618 if FvNameInFd not in RefFvStack:\r
5a264f28 4619 RefFvStack.add(FvNameInFd)\r
fd171542 4620\r
4621 if FvName in RefFvStack or FvNameFromStack in RefFvStack:\r
4622 EdkLogger.info(LogStr)\r
4623 return True\r
5a264f28 4624 FdAnalyzedList.add(RefFdName)\r
30fdf114 4625\r
fd171542 4626 for RefFvName in RefFvList:\r
4627 LogStr += "FV %s contains FV %s\n" % (FvNameFromStack, RefFvName)\r
4628 if RefFvName not in RefFvStack:\r
5a264f28 4629 RefFvStack.add(RefFvName)\r
fd171542 4630\r
4631 if FvName in RefFvStack or FvNameFromStack in RefFvStack:\r
4632 EdkLogger.info(LogStr)\r
4633 return True\r
4634\r
4635 #\r
4636 # Check the cycle between Capsule and FD image\r
4637 #\r
4638 MaxLength = len (self.Profile.CapsuleDict)\r
9eb87141 4639 for CapName in self.Profile.CapsuleDict:\r
fd171542 4640 #\r
4641 # Capsule image to be checked.\r
4642 #\r
4643 LogStr = "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName\r
5a264f28
CJ
4644 RefCapStack = {CapName}\r
4645 FdAnalyzedList = set()\r
4646 FvAnalyzedList = set()\r
f7496d71 4647\r
fd171542 4648 Index = 0\r
5a264f28 4649 while RefCapStack and Index < MaxLength:\r
fd171542 4650 Index = Index + 1\r
4651 CapNameFromStack = RefCapStack.pop()\r
9eb87141 4652 if CapNameFromStack.upper() in self.Profile.CapsuleDict:\r
fd171542 4653 CapObj = self.Profile.CapsuleDict[CapNameFromStack.upper()]\r
4654 else:\r
4655 continue\r
4656\r
4657 RefFvList = []\r
4658 RefFdList = []\r
9e47e6f9 4659 self._GetReferencedFdCapTuple(CapObj, RefFdList, RefFvList)\r
fd171542 4660\r
4661 FvListLength = 0\r
4662 FdListLength = 0\r
4663 while FvListLength < len (RefFvList) or FdListLength < len (RefFdList):\r
30fdf114
LG
4664 for RefFdName in RefFdList:\r
4665 if RefFdName in FdAnalyzedList:\r
4666 continue\r
4667\r
fd171542 4668 LogStr += "Capsule %s contains FD %s\n" % (CapNameFromStack, RefFdName)\r
5a264f28
CJ
4669 for CapNameInFd in self._GetCapInFd(RefFdName):\r
4670 LogStr += "FD %s contains Capsule %s\n" % (RefFdName, CapNameInFd)\r
4671 if CapNameInFd not in RefCapStack:\r
4672 RefCapStack.append(CapNameInFd)\r
4673\r
4674 if CapName in RefCapStack or CapNameFromStack in RefCapStack:\r
4675 EdkLogger.info(LogStr)\r
4676 return True\r
4677\r
4678 for FvNameInFd in self._GetFvInFd(RefFdName):\r
4679 LogStr += "FD %s contains FV %s\n" % (RefFdName, FvNameInFd)\r
4680 if FvNameInFd not in RefFvList:\r
4681 RefFvList.append(FvNameInFd)\r
4682\r
4683 FdAnalyzedList.add(RefFdName)\r
fd171542 4684 #\r
4685 # the number of the parsed FV and FD image\r
4686 #\r
4687 FvListLength = len (RefFvList)\r
4688 FdListLength = len (RefFdList)\r
30fdf114 4689 for RefFvName in RefFvList:\r
fd171542 4690 if RefFvName in FvAnalyzedList:\r
4691 continue\r
4692 LogStr += "Capsule %s contains FV %s\n" % (CapNameFromStack, RefFvName)\r
9eb87141 4693 if RefFvName.upper() in self.Profile.FvDict:\r
fd171542 4694 FvObj = self.Profile.FvDict[RefFvName.upper()]\r
4695 else:\r
4696 continue\r
9e47e6f9 4697 self._GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)\r
5a264f28 4698 FvAnalyzedList.add(RefFvName)\r
30fdf114 4699\r
fd171542 4700 return False\r
30fdf114 4701\r
c17956e0
DL
4702 def GetAllIncludedFile (self):\r
4703 global AllIncludeFileList\r
4704 return AllIncludeFileList\r
4705\r
30fdf114 4706if __name__ == "__main__":\r
b36d134f
LG
4707 import sys\r
4708 try:\r
4709 test_file = sys.argv[1]\r
5b0671c1 4710 except IndexError as v:\r
72443dd2 4711 print("Usage: %s filename" % sys.argv[0])\r
b36d134f
LG
4712 sys.exit(1)\r
4713\r
4714 parser = FdfParser(test_file)\r
30fdf114
LG
4715 try:\r
4716 parser.ParseFile()\r
4717 parser.CycleReferenceCheck()\r
5b0671c1 4718 except Warning as X:\r
72443dd2 4719 print(str(X))\r
30fdf114 4720 else:\r
72443dd2 4721 print("Success!")\r
30fdf114 4722\r