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