]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/FdfParser.py
BaseTools/Source/Python: Remove CPU architecture assumptions
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FdfParser.py
CommitLineData
30fdf114
LG
1## @file\r
2# parse FDF file\r
3#\r
3c139380 4# Copyright (c) 2007 - 2021, 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
d35773d5 21from Common.Misc import PathClass, tdict, ProcessDuplicatedInf, GuidStructureStringToGuidString\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 1089 return True\r
d35773d5
YC
1090 elif self._Token in GlobalData.gGuidDict:\r
1091 return True\r
30fdf114 1092 else:\r
9e47e6f9 1093 self._UndoToken()\r
30fdf114
LG
1094 return False\r
1095\r
227dbb11 1096 @staticmethod\r
9e47e6f9 1097 def _Verify(Name, Value, Scope):\r
bff74750 1098 # value verification only applies to numeric values.\r
053cd183 1099 if Scope not in TAB_PCD_NUMERIC_TYPES:\r
bff74750
CJ
1100 return\r
1101\r
1102 ValueNumber = 0\r
1103 try:\r
1104 ValueNumber = int(Value, 0)\r
1105 except:\r
1106 EdkLogger.error("FdfParser", FORMAT_INVALID, "The value is not valid dec or hex number for %s." % Name)\r
1107 if ValueNumber < 0:\r
1108 EdkLogger.error("FdfParser", FORMAT_INVALID, "The value can't be set to negative value for %s." % Name)\r
1109 if ValueNumber > MAX_VAL_TYPE[Scope]:\r
1110 EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name)\r
1111 return True\r
91ae2988 1112\r
9e47e6f9 1113 ## _UndoToken() method\r
30fdf114
LG
1114 #\r
1115 # Go back one token unit in file buffer\r
1116 #\r
1117 # @param self The object pointer\r
1118 #\r
9e47e6f9
CJ
1119 def _UndoToken(self):\r
1120 self._UndoOneChar()\r
1121 while self._CurrentChar().isspace():\r
1122 if not self._UndoOneChar():\r
1123 self._GetOneChar()\r
30fdf114
LG
1124 return\r
1125\r
1126\r
1127 StartPos = self.CurrentOffsetWithinLine\r
1128 CurrentLine = self.CurrentLineNumber\r
1129 while CurrentLine == self.CurrentLineNumber:\r
1130\r
9e47e6f9 1131 TempChar = self._CurrentChar()\r
fb0b35e0 1132 # Try to find the end char that is not a space and not in separator tuple.\r
30fdf114 1133 # That is, when we got a space or any char in the tuple, we got the end of token.\r
9e47e6f9
CJ
1134 if not str(TempChar).isspace() and not TempChar in SEPARATORS:\r
1135 if not self._UndoOneChar():\r
d0acc87a 1136 return\r
fb0b35e0
AC
1137 # if we happen to meet a separator as the first char, we must proceed to get it.\r
1138 # That is, we get a token that is a separator char. normally it is the boundary of other tokens.\r
9e47e6f9 1139 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPARATORS:\r
30fdf114
LG
1140 return\r
1141 else:\r
1142 break\r
1143\r
9e47e6f9 1144 self._GetOneChar()\r
30fdf114 1145\r
9e47e6f9 1146 ## _GetNextHexNumber() method\r
30fdf114 1147 #\r
fb0b35e0 1148 # Get next HEX data before a separator\r
9e47e6f9 1149 # If found, the HEX data is put into self._Token\r
30fdf114
LG
1150 #\r
1151 # @param self The object pointer\r
1152 # @retval True Successfully find a HEX data, file buffer pointer moved forward\r
1153 # @retval False Not able to find a HEX data, file buffer pointer not changed\r
1154 #\r
9e47e6f9
CJ
1155 def _GetNextHexNumber(self):\r
1156 if not self._GetNextToken():\r
30fdf114 1157 return False\r
938cf4c3 1158 if GlobalData.gHexPatternAll.match(self._Token):\r
30fdf114
LG
1159 return True\r
1160 else:\r
9e47e6f9 1161 self._UndoToken()\r
30fdf114
LG
1162 return False\r
1163\r
9e47e6f9 1164 ## _GetNextDecimalNumber() method\r
30fdf114 1165 #\r
fb0b35e0 1166 # Get next decimal data before a separator\r
9e47e6f9 1167 # If found, the decimal data is put into self._Token\r
30fdf114
LG
1168 #\r
1169 # @param self The object pointer\r
1170 # @retval True Successfully find a decimal data, file buffer pointer moved forward\r
1171 # @retval False Not able to find a decimal data, file buffer pointer not changed\r
1172 #\r
9e47e6f9
CJ
1173 def _GetNextDecimalNumber(self):\r
1174 if not self._GetNextToken():\r
30fdf114 1175 return False\r
9e47e6f9 1176 if self._Token.isdigit():\r
30fdf114
LG
1177 return True\r
1178 else:\r
9e47e6f9 1179 self._UndoToken()\r
30fdf114
LG
1180 return False\r
1181\r
9e47e6f9
CJ
1182 def _GetNextPcdSettings(self):\r
1183 if not self._GetNextWord():\r
ca957eb5 1184 raise Warning.Expected("<PcdTokenSpaceCName>", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 1185 pcdTokenSpaceCName = self._Token\r
543f5ac3 1186\r
9e47e6f9 1187 if not self._IsToken(TAB_SPLIT):\r
ca957eb5 1188 raise Warning.Expected(".", self.FileName, self.CurrentLineNumber)\r
543f5ac3 1189\r
9e47e6f9 1190 if not self._GetNextWord():\r
ca957eb5 1191 raise Warning.Expected("<PcdCName>", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 1192 pcdCName = self._Token\r
543f5ac3
B
1193\r
1194 Fields = []\r
9e47e6f9
CJ
1195 while self._IsToken(TAB_SPLIT):\r
1196 if not self._GetNextPcdWord():\r
ca957eb5 1197 raise Warning.Expected("Pcd Fields", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 1198 Fields.append(self._Token)\r
543f5ac3 1199\r
9e47e6f9 1200 return (pcdCName, pcdTokenSpaceCName,TAB_SPLIT.join(Fields))\r
543f5ac3 1201\r
9e47e6f9 1202 ## _GetStringData() method\r
30fdf114
LG
1203 #\r
1204 # Get string contents quoted in ""\r
9e47e6f9 1205 # If found, the decimal data is put into self._Token\r
30fdf114
LG
1206 #\r
1207 # @param self The object pointer\r
1208 # @retval True Successfully find a string data, file buffer pointer moved forward\r
1209 # @retval False Not able to find a string data, file buffer pointer not changed\r
1210 #\r
9e47e6f9 1211 def _GetStringData(self):\r
ca957eb5 1212 QuoteToUse = None\r
9e47e6f9 1213 if self._Token.startswith(T_CHAR_DOUBLE_QUOTE) or self._Token.startswith("L\""):\r
ca957eb5 1214 QuoteToUse = T_CHAR_DOUBLE_QUOTE\r
9e47e6f9 1215 elif self._Token.startswith(T_CHAR_SINGLE_QUOTE) or self._Token.startswith("L\'"):\r
ca957eb5 1216 QuoteToUse = T_CHAR_SINGLE_QUOTE\r
30fdf114
LG
1217 else:\r
1218 return False\r
1219\r
ca957eb5
CJ
1220 self._UndoToken()\r
1221 self._SkipToToken(QuoteToUse)\r
1222 currentLineNumber = self.CurrentLineNumber\r
1223\r
1224 if not self._SkipToToken(QuoteToUse):\r
1225 raise Warning(QuoteToUse, self.FileName, self.CurrentLineNumber)\r
1226 if currentLineNumber != self.CurrentLineNumber:\r
1227 raise Warning(QuoteToUse, self.FileName, self.CurrentLineNumber)\r
1228 self._Token = self._SkippedChars.rstrip(QuoteToUse)\r
1229 return True\r
1230\r
9e47e6f9 1231 ## _SkipToToken() method\r
30fdf114
LG
1232 #\r
1233 # Search forward in file buffer for the string\r
9e47e6f9 1234 # The skipped chars are put into self._SkippedChars\r
30fdf114
LG
1235 #\r
1236 # @param self The object pointer\r
1237 # @param String The string to search\r
1238 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive\r
1239 # @retval True Successfully find the string, file buffer pointer moved forward\r
1240 # @retval False Not able to find the string, file buffer pointer not changed\r
1241 #\r
9e47e6f9 1242 def _SkipToToken(self, String, IgnoreCase = False):\r
30fdf114
LG
1243 StartPos = self.GetFileBufferPos()\r
1244\r
9e47e6f9
CJ
1245 self._SkippedChars = ""\r
1246 while not self._EndOfFile():\r
30fdf114
LG
1247 index = -1\r
1248 if IgnoreCase:\r
9e47e6f9 1249 index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].upper().find(String.upper())\r
30fdf114 1250 else:\r
9e47e6f9 1251 index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].find(String)\r
30fdf114
LG
1252 if index == 0:\r
1253 self.CurrentOffsetWithinLine += len(String)\r
9e47e6f9 1254 self._SkippedChars += String\r
30fdf114 1255 return True\r
9e47e6f9
CJ
1256 self._SkippedChars += str(self._CurrentChar())\r
1257 self._GetOneChar()\r
30fdf114 1258\r
9e47e6f9
CJ
1259 self.SetFileBufferPos(StartPos)\r
1260 self._SkippedChars = ""\r
30fdf114
LG
1261 return False\r
1262\r
1263 ## GetFileBufferPos() method\r
1264 #\r
1265 # Return the tuple of current line and offset within the line\r
1266 #\r
1267 # @param self The object pointer\r
1268 # @retval Tuple Line number and offset pair\r
1269 #\r
1270 def GetFileBufferPos(self):\r
1271 return (self.CurrentLineNumber, self.CurrentOffsetWithinLine)\r
1272\r
1273 ## SetFileBufferPos() method\r
1274 #\r
1275 # Restore the file buffer position\r
1276 #\r
1277 # @param self The object pointer\r
1278 # @param Pos The new file buffer position\r
1279 #\r
1280 def SetFileBufferPos(self, Pos):\r
1281 (self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos\r
1282\r
d40b2ee6
LG
1283 ## Preprocess() method\r
1284 #\r
1285 # Preprocess comment, conditional directive, include directive, replace macro.\r
1286 # Exception will be raised if syntax error found\r
1287 #\r
1288 # @param self The object pointer\r
1289 #\r
1290 def Preprocess(self):\r
9e47e6f9 1291 self._StringToList()\r
d40b2ee6
LG
1292 self.PreprocessFile()\r
1293 self.PreprocessIncludeFile()\r
9e47e6f9 1294 self._StringToList()\r
d40b2ee6
LG
1295 self.PreprocessFile()\r
1296 self.PreprocessConditionalStatement()\r
9e47e6f9
CJ
1297 self._StringToList()\r
1298 for Pos in self._WipeOffArea:\r
1299 self._ReplaceFragment(Pos[0], Pos[1])\r
d40b2ee6
LG
1300 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]\r
1301\r
9e47e6f9 1302 while self._GetDefines():\r
d40b2ee6 1303 pass\r
d40b2ee6 1304\r
30fdf114
LG
1305 ## ParseFile() method\r
1306 #\r
1307 # Parse the file profile buffer to extract fd, fv ... information\r
1308 # Exception will be raised if syntax error found\r
1309 #\r
1310 # @param self The object pointer\r
1311 #\r
1312 def ParseFile(self):\r
30fdf114 1313 try:\r
d40b2ee6 1314 self.Preprocess()\r
9e47e6f9 1315 self._GetError()\r
dd170333
MK
1316 #\r
1317 # Keep processing sections of the FDF until no new sections or a syntax error is found\r
1318 #\r
39879ef2 1319 while self._GetFd() or self._GetFv() or self._GetFmp() or self._GetCapsule() or self._GetRule() or self._GetOptionRom():\r
30fdf114
LG
1320 pass\r
1321\r
5b0671c1 1322 except Warning as X:\r
9e47e6f9
CJ
1323 self._UndoToken()\r
1324 #'\n\tGot Token: \"%s\" from File %s\n' % (self._Token, FileLineTuple[0]) + \\r
118bf096
CS
1325 # At this point, the closest parent would be the included file itself\r
1326 Profile = GetParentAtLine(X.OriginalLineNumber)\r
4231a819 1327 if Profile is not None:\r
118bf096
CS
1328 X.Message += ' near line %d, column %d: %s' \\r
1329 % (X.LineNumber, 0, Profile.FileLinesList[X.LineNumber-1])\r
1330 else:\r
1331 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1332 X.Message += ' near line %d, column %d: %s' \\r
9e47e6f9 1333 % (FileLineTuple[1], self.CurrentOffsetWithinLine + 1, self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:].rstrip(TAB_LINE_BREAK).rstrip(T_CHAR_CR))\r
30fdf114
LG
1334 raise\r
1335\r
df81077f
YZ
1336 ## SectionParser() method\r
1337 #\r
1338 # Parse the file section info\r
1339 # Exception will be raised if syntax error found\r
1340 #\r
1341 # @param self The object pointer\r
1342 # @param section The section string\r
1343\r
1344 def SectionParser(self, section):\r
1345 S = section.upper()\r
1346 if not S.startswith("[DEFINES") and not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \\r
39879ef2
FB
1347 and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM.") and not S.startswith('[FMPPAYLOAD.'):\r
1348 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 1349\r
9e47e6f9 1350 ## _GetDefines() method\r
30fdf114
LG
1351 #\r
1352 # Get Defines section contents and store its data into AllMacrosList\r
1353 #\r
1354 # @param self The object pointer\r
1355 # @retval True Successfully find a Defines\r
1356 # @retval False Not able to find a Defines\r
1357 #\r
9e47e6f9
CJ
1358 def _GetDefines(self):\r
1359 if not self._GetNextToken():\r
30fdf114
LG
1360 return False\r
1361\r
9e47e6f9
CJ
1362 S = self._Token.upper()\r
1363 if S.startswith(TAB_SECTION_START) and not S.startswith("[DEFINES"):\r
df81077f 1364 self.SectionParser(S)\r
9e47e6f9 1365 self._UndoToken()\r
30fdf114
LG
1366 return False\r
1367\r
9e47e6f9
CJ
1368 self._UndoToken()\r
1369 if not self._IsToken("[DEFINES", True):\r
30fdf114
LG
1370 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1371 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
9e47e6f9 1372 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
ca957eb5 1373 raise Warning.Expected("[DEFINES", self.FileName, self.CurrentLineNumber)\r
30fdf114 1374\r
9e47e6f9 1375 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 1376 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 1377\r
9e47e6f9 1378 while self._GetNextWord():\r
6780eef1 1379 # handle the SET statement\r
9e47e6f9
CJ
1380 if self._Token == 'SET':\r
1381 self._UndoToken()\r
1382 self._GetSetStatement(None)\r
6780eef1 1383 continue\r
f7496d71 1384\r
9e47e6f9 1385 Macro = self._Token\r
f7496d71 1386\r
9e47e6f9 1387 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1388 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 1389 if not self._GetNextToken() or self._Token.startswith(TAB_SECTION_START):\r
ca957eb5 1390 raise Warning.Expected("MACRO value", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 1391 Value = self._Token\r
30fdf114
LG
1392\r
1393 return False\r
1394\r
9e47e6f9
CJ
1395 ##_GetError() method\r
1396 def _GetError(self):\r
09ef8e92
YF
1397 #save the Current information\r
1398 CurrentLine = self.CurrentLineNumber\r
1399 CurrentOffset = self.CurrentOffsetWithinLine\r
9e47e6f9
CJ
1400 while self._GetNextToken():\r
1401 if self._Token == TAB_ERROR:\r
1402 EdkLogger.error('FdfParser', ERROR_STATEMENT, self._CurrentLine().replace(TAB_ERROR, '', 1), File=self.FileName, Line=self.CurrentLineNumber)\r
09ef8e92
YF
1403 self.CurrentLineNumber = CurrentLine\r
1404 self.CurrentOffsetWithinLine = CurrentOffset\r
1405\r
9e47e6f9 1406 ## _GetFd() method\r
30fdf114
LG
1407 #\r
1408 # Get FD section contents and store its data into FD dictionary of self.Profile\r
1409 #\r
1410 # @param self The object pointer\r
1411 # @retval True Successfully find a FD\r
1412 # @retval False Not able to find a FD\r
1413 #\r
9e47e6f9
CJ
1414 def _GetFd(self):\r
1415 if not self._GetNextToken():\r
30fdf114
LG
1416 return False\r
1417\r
9e47e6f9
CJ
1418 S = self._Token.upper()\r
1419 if S.startswith(TAB_SECTION_START) and not S.startswith("[FD."):\r
a3251d84 1420 if not S.startswith("[FV.") and not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \\r
39879ef2 1421 and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):\r
30fdf114 1422 raise Warning("Unknown section", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 1423 self._UndoToken()\r
30fdf114
LG
1424 return False\r
1425\r
9e47e6f9
CJ
1426 self._UndoToken()\r
1427 if not self._IsToken("[FD.", True):\r
30fdf114
LG
1428 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1429 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
9e47e6f9 1430 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
ca957eb5 1431 raise Warning.Expected("[FD.]", self.FileName, self.CurrentLineNumber)\r
30fdf114 1432\r
9e47e6f9 1433 FdName = self._GetUiName()\r
52302d4d
LG
1434 if FdName == "":\r
1435 if len (self.Profile.FdDict) == 0:\r
1436 FdName = GenFdsGlobalVariable.PlatformName\r
d0acc87a
LG
1437 if FdName == "" and GlobalData.gActivePlatform:\r
1438 FdName = GlobalData.gActivePlatform.PlatformName\r
52302d4d
LG
1439 self.Profile.FdNameNotSet = True\r
1440 else:\r
ca957eb5 1441 raise Warning.Expected("FdName in [FD.] section", self.FileName, self.CurrentLineNumber)\r
30fdf114 1442 self.CurrentFdName = FdName.upper()\r
f7496d71 1443\r
52302d4d
LG
1444 if self.CurrentFdName in self.Profile.FdDict:\r
1445 raise Warning("Unexpected the same FD name", self.FileName, self.CurrentLineNumber)\r
30fdf114 1446\r
9e47e6f9 1447 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 1448 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 1449\r
9e47e6f9 1450 FdObj = FD()\r
30fdf114
LG
1451 FdObj.FdUiName = self.CurrentFdName\r
1452 self.Profile.FdDict[self.CurrentFdName] = FdObj\r
52302d4d
LG
1453\r
1454 if len (self.Profile.FdDict) > 1 and self.Profile.FdNameNotSet:\r
ca957eb5 1455 raise Warning.Expected("all FDs have their name", self.FileName, self.CurrentLineNumber)\r
52302d4d 1456\r
9e47e6f9 1457 Status = self._GetCreateFile(FdObj)\r
30fdf114
LG
1458 if not Status:\r
1459 raise Warning("FD name error", self.FileName, self.CurrentLineNumber)\r
1460\r
9e47e6f9 1461 while self._GetTokenStatements(FdObj):\r
e8a47801
LG
1462 pass\r
1463 for Attr in ("BaseAddress", "Size", "ErasePolarity"):\r
4231a819 1464 if getattr(FdObj, Attr) is None:\r
9e47e6f9 1465 self._GetNextToken()\r
e8a47801
LG
1466 raise Warning("Keyword %s missing" % Attr, self.FileName, self.CurrentLineNumber)\r
1467\r
1468 if not FdObj.BlockSizeList:\r
1469 FdObj.BlockSizeList.append((1, FdObj.Size, None))\r
30fdf114 1470\r
9e47e6f9 1471 self._GetDefineStatements(FdObj)\r
30fdf114 1472\r
9e47e6f9 1473 self._GetSetStatements(FdObj)\r
30fdf114 1474\r
9e47e6f9 1475 if not self._GetRegionLayout(FdObj):\r
ca957eb5 1476 raise Warning.Expected("region layout", self.FileName, self.CurrentLineNumber)\r
30fdf114 1477\r
9e47e6f9 1478 while self._GetRegionLayout(FdObj):\r
30fdf114
LG
1479 pass\r
1480 return True\r
1481\r
9e47e6f9 1482 ## _GetUiName() method\r
30fdf114
LG
1483 #\r
1484 # Return the UI name of a section\r
1485 #\r
1486 # @param self The object pointer\r
1487 # @retval FdName UI name\r
1488 #\r
9e47e6f9 1489 def _GetUiName(self):\r
30fdf114 1490 Name = ""\r
9e47e6f9
CJ
1491 if self._GetNextWord():\r
1492 Name = self._Token\r
30fdf114
LG
1493\r
1494 return Name\r
1495\r
9e47e6f9 1496 ## _GetCreateFile() method\r
30fdf114
LG
1497 #\r
1498 # Return the output file name of object\r
1499 #\r
1500 # @param self The object pointer\r
1501 # @param Obj object whose data will be stored in file\r
1502 # @retval FdName UI name\r
1503 #\r
9e47e6f9
CJ
1504 def _GetCreateFile(self, Obj):\r
1505 if self._IsKeyword("CREATE_FILE"):\r
1506 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1507 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1508\r
9e47e6f9 1509 if not self._GetNextToken():\r
ca957eb5 1510 raise Warning.Expected("file name", self.FileName, self.CurrentLineNumber)\r
30fdf114 1511\r
9e47e6f9 1512 FileName = self._Token\r
30fdf114
LG
1513 Obj.CreateFileName = FileName\r
1514\r
1515 return True\r
1516\r
543f5ac3
B
1517 def SetPcdLocalation(self,pcdpair):\r
1518 self.Profile.PcdLocalDict[pcdpair] = (self.Profile.FileName,self.CurrentLineNumber)\r
1519\r
9e47e6f9 1520 ## _GetTokenStatements() method\r
30fdf114
LG
1521 #\r
1522 # Get token statements\r
1523 #\r
1524 # @param self The object pointer\r
1525 # @param Obj for whom token statement is got\r
30fdf114 1526 #\r
9e47e6f9
CJ
1527 def _GetTokenStatements(self, Obj):\r
1528 if self._IsKeyword("BaseAddress"):\r
1529 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1530 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
f7496d71 1531\r
9e47e6f9 1532 if not self._GetNextHexNumber():\r
ca957eb5 1533 raise Warning.Expected("Hex base address", self.FileName, self.CurrentLineNumber)\r
f7496d71 1534\r
9e47e6f9 1535 Obj.BaseAddress = self._Token\r
f7496d71 1536\r
9e47e6f9
CJ
1537 if self._IsToken(TAB_VALUE_SPLIT):\r
1538 pcdPair = self._GetNextPcdSettings()\r
e8a47801
LG
1539 Obj.BaseAddressPcd = pcdPair\r
1540 self.Profile.PcdDict[pcdPair] = Obj.BaseAddress\r
543f5ac3 1541 self.SetPcdLocalation(pcdPair)\r
e8a47801
LG
1542 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1543 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple\r
1544 return True\r
30fdf114 1545\r
9e47e6f9
CJ
1546 if self._IsKeyword("Size"):\r
1547 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1548 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
f7496d71 1549\r
9e47e6f9 1550 if not self._GetNextHexNumber():\r
ca957eb5 1551 raise Warning.Expected("Hex size", self.FileName, self.CurrentLineNumber)\r
30fdf114 1552\r
9e47e6f9
CJ
1553 Size = self._Token\r
1554 if self._IsToken(TAB_VALUE_SPLIT):\r
1555 pcdPair = self._GetNextPcdSettings()\r
e8a47801
LG
1556 Obj.SizePcd = pcdPair\r
1557 self.Profile.PcdDict[pcdPair] = Size\r
543f5ac3 1558 self.SetPcdLocalation(pcdPair)\r
e8a47801
LG
1559 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1560 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple\r
af881abc 1561 Obj.Size = int(Size, 0)\r
e8a47801 1562 return True\r
30fdf114 1563\r
9e47e6f9
CJ
1564 if self._IsKeyword("ErasePolarity"):\r
1565 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1566 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
f7496d71 1567\r
9e47e6f9 1568 if not self._GetNextToken():\r
ca957eb5 1569 raise Warning.Expected("Erase Polarity", self.FileName, self.CurrentLineNumber)\r
f7496d71 1570\r
ca957eb5
CJ
1571 if not self._Token in {"1", "0"}:\r
1572 raise Warning.Expected("1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber)\r
f7496d71 1573\r
9e47e6f9 1574 Obj.ErasePolarity = self._Token\r
e8a47801 1575 return True\r
30fdf114 1576\r
9e47e6f9 1577 return self._GetBlockStatements(Obj)\r
30fdf114 1578\r
9e47e6f9 1579 ## _GetAddressStatements() method\r
30fdf114
LG
1580 #\r
1581 # Get address statements\r
1582 #\r
1583 # @param self The object pointer\r
1584 # @param Obj for whom address statement is got\r
1585 # @retval True Successfully find\r
1586 # @retval False Not able to find\r
1587 #\r
9e47e6f9
CJ
1588 def _GetAddressStatements(self, Obj):\r
1589 if self._IsKeyword("BsBaseAddress"):\r
1590 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1591 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1592\r
9e47e6f9 1593 if not self._GetNextDecimalNumber() and not self._GetNextHexNumber():\r
ca957eb5 1594 raise Warning.Expected("address", self.FileName, self.CurrentLineNumber)\r
30fdf114 1595\r
af881abc 1596 BsAddress = int(self._Token, 0)\r
30fdf114
LG
1597 Obj.BsBaseAddress = BsAddress\r
1598\r
9e47e6f9
CJ
1599 if self._IsKeyword("RtBaseAddress"):\r
1600 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1601 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1602\r
9e47e6f9 1603 if not self._GetNextDecimalNumber() and not self._GetNextHexNumber():\r
ca957eb5 1604 raise Warning.Expected("address", self.FileName, self.CurrentLineNumber)\r
30fdf114 1605\r
af881abc 1606 RtAddress = int(self._Token, 0)\r
30fdf114
LG
1607 Obj.RtBaseAddress = RtAddress\r
1608\r
9e47e6f9 1609 ## _GetBlockStatements() method\r
30fdf114
LG
1610 #\r
1611 # Get block statements\r
1612 #\r
1613 # @param self The object pointer\r
1614 # @param Obj for whom block statement is got\r
30fdf114 1615 #\r
9e47e6f9 1616 def _GetBlockStatements(self, Obj):\r
e8a47801 1617 IsBlock = False\r
9e47e6f9 1618 while self._GetBlockStatement(Obj):\r
e8a47801 1619 IsBlock = True\r
f7496d71 1620\r
e8a47801 1621 Item = Obj.BlockSizeList[-1]\r
4231a819 1622 if Item[0] is None or Item[1] is None:\r
ca957eb5 1623 raise Warning.Expected("block statement", self.FileName, self.CurrentLineNumber)\r
e8a47801 1624 return IsBlock\r
30fdf114 1625\r
9e47e6f9 1626 ## _GetBlockStatement() method\r
30fdf114
LG
1627 #\r
1628 # Get block statement\r
1629 #\r
1630 # @param self The object pointer\r
1631 # @param Obj for whom block statement is got\r
1632 # @retval True Successfully find\r
1633 # @retval False Not able to find\r
1634 #\r
9e47e6f9
CJ
1635 def _GetBlockStatement(self, Obj):\r
1636 if not self._IsKeyword("BlockSize"):\r
30fdf114
LG
1637 return False\r
1638\r
9e47e6f9 1639 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1640 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1641\r
9e47e6f9 1642 if not self._GetNextHexNumber() and not self._GetNextDecimalNumber():\r
ca957eb5 1643 raise Warning.Expected("Hex or Integer block size", self.FileName, self.CurrentLineNumber)\r
30fdf114 1644\r
9e47e6f9 1645 BlockSize = self._Token\r
30fdf114 1646 BlockSizePcd = None\r
9e47e6f9
CJ
1647 if self._IsToken(TAB_VALUE_SPLIT):\r
1648 PcdPair = self._GetNextPcdSettings()\r
30fdf114
LG
1649 BlockSizePcd = PcdPair\r
1650 self.Profile.PcdDict[PcdPair] = BlockSize\r
543f5ac3 1651 self.SetPcdLocalation(PcdPair)\r
d0acc87a
LG
1652 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1653 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple\r
af881abc 1654 BlockSize = int(BlockSize, 0)\r
30fdf114
LG
1655\r
1656 BlockNumber = None\r
9e47e6f9
CJ
1657 if self._IsKeyword("NumBlocks"):\r
1658 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1659 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1660\r
9e47e6f9 1661 if not self._GetNextDecimalNumber() and not self._GetNextHexNumber():\r
ca957eb5 1662 raise Warning.Expected("block numbers", self.FileName, self.CurrentLineNumber)\r
30fdf114 1663\r
af881abc 1664 BlockNumber = int(self._Token, 0)\r
30fdf114
LG
1665\r
1666 Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd))\r
1667 return True\r
1668\r
9e47e6f9 1669 ## _GetDefineStatements() method\r
30fdf114
LG
1670 #\r
1671 # Get define statements\r
1672 #\r
1673 # @param self The object pointer\r
1674 # @param Obj for whom define statement is got\r
1675 # @retval True Successfully find\r
1676 # @retval False Not able to find\r
1677 #\r
9e47e6f9
CJ
1678 def _GetDefineStatements(self, Obj):\r
1679 while self._GetDefineStatement(Obj):\r
30fdf114
LG
1680 pass\r
1681\r
9e47e6f9 1682 ## _GetDefineStatement() method\r
30fdf114
LG
1683 #\r
1684 # Get define statement\r
1685 #\r
1686 # @param self The object pointer\r
1687 # @param Obj for whom define statement is got\r
1688 # @retval True Successfully find\r
1689 # @retval False Not able to find\r
1690 #\r
9e47e6f9
CJ
1691 def _GetDefineStatement(self, Obj):\r
1692 if self._IsKeyword(TAB_DEFINE):\r
1693 self._GetNextToken()\r
1694 Macro = self._Token\r
1695 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1696 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1697\r
9e47e6f9 1698 if not self._GetNextToken():\r
ca957eb5 1699 raise Warning.Expected("value", self.FileName, self.CurrentLineNumber)\r
30fdf114 1700\r
9e47e6f9 1701 Value = self._Token\r
30fdf114
LG
1702 Macro = '$(' + Macro + ')'\r
1703 Obj.DefineVarDict[Macro] = Value\r
1704 return True\r
1705\r
1706 return False\r
1707\r
9e47e6f9 1708 ## _GetSetStatements() method\r
30fdf114
LG
1709 #\r
1710 # Get set statements\r
1711 #\r
1712 # @param self The object pointer\r
1713 # @param Obj for whom set statement is got\r
1714 # @retval True Successfully find\r
1715 # @retval False Not able to find\r
1716 #\r
9e47e6f9
CJ
1717 def _GetSetStatements(self, Obj):\r
1718 while self._GetSetStatement(Obj):\r
30fdf114
LG
1719 pass\r
1720\r
9e47e6f9 1721 ## _GetSetStatement() method\r
30fdf114
LG
1722 #\r
1723 # Get set statement\r
1724 #\r
1725 # @param self The object pointer\r
1726 # @param Obj for whom set statement is got\r
1727 # @retval True Successfully find\r
1728 # @retval False Not able to find\r
1729 #\r
9e47e6f9
CJ
1730 def _GetSetStatement(self, Obj):\r
1731 if self._IsKeyword("SET"):\r
1732 PcdPair = self._GetNextPcdSettings()\r
30fdf114 1733\r
9e47e6f9 1734 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1735 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1736\r
9e47e6f9
CJ
1737 Value = self._GetExpression()\r
1738 Value = self._EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)\r
30fdf114 1739\r
6780eef1
LG
1740 if Obj:\r
1741 Obj.SetVarDict[PcdPair] = Value\r
30fdf114 1742 self.Profile.PcdDict[PcdPair] = Value\r
543f5ac3 1743 self.SetPcdLocalation(PcdPair)\r
d0acc87a
LG
1744 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1745 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple\r
30fdf114
LG
1746 return True\r
1747\r
1748 return False\r
1749\r
9e47e6f9 1750 ## _CalcRegionExpr(self)\r
4afd3d04
LG
1751 #\r
1752 # Calculate expression for offset or size of a region\r
1753 #\r
1754 # @return: None if invalid expression\r
1755 # Calculated number if successfully\r
1756 #\r
9e47e6f9 1757 def _CalcRegionExpr(self):\r
4afd3d04
LG
1758 StartPos = self.GetFileBufferPos()\r
1759 Expr = ''\r
1760 PairCount = 0\r
9e47e6f9
CJ
1761 while not self._EndOfFile():\r
1762 CurCh = self._CurrentChar()\r
4afd3d04
LG
1763 if CurCh == '(':\r
1764 PairCount += 1\r
1765 elif CurCh == ')':\r
1766 PairCount -= 1\r
1767\r
1768 if CurCh in '|\r\n' and PairCount == 0:\r
1769 break\r
1770 Expr += CurCh\r
9e47e6f9 1771 self._GetOneChar()\r
4afd3d04 1772 try:\r
af881abc 1773 return int(\r
4afd3d04 1774 ValueExpression(Expr,\r
9e47e6f9 1775 self._CollectMacroPcd()\r
ccaa7754 1776 )(True), 0)\r
4afd3d04
LG
1777 except Exception:\r
1778 self.SetFileBufferPos(StartPos)\r
1779 return None\r
1780\r
9e47e6f9 1781 ## _GetRegionLayout() method\r
30fdf114
LG
1782 #\r
1783 # Get region layout for FD\r
1784 #\r
1785 # @param self The object pointer\r
9e47e6f9 1786 # @param theFd for whom region is got\r
30fdf114
LG
1787 # @retval True Successfully find\r
1788 # @retval False Not able to find\r
1789 #\r
9e47e6f9
CJ
1790 def _GetRegionLayout(self, theFd):\r
1791 Offset = self._CalcRegionExpr()\r
4231a819 1792 if Offset is None:\r
30fdf114
LG
1793 return False\r
1794\r
9e47e6f9 1795 RegionObj = Region()\r
4afd3d04 1796 RegionObj.Offset = Offset\r
9e47e6f9 1797 theFd.RegionList.append(RegionObj)\r
30fdf114 1798\r
9e47e6f9 1799 if not self._IsToken(TAB_VALUE_SPLIT):\r
ca957eb5 1800 raise Warning.Expected("'|'", self.FileName, self.CurrentLineNumber)\r
30fdf114 1801\r
9e47e6f9 1802 Size = self._CalcRegionExpr()\r
4231a819 1803 if Size is None:\r
ca957eb5 1804 raise Warning.Expected("Region Size", self.FileName, self.CurrentLineNumber)\r
4afd3d04 1805 RegionObj.Size = Size\r
30fdf114 1806\r
9e47e6f9 1807 if not self._GetNextWord():\r
30fdf114
LG
1808 return True\r
1809\r
5a264f28 1810 if not self._Token in {"SET", BINARY_FILE_TYPE_FV, "FILE", "DATA", "CAPSULE", "INF"}:\r
2bc3256c
LG
1811 #\r
1812 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]\r
1813 # Or it might be next region's offset described by an expression which starts with a PCD.\r
1814 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size\r
1815 #\r
9e47e6f9
CJ
1816 self._UndoToken()\r
1817 IsRegionPcd = (RegionSizeGuidPattern.match(self._CurrentLine()[self.CurrentOffsetWithinLine:]) or\r
1818 RegionOffsetPcdPattern.match(self._CurrentLine()[self.CurrentOffsetWithinLine:]))\r
2bc3256c 1819 if IsRegionPcd:\r
9e47e6f9 1820 RegionObj.PcdOffset = self._GetNextPcdSettings()\r
af881abc 1821 self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + int(theFd.BaseAddress, 0))\r
543f5ac3 1822 self.SetPcdLocalation(RegionObj.PcdOffset)\r
9e47e6f9 1823 self._PcdDict['%s.%s' % (RegionObj.PcdOffset[1], RegionObj.PcdOffset[0])] = "0x%x" % RegionObj.Offset\r
d0acc87a 1824 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2bc3256c 1825 self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple\r
9e47e6f9
CJ
1826 if self._IsToken(TAB_VALUE_SPLIT):\r
1827 RegionObj.PcdSize = self._GetNextPcdSettings()\r
2bc3256c 1828 self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size\r
543f5ac3 1829 self.SetPcdLocalation(RegionObj.PcdSize)\r
9e47e6f9 1830 self._PcdDict['%s.%s' % (RegionObj.PcdSize[1], RegionObj.PcdSize[0])] = "0x%x" % RegionObj.Size\r
2bc3256c
LG
1831 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1832 self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple\r
30fdf114 1833\r
9e47e6f9 1834 if not self._GetNextWord():\r
30fdf114
LG
1835 return True\r
1836\r
9e47e6f9
CJ
1837 if self._Token == "SET":\r
1838 self._UndoToken()\r
1839 self._GetSetStatements(RegionObj)\r
1840 if not self._GetNextWord():\r
30fdf114
LG
1841 return True\r
1842\r
9e47e6f9
CJ
1843 elif self._Token == BINARY_FILE_TYPE_FV:\r
1844 self._UndoToken()\r
1845 self._GetRegionFvType(RegionObj)\r
30fdf114 1846\r
9e47e6f9
CJ
1847 elif self._Token == "CAPSULE":\r
1848 self._UndoToken()\r
1849 self._GetRegionCapType(RegionObj)\r
fd171542 1850\r
9e47e6f9
CJ
1851 elif self._Token == "FILE":\r
1852 self._UndoToken()\r
1853 self._GetRegionFileType(RegionObj)\r
b21a13fb 1854\r
9e47e6f9
CJ
1855 elif self._Token == "INF":\r
1856 self._UndoToken()\r
b21a13fb 1857 RegionObj.RegionType = "INF"\r
9e47e6f9
CJ
1858 while self._IsKeyword("INF"):\r
1859 self._UndoToken()\r
1860 ffsInf = self._ParseInfStatement()\r
b21a13fb
YZ
1861 if not ffsInf:\r
1862 break\r
1863 RegionObj.RegionDataList.append(ffsInf)\r
30fdf114 1864\r
9e47e6f9
CJ
1865 elif self._Token == "DATA":\r
1866 self._UndoToken()\r
1867 self._GetRegionDataType(RegionObj)\r
79b74a03 1868 else:\r
9e47e6f9
CJ
1869 self._UndoToken()\r
1870 if self._GetRegionLayout(theFd):\r
2bc3256c 1871 return True\r
79b74a03 1872 raise Warning("A valid region type was not found. "\r
b21a13fb 1873 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",\r
79b74a03 1874 self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
1875\r
1876 return True\r
1877\r
9e47e6f9 1878 ## _GetRegionFvType() method\r
30fdf114
LG
1879 #\r
1880 # Get region fv data for region\r
1881 #\r
1882 # @param self The object pointer\r
1883 # @param RegionObj for whom region data is got\r
1884 #\r
9e47e6f9
CJ
1885 def _GetRegionFvType(self, RegionObj):\r
1886 if not self._IsKeyword(BINARY_FILE_TYPE_FV):\r
ca957eb5 1887 raise Warning.Expected("'FV'", self.FileName, self.CurrentLineNumber)\r
30fdf114 1888\r
9e47e6f9 1889 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1890 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1891\r
9e47e6f9 1892 if not self._GetNextToken():\r
ca957eb5 1893 raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)\r
30fdf114 1894\r
91fa33ee 1895 RegionObj.RegionType = BINARY_FILE_TYPE_FV\r
9e47e6f9 1896 RegionObj.RegionDataList.append((self._Token).upper())\r
30fdf114 1897\r
9e47e6f9 1898 while self._IsKeyword(BINARY_FILE_TYPE_FV):\r
30fdf114 1899\r
9e47e6f9 1900 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1901 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1902\r
9e47e6f9 1903 if not self._GetNextToken():\r
ca957eb5 1904 raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)\r
30fdf114 1905\r
9e47e6f9 1906 RegionObj.RegionDataList.append((self._Token).upper())\r
30fdf114 1907\r
9e47e6f9 1908 ## _GetRegionCapType() method\r
fd171542 1909 #\r
1910 # Get region capsule data for region\r
1911 #\r
1912 # @param self The object pointer\r
1913 # @param RegionObj for whom region data is got\r
1914 #\r
9e47e6f9
CJ
1915 def _GetRegionCapType(self, RegionObj):\r
1916 if not self._IsKeyword("CAPSULE"):\r
ca957eb5 1917 raise Warning.Expected("'CAPSULE'", self.FileName, self.CurrentLineNumber)\r
fd171542 1918\r
9e47e6f9 1919 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1920 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
fd171542 1921\r
9e47e6f9 1922 if not self._GetNextToken():\r
ca957eb5 1923 raise Warning.Expected("CAPSULE name", self.FileName, self.CurrentLineNumber)\r
fd171542 1924\r
1925 RegionObj.RegionType = "CAPSULE"\r
9e47e6f9 1926 RegionObj.RegionDataList.append(self._Token)\r
fd171542 1927\r
9e47e6f9 1928 while self._IsKeyword("CAPSULE"):\r
fd171542 1929\r
9e47e6f9 1930 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1931 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
fd171542 1932\r
9e47e6f9 1933 if not self._GetNextToken():\r
ca957eb5 1934 raise Warning.Expected("CAPSULE name", self.FileName, self.CurrentLineNumber)\r
fd171542 1935\r
9e47e6f9 1936 RegionObj.RegionDataList.append(self._Token)\r
fd171542 1937\r
9e47e6f9 1938 ## _GetRegionFileType() method\r
30fdf114
LG
1939 #\r
1940 # Get region file data for region\r
1941 #\r
1942 # @param self The object pointer\r
1943 # @param RegionObj for whom region data is got\r
1944 #\r
9e47e6f9
CJ
1945 def _GetRegionFileType(self, RegionObj):\r
1946 if not self._IsKeyword("FILE"):\r
ca957eb5 1947 raise Warning.Expected("'FILE'", self.FileName, self.CurrentLineNumber)\r
30fdf114 1948\r
9e47e6f9 1949 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1950 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1951\r
9e47e6f9 1952 if not self._GetNextToken():\r
ca957eb5 1953 raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
1954\r
1955 RegionObj.RegionType = "FILE"\r
9e47e6f9 1956 RegionObj.RegionDataList.append(self._Token)\r
30fdf114 1957\r
9e47e6f9 1958 while self._IsKeyword("FILE"):\r
30fdf114 1959\r
9e47e6f9 1960 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1961 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1962\r
9e47e6f9 1963 if not self._GetNextToken():\r
ca957eb5 1964 raise Warning.Expected("FILE name", self.FileName, self.CurrentLineNumber)\r
30fdf114 1965\r
9e47e6f9 1966 RegionObj.RegionDataList.append(self._Token)\r
30fdf114 1967\r
9e47e6f9 1968 ## _GetRegionDataType() method\r
30fdf114
LG
1969 #\r
1970 # Get region array data for region\r
1971 #\r
1972 # @param self The object pointer\r
1973 # @param RegionObj for whom region data is got\r
1974 #\r
9e47e6f9
CJ
1975 def _GetRegionDataType(self, RegionObj):\r
1976 if not self._IsKeyword("DATA"):\r
ca957eb5 1977 raise Warning.Expected("Region Data type", self.FileName, self.CurrentLineNumber)\r
30fdf114 1978\r
9e47e6f9 1979 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1980 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1981\r
9e47e6f9 1982 if not self._IsToken("{"):\r
ca957eb5 1983 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
30fdf114 1984\r
9e47e6f9 1985 if not self._GetNextHexNumber():\r
ca957eb5 1986 raise Warning.Expected("Hex byte", self.FileName, self.CurrentLineNumber)\r
30fdf114 1987\r
9e47e6f9 1988 if len(self._Token) > 18:\r
636f2be6
LG
1989 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)\r
1990\r
1991 # convert hex string value to byte hex string array\r
9e47e6f9 1992 AllString = self._Token\r
636f2be6
LG
1993 AllStrLen = len (AllString)\r
1994 DataString = ""\r
1995 while AllStrLen > 4:\r
9e47e6f9 1996 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + TAB_COMMA_SPLIT\r
636f2be6 1997 AllStrLen = AllStrLen - 2\r
9e47e6f9 1998 DataString = DataString + AllString[:AllStrLen] + TAB_COMMA_SPLIT\r
636f2be6
LG
1999\r
2000 # byte value array\r
9e47e6f9
CJ
2001 if len (self._Token) <= 4:\r
2002 while self._IsToken(TAB_COMMA_SPLIT):\r
2003 if not self._GetNextHexNumber():\r
636f2be6 2004 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2005 if len(self._Token) > 4:\r
636f2be6 2006 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
2007 DataString += self._Token\r
2008 DataString += TAB_COMMA_SPLIT\r
30fdf114 2009\r
ea98a825 2010 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2011 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 2012\r
9e47e6f9 2013 DataString = DataString.rstrip(TAB_COMMA_SPLIT)\r
30fdf114 2014 RegionObj.RegionType = "DATA"\r
9e47e6f9 2015 RegionObj.RegionDataList.append(DataString)\r
30fdf114 2016\r
9e47e6f9 2017 while self._IsKeyword("DATA"):\r
30fdf114 2018\r
9e47e6f9 2019 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2020 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 2021\r
9e47e6f9 2022 if not self._IsToken("{"):\r
ca957eb5 2023 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
30fdf114 2024\r
9e47e6f9 2025 if not self._GetNextHexNumber():\r
ca957eb5 2026 raise Warning.Expected("Hex byte", self.FileName, self.CurrentLineNumber)\r
30fdf114 2027\r
9e47e6f9 2028 if len(self._Token) > 18:\r
636f2be6
LG
2029 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)\r
2030\r
2031 # convert hex string value to byte hex string array\r
9e47e6f9 2032 AllString = self._Token\r
636f2be6
LG
2033 AllStrLen = len (AllString)\r
2034 DataString = ""\r
2035 while AllStrLen > 4:\r
9e47e6f9 2036 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + TAB_COMMA_SPLIT\r
636f2be6 2037 AllStrLen = AllStrLen - 2\r
9e47e6f9 2038 DataString = DataString + AllString[:AllStrLen] + TAB_COMMA_SPLIT\r
636f2be6
LG
2039\r
2040 # byte value array\r
9e47e6f9
CJ
2041 if len (self._Token) <= 4:\r
2042 while self._IsToken(TAB_COMMA_SPLIT):\r
2043 if not self._GetNextHexNumber():\r
636f2be6 2044 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2045 if len(self._Token) > 4:\r
636f2be6 2046 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
2047 DataString += self._Token\r
2048 DataString += TAB_COMMA_SPLIT\r
30fdf114 2049\r
ea98a825 2050 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2051 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 2052\r
9e47e6f9
CJ
2053 DataString = DataString.rstrip(TAB_COMMA_SPLIT)\r
2054 RegionObj.RegionDataList.append(DataString)\r
30fdf114 2055\r
9e47e6f9 2056 ## _GetFv() method\r
30fdf114
LG
2057 #\r
2058 # Get FV section contents and store its data into FV dictionary of self.Profile\r
2059 #\r
2060 # @param self The object pointer\r
2061 # @retval True Successfully find a FV\r
2062 # @retval False Not able to find a FV\r
2063 #\r
9e47e6f9
CJ
2064 def _GetFv(self):\r
2065 if not self._GetNextToken():\r
30fdf114
LG
2066 return False\r
2067\r
9e47e6f9
CJ
2068 S = self._Token.upper()\r
2069 if S.startswith(TAB_SECTION_START) and not S.startswith("[FV."):\r
df81077f 2070 self.SectionParser(S)\r
9e47e6f9 2071 self._UndoToken()\r
30fdf114
LG
2072 return False\r
2073\r
9e47e6f9
CJ
2074 self._UndoToken()\r
2075 if not self._IsToken("[FV.", True):\r
30fdf114
LG
2076 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2077 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
9e47e6f9
CJ
2078 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
2079 raise Warning("Unknown Keyword '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114 2080\r
9e47e6f9 2081 FvName = self._GetUiName()\r
30fdf114
LG
2082 self.CurrentFvName = FvName.upper()\r
2083\r
9e47e6f9 2084 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 2085 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 2086\r
9ffaaac2 2087 FvObj = FV(Name=self.CurrentFvName)\r
30fdf114
LG
2088 self.Profile.FvDict[self.CurrentFvName] = FvObj\r
2089\r
9e47e6f9 2090 Status = self._GetCreateFile(FvObj)\r
30fdf114
LG
2091 if not Status:\r
2092 raise Warning("FV name error", self.FileName, self.CurrentLineNumber)\r
2093\r
9e47e6f9 2094 self._GetDefineStatements(FvObj)\r
30fdf114 2095\r
9e47e6f9 2096 self._GetAddressStatements(FvObj)\r
30fdf114 2097\r
b303ea72 2098 while True:\r
9e47e6f9 2099 self._GetSetStatements(FvObj)\r
e8a47801 2100\r
9e47e6f9
CJ
2101 if not (self._GetBlockStatement(FvObj) or self._GetFvBaseAddress(FvObj) or\r
2102 self._GetFvForceRebase(FvObj) or self._GetFvAlignment(FvObj) or\r
2103 self._GetFvAttributes(FvObj) or self._GetFvNameGuid(FvObj) or\r
2104 self._GetFvExtEntryStatement(FvObj) or self._GetFvNameString(FvObj)):\r
b303ea72
LG
2105 break\r
2106\r
aaf8aa7b
YL
2107 if FvObj.FvNameString == 'TRUE' and not FvObj.FvNameGuid:\r
2108 raise Warning("FvNameString found but FvNameGuid was not found", self.FileName, self.CurrentLineNumber)\r
2109\r
5a6a268d
JC
2110 self._GetAprioriSection(FvObj)\r
2111 self._GetAprioriSection(FvObj)\r
30fdf114
LG
2112\r
2113 while True:\r
9e47e6f9 2114 isInf = self._GetInfStatement(FvObj)\r
5a6a268d 2115 isFile = self._GetFileStatement(FvObj)\r
30fdf114
LG
2116 if not isInf and not isFile:\r
2117 break\r
2118\r
2119 return True\r
2120\r
9e47e6f9 2121 ## _GetFvAlignment() method\r
30fdf114
LG
2122 #\r
2123 # Get alignment for FV\r
2124 #\r
2125 # @param self The object pointer\r
2126 # @param Obj for whom alignment is got\r
2127 # @retval True Successfully find a alignment statement\r
2128 # @retval False Not able to find a alignment statement\r
2129 #\r
9e47e6f9
CJ
2130 def _GetFvAlignment(self, Obj):\r
2131 if not self._IsKeyword("FvAlignment"):\r
30fdf114
LG
2132 return False\r
2133\r
9e47e6f9 2134 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2135 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 2136\r
9e47e6f9 2137 if not self._GetNextToken():\r
ca957eb5 2138 raise Warning.Expected("alignment value", self.FileName, self.CurrentLineNumber)\r
30fdf114 2139\r
5a264f28 2140 if self._Token.upper() not in {"1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \\r
30fdf114
LG
2141 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \\r
2142 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \\r
5a264f28 2143 "1G", "2G"}:\r
9e47e6f9
CJ
2144 raise Warning("Unknown alignment value '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
2145 Obj.FvAlignment = self._Token\r
30fdf114 2146 return True\r
f7496d71 2147\r
9e47e6f9 2148 ## _GetFvBaseAddress() method\r
4234283c
LG
2149 #\r
2150 # Get BaseAddress for FV\r
2151 #\r
2152 # @param self The object pointer\r
2153 # @param Obj for whom FvBaseAddress is got\r
2154 # @retval True Successfully find a FvBaseAddress statement\r
2155 # @retval False Not able to find a FvBaseAddress statement\r
2156 #\r
9e47e6f9
CJ
2157 def _GetFvBaseAddress(self, Obj):\r
2158 if not self._IsKeyword("FvBaseAddress"):\r
4234283c
LG
2159 return False\r
2160\r
9e47e6f9 2161 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2162 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
4234283c 2163\r
9e47e6f9 2164 if not self._GetNextToken():\r
ca957eb5 2165 raise Warning.Expected("FV base address value", self.FileName, self.CurrentLineNumber)\r
4234283c 2166\r
9e47e6f9
CJ
2167 if not BaseAddrValuePattern.match(self._Token.upper()):\r
2168 raise Warning("Unknown FV base address value '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
2169 Obj.FvBaseAddress = self._Token\r
f7496d71
LG
2170 return True\r
2171\r
9e47e6f9 2172 ## _GetFvForceRebase() method\r
79b74a03
LG
2173 #\r
2174 # Get FvForceRebase for FV\r
2175 #\r
2176 # @param self The object pointer\r
2177 # @param Obj for whom FvForceRebase is got\r
2178 # @retval True Successfully find a FvForceRebase statement\r
2179 # @retval False Not able to find a FvForceRebase statement\r
2180 #\r
9e47e6f9
CJ
2181 def _GetFvForceRebase(self, Obj):\r
2182 if not self._IsKeyword("FvForceRebase"):\r
79b74a03
LG
2183 return False\r
2184\r
9e47e6f9 2185 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2186 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
79b74a03 2187\r
9e47e6f9 2188 if not self._GetNextToken():\r
ca957eb5 2189 raise Warning.Expected("FvForceRebase value", self.FileName, self.CurrentLineNumber)\r
30fdf114 2190\r
5a264f28 2191 if self._Token.upper() not in {"TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"}:\r
9e47e6f9 2192 raise Warning("Unknown FvForceRebase value '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
f7496d71 2193\r
5a264f28 2194 if self._Token.upper() in {"TRUE", "1", "0X1", "0X01"}:\r
79b74a03 2195 Obj.FvForceRebase = True\r
5a264f28 2196 elif self._Token.upper() in {"FALSE", "0", "0X0", "0X00"}:\r
79b74a03
LG
2197 Obj.FvForceRebase = False\r
2198 else:\r
2199 Obj.FvForceRebase = None\r
f7496d71 2200\r
79b74a03 2201 return True\r
0d2711a6
LG
2202\r
2203\r
9e47e6f9 2204 ## _GetFvAttributes() method\r
30fdf114
LG
2205 #\r
2206 # Get attributes for FV\r
2207 #\r
2208 # @param self The object pointer\r
2209 # @param Obj for whom attribute is got\r
2210 # @retval None\r
2211 #\r
9e47e6f9 2212 def _GetFvAttributes(self, FvObj):\r
2bc3256c 2213 IsWordToken = False\r
9e47e6f9 2214 while self._GetNextWord():\r
2bc3256c 2215 IsWordToken = True\r
9e47e6f9 2216 name = self._Token\r
5a264f28 2217 if name not in {"ERASE_POLARITY", "MEMORY_MAPPED", \\r
30fdf114
LG
2218 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \\r
2219 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \\r
2220 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \\r
2221 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \\r
5a264f28 2222 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"}:\r
9e47e6f9 2223 self._UndoToken()\r
e8a47801 2224 return False\r
30fdf114 2225\r
9e47e6f9 2226 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2227 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 2228\r
5a264f28 2229 if not self._GetNextToken() or self._Token.upper() not in {"TRUE", "FALSE", "1", "0"}:\r
ca957eb5 2230 raise Warning.Expected("TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)\r
30fdf114 2231\r
9e47e6f9 2232 FvObj.FvAttributeDict[name] = self._Token\r
30fdf114 2233\r
2bc3256c 2234 return IsWordToken\r
f7496d71 2235\r
9e47e6f9 2236 ## _GetFvNameGuid() method\r
30fdf114
LG
2237 #\r
2238 # Get FV GUID for FV\r
2239 #\r
2240 # @param self The object pointer\r
2241 # @param Obj for whom GUID is got\r
2242 # @retval None\r
2243 #\r
9e47e6f9
CJ
2244 def _GetFvNameGuid(self, FvObj):\r
2245 if not self._IsKeyword("FvNameGuid"):\r
e8a47801 2246 return False\r
30fdf114 2247\r
9e47e6f9 2248 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2249 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 2250\r
9e47e6f9 2251 if not self._GetNextGuid():\r
ca957eb5 2252 raise Warning.Expected("GUID value", self.FileName, self.CurrentLineNumber)\r
d35773d5
YC
2253 if self._Token in GlobalData.gGuidDict:\r
2254 self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper()\r
30fdf114 2255\r
9e47e6f9 2256 FvObj.FvNameGuid = self._Token\r
30fdf114 2257\r
e8a47801 2258 return True\r
30fdf114 2259\r
9e47e6f9
CJ
2260 def _GetFvNameString(self, FvObj):\r
2261 if not self._IsKeyword("FvNameString"):\r
aaf8aa7b
YL
2262 return False\r
2263\r
9e47e6f9 2264 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2265 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
aaf8aa7b 2266\r
ca957eb5
CJ
2267 if not self._GetNextToken() or self._Token.upper() not in {'TRUE', 'FALSE'}:\r
2268 raise Warning.Expected("TRUE or FALSE for FvNameString", self.FileName, self.CurrentLineNumber)\r
aaf8aa7b 2269\r
9e47e6f9 2270 FvObj.FvNameString = self._Token\r
aaf8aa7b
YL
2271\r
2272 return True\r
2273\r
9e47e6f9
CJ
2274 def _GetFvExtEntryStatement(self, FvObj):\r
2275 if not (self._IsKeyword("FV_EXT_ENTRY") or self._IsKeyword("FV_EXT_ENTRY_TYPE")):\r
b303ea72
LG
2276 return False\r
2277\r
9e47e6f9 2278 if not self._IsKeyword ("TYPE"):\r
ca957eb5 2279 raise Warning.Expected("'TYPE'", self.FileName, self.CurrentLineNumber)\r
f7496d71 2280\r
9e47e6f9 2281 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2282 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
b303ea72 2283\r
9e47e6f9 2284 if not self._GetNextHexNumber() and not self._GetNextDecimalNumber():\r
ca957eb5 2285 raise Warning.Expected("Hex FV extension entry type value At Line ", self.FileName, self.CurrentLineNumber)\r
b303ea72 2286\r
9e47e6f9 2287 FvObj.FvExtEntryTypeValue.append(self._Token)\r
b303ea72 2288\r
9e47e6f9 2289 if not self._IsToken("{"):\r
ca957eb5 2290 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
b303ea72 2291\r
ca957eb5
CJ
2292 if not self._IsKeyword("FILE") and not self._IsKeyword("DATA"):\r
2293 raise Warning.Expected("'FILE' or 'DATA'", self.FileName, self.CurrentLineNumber)\r
b303ea72 2294\r
9e47e6f9 2295 FvObj.FvExtEntryType.append(self._Token)\r
b303ea72 2296\r
9e47e6f9 2297 if self._Token == 'DATA':\r
9e47e6f9 2298 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2299 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
f7496d71 2300\r
9e47e6f9 2301 if not self._IsToken("{"):\r
ca957eb5 2302 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
b303ea72 2303\r
9e47e6f9 2304 if not self._GetNextHexNumber():\r
ca957eb5 2305 raise Warning.Expected("Hex byte", self.FileName, self.CurrentLineNumber)\r
b303ea72 2306\r
9e47e6f9 2307 if len(self._Token) > 4:\r
b303ea72
LG
2308 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
2309\r
9e47e6f9
CJ
2310 DataString = self._Token\r
2311 DataString += TAB_COMMA_SPLIT\r
b303ea72 2312\r
9e47e6f9
CJ
2313 while self._IsToken(TAB_COMMA_SPLIT):\r
2314 if not self._GetNextHexNumber():\r
b303ea72 2315 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2316 if len(self._Token) > 4:\r
b303ea72 2317 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
2318 DataString += self._Token\r
2319 DataString += TAB_COMMA_SPLIT\r
b303ea72 2320\r
ea98a825 2321 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2322 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
b303ea72 2323\r
ea98a825 2324 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2325 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
b303ea72 2326\r
9e47e6f9 2327 DataString = DataString.rstrip(TAB_COMMA_SPLIT)\r
caf74495 2328 FvObj.FvExtEntryData.append(DataString)\r
b303ea72 2329\r
9e47e6f9 2330 if self._Token == 'FILE':\r
9e47e6f9 2331 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2332 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
f7496d71 2333\r
9e47e6f9 2334 if not self._GetNextToken():\r
ca957eb5 2335 raise Warning.Expected("FV Extension Entry file path At Line ", self.FileName, self.CurrentLineNumber)\r
f7496d71 2336\r
9e47e6f9 2337 FvObj.FvExtEntryData.append(self._Token)\r
b303ea72 2338\r
ea98a825 2339 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2340 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
b303ea72
LG
2341\r
2342 return True\r
2343\r
9e47e6f9 2344 ## _GetAprioriSection() method\r
30fdf114
LG
2345 #\r
2346 # Get token statements\r
2347 #\r
2348 # @param self The object pointer\r
2349 # @param FvObj for whom apriori is got\r
30fdf114
LG
2350 # @retval True Successfully find apriori statement\r
2351 # @retval False Not able to find apriori statement\r
2352 #\r
5a6a268d 2353 def _GetAprioriSection(self, FvObj):\r
9e47e6f9 2354 if not self._IsKeyword("APRIORI"):\r
30fdf114
LG
2355 return False\r
2356\r
9e47e6f9 2357 if not self._IsKeyword("PEI") and not self._IsKeyword("DXE"):\r
ca957eb5 2358 raise Warning.Expected("Apriori file type", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2359 AprType = self._Token\r
30fdf114 2360\r
9e47e6f9 2361 if not self._IsToken("{"):\r
ca957eb5 2362 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
30fdf114 2363\r
9e47e6f9 2364 AprSectionObj = AprioriSection()\r
30fdf114
LG
2365 AprSectionObj.AprioriType = AprType\r
2366\r
9e47e6f9 2367 self._GetDefineStatements(AprSectionObj)\r
30fdf114
LG
2368\r
2369 while True:\r
9e47e6f9
CJ
2370 IsInf = self._GetInfStatement(AprSectionObj)\r
2371 IsFile = self._GetFileStatement(AprSectionObj)\r
30fdf114
LG
2372 if not IsInf and not IsFile:\r
2373 break\r
2374\r
ea98a825 2375 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2376 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2377\r
2378 FvObj.AprioriSectionList.append(AprSectionObj)\r
2379 return True\r
2380\r
9e47e6f9
CJ
2381 def _ParseInfStatement(self):\r
2382 if not self._IsKeyword("INF"):\r
b21a13fb 2383 return None\r
30fdf114 2384\r
9e47e6f9
CJ
2385 ffsInf = FfsInfStatement()\r
2386 self._GetInfOptions(ffsInf)\r
30fdf114 2387\r
9e47e6f9 2388 if not self._GetNextToken():\r
ca957eb5 2389 raise Warning.Expected("INF file path", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2390 ffsInf.InfFileName = self._Token\r
a87e79d9 2391 if not ffsInf.InfFileName.endswith('.inf'):\r
ca957eb5 2392 raise Warning.Expected(".inf file path", self.FileName, self.CurrentLineNumber)\r
64b2609f
LG
2393\r
2394 ffsInf.CurrentLineNum = self.CurrentLineNumber\r
9e47e6f9 2395 ffsInf.CurrentLineContent = self._CurrentLine()\r
64b2609f 2396\r
97fa0ee9
YL
2397 #Replace $(SAPCE) with real space\r
2398 ffsInf.InfFileName = ffsInf.InfFileName.replace('$(SPACE)', ' ')\r
2399\r
9e47e6f9 2400 if ffsInf.InfFileName.replace(TAB_WORKSPACE, '').find('$') == -1:\r
14c48571 2401 #do case sensitive check for file path\r
2402 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
2403 if ErrorCode != 0:\r
2404 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114 2405\r
3d3416e8
FB
2406 NewFileName = ffsInf.InfFileName\r
2407 if ffsInf.OverrideGuid:\r
2408 NewFileName = ProcessDuplicatedInf(PathClass(ffsInf.InfFileName,GenFdsGlobalVariable.WorkSpaceDir), ffsInf.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir).Path\r
2409\r
2410 if not NewFileName in self.Profile.InfList:\r
2411 self.Profile.InfList.append(NewFileName)\r
d0acc87a
LG
2412 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2413 self.Profile.InfFileLineList.append(FileLineTuple)\r
2502b735
YZ
2414 if ffsInf.UseArch:\r
2415 if ffsInf.UseArch not in self.Profile.InfDict:\r
2416 self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]\r
2417 else:\r
2418 self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)\r
2419 else:\r
2420 self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)\r
30fdf114 2421\r
9e47e6f9
CJ
2422 if self._IsToken(TAB_VALUE_SPLIT):\r
2423 if self._IsKeyword('RELOCS_STRIPPED'):\r
30fdf114 2424 ffsInf.KeepReloc = False\r
9e47e6f9 2425 elif self._IsKeyword('RELOCS_RETAINED'):\r
30fdf114
LG
2426 ffsInf.KeepReloc = True\r
2427 else:\r
9e47e6f9 2428 raise Warning("Unknown reloc strip flag '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
b21a13fb
YZ
2429 return ffsInf\r
2430\r
9e47e6f9 2431 ## _GetInfStatement() method\r
b21a13fb
YZ
2432 #\r
2433 # Get INF statements\r
2434 #\r
2435 # @param self The object pointer\r
2436 # @param Obj for whom inf statement is got\r
b21a13fb
YZ
2437 # @retval True Successfully find inf statement\r
2438 # @retval False Not able to find inf statement\r
2439 #\r
9e47e6f9
CJ
2440 def _GetInfStatement(self, Obj, ForCapsule=False):\r
2441 ffsInf = self._ParseInfStatement()\r
b21a13fb
YZ
2442 if not ffsInf:\r
2443 return False\r
2444\r
30fdf114 2445 if ForCapsule:\r
9e47e6f9
CJ
2446 myCapsuleFfs = CapsuleFfs()\r
2447 myCapsuleFfs.Ffs = ffsInf\r
2448 Obj.CapsuleDataList.append(myCapsuleFfs)\r
30fdf114
LG
2449 else:\r
2450 Obj.FfsList.append(ffsInf)\r
2451 return True\r
2452\r
9e47e6f9 2453 ## _GetInfOptions() method\r
30fdf114
LG
2454 #\r
2455 # Get options for INF\r
2456 #\r
2457 # @param self The object pointer\r
2458 # @param FfsInfObj for whom option is got\r
2459 #\r
9e47e6f9
CJ
2460 def _GetInfOptions(self, FfsInfObj):\r
2461 if self._IsKeyword("FILE_GUID"):\r
2462 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2463 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2464 if not self._GetNextGuid():\r
ca957eb5 2465 raise Warning.Expected("GUID value", self.FileName, self.CurrentLineNumber)\r
d35773d5
YC
2466 if self._Token in GlobalData.gGuidDict:\r
2467 self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper()\r
9e47e6f9 2468 FfsInfObj.OverrideGuid = self._Token\r
30fdf114 2469\r
9e47e6f9
CJ
2470 if self._IsKeyword("RuleOverride"):\r
2471 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2472 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2473 if not self._GetNextToken():\r
ca957eb5 2474 raise Warning.Expected("Rule name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2475 FfsInfObj.Rule = self._Token\r
30fdf114 2476\r
9e47e6f9
CJ
2477 if self._IsKeyword("VERSION"):\r
2478 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2479 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2480 if not self._GetNextToken():\r
ca957eb5 2481 raise Warning.Expected("Version", self.FileName, self.CurrentLineNumber)\r
30fdf114 2482\r
9e47e6f9
CJ
2483 if self._GetStringData():\r
2484 FfsInfObj.Version = self._Token\r
30fdf114 2485\r
9e47e6f9
CJ
2486 if self._IsKeyword(BINARY_FILE_TYPE_UI):\r
2487 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2488 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2489 if not self._GetNextToken():\r
ca957eb5 2490 raise Warning.Expected("UI name", self.FileName, self.CurrentLineNumber)\r
30fdf114 2491\r
9e47e6f9
CJ
2492 if self._GetStringData():\r
2493 FfsInfObj.Ui = self._Token\r
30fdf114 2494\r
9e47e6f9
CJ
2495 if self._IsKeyword("USE"):\r
2496 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2497 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2498 if not self._GetNextToken():\r
ca957eb5 2499 raise Warning.Expected("ARCH name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2500 FfsInfObj.UseArch = self._Token\r
30fdf114 2501\r
f7496d71 2502\r
9e47e6f9
CJ
2503 if self._GetNextToken():\r
2504 p = compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')\r
2505 if p.match(self._Token) and p.match(self._Token).span()[1] == len(self._Token):\r
2506 FfsInfObj.KeyStringList.append(self._Token)\r
2507 if not self._IsToken(TAB_COMMA_SPLIT):\r
30fdf114
LG
2508 return\r
2509 else:\r
9e47e6f9 2510 self._UndoToken()\r
30fdf114
LG
2511 return\r
2512\r
9e47e6f9
CJ
2513 while self._GetNextToken():\r
2514 if not p.match(self._Token):\r
ca957eb5 2515 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2516 FfsInfObj.KeyStringList.append(self._Token)\r
30fdf114 2517\r
9e47e6f9 2518 if not self._IsToken(TAB_COMMA_SPLIT):\r
30fdf114
LG
2519 break\r
2520\r
9e47e6f9 2521 ## _GetFileStatement() method\r
30fdf114
LG
2522 #\r
2523 # Get FILE statements\r
2524 #\r
2525 # @param self The object pointer\r
2526 # @param Obj for whom FILE statement is got\r
30fdf114
LG
2527 # @retval True Successfully find FILE statement\r
2528 # @retval False Not able to find FILE statement\r
2529 #\r
5a6a268d 2530 def _GetFileStatement(self, Obj, ForCapsule = False):\r
9e47e6f9 2531 if not self._IsKeyword("FILE"):\r
30fdf114
LG
2532 return False\r
2533\r
9e47e6f9 2534 if not self._GetNextWord():\r
ca957eb5 2535 raise Warning.Expected("FFS type", self.FileName, self.CurrentLineNumber)\r
b36d134f 2536\r
9e47e6f9
CJ
2537 if ForCapsule and self._Token == 'DATA':\r
2538 self._UndoToken()\r
2539 self._UndoToken()\r
b36d134f 2540 return False\r
f7496d71 2541\r
9e47e6f9
CJ
2542 FfsFileObj = FileStatement()\r
2543 FfsFileObj.FvFileType = self._Token\r
30fdf114 2544\r
9e47e6f9 2545 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2546 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 2547\r
9e47e6f9
CJ
2548 if not self._GetNextGuid():\r
2549 if not self._GetNextWord():\r
ca957eb5 2550 raise Warning.Expected("File GUID", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
2551 if self._Token == 'PCD':\r
2552 if not self._IsToken("("):\r
ca957eb5 2553 raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
2554 PcdPair = self._GetNextPcdSettings()\r
2555 if not self._IsToken(")"):\r
ca957eb5 2556 raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2557 self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'\r
f7496d71 2558\r
d35773d5
YC
2559 if self._Token in GlobalData.gGuidDict:\r
2560 self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper()\r
9e47e6f9 2561 FfsFileObj.NameGuid = self._Token\r
f7496d71 2562\r
5a6a268d 2563 self._GetFilePart(FfsFileObj)\r
30fdf114
LG
2564\r
2565 if ForCapsule:\r
9e47e6f9 2566 capsuleFfs = CapsuleFfs()\r
30fdf114
LG
2567 capsuleFfs.Ffs = FfsFileObj\r
2568 Obj.CapsuleDataList.append(capsuleFfs)\r
2569 else:\r
2570 Obj.FfsList.append(FfsFileObj)\r
2571\r
2572 return True\r
2573\r
9e47e6f9 2574 ## _FileCouldHaveRelocFlag() method\r
30fdf114
LG
2575 #\r
2576 # Check whether reloc strip flag can be set for a file type.\r
2577 #\r
30fdf114
LG
2578 # @param FileType The file type to check with\r
2579 # @retval True This type could have relocation strip flag\r
2580 # @retval False No way to have it\r
2581 #\r
5bcf1d56 2582 @staticmethod\r
9e47e6f9 2583 def _FileCouldHaveRelocFlag (FileType):\r
8ef653aa 2584 if FileType in {SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_MM_CORE_STANDALONE, 'PEI_DXE_COMBO'}:\r
30fdf114
LG
2585 return True\r
2586 else:\r
2587 return False\r
2588\r
9e47e6f9 2589 ## _SectionCouldHaveRelocFlag() method\r
30fdf114
LG
2590 #\r
2591 # Check whether reloc strip flag can be set for a section type.\r
2592 #\r
30fdf114
LG
2593 # @param SectionType The section type to check with\r
2594 # @retval True This type could have relocation strip flag\r
2595 # @retval False No way to have it\r
2596 #\r
5bcf1d56 2597 @staticmethod\r
9e47e6f9 2598 def _SectionCouldHaveRelocFlag (SectionType):\r
5a264f28 2599 if SectionType in {BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32}:\r
30fdf114
LG
2600 return True\r
2601 else:\r
2602 return False\r
2603\r
9e47e6f9 2604 ## _GetFilePart() method\r
30fdf114
LG
2605 #\r
2606 # Get components for FILE statement\r
2607 #\r
2608 # @param self The object pointer\r
2609 # @param FfsFileObj for whom component is got\r
30fdf114 2610 #\r
5a6a268d 2611 def _GetFilePart(self, FfsFileObj):\r
9e47e6f9 2612 self._GetFileOpts(FfsFileObj)\r
30fdf114 2613\r
9e47e6f9
CJ
2614 if not self._IsToken("{"):\r
2615 if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):\r
2616 if self._FileCouldHaveRelocFlag(FfsFileObj.FvFileType):\r
2617 if self._Token == 'RELOCS_STRIPPED':\r
4afd3d04
LG
2618 FfsFileObj.KeepReloc = False\r
2619 else:\r
2620 FfsFileObj.KeepReloc = True\r
2621 else:\r
2622 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
2623\r
9e47e6f9 2624 if not self._IsToken("{"):\r
ca957eb5 2625 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
30fdf114 2626\r
9e47e6f9 2627 if not self._GetNextToken():\r
ca957eb5 2628 raise Warning.Expected("File name or section data", self.FileName, self.CurrentLineNumber)\r
30fdf114 2629\r
9e47e6f9
CJ
2630 if self._Token == BINARY_FILE_TYPE_FV:\r
2631 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2632 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2633 if not self._GetNextToken():\r
ca957eb5 2634 raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2635 FfsFileObj.FvName = self._Token\r
30fdf114 2636\r
9e47e6f9
CJ
2637 elif self._Token == "FD":\r
2638 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2639 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2640 if not self._GetNextToken():\r
ca957eb5 2641 raise Warning.Expected("FD name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2642 FfsFileObj.FdName = self._Token\r
30fdf114 2643\r
5a264f28 2644 elif self._Token in {TAB_DEFINE, "APRIORI", "SECTION"}:\r
9e47e6f9 2645 self._UndoToken()\r
5a6a268d 2646 self._GetSectionData(FfsFileObj)\r
860992ed
YZ
2647\r
2648 elif hasattr(FfsFileObj, 'FvFileType') and FfsFileObj.FvFileType == 'RAW':\r
9e47e6f9 2649 self._UndoToken()\r
5a6a268d 2650 self._GetRAWData(FfsFileObj)\r
860992ed 2651\r
30fdf114 2652 else:\r
64b2609f 2653 FfsFileObj.CurrentLineNum = self.CurrentLineNumber\r
9e47e6f9
CJ
2654 FfsFileObj.CurrentLineContent = self._CurrentLine()\r
2655 FfsFileObj.FileName = self._Token.replace('$(SPACE)', ' ')\r
2656 self._VerifyFile(FfsFileObj.FileName)\r
0d2711a6 2657\r
ea98a825 2658 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2659 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 2660\r
9e47e6f9 2661 ## _GetRAWData() method\r
860992ed
YZ
2662 #\r
2663 # Get RAW data for FILE statement\r
2664 #\r
2665 # @param self The object pointer\r
2666 # @param FfsFileObj for whom section is got\r
860992ed 2667 #\r
5a6a268d 2668 def _GetRAWData(self, FfsFileObj):\r
860992ed 2669 FfsFileObj.FileName = []\r
cfaaf99b 2670 FfsFileObj.SubAlignment = []\r
860992ed
YZ
2671 while True:\r
2672 AlignValue = None\r
9e47e6f9
CJ
2673 if self._GetAlignment():\r
2674 if self._Token not in ALIGNMENTS:\r
2675 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
f475f1e2 2676 #For FFS, Auto is default option same to ""\r
9e47e6f9
CJ
2677 if not self._Token == "Auto":\r
2678 AlignValue = self._Token\r
2679 if not self._GetNextToken():\r
ca957eb5 2680 raise Warning.Expected("Filename value", self.FileName, self.CurrentLineNumber)\r
860992ed 2681\r
9e47e6f9 2682 FileName = self._Token.replace('$(SPACE)', ' ')\r
ea98a825 2683 if FileName == T_CHAR_BRACE_R:\r
9e47e6f9 2684 self._UndoToken()\r
ca957eb5 2685 raise Warning.Expected("Filename value", self.FileName, self.CurrentLineNumber)\r
860992ed 2686\r
9e47e6f9 2687 self._VerifyFile(FileName)\r
860992ed
YZ
2688 File = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir)\r
2689 FfsFileObj.FileName.append(File.Path)\r
cfaaf99b 2690 FfsFileObj.SubAlignment.append(AlignValue)\r
860992ed 2691\r
ea98a825 2692 if self._IsToken(T_CHAR_BRACE_R):\r
9e47e6f9 2693 self._UndoToken()\r
860992ed
YZ
2694 break\r
2695\r
cfaaf99b
YZ
2696 if len(FfsFileObj.SubAlignment) == 1:\r
2697 FfsFileObj.SubAlignment = FfsFileObj.SubAlignment[0]\r
860992ed
YZ
2698 if len(FfsFileObj.FileName) == 1:\r
2699 FfsFileObj.FileName = FfsFileObj.FileName[0]\r
2700\r
9e47e6f9 2701 ## _GetFileOpts() method\r
30fdf114
LG
2702 #\r
2703 # Get options for FILE statement\r
2704 #\r
2705 # @param self The object pointer\r
2706 # @param FfsFileObj for whom options is got\r
2707 #\r
9e47e6f9
CJ
2708 def _GetFileOpts(self, FfsFileObj):\r
2709 if self._GetNextToken():\r
2710 if TokenFindPattern.match(self._Token):\r
2711 FfsFileObj.KeyStringList.append(self._Token)\r
2712 if self._IsToken(TAB_COMMA_SPLIT):\r
2713 while self._GetNextToken():\r
2714 if not TokenFindPattern.match(self._Token):\r
ca957eb5 2715 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2716 FfsFileObj.KeyStringList.append(self._Token)\r
30fdf114 2717\r
9e47e6f9 2718 if not self._IsToken(TAB_COMMA_SPLIT):\r
30fdf114
LG
2719 break\r
2720\r
2721 else:\r
9e47e6f9 2722 self._UndoToken()\r
30fdf114 2723\r
9e47e6f9 2724 if self._IsKeyword("FIXED", True):\r
30fdf114
LG
2725 FfsFileObj.Fixed = True\r
2726\r
9e47e6f9 2727 if self._IsKeyword("CHECKSUM", True):\r
30fdf114
LG
2728 FfsFileObj.CheckSum = True\r
2729\r
9e47e6f9
CJ
2730 if self._GetAlignment():\r
2731 if self._Token not in ALIGNMENTS:\r
2732 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
9053bc51 2733 #For FFS, Auto is default option same to ""\r
9e47e6f9
CJ
2734 if not self._Token == "Auto":\r
2735 FfsFileObj.Alignment = self._Token\r
30fdf114 2736\r
9e47e6f9 2737 ## _GetAlignment() method\r
30fdf114
LG
2738 #\r
2739 # Return the alignment value\r
2740 #\r
2741 # @param self The object pointer\r
2742 # @retval True Successfully find alignment\r
2743 # @retval False Not able to find alignment\r
2744 #\r
9e47e6f9
CJ
2745 def _GetAlignment(self):\r
2746 if self._IsKeyword("Align", True):\r
2747 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2748 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 2749\r
9e47e6f9 2750 if not self._GetNextToken():\r
ca957eb5 2751 raise Warning.Expected("alignment value", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2752 return True\r
2753\r
2754 return False\r
2755\r
5a6a268d 2756 ## _GetSectionData() method\r
30fdf114
LG
2757 #\r
2758 # Get section data for FILE statement\r
2759 #\r
2760 # @param self The object pointer\r
2761 # @param FfsFileObj for whom section is got\r
30fdf114 2762 #\r
5a6a268d 2763 def _GetSectionData(self, FfsFileObj):\r
9e47e6f9 2764 self._GetDefineStatements(FfsFileObj)\r
30fdf114 2765\r
30fdf114 2766 while True:\r
5a6a268d 2767 IsLeafSection = self._GetLeafSection(FfsFileObj)\r
9e47e6f9 2768 IsEncapSection = self._GetEncapsulationSec(FfsFileObj)\r
30fdf114
LG
2769 if not IsLeafSection and not IsEncapSection:\r
2770 break\r
2771\r
9e47e6f9 2772 ## _GetLeafSection() method\r
30fdf114
LG
2773 #\r
2774 # Get leaf section for Obj\r
2775 #\r
2776 # @param self The object pointer\r
2777 # @param Obj for whom leaf section is got\r
30fdf114
LG
2778 # @retval True Successfully find section statement\r
2779 # @retval False Not able to find section statement\r
2780 #\r
5a6a268d 2781 def _GetLeafSection(self, Obj):\r
30fdf114
LG
2782 OldPos = self.GetFileBufferPos()\r
2783\r
9e47e6f9 2784 if not self._IsKeyword("SECTION"):\r
30fdf114 2785 if len(Obj.SectionList) == 0:\r
ca957eb5 2786 raise Warning.Expected("SECTION", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2787 else:\r
2788 return False\r
2789\r
2790 AlignValue = None\r
9e47e6f9
CJ
2791 if self._GetAlignment():\r
2792 if self._Token not in ALIGNMENTS:\r
2793 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
2794 AlignValue = self._Token\r
30fdf114
LG
2795\r
2796 BuildNum = None\r
9e47e6f9
CJ
2797 if self._IsKeyword("BUILD_NUM"):\r
2798 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2799 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 2800\r
9e47e6f9 2801 if not self._GetNextToken():\r
ca957eb5 2802 raise Warning.Expected("Build number value", self.FileName, self.CurrentLineNumber)\r
30fdf114 2803\r
9e47e6f9 2804 BuildNum = self._Token\r
30fdf114 2805\r
9e47e6f9 2806 if self._IsKeyword("VERSION"):\r
52302d4d
LG
2807 if AlignValue == 'Auto':\r
2808 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2809 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2810 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2811 if not self._GetNextToken():\r
ca957eb5 2812 raise Warning.Expected("version", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2813 VerSectionObj = VerSection()\r
30fdf114
LG
2814 VerSectionObj.Alignment = AlignValue\r
2815 VerSectionObj.BuildNum = BuildNum\r
9e47e6f9
CJ
2816 if self._GetStringData():\r
2817 VerSectionObj.StringData = self._Token\r
30fdf114 2818 else:\r
9e47e6f9 2819 VerSectionObj.FileName = self._Token\r
30fdf114 2820 Obj.SectionList.append(VerSectionObj)\r
f7496d71 2821\r
9e47e6f9 2822 elif self._IsKeyword(BINARY_FILE_TYPE_UI):\r
52302d4d
LG
2823 if AlignValue == 'Auto':\r
2824 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2825 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2826 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2827 if not self._GetNextToken():\r
ca957eb5 2828 raise Warning.Expected("UI", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2829 UiSectionObj = UiSection()\r
30fdf114 2830 UiSectionObj.Alignment = AlignValue\r
9e47e6f9
CJ
2831 if self._GetStringData():\r
2832 UiSectionObj.StringData = self._Token\r
30fdf114 2833 else:\r
9e47e6f9 2834 UiSectionObj.FileName = self._Token\r
30fdf114
LG
2835 Obj.SectionList.append(UiSectionObj)\r
2836\r
9e47e6f9 2837 elif self._IsKeyword("FV_IMAGE"):\r
52302d4d
LG
2838 if AlignValue == 'Auto':\r
2839 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2840 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2841 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2842 if not self._GetNextToken():\r
ca957eb5 2843 raise Warning.Expected("FV name or FV file path", self.FileName, self.CurrentLineNumber)\r
30fdf114 2844\r
9e47e6f9 2845 FvName = self._Token\r
30fdf114
LG
2846 FvObj = None\r
2847\r
9e47e6f9
CJ
2848 if self._IsToken("{"):\r
2849 FvObj = FV()\r
30fdf114 2850 FvObj.UiFvName = FvName.upper()\r
9e47e6f9 2851 self._GetDefineStatements(FvObj)\r
5a6a268d 2852\r
9e47e6f9
CJ
2853 self._GetBlockStatement(FvObj)\r
2854 self._GetSetStatements(FvObj)\r
2855 self._GetFvAlignment(FvObj)\r
2856 self._GetFvAttributes(FvObj)\r
30fdf114
LG
2857\r
2858 while True:\r
9e47e6f9 2859 IsInf = self._GetInfStatement(FvObj)\r
5a6a268d 2860 IsFile = self._GetFileStatement(FvObj)\r
30fdf114
LG
2861 if not IsInf and not IsFile:\r
2862 break\r
2863\r
ea98a825 2864 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2865 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 2866\r
9e47e6f9 2867 FvImageSectionObj = FvImageSection()\r
30fdf114 2868 FvImageSectionObj.Alignment = AlignValue\r
4231a819 2869 if FvObj is not None:\r
30fdf114
LG
2870 FvImageSectionObj.Fv = FvObj\r
2871 FvImageSectionObj.FvName = None\r
2872 else:\r
2873 FvImageSectionObj.FvName = FvName.upper()\r
2874 FvImageSectionObj.FvFileName = FvName\r
2875\r
2876 Obj.SectionList.append(FvImageSectionObj)\r
2877\r
9e47e6f9 2878 elif self._IsKeyword("PEI_DEPEX_EXP") or self._IsKeyword("DXE_DEPEX_EXP") or self._IsKeyword("SMM_DEPEX_EXP"):\r
52302d4d
LG
2879 if AlignValue == 'Auto':\r
2880 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2881 DepexSectionObj = DepexSection()\r
30fdf114 2882 DepexSectionObj.Alignment = AlignValue\r
9e47e6f9 2883 DepexSectionObj.DepexType = self._Token\r
30fdf114 2884\r
9e47e6f9 2885 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2886 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2887 if not self._IsToken("{"):\r
ca957eb5 2888 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
ea98a825 2889 if not self._SkipToToken(T_CHAR_BRACE_R):\r
ca957eb5 2890 raise Warning.Expected("Depex expression ending '}'", self.FileName, self.CurrentLineNumber)\r
30fdf114 2891\r
ea98a825 2892 DepexSectionObj.Expression = self._SkippedChars.rstrip(T_CHAR_BRACE_R)\r
30fdf114
LG
2893 Obj.SectionList.append(DepexSectionObj)\r
2894\r
2895 else:\r
9e47e6f9 2896 if not self._GetNextWord():\r
ca957eb5 2897 raise Warning.Expected("section type", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2898\r
2899 # Encapsulation section appear, UndoToken and return\r
9e47e6f9 2900 if self._Token == "COMPRESS" or self._Token == "GUIDED":\r
30fdf114
LG
2901 self.SetFileBufferPos(OldPos)\r
2902 return False\r
2903\r
5a264f28
CJ
2904 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
2905 BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX}:\r
9e47e6f9
CJ
2906 raise Warning("Unknown section type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
2907 if AlignValue == 'Auto'and (not self._Token == BINARY_FILE_TYPE_PE32) and (not self._Token == BINARY_FILE_TYPE_TE):\r
52302d4d
LG
2908 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
2909\r
30fdf114 2910 # DataSection\r
9e47e6f9 2911 DataSectionObj = DataSection()\r
30fdf114 2912 DataSectionObj.Alignment = AlignValue\r
9e47e6f9 2913 DataSectionObj.SecType = self._Token\r
30fdf114 2914\r
9e47e6f9
CJ
2915 if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):\r
2916 if self._FileCouldHaveRelocFlag(Obj.FvFileType) and self._SectionCouldHaveRelocFlag(DataSectionObj.SecType):\r
2917 if self._Token == 'RELOCS_STRIPPED':\r
30fdf114
LG
2918 DataSectionObj.KeepReloc = False\r
2919 else:\r
2920 DataSectionObj.KeepReloc = True\r
2921 else:\r
2922 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
2923\r
9e47e6f9
CJ
2924 if self._IsToken(TAB_EQUAL_SPLIT):\r
2925 if not self._GetNextToken():\r
ca957eb5 2926 raise Warning.Expected("section file path", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
2927 DataSectionObj.SectFileName = self._Token\r
2928 self._VerifyFile(DataSectionObj.SectFileName)\r
30fdf114 2929 else:\r
9e47e6f9 2930 if not self._GetCglSection(DataSectionObj):\r
30fdf114
LG
2931 return False\r
2932\r
2933 Obj.SectionList.append(DataSectionObj)\r
2934\r
2935 return True\r
2936\r
9e47e6f9 2937 ## _VerifyFile\r
2bc3256c
LG
2938 #\r
2939 # Check if file exists or not:\r
2940 # If current phase if GenFds, the file must exist;\r
2941 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist\r
2942 # @param FileName: File path to be verified.\r
2943 #\r
9e47e6f9
CJ
2944 def _VerifyFile(self, FileName):\r
2945 if FileName.replace(TAB_WORKSPACE, '').find('$') != -1:\r
2bc3256c 2946 return\r
9e47e6f9 2947 if not GlobalData.gAutoGenPhase or not self._GetMacroValue(TAB_DSC_DEFINES_OUTPUT_DIRECTORY) in FileName:\r
2bc3256c
LG
2948 ErrorCode, ErrorInfo = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
2949 if ErrorCode != 0:\r
2950 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
2951\r
9e47e6f9 2952 ## _GetCglSection() method\r
30fdf114
LG
2953 #\r
2954 # Get compressed or GUIDed section for Obj\r
2955 #\r
2956 # @param self The object pointer\r
2957 # @param Obj for whom leaf section is got\r
2958 # @param AlignValue alignment value for complex section\r
2959 # @retval True Successfully find section statement\r
2960 # @retval False Not able to find section statement\r
2961 #\r
9e47e6f9 2962 def _GetCglSection(self, Obj, AlignValue = None):\r
30fdf114 2963\r
9e47e6f9 2964 if self._IsKeyword("COMPRESS"):\r
30fdf114 2965 type = "PI_STD"\r
9e47e6f9
CJ
2966 if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE"):\r
2967 type = self._Token\r
30fdf114 2968\r
9e47e6f9 2969 if not self._IsToken("{"):\r
ca957eb5 2970 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
30fdf114 2971\r
9e47e6f9 2972 CompressSectionObj = CompressSection()\r
30fdf114
LG
2973 CompressSectionObj.Alignment = AlignValue\r
2974 CompressSectionObj.CompType = type\r
2975 # Recursive sections...\r
2976 while True:\r
9e47e6f9
CJ
2977 IsLeafSection = self._GetLeafSection(CompressSectionObj)\r
2978 IsEncapSection = self._GetEncapsulationSec(CompressSectionObj)\r
30fdf114
LG
2979 if not IsLeafSection and not IsEncapSection:\r
2980 break\r
2981\r
2982\r
ea98a825 2983 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2984 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 2985 Obj.SectionList.append(CompressSectionObj)\r
30fdf114
LG
2986 return True\r
2987\r
9e47e6f9 2988 elif self._IsKeyword("GUIDED"):\r
30fdf114 2989 GuidValue = None\r
9e47e6f9 2990 if self._GetNextGuid():\r
d35773d5
YC
2991 if self._Token in GlobalData.gGuidDict:\r
2992 self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper()\r
9e47e6f9 2993 GuidValue = self._Token\r
30fdf114 2994\r
9e47e6f9
CJ
2995 AttribDict = self._GetGuidAttrib()\r
2996 if not self._IsToken("{"):\r
ca957eb5 2997 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2998 GuidSectionObj = GuidSection()\r
30fdf114
LG
2999 GuidSectionObj.Alignment = AlignValue\r
3000 GuidSectionObj.NameGuid = GuidValue\r
3001 GuidSectionObj.SectionType = "GUIDED"\r
3002 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]\r
3003 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]\r
25918452 3004 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]\r
30fdf114
LG
3005 # Recursive sections...\r
3006 while True:\r
9e47e6f9
CJ
3007 IsLeafSection = self._GetLeafSection(GuidSectionObj)\r
3008 IsEncapSection = self._GetEncapsulationSec(GuidSectionObj)\r
30fdf114
LG
3009 if not IsLeafSection and not IsEncapSection:\r
3010 break\r
3011\r
ea98a825 3012 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 3013 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3014 Obj.SectionList.append(GuidSectionObj)\r
3015\r
3016 return True\r
3017\r
3018 return False\r
3019\r
9e47e6f9 3020 ## _GetGuidAttri() method\r
30fdf114
LG
3021 #\r
3022 # Get attributes for GUID section\r
3023 #\r
3024 # @param self The object pointer\r
3025 # @retval AttribDict Dictionary of key-value pair of section attributes\r
3026 #\r
9e47e6f9 3027 def _GetGuidAttrib(self):\r
30fdf114 3028 AttribDict = {}\r
14c48571 3029 AttribDict["PROCESSING_REQUIRED"] = "NONE"\r
3030 AttribDict["AUTH_STATUS_VALID"] = "NONE"\r
25918452 3031 AttribDict["EXTRA_HEADER_SIZE"] = -1\r
9e47e6f9
CJ
3032 while self._IsKeyword("PROCESSING_REQUIRED") or self._IsKeyword("AUTH_STATUS_VALID") \\r
3033 or self._IsKeyword("EXTRA_HEADER_SIZE"):\r
3034 AttribKey = self._Token\r
30fdf114 3035\r
9e47e6f9 3036 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3037 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 3038\r
9e47e6f9 3039 if not self._GetNextToken():\r
ca957eb5 3040 raise Warning.Expected("TRUE(1)/FALSE(0)/Number", self.FileName, self.CurrentLineNumber)\r
25918452
LG
3041 elif AttribKey == "EXTRA_HEADER_SIZE":\r
3042 Base = 10\r
9e47e6f9 3043 if self._Token[0:2].upper() == "0X":\r
25918452
LG
3044 Base = 16\r
3045 try:\r
9e47e6f9 3046 AttribDict[AttribKey] = int(self._Token, Base)\r
25918452
LG
3047 continue\r
3048 except ValueError:\r
ca957eb5 3049 raise Warning.Expected("Number", self.FileName, self.CurrentLineNumber)\r
5a264f28 3050 elif self._Token.upper() not in {"TRUE", "FALSE", "1", "0"}:\r
ca957eb5 3051 raise Warning.Expected("TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3052 AttribDict[AttribKey] = self._Token\r
30fdf114
LG
3053\r
3054 return AttribDict\r
3055\r
9e47e6f9 3056 ## _GetEncapsulationSec() method\r
30fdf114
LG
3057 #\r
3058 # Get encapsulation section for FILE\r
3059 #\r
3060 # @param self The object pointer\r
3061 # @param FfsFile for whom section is got\r
3062 # @retval True Successfully find section statement\r
3063 # @retval False Not able to find section statement\r
3064 #\r
9e47e6f9 3065 def _GetEncapsulationSec(self, FfsFileObj):\r
30fdf114 3066 OldPos = self.GetFileBufferPos()\r
9e47e6f9 3067 if not self._IsKeyword("SECTION"):\r
30fdf114 3068 if len(FfsFileObj.SectionList) == 0:\r
ca957eb5 3069 raise Warning.Expected("SECTION", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3070 else:\r
3071 return False\r
3072\r
3073 AlignValue = None\r
9e47e6f9
CJ
3074 if self._GetAlignment():\r
3075 if self._Token not in ALIGNMENT_NOAUTO:\r
3076 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
3077 AlignValue = self._Token\r
30fdf114 3078\r
9e47e6f9 3079 if not self._GetCglSection(FfsFileObj, AlignValue):\r
30fdf114
LG
3080 self.SetFileBufferPos(OldPos)\r
3081 return False\r
3082 else:\r
3083 return True\r
3084\r
9e47e6f9
CJ
3085 def _GetFmp(self):\r
3086 if not self._GetNextToken():\r
a3251d84 3087 return False\r
9e47e6f9
CJ
3088 S = self._Token.upper()\r
3089 if S.startswith(TAB_SECTION_START) and not S.startswith("[FMPPAYLOAD."):\r
df81077f 3090 self.SectionParser(S)\r
9e47e6f9 3091 self._UndoToken()\r
a3251d84
YL
3092 return False\r
3093\r
9e47e6f9
CJ
3094 self._UndoToken()\r
3095 self._SkipToToken("[FMPPAYLOAD.", True)\r
3096 FmpUiName = self._GetUiName().upper()\r
a3251d84
YL
3097 if FmpUiName in self.Profile.FmpPayloadDict:\r
3098 raise Warning("Duplicated FMP UI name found: %s" % FmpUiName, self.FileName, self.CurrentLineNumber)\r
3099\r
9e47e6f9 3100 FmpData = CapsulePayload()\r
a3251d84
YL
3101 FmpData.UiName = FmpUiName\r
3102\r
9e47e6f9 3103 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 3104 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
a3251d84 3105\r
9e47e6f9 3106 if not self._GetNextToken():\r
a3251d84 3107 raise Warning("The FMP payload section is empty!", self.FileName, self.CurrentLineNumber)\r
91ae2988 3108 FmpKeyList = ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']\r
9e47e6f9
CJ
3109 while self._Token in FmpKeyList:\r
3110 Name = self._Token\r
a3251d84 3111 FmpKeyList.remove(Name)\r
9e47e6f9 3112 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3113 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
a3251d84 3114 if Name == 'IMAGE_TYPE_ID':\r
9e47e6f9 3115 if not self._GetNextGuid():\r
ca957eb5 3116 raise Warning.Expected("GUID value for IMAGE_TYPE_ID.", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3117 FmpData.ImageTypeId = self._Token\r
91ae2988 3118 elif Name == 'CERTIFICATE_GUID':\r
9e47e6f9 3119 if not self._GetNextGuid():\r
ca957eb5 3120 raise Warning.Expected("GUID value for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3121 FmpData.Certificate_Guid = self._Token\r
3122 if UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_RSA2048_SHA256_GUID and UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_PKCS7_GUID:\r
91ae2988 3123 raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)\r
a3251d84 3124 else:\r
9e47e6f9 3125 if not self._GetNextToken():\r
ca957eb5 3126 raise Warning.Expected("value of %s" % Name, self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3127 Value = self._Token\r
a3251d84 3128 if Name == 'IMAGE_HEADER_INIT_VERSION':\r
9e47e6f9 3129 if FdfParser._Verify(Name, Value, 'UINT8'):\r
91ae2988 3130 FmpData.Version = Value\r
a3251d84 3131 elif Name == 'IMAGE_INDEX':\r
9e47e6f9 3132 if FdfParser._Verify(Name, Value, 'UINT8'):\r
91ae2988 3133 FmpData.ImageIndex = Value\r
a3251d84 3134 elif Name == 'HARDWARE_INSTANCE':\r
9e47e6f9 3135 if FdfParser._Verify(Name, Value, 'UINT8'):\r
91ae2988
YZ
3136 FmpData.HardwareInstance = Value\r
3137 elif Name == 'MONOTONIC_COUNT':\r
9e47e6f9 3138 if FdfParser._Verify(Name, Value, 'UINT64'):\r
91ae2988
YZ
3139 FmpData.MonotonicCount = Value\r
3140 if FmpData.MonotonicCount.upper().startswith('0X'):\r
af881abc 3141 FmpData.MonotonicCount = int(FmpData.MonotonicCount, 16)\r
91ae2988 3142 else:\r
af881abc 3143 FmpData.MonotonicCount = int(FmpData.MonotonicCount)\r
9e47e6f9 3144 if not self._GetNextToken():\r
a3251d84
YL
3145 break\r
3146 else:\r
9e47e6f9 3147 self._UndoToken()\r
a3251d84 3148\r
91ae2988
YZ
3149 if (FmpData.MonotonicCount and not FmpData.Certificate_Guid) or (not FmpData.MonotonicCount and FmpData.Certificate_Guid):\r
3150 EdkLogger.error("FdfParser", FORMAT_INVALID, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")\r
9ce9bf53
YZ
3151\r
3152 # Only the IMAGE_TYPE_ID is required item\r
3153 if FmpKeyList and 'IMAGE_TYPE_ID' in FmpKeyList:\r
ca957eb5 3154 raise Warning("'IMAGE_TYPE_ID' in FMP payload section.", self.FileName, self.CurrentLineNumber)\r
19e3aa7a 3155 # get the Image file and Vendor code file\r
9e47e6f9 3156 self._GetFMPCapsuleData(FmpData)\r
19e3aa7a 3157 if not FmpData.ImageFile:\r
91ae2988 3158 raise Warning("Missing image file in FMP payload section.", self.FileName, self.CurrentLineNumber)\r
19e3aa7a
YZ
3159 # check whether more than one Vendor code file\r
3160 if len(FmpData.VendorCodeFile) > 1:\r
ca957eb5 3161 raise Warning("Vendor code file max of 1 per FMP payload section.", self.FileName, self.CurrentLineNumber)\r
a3251d84
YL
3162 self.Profile.FmpPayloadDict[FmpUiName] = FmpData\r
3163 return True\r
3164\r
9e47e6f9 3165 ## _GetCapsule() method\r
30fdf114
LG
3166 #\r
3167 # Get capsule section contents and store its data into capsule list of self.Profile\r
3168 #\r
3169 # @param self The object pointer\r
3170 # @retval True Successfully find a capsule\r
3171 # @retval False Not able to find a capsule\r
3172 #\r
9e47e6f9
CJ
3173 def _GetCapsule(self):\r
3174 if not self._GetNextToken():\r
30fdf114
LG
3175 return False\r
3176\r
9e47e6f9
CJ
3177 S = self._Token.upper()\r
3178 if S.startswith(TAB_SECTION_START) and not S.startswith("[CAPSULE."):\r
df81077f 3179 self.SectionParser(S)\r
9e47e6f9 3180 self._UndoToken()\r
30fdf114
LG
3181 return False\r
3182\r
9e47e6f9
CJ
3183 self._UndoToken()\r
3184 if not self._IsToken("[CAPSULE.", True):\r
30fdf114
LG
3185 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
3186 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
9e47e6f9 3187 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
ca957eb5 3188 raise Warning.Expected("[Capsule.]", self.FileName, self.CurrentLineNumber)\r
30fdf114 3189\r
9e47e6f9 3190 CapsuleObj = Capsule()\r
30fdf114 3191\r
9e47e6f9 3192 CapsuleName = self._GetUiName()\r
30fdf114 3193 if not CapsuleName:\r
ca957eb5 3194 raise Warning.Expected("capsule name", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3195\r
3196 CapsuleObj.UiCapsuleName = CapsuleName.upper()\r
3197\r
9e47e6f9 3198 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 3199 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 3200\r
9e47e6f9
CJ
3201 if self._IsKeyword("CREATE_FILE"):\r
3202 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3203 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 3204\r
9e47e6f9 3205 if not self._GetNextToken():\r
ca957eb5 3206 raise Warning.Expected("file name", self.FileName, self.CurrentLineNumber)\r
30fdf114 3207\r
9e47e6f9 3208 CapsuleObj.CreateFile = self._Token\r
30fdf114 3209\r
9e47e6f9 3210 self._GetCapsuleStatements(CapsuleObj)\r
fd171542 3211 self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj\r
30fdf114
LG
3212 return True\r
3213\r
9e47e6f9 3214 ## _GetCapsuleStatements() method\r
30fdf114
LG
3215 #\r
3216 # Get statements for capsule\r
3217 #\r
3218 # @param self The object pointer\r
3219 # @param Obj for whom statements are got\r
3220 #\r
9e47e6f9
CJ
3221 def _GetCapsuleStatements(self, Obj):\r
3222 self._GetCapsuleTokens(Obj)\r
3223 self._GetDefineStatements(Obj)\r
3224 self._GetSetStatements(Obj)\r
3225 self._GetCapsuleData(Obj)\r
30fdf114 3226\r
9e47e6f9 3227 ## _GetCapsuleTokens() method\r
30fdf114
LG
3228 #\r
3229 # Get token statements for capsule\r
3230 #\r
3231 # @param self The object pointer\r
3232 # @param Obj for whom token statements are got\r
3233 #\r
9e47e6f9
CJ
3234 def _GetCapsuleTokens(self, Obj):\r
3235 if not self._GetNextToken():\r
b303ea72 3236 return False\r
5a264f28 3237 while self._Token in {"CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"}:\r
9e47e6f9
CJ
3238 Name = self._Token.strip()\r
3239 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3240 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3241 if not self._GetNextToken():\r
ca957eb5 3242 raise Warning.Expected("value", self.FileName, self.CurrentLineNumber)\r
b303ea72 3243 if Name == 'CAPSULE_FLAGS':\r
5a264f28 3244 if not self._Token in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:\r
ca957eb5 3245 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3246 Value = self._Token.strip()\r
3247 while self._IsToken(TAB_COMMA_SPLIT):\r
3248 Value += TAB_COMMA_SPLIT\r
3249 if not self._GetNextToken():\r
ca957eb5 3250 raise Warning.Expected("value", self.FileName, self.CurrentLineNumber)\r
5a264f28 3251 if not self._Token in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:\r
ca957eb5 3252 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3253 Value += self._Token.strip()\r
e8a47801 3254 elif Name == 'OEM_CAPSULE_FLAGS':\r
9e47e6f9 3255 Value = self._Token.strip()\r
2bc3256c 3256 if not Value.upper().startswith('0X'):\r
ca957eb5 3257 raise Warning.Expected("hex value starting with 0x", self.FileName, self.CurrentLineNumber)\r
e8a47801
LG
3258 try:\r
3259 Value = int(Value, 0)\r
3260 except ValueError:\r
ca957eb5 3261 raise Warning.Expected("hex string failed to convert to value", self.FileName, self.CurrentLineNumber)\r
e8a47801 3262 if not 0x0000 <= Value <= 0xFFFF:\r
ca957eb5 3263 raise Warning.Expected("hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3264 Value = self._Token.strip()\r
b303ea72 3265 else:\r
9e47e6f9 3266 Value = self._Token.strip()\r
f7496d71 3267 Obj.TokensDict[Name] = Value\r
9e47e6f9 3268 if not self._GetNextToken():\r
b303ea72 3269 return False\r
9e47e6f9 3270 self._UndoToken()\r
30fdf114 3271\r
9e47e6f9 3272 ## _GetCapsuleData() method\r
30fdf114
LG
3273 #\r
3274 # Get capsule data for capsule\r
3275 #\r
3276 # @param self The object pointer\r
3277 # @param Obj for whom capsule data are got\r
3278 #\r
9e47e6f9 3279 def _GetCapsuleData(self, Obj):\r
30fdf114 3280 while True:\r
9e47e6f9
CJ
3281 IsInf = self._GetInfStatement(Obj, True)\r
3282 IsFile = self._GetFileStatement(Obj, True)\r
3283 IsFv = self._GetFvStatement(Obj)\r
3284 IsFd = self._GetFdStatement(Obj)\r
3285 IsAnyFile = self._GetAnyFileStatement(Obj)\r
3286 IsAfile = self._GetAfileStatement(Obj)\r
3287 IsFmp = self._GetFmpStatement(Obj)\r
a3251d84 3288 if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile or IsAfile or IsFmp):\r
30fdf114
LG
3289 break\r
3290\r
9e47e6f9 3291 ## _GetFMPCapsuleData() method\r
19e3aa7a
YZ
3292 #\r
3293 # Get capsule data for FMP capsule\r
3294 #\r
3295 # @param self The object pointer\r
3296 # @param Obj for whom capsule data are got\r
3297 #\r
9e47e6f9 3298 def _GetFMPCapsuleData(self, Obj):\r
19e3aa7a 3299 while True:\r
9e47e6f9
CJ
3300 IsFv = self._GetFvStatement(Obj, True)\r
3301 IsFd = self._GetFdStatement(Obj, True)\r
3302 IsAnyFile = self._GetAnyFileStatement(Obj, True)\r
19e3aa7a
YZ
3303 if not (IsFv or IsFd or IsAnyFile):\r
3304 break\r
3305\r
9e47e6f9 3306 ## _GetFvStatement() method\r
30fdf114
LG
3307 #\r
3308 # Get FV for capsule\r
3309 #\r
3310 # @param self The object pointer\r
3311 # @param CapsuleObj for whom FV is got\r
3312 # @retval True Successfully find a FV statement\r
3313 # @retval False Not able to find a FV statement\r
3314 #\r
9e47e6f9
CJ
3315 def _GetFvStatement(self, CapsuleObj, FMPCapsule = False):\r
3316 if not self._IsKeyword(BINARY_FILE_TYPE_FV):\r
30fdf114
LG
3317 return False\r
3318\r
9e47e6f9 3319 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3320 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 3321\r
9e47e6f9 3322 if not self._GetNextToken():\r
ca957eb5 3323 raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)\r
30fdf114 3324\r
9e47e6f9 3325 if self._Token.upper() not in self.Profile.FvDict:\r
2bcc713e
LG
3326 raise Warning("FV name does not exist", self.FileName, self.CurrentLineNumber)\r
3327\r
9e47e6f9
CJ
3328 myCapsuleFv = CapsuleFv()\r
3329 myCapsuleFv.FvName = self._Token\r
19e3aa7a
YZ
3330 if FMPCapsule:\r
3331 if not CapsuleObj.ImageFile:\r
9e47e6f9 3332 CapsuleObj.ImageFile.append(myCapsuleFv)\r
19e3aa7a 3333 else:\r
9e47e6f9 3334 CapsuleObj.VendorCodeFile.append(myCapsuleFv)\r
19e3aa7a 3335 else:\r
9e47e6f9 3336 CapsuleObj.CapsuleDataList.append(myCapsuleFv)\r
30fdf114
LG
3337 return True\r
3338\r
9e47e6f9 3339 ## _GetFdStatement() method\r
b36d134f
LG
3340 #\r
3341 # Get FD for capsule\r
3342 #\r
3343 # @param self The object pointer\r
3344 # @param CapsuleObj for whom FD is got\r
3345 # @retval True Successfully find a FD statement\r
3346 # @retval False Not able to find a FD statement\r
3347 #\r
9e47e6f9
CJ
3348 def _GetFdStatement(self, CapsuleObj, FMPCapsule = False):\r
3349 if not self._IsKeyword("FD"):\r
b36d134f
LG
3350 return False\r
3351\r
9e47e6f9 3352 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3353 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
b36d134f 3354\r
9e47e6f9 3355 if not self._GetNextToken():\r
ca957eb5 3356 raise Warning.Expected("FD name", self.FileName, self.CurrentLineNumber)\r
b36d134f 3357\r
9e47e6f9 3358 if self._Token.upper() not in self.Profile.FdDict:\r
2bcc713e
LG
3359 raise Warning("FD name does not exist", self.FileName, self.CurrentLineNumber)\r
3360\r
9e47e6f9
CJ
3361 myCapsuleFd = CapsuleFd()\r
3362 myCapsuleFd.FdName = self._Token\r
19e3aa7a
YZ
3363 if FMPCapsule:\r
3364 if not CapsuleObj.ImageFile:\r
9e47e6f9 3365 CapsuleObj.ImageFile.append(myCapsuleFd)\r
19e3aa7a 3366 else:\r
9e47e6f9 3367 CapsuleObj.VendorCodeFile.append(myCapsuleFd)\r
19e3aa7a 3368 else:\r
9e47e6f9 3369 CapsuleObj.CapsuleDataList.append(myCapsuleFd)\r
b36d134f
LG
3370 return True\r
3371\r
9e47e6f9
CJ
3372 def _GetFmpStatement(self, CapsuleObj):\r
3373 if not self._IsKeyword("FMP_PAYLOAD"):\r
3374 if not self._IsKeyword("FMP"):\r
df81077f 3375 return False\r
b36d134f 3376\r
9e47e6f9
CJ
3377 if not self._IsKeyword("PAYLOAD"):\r
3378 self._UndoToken()\r
df81077f 3379 return False\r
b36d134f 3380\r
9e47e6f9 3381 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3382 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
a3251d84 3383\r
9e47e6f9 3384 if not self._GetNextToken():\r
ca957eb5 3385 raise Warning.Expected("payload name after FMP_PAYLOAD =", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3386 Payload = self._Token.upper()\r
a3251d84 3387 if Payload not in self.Profile.FmpPayloadDict:\r
9e47e6f9 3388 raise Warning("This FMP Payload does not exist: %s" % self._Token, self.FileName, self.CurrentLineNumber)\r
a3251d84
YL
3389 CapsuleObj.FmpPayloadList.append(self.Profile.FmpPayloadDict[Payload])\r
3390 return True\r
3391\r
9e47e6f9
CJ
3392 def _ParseRawFileStatement(self):\r
3393 if not self._IsKeyword("FILE"):\r
a3251d84
YL
3394 return None\r
3395\r
9e47e6f9
CJ
3396 if not self._IsKeyword("DATA"):\r
3397 self._UndoToken()\r
a3251d84 3398 return None\r
b36d134f 3399\r
9e47e6f9 3400 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3401 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
b36d134f 3402\r
9e47e6f9 3403 if not self._GetNextToken():\r
ca957eb5 3404 raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber)\r
f7496d71 3405\r
9e47e6f9
CJ
3406 AnyFileName = self._Token\r
3407 self._VerifyFile(AnyFileName)\r
35217a33 3408\r
94e4bcbb
YZ
3409 if not os.path.isabs(AnyFileName):\r
3410 AnyFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, AnyFileName)\r
3411\r
a3251d84
YL
3412 return AnyFileName\r
3413\r
9e47e6f9 3414 ## _GetAnyFileStatement() method\r
a3251d84
YL
3415 #\r
3416 # Get AnyFile for capsule\r
3417 #\r
3418 # @param self The object pointer\r
3419 # @param CapsuleObj for whom AnyFile is got\r
3420 # @retval True Successfully find a Anyfile statement\r
3421 # @retval False Not able to find a AnyFile statement\r
3422 #\r
9e47e6f9
CJ
3423 def _GetAnyFileStatement(self, CapsuleObj, FMPCapsule = False):\r
3424 AnyFileName = self._ParseRawFileStatement()\r
a3251d84
YL
3425 if not AnyFileName:\r
3426 return False\r
b36d134f 3427\r
9e47e6f9
CJ
3428 myCapsuleAnyFile = CapsuleAnyFile()\r
3429 myCapsuleAnyFile.FileName = AnyFileName\r
19e3aa7a
YZ
3430 if FMPCapsule:\r
3431 if not CapsuleObj.ImageFile:\r
9e47e6f9 3432 CapsuleObj.ImageFile.append(myCapsuleAnyFile)\r
19e3aa7a 3433 else:\r
9e47e6f9 3434 CapsuleObj.VendorCodeFile.append(myCapsuleAnyFile)\r
19e3aa7a 3435 else:\r
9e47e6f9 3436 CapsuleObj.CapsuleDataList.append(myCapsuleAnyFile)\r
b36d134f 3437 return True\r
f7496d71 3438\r
9e47e6f9 3439 ## _GetAfileStatement() method\r
2bc3256c
LG
3440 #\r
3441 # Get Afile for capsule\r
3442 #\r
3443 # @param self The object pointer\r
3444 # @param CapsuleObj for whom Afile is got\r
3445 # @retval True Successfully find a Afile statement\r
3446 # @retval False Not able to find a Afile statement\r
3447 #\r
9e47e6f9
CJ
3448 def _GetAfileStatement(self, CapsuleObj):\r
3449 if not self._IsKeyword("APPEND"):\r
2bc3256c
LG
3450 return False\r
3451\r
9e47e6f9 3452 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3453 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
2bc3256c 3454\r
9e47e6f9 3455 if not self._GetNextToken():\r
ca957eb5 3456 raise Warning.Expected("Afile name", self.FileName, self.CurrentLineNumber)\r
f7496d71 3457\r
9e47e6f9 3458 AfileName = self._Token\r
2bc3256c 3459 AfileBaseName = os.path.basename(AfileName)\r
f7496d71 3460\r
5a264f28 3461 if os.path.splitext(AfileBaseName)[1] not in {".bin", ".BIN", ".Bin", ".dat", ".DAT", ".Dat", ".data", ".DATA", ".Data"}:\r
91fa33ee 3462 raise Warning('invalid binary file type, should be one of "bin",BINARY_FILE_TYPE_BIN,"Bin","dat","DAT","Dat","data","DATA","Data"', \\r
2bc3256c 3463 self.FileName, self.CurrentLineNumber)\r
f7496d71 3464\r
2bc3256c
LG
3465 if not os.path.isabs(AfileName):\r
3466 AfileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AfileName)\r
9e47e6f9 3467 self._VerifyFile(AfileName)\r
2bc3256c
LG
3468 else:\r
3469 if not os.path.exists(AfileName):\r
3470 raise Warning('%s does not exist' % AfileName, self.FileName, self.CurrentLineNumber)\r
3471 else:\r
3472 pass\r
3473\r
9e47e6f9
CJ
3474 myCapsuleAfile = CapsuleAfile()\r
3475 myCapsuleAfile.FileName = AfileName\r
3476 CapsuleObj.CapsuleDataList.append(myCapsuleAfile)\r
2bc3256c 3477 return True\r
b36d134f 3478\r
9e47e6f9 3479 ## _GetRule() method\r
30fdf114
LG
3480 #\r
3481 # Get Rule section contents and store its data into rule list of self.Profile\r
3482 #\r
3483 # @param self The object pointer\r
3484 # @retval True Successfully find a Rule\r
3485 # @retval False Not able to find a Rule\r
3486 #\r
9e47e6f9
CJ
3487 def _GetRule(self):\r
3488 if not self._GetNextToken():\r
30fdf114
LG
3489 return False\r
3490\r
9e47e6f9
CJ
3491 S = self._Token.upper()\r
3492 if S.startswith(TAB_SECTION_START) and not S.startswith("[RULE."):\r
df81077f 3493 self.SectionParser(S)\r
9e47e6f9 3494 self._UndoToken()\r
30fdf114 3495 return False\r
9e47e6f9
CJ
3496 self._UndoToken()\r
3497 if not self._IsToken("[Rule.", True):\r
30fdf114
LG
3498 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
3499 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
9e47e6f9 3500 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
ca957eb5 3501 raise Warning.Expected("[Rule.]", self.FileName, self.CurrentLineNumber)\r
30fdf114 3502\r
9e47e6f9 3503 if not self._SkipToToken(TAB_SPLIT):\r
ca957eb5 3504 raise Warning.Expected("'.'", self.FileName, self.CurrentLineNumber)\r
30fdf114 3505\r
9e47e6f9 3506 Arch = self._SkippedChars.rstrip(TAB_SPLIT)\r
30fdf114 3507\r
9e47e6f9 3508 ModuleType = self._GetModuleType()\r
30fdf114
LG
3509\r
3510 TemplateName = ""\r
9e47e6f9
CJ
3511 if self._IsToken(TAB_SPLIT):\r
3512 if not self._GetNextWord():\r
ca957eb5 3513 raise Warning.Expected("template name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3514 TemplateName = self._Token\r
30fdf114 3515\r
9e47e6f9 3516 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 3517 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 3518\r
9e47e6f9 3519 RuleObj = self._GetRuleFileStatements()\r
30fdf114
LG
3520 RuleObj.Arch = Arch.upper()\r
3521 RuleObj.ModuleType = ModuleType\r
3522 RuleObj.TemplateName = TemplateName\r
9e47e6f9 3523 if TemplateName == '':\r
30fdf114 3524 self.Profile.RuleDict['RULE' + \\r
9e47e6f9 3525 TAB_SPLIT + \\r
30fdf114 3526 Arch.upper() + \\r
9e47e6f9 3527 TAB_SPLIT + \\r
30fdf114 3528 ModuleType.upper() ] = RuleObj\r
9e47e6f9 3529 else:\r
30fdf114 3530 self.Profile.RuleDict['RULE' + \\r
9e47e6f9 3531 TAB_SPLIT + \\r
30fdf114 3532 Arch.upper() + \\r
9e47e6f9 3533 TAB_SPLIT + \\r
30fdf114 3534 ModuleType.upper() + \\r
9e47e6f9 3535 TAB_SPLIT + \\r
30fdf114 3536 TemplateName.upper() ] = RuleObj\r
30fdf114
LG
3537 return True\r
3538\r
9e47e6f9 3539 ## _GetModuleType() method\r
30fdf114
LG
3540 #\r
3541 # Return the module type\r
3542 #\r
3543 # @param self The object pointer\r
3544 # @retval string module type\r
3545 #\r
9e47e6f9
CJ
3546 def _GetModuleType(self):\r
3547 if not self._GetNextWord():\r
ca957eb5 3548 raise Warning.Expected("Module type", self.FileName, self.CurrentLineNumber)\r
5a264f28
CJ
3549 if self._Token.upper() not in {\r
3550 SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM,\r
3551 SUP_MODULE_DXE_CORE, SUP_MODULE_DXE_DRIVER,\r
3552 SUP_MODULE_DXE_SAL_DRIVER, SUP_MODULE_DXE_SMM_DRIVER,\r
3553 SUP_MODULE_DXE_RUNTIME_DRIVER, SUP_MODULE_UEFI_DRIVER,\r
a79841a0 3554 SUP_MODULE_UEFI_APPLICATION, SUP_MODULE_USER_DEFINED, SUP_MODULE_HOST_APPLICATION,\r
5a264f28
CJ
3555 TAB_DEFAULT, SUP_MODULE_BASE,\r
3556 EDK_COMPONENT_TYPE_SECURITY_CORE,\r
3557 EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER,\r
3558 EDK_COMPONENT_TYPE_PIC_PEIM,\r
3559 EDK_COMPONENT_TYPE_RELOCATABLE_PEIM, "PE32_PEIM",\r
3560 EDK_COMPONENT_TYPE_BS_DRIVER, EDK_COMPONENT_TYPE_RT_DRIVER,\r
3561 EDK_COMPONENT_TYPE_SAL_RT_DRIVER,\r
3562 EDK_COMPONENT_TYPE_APPLICATION, "ACPITABLE",\r
3563 SUP_MODULE_SMM_CORE, SUP_MODULE_MM_STANDALONE,\r
3564 SUP_MODULE_MM_CORE_STANDALONE}:\r
9e47e6f9
CJ
3565 raise Warning("Unknown Module type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
3566 return self._Token\r
30fdf114 3567\r
9e47e6f9 3568 ## _GetFileExtension() method\r
30fdf114
LG
3569 #\r
3570 # Return the file extension\r
3571 #\r
3572 # @param self The object pointer\r
3573 # @retval string file name extension\r
3574 #\r
9e47e6f9
CJ
3575 def _GetFileExtension(self):\r
3576 if not self._IsToken(TAB_SPLIT):\r
ca957eb5 3577 raise Warning.Expected("'.'", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3578\r
3579 Ext = ""\r
9e47e6f9
CJ
3580 if self._GetNextToken():\r
3581 if FileExtensionPattern.match(self._Token):\r
3582 Ext = self._Token\r
3583 return TAB_SPLIT + Ext\r
30fdf114 3584 else:\r
9e47e6f9 3585 raise Warning("Unknown file extension '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3586\r
3587 else:\r
ca957eb5 3588 raise Warning.Expected("file extension", self.FileName, self.CurrentLineNumber)\r
30fdf114 3589\r
9e47e6f9 3590 ## _GetRuleFileStatement() method\r
30fdf114
LG
3591 #\r
3592 # Get rule contents\r
3593 #\r
3594 # @param self The object pointer\r
3595 # @retval Rule Rule object\r
3596 #\r
9e47e6f9
CJ
3597 def _GetRuleFileStatements(self):\r
3598 if not self._IsKeyword("FILE"):\r
ca957eb5 3599 raise Warning.Expected("FILE", self.FileName, self.CurrentLineNumber)\r
30fdf114 3600\r
9e47e6f9 3601 if not self._GetNextWord():\r
ca957eb5 3602 raise Warning.Expected("FFS type", self.FileName, self.CurrentLineNumber)\r
30fdf114 3603\r
9e47e6f9 3604 Type = self._Token.strip().upper()\r
5a264f28
CJ
3605 if Type not in {"RAW", "FREEFORM", SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM,\r
3606 "PEI_DXE_COMBO", "DRIVER", SUP_MODULE_DXE_CORE, EDK_COMPONENT_TYPE_APPLICATION,\r
3607 "FV_IMAGE", "SMM", SUP_MODULE_SMM_CORE, SUP_MODULE_MM_STANDALONE,\r
3608 SUP_MODULE_MM_CORE_STANDALONE}:\r
9e47e6f9 3609 raise Warning("Unknown FV type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114 3610\r
9e47e6f9 3611 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3612 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 3613\r
9e47e6f9
CJ
3614 if not self._IsKeyword("$(NAMED_GUID)"):\r
3615 if not self._GetNextWord():\r
6b74ccf0
FZ
3616 NamedGuid = self._CurrentLine()[self.CurrentOffsetWithinLine:].split()[0].strip()\r
3617 if GlobalData.gGuidPatternEnd.match(NamedGuid):\r
3618 self.CurrentOffsetWithinLine += len(NamedGuid)\r
3619 self._Token = NamedGuid\r
3620 else:\r
3621 raise Warning.Expected("$(NAMED_GUID)", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3622 if self._Token == 'PCD':\r
3623 if not self._IsToken("("):\r
ca957eb5 3624 raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3625 PcdPair = self._GetNextPcdSettings()\r
3626 if not self._IsToken(")"):\r
ca957eb5 3627 raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3628 self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'\r
f7496d71 3629\r
9e47e6f9 3630 NameGuid = self._Token\r
30fdf114
LG
3631\r
3632 KeepReloc = None\r
9e47e6f9
CJ
3633 if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):\r
3634 if self._FileCouldHaveRelocFlag(Type):\r
3635 if self._Token == 'RELOCS_STRIPPED':\r
30fdf114
LG
3636 KeepReloc = False\r
3637 else:\r
3638 KeepReloc = True\r
3639 else:\r
3640 raise Warning("File type %s could not have reloc strip flag%d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3641\r
3642 KeyStringList = []\r
9e47e6f9
CJ
3643 if self._GetNextToken():\r
3644 if TokenFindPattern.match(self._Token):\r
3645 KeyStringList.append(self._Token)\r
3646 if self._IsToken(TAB_COMMA_SPLIT):\r
3647 while self._GetNextToken():\r
3648 if not TokenFindPattern.match(self._Token):\r
ca957eb5 3649 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3650 KeyStringList.append(self._Token)\r
30fdf114 3651\r
9e47e6f9 3652 if not self._IsToken(TAB_COMMA_SPLIT):\r
30fdf114
LG
3653 break\r
3654\r
3655 else:\r
9e47e6f9 3656 self._UndoToken()\r
30fdf114
LG
3657\r
3658\r
3659 Fixed = False\r
9e47e6f9 3660 if self._IsKeyword("Fixed", True):\r
30fdf114
LG
3661 Fixed = True\r
3662\r
3663 CheckSum = False\r
9e47e6f9 3664 if self._IsKeyword("CheckSum", True):\r
30fdf114
LG
3665 CheckSum = True\r
3666\r
3667 AlignValue = ""\r
9e47e6f9
CJ
3668 if self._GetAlignment():\r
3669 if self._Token not in ALIGNMENTS:\r
3670 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
52302d4d 3671 #For FFS, Auto is default option same to ""\r
9e47e6f9
CJ
3672 if not self._Token == "Auto":\r
3673 AlignValue = self._Token\r
30fdf114 3674\r
9e47e6f9 3675 if self._IsToken("{"):\r
30fdf114 3676 # Complex file rule expected\r
9e47e6f9
CJ
3677 NewRule = RuleComplexFile()\r
3678 NewRule.FvFileType = Type\r
3679 NewRule.NameGuid = NameGuid\r
3680 NewRule.Alignment = AlignValue\r
3681 NewRule.CheckSum = CheckSum\r
3682 NewRule.Fixed = Fixed\r
3683 NewRule.KeyStringList = KeyStringList\r
4231a819 3684 if KeepReloc is not None:\r
9e47e6f9 3685 NewRule.KeepReloc = KeepReloc\r
30fdf114
LG
3686\r
3687 while True:\r
9e47e6f9
CJ
3688 IsEncapsulate = self._GetRuleEncapsulationSection(NewRule)\r
3689 IsLeaf = self._GetEfiSection(NewRule)\r
30fdf114
LG
3690 if not IsEncapsulate and not IsLeaf:\r
3691 break\r
3692\r
ea98a825 3693 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 3694 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 3695\r
9e47e6f9 3696 return NewRule\r
30fdf114 3697\r
30fdf114
LG
3698 else:\r
3699 # Simple file rule expected\r
9e47e6f9 3700 if not self._GetNextWord():\r
ca957eb5 3701 raise Warning.Expected("leaf section type", self.FileName, self.CurrentLineNumber)\r
30fdf114 3702\r
9e47e6f9 3703 SectionName = self._Token\r
30fdf114 3704\r
5a264f28
CJ
3705 if SectionName not in {\r
3706 "COMPAT16", BINARY_FILE_TYPE_PE32,\r
3707 BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE",\r
3708 "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI,\r
3709 BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID",\r
3710 BINARY_FILE_TYPE_SMM_DEPEX}:\r
30fdf114
LG
3711 raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber)\r
3712\r
3713\r
9e47e6f9 3714 if self._IsKeyword("Fixed", True):\r
30fdf114
LG
3715 Fixed = True\r
3716\r
9e47e6f9 3717 if self._IsKeyword("CheckSum", True):\r
30fdf114
LG
3718 CheckSum = True\r
3719\r
52302d4d 3720 SectAlignment = ""\r
9e47e6f9
CJ
3721 if self._GetAlignment():\r
3722 if self._Token not in ALIGNMENTS:\r
3723 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
3724 if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_TE):\r
52302d4d 3725 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3726 SectAlignment = self._Token\r
52302d4d
LG
3727\r
3728 Ext = None\r
9e47e6f9
CJ
3729 if self._IsToken(TAB_VALUE_SPLIT):\r
3730 Ext = self._GetFileExtension()\r
3731 elif not self._GetNextToken():\r
ca957eb5 3732 raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber)\r
30fdf114 3733\r
9e47e6f9
CJ
3734 NewRule = RuleSimpleFile()\r
3735 NewRule.SectionType = SectionName\r
3736 NewRule.FvFileType = Type\r
3737 NewRule.NameGuid = NameGuid\r
3738 NewRule.Alignment = AlignValue\r
3739 NewRule.SectAlignment = SectAlignment\r
3740 NewRule.CheckSum = CheckSum\r
3741 NewRule.Fixed = Fixed\r
3742 NewRule.KeyStringList = KeyStringList\r
4231a819 3743 if KeepReloc is not None:\r
9e47e6f9
CJ
3744 NewRule.KeepReloc = KeepReloc\r
3745 NewRule.FileExtension = Ext\r
3746 NewRule.FileName = self._Token\r
3747 return NewRule\r
30fdf114 3748\r
9e47e6f9 3749 ## _GetEfiSection() method\r
30fdf114
LG
3750 #\r
3751 # Get section list for Rule\r
3752 #\r
3753 # @param self The object pointer\r
3754 # @param Obj for whom section is got\r
3755 # @retval True Successfully find section statement\r
3756 # @retval False Not able to find section statement\r
3757 #\r
9e47e6f9 3758 def _GetEfiSection(self, Obj):\r
30fdf114 3759 OldPos = self.GetFileBufferPos()\r
04797875 3760 EfiSectionObj = EfiSection()\r
9e47e6f9 3761 if not self._GetNextWord():\r
04797875
FZ
3762 CurrentLine = self._CurrentLine()[self.CurrentOffsetWithinLine:].split()[0].strip()\r
3763 if self._Token == '{' and Obj.FvFileType == "RAW" and TAB_SPLIT in CurrentLine:\r
3764 if self._IsToken(TAB_VALUE_SPLIT):\r
3765 EfiSectionObj.FileExtension = self._GetFileExtension()\r
3766 elif self._GetNextToken():\r
3767 EfiSectionObj.FileName = self._Token\r
3768 EfiSectionObj.SectionType = BINARY_FILE_TYPE_RAW\r
3769 Obj.SectionList.append(EfiSectionObj)\r
3770 return True\r
3771 else:\r
3772 return False\r
9e47e6f9 3773 SectionName = self._Token\r
30fdf114 3774\r
5a264f28
CJ
3775 if SectionName not in {\r
3776 "COMPAT16", BINARY_FILE_TYPE_PE32,\r
3777 BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE",\r
3778 "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI,\r
3779 BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID",\r
3780 BINARY_FILE_TYPE_SMM_DEPEX, BINARY_FILE_TYPE_GUID}:\r
9e47e6f9 3781 self._UndoToken()\r
30fdf114
LG
3782 return False\r
3783\r
3784 if SectionName == "FV_IMAGE":\r
9e47e6f9
CJ
3785 FvImageSectionObj = FvImageSection()\r
3786 if self._IsKeyword("FV_IMAGE"):\r
30fdf114 3787 pass\r
9e47e6f9
CJ
3788 if self._IsToken("{"):\r
3789 FvObj = FV()\r
3790 self._GetDefineStatements(FvObj)\r
3791 self._GetBlockStatement(FvObj)\r
3792 self._GetSetStatements(FvObj)\r
3793 self._GetFvAlignment(FvObj)\r
3794 self._GetFvAttributes(FvObj)\r
3795 self._GetAprioriSection(FvObj)\r
3796 self._GetAprioriSection(FvObj)\r
30fdf114
LG
3797\r
3798 while True:\r
9e47e6f9
CJ
3799 IsInf = self._GetInfStatement(FvObj)\r
3800 IsFile = self._GetFileStatement(FvObj)\r
30fdf114
LG
3801 if not IsInf and not IsFile:\r
3802 break\r
3803\r
ea98a825 3804 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 3805 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3806 FvImageSectionObj.Fv = FvObj\r
3807 FvImageSectionObj.FvName = None\r
3808\r
3809 else:\r
9e47e6f9 3810 if not self._IsKeyword(BINARY_FILE_TYPE_FV):\r
ca957eb5 3811 raise Warning.Expected("'FV'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3812 FvImageSectionObj.FvFileType = self._Token\r
3813\r
3814 if self._GetAlignment():\r
3815 if self._Token not in ALIGNMENT_NOAUTO:\r
3816 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
3817 FvImageSectionObj.Alignment = self._Token\r
3818\r
3819 if self._IsToken(TAB_VALUE_SPLIT):\r
3820 FvImageSectionObj.FvFileExtension = self._GetFileExtension()\r
3821 elif self._GetNextToken():\r
5a264f28 3822 if self._Token not in {\r
ea98a825 3823 T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32,\r
5a264f28
CJ
3824 BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE,\r
3825 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,\r
3826 BINARY_FILE_TYPE_UI, "VERSION",\r
3827 BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID,\r
3828 BINARY_FILE_TYPE_SMM_DEPEX}:\r
9e47e6f9 3829 FvImageSectionObj.FvFileName = self._Token\r
30fdf114 3830 else:\r
9e47e6f9 3831 self._UndoToken()\r
30fdf114 3832 else:\r
ca957eb5 3833 raise Warning.Expected("FV file name", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3834\r
3835 Obj.SectionList.append(FvImageSectionObj)\r
3836 return True\r
3837\r
30fdf114
LG
3838 EfiSectionObj.SectionType = SectionName\r
3839\r
9e47e6f9 3840 if not self._GetNextToken():\r
ca957eb5 3841 raise Warning.Expected("file type", self.FileName, self.CurrentLineNumber)\r
30fdf114 3842\r
9e47e6f9
CJ
3843 if self._Token == "STRING":\r
3844 if not self._RuleSectionCouldHaveString(EfiSectionObj.SectionType):\r
30fdf114
LG
3845 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3846\r
9e47e6f9 3847 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3848 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 3849\r
9e47e6f9 3850 if not self._GetNextToken():\r
ca957eb5 3851 raise Warning.Expected("Quoted String", self.FileName, self.CurrentLineNumber)\r
30fdf114 3852\r
9e47e6f9
CJ
3853 if self._GetStringData():\r
3854 EfiSectionObj.StringData = self._Token\r
30fdf114 3855\r
9e47e6f9
CJ
3856 if self._IsKeyword("BUILD_NUM"):\r
3857 if not self._RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):\r
30fdf114
LG
3858 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3859\r
9e47e6f9 3860 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3861 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3862 if not self._GetNextToken():\r
ca957eb5 3863 raise Warning.Expected("Build number", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3864 EfiSectionObj.BuildNum = self._Token\r
30fdf114
LG
3865\r
3866 else:\r
9e47e6f9
CJ
3867 EfiSectionObj.FileType = self._Token\r
3868 self._CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType)\r
30fdf114 3869\r
9e47e6f9
CJ
3870 if self._IsKeyword("Optional"):\r
3871 if not self._RuleSectionCouldBeOptional(EfiSectionObj.SectionType):\r
30fdf114
LG
3872 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3873 EfiSectionObj.Optional = True\r
3874\r
9e47e6f9
CJ
3875 if self._IsKeyword("BUILD_NUM"):\r
3876 if not self._RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):\r
30fdf114
LG
3877 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3878\r
9e47e6f9 3879 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3880 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3881 if not self._GetNextToken():\r
ca957eb5 3882 raise Warning.Expected("Build number", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3883 EfiSectionObj.BuildNum = self._Token\r
30fdf114 3884\r
9e47e6f9
CJ
3885 if self._GetAlignment():\r
3886 if self._Token not in ALIGNMENTS:\r
3887 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
3888 if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_TE):\r
52302d4d 3889 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3890 EfiSectionObj.Alignment = self._Token\r
30fdf114 3891\r
9e47e6f9
CJ
3892 if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):\r
3893 if self._SectionCouldHaveRelocFlag(EfiSectionObj.SectionType):\r
3894 if self._Token == 'RELOCS_STRIPPED':\r
30fdf114
LG
3895 EfiSectionObj.KeepReloc = False\r
3896 else:\r
3897 EfiSectionObj.KeepReloc = True\r
4231a819 3898 if Obj.KeepReloc is not None and Obj.KeepReloc != EfiSectionObj.KeepReloc:\r
30fdf114
LG
3899 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)\r
3900 else:\r
3901 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)\r
3902\r
3903\r
9e47e6f9
CJ
3904 if self._IsToken(TAB_VALUE_SPLIT):\r
3905 EfiSectionObj.FileExtension = self._GetFileExtension()\r
3906 elif self._GetNextToken():\r
5a264f28 3907 if self._Token not in {\r
ea98a825 3908 T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32,\r
5a264f28
CJ
3909 BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE,\r
3910 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,\r
3911 BINARY_FILE_TYPE_UI, "VERSION",\r
3912 BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID,\r
3913 BINARY_FILE_TYPE_SMM_DEPEX}:\r
f7496d71 3914\r
9e47e6f9
CJ
3915 if self._Token.startswith('PCD'):\r
3916 self._UndoToken()\r
3917 self._GetNextWord()\r
f7496d71 3918\r
9e47e6f9
CJ
3919 if self._Token == 'PCD':\r
3920 if not self._IsToken("("):\r
ca957eb5 3921 raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3922 PcdPair = self._GetNextPcdSettings()\r
3923 if not self._IsToken(")"):\r
ca957eb5 3924 raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3925 self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'\r
f7496d71 3926\r
9e47e6f9 3927 EfiSectionObj.FileName = self._Token\r
f7496d71 3928\r
30fdf114 3929 else:\r
9e47e6f9 3930 self._UndoToken()\r
30fdf114 3931 else:\r
ca957eb5 3932 raise Warning.Expected("section file name", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3933\r
3934 Obj.SectionList.append(EfiSectionObj)\r
3935 return True\r
3936\r
9e47e6f9 3937 ## _RuleSectionCouldBeOptional() method\r
30fdf114
LG
3938 #\r
3939 # Get whether a section could be optional\r
3940 #\r
30fdf114
LG
3941 # @param SectionType The section type to check\r
3942 # @retval True section could be optional\r
3943 # @retval False section never optional\r
3944 #\r
5bcf1d56 3945 @staticmethod\r
9e47e6f9 3946 def _RuleSectionCouldBeOptional(SectionType):\r
5a264f28 3947 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
3948 return True\r
3949 else:\r
3950 return False\r
3951\r
9e47e6f9 3952 ## _RuleSectionCouldHaveBuildNum() method\r
30fdf114
LG
3953 #\r
3954 # Get whether a section could have build number information\r
3955 #\r
30fdf114
LG
3956 # @param SectionType The section type to check\r
3957 # @retval True section could have build number information\r
3958 # @retval False section never have build number information\r
3959 #\r
5bcf1d56 3960 @staticmethod\r
9e47e6f9 3961 def _RuleSectionCouldHaveBuildNum(SectionType):\r
5a264f28 3962 if SectionType == "VERSION":\r
30fdf114
LG
3963 return True\r
3964 else:\r
3965 return False\r
3966\r
9e47e6f9 3967 ## _RuleSectionCouldHaveString() method\r
30fdf114
LG
3968 #\r
3969 # Get whether a section could have string\r
3970 #\r
30fdf114
LG
3971 # @param SectionType The section type to check\r
3972 # @retval True section could have string\r
3973 # @retval False section never have string\r
3974 #\r
5bcf1d56 3975 @staticmethod\r
9e47e6f9 3976 def _RuleSectionCouldHaveString(SectionType):\r
5a264f28 3977 if SectionType in {BINARY_FILE_TYPE_UI, "VERSION"}:\r
30fdf114
LG
3978 return True\r
3979 else:\r
3980 return False\r
3981\r
9e47e6f9 3982 ## _CheckRuleSectionFileType() method\r
30fdf114
LG
3983 #\r
3984 # Get whether a section matches a file type\r
3985 #\r
3986 # @param self The object pointer\r
3987 # @param SectionType The section type to check\r
3988 # @param FileType The file type to check\r
3989 #\r
9e47e6f9 3990 def _CheckRuleSectionFileType(self, SectionType, FileType):\r
ca957eb5 3991 WarningString = "Incorrect section file type '%s'"\r
30fdf114 3992 if SectionType == "COMPAT16":\r
5a264f28 3993 if FileType not in {"COMPAT16", "SEC_COMPAT16"}:\r
ca957eb5 3994 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 3995 elif SectionType == BINARY_FILE_TYPE_PE32:\r
5a264f28 3996 if FileType not in {BINARY_FILE_TYPE_PE32, "SEC_PE32"}:\r
ca957eb5 3997 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 3998 elif SectionType == BINARY_FILE_TYPE_PIC:\r
5a264f28 3999 if FileType not in {BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_PIC}:\r
ca957eb5 4000 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 4001 elif SectionType == BINARY_FILE_TYPE_TE:\r
5a264f28 4002 if FileType not in {BINARY_FILE_TYPE_TE, "SEC_TE"}:\r
ca957eb5 4003 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
30fdf114 4004 elif SectionType == "RAW":\r
5a264f28 4005 if FileType not in {BINARY_FILE_TYPE_BIN, "SEC_BIN", "RAW", "ASL", "ACPI"}:\r
ca957eb5 4006 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 4007 elif SectionType == BINARY_FILE_TYPE_DXE_DEPEX or SectionType == BINARY_FILE_TYPE_SMM_DEPEX:\r
5a264f28 4008 if FileType not in {BINARY_FILE_TYPE_DXE_DEPEX, "SEC_DXE_DEPEX", BINARY_FILE_TYPE_SMM_DEPEX}:\r
ca957eb5 4009 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 4010 elif SectionType == BINARY_FILE_TYPE_UI:\r
5a264f28 4011 if FileType not in {BINARY_FILE_TYPE_UI, "SEC_UI"}:\r
ca957eb5 4012 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
30fdf114 4013 elif SectionType == "VERSION":\r
5a264f28 4014 if FileType not in {"VERSION", "SEC_VERSION"}:\r
ca957eb5 4015 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 4016 elif SectionType == BINARY_FILE_TYPE_PEI_DEPEX:\r
5a264f28 4017 if FileType not in {BINARY_FILE_TYPE_PEI_DEPEX, "SEC_PEI_DEPEX"}:\r
ca957eb5 4018 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 4019 elif SectionType == BINARY_FILE_TYPE_GUID:\r
5a264f28 4020 if FileType not in {BINARY_FILE_TYPE_PE32, "SEC_GUID"}:\r
ca957eb5 4021 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
30fdf114 4022\r
9e47e6f9 4023 ## _GetRuleEncapsulationSection() method\r
30fdf114
LG
4024 #\r
4025 # Get encapsulation section for Rule\r
4026 #\r
4027 # @param self The object pointer\r
9e47e6f9 4028 # @param theRule for whom section is got\r
30fdf114
LG
4029 # @retval True Successfully find section statement\r
4030 # @retval False Not able to find section statement\r
4031 #\r
9e47e6f9
CJ
4032 def _GetRuleEncapsulationSection(self, theRule):\r
4033 if self._IsKeyword("COMPRESS"):\r
30fdf114 4034 Type = "PI_STD"\r
9e47e6f9
CJ
4035 if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE"):\r
4036 Type = self._Token\r
30fdf114 4037\r
9e47e6f9 4038 if not self._IsToken("{"):\r
ca957eb5 4039 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
30fdf114 4040\r
9e47e6f9 4041 CompressSectionObj = CompressSection()\r
30fdf114
LG
4042\r
4043 CompressSectionObj.CompType = Type\r
4044 # Recursive sections...\r
4045 while True:\r
9e47e6f9
CJ
4046 IsEncapsulate = self._GetRuleEncapsulationSection(CompressSectionObj)\r
4047 IsLeaf = self._GetEfiSection(CompressSectionObj)\r
30fdf114
LG
4048 if not IsEncapsulate and not IsLeaf:\r
4049 break\r
4050\r
ea98a825 4051 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 4052 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4053 theRule.SectionList.append(CompressSectionObj)\r
30fdf114
LG
4054\r
4055 return True\r
4056\r
9e47e6f9 4057 elif self._IsKeyword("GUIDED"):\r
30fdf114 4058 GuidValue = None\r
9e47e6f9 4059 if self._GetNextGuid():\r
d35773d5
YC
4060 if self._Token in GlobalData.gGuidDict:\r
4061 self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper()\r
9e47e6f9 4062 GuidValue = self._Token\r
30fdf114 4063\r
9e47e6f9
CJ
4064 if self._IsKeyword("$(NAMED_GUID)"):\r
4065 GuidValue = self._Token\r
30fdf114 4066\r
9e47e6f9 4067 AttribDict = self._GetGuidAttrib()\r
30fdf114 4068\r
9e47e6f9 4069 if not self._IsToken("{"):\r
ca957eb5 4070 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4071 GuidSectionObj = GuidSection()\r
30fdf114
LG
4072 GuidSectionObj.NameGuid = GuidValue\r
4073 GuidSectionObj.SectionType = "GUIDED"\r
4074 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]\r
4075 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]\r
25918452 4076 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]\r
30fdf114
LG
4077\r
4078 # Efi sections...\r
4079 while True:\r
9e47e6f9
CJ
4080 IsEncapsulate = self._GetRuleEncapsulationSection(GuidSectionObj)\r
4081 IsLeaf = self._GetEfiSection(GuidSectionObj)\r
30fdf114
LG
4082 if not IsEncapsulate and not IsLeaf:\r
4083 break\r
4084\r
ea98a825 4085 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 4086 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4087 theRule.SectionList.append(GuidSectionObj)\r
30fdf114
LG
4088\r
4089 return True\r
4090\r
4091 return False\r
4092\r
9e47e6f9 4093 ## _GetOptionRom() method\r
30fdf114
LG
4094 #\r
4095 # Get OptionROM section contents and store its data into OptionROM list of self.Profile\r
4096 #\r
4097 # @param self The object pointer\r
4098 # @retval True Successfully find a OptionROM\r
4099 # @retval False Not able to find a OptionROM\r
4100 #\r
9e47e6f9
CJ
4101 def _GetOptionRom(self):\r
4102 if not self._GetNextToken():\r
30fdf114
LG
4103 return False\r
4104\r
9e47e6f9
CJ
4105 S = self._Token.upper()\r
4106 if S.startswith(TAB_SECTION_START) and not S.startswith("[OPTIONROM."):\r
df81077f 4107 self.SectionParser(S)\r
9e47e6f9 4108 self._UndoToken()\r
df81077f 4109 return False\r
f7496d71 4110\r
9e47e6f9
CJ
4111 self._UndoToken()\r
4112 if not self._IsToken("[OptionRom.", True):\r
4113 raise Warning("Unknown Keyword '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114 4114\r
9e47e6f9 4115 OptRomName = self._GetUiName()\r
30fdf114 4116\r
9e47e6f9 4117 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 4118 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 4119\r
9e47e6f9 4120 OptRomObj = OPTIONROM(OptRomName)\r
30fdf114
LG
4121 self.Profile.OptRomDict[OptRomName] = OptRomObj\r
4122\r
4123 while True:\r
9e47e6f9
CJ
4124 isInf = self._GetOptRomInfStatement(OptRomObj)\r
4125 isFile = self._GetOptRomFileStatement(OptRomObj)\r
30fdf114
LG
4126 if not isInf and not isFile:\r
4127 break\r
f7496d71 4128\r
30fdf114
LG
4129 return True\r
4130\r
9e47e6f9 4131 ## _GetOptRomInfStatement() method\r
30fdf114
LG
4132 #\r
4133 # Get INF statements\r
4134 #\r
4135 # @param self The object pointer\r
4136 # @param Obj for whom inf statement is got\r
4137 # @retval True Successfully find inf statement\r
4138 # @retval False Not able to find inf statement\r
4139 #\r
9e47e6f9
CJ
4140 def _GetOptRomInfStatement(self, Obj):\r
4141 if not self._IsKeyword("INF"):\r
30fdf114
LG
4142 return False\r
4143\r
9e47e6f9
CJ
4144 ffsInf = OptRomInfStatement()\r
4145 self._GetInfOptions(ffsInf)\r
30fdf114 4146\r
9e47e6f9 4147 if not self._GetNextToken():\r
ca957eb5 4148 raise Warning.Expected("INF file path", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
4149 ffsInf.InfFileName = self._Token\r
4150 if ffsInf.InfFileName.replace(TAB_WORKSPACE, '').find('$') == -1:\r
6310ffd7 4151 #check for file path\r
4152 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4153 if ErrorCode != 0:\r
4154 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114 4155\r
3d3416e8
FB
4156 NewFileName = ffsInf.InfFileName\r
4157 if ffsInf.OverrideGuid:\r
4158 NewFileName = ProcessDuplicatedInf(PathClass(ffsInf.InfFileName,GenFdsGlobalVariable.WorkSpaceDir), ffsInf.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir).Path\r
4159\r
4160 if not NewFileName in self.Profile.InfList:\r
4161 self.Profile.InfList.append(NewFileName)\r
d0acc87a
LG
4162 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
4163 self.Profile.InfFileLineList.append(FileLineTuple)\r
2502b735
YZ
4164 if ffsInf.UseArch:\r
4165 if ffsInf.UseArch not in self.Profile.InfDict:\r
4166 self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]\r
4167 else:\r
4168 self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)\r
4169 else:\r
4170 self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)\r
30fdf114 4171\r
f7496d71 4172\r
9e47e6f9 4173 self._GetOptRomOverrides (ffsInf)\r
f7496d71 4174\r
30fdf114
LG
4175 Obj.FfsList.append(ffsInf)\r
4176 return True\r
4177\r
9e47e6f9 4178 ## _GetOptRomOverrides() method\r
30fdf114
LG
4179 #\r
4180 # Get overrides for OptROM INF & FILE\r
4181 #\r
4182 # @param self The object pointer\r
4183 # @param FfsInfObj for whom overrides is got\r
4184 #\r
9e47e6f9
CJ
4185 def _GetOptRomOverrides(self, Obj):\r
4186 if self._IsToken('{'):\r
4187 Overrides = OverrideAttribs()\r
fd171542 4188 while True:\r
9e47e6f9
CJ
4189 if self._IsKeyword("PCI_VENDOR_ID"):\r
4190 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4191 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4192 if not self._GetNextHexNumber():\r
ca957eb5 4193 raise Warning.Expected("Hex vendor id", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4194 Overrides.PciVendorId = self._Token\r
fd171542 4195 continue\r
4196\r
9e47e6f9
CJ
4197 if self._IsKeyword("PCI_CLASS_CODE"):\r
4198 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4199 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4200 if not self._GetNextHexNumber():\r
ca957eb5 4201 raise Warning.Expected("Hex class code", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4202 Overrides.PciClassCode = self._Token\r
fd171542 4203 continue\r
4204\r
9e47e6f9
CJ
4205 if self._IsKeyword("PCI_DEVICE_ID"):\r
4206 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4207 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
f157f973
TP
4208 # Get a list of PCI IDs\r
4209 Overrides.PciDeviceId = ""\r
5b9639e6
TP
4210 while (self._GetNextHexNumber()):\r
4211 Overrides.PciDeviceId = "{} {}".format(Overrides.PciDeviceId, self._Token)\r
f157f973
TP
4212 if not Overrides.PciDeviceId:\r
4213 raise Warning.Expected("one or more Hex device ids", self.FileName, self.CurrentLineNumber)\r
fd171542 4214 continue\r
4215\r
9e47e6f9
CJ
4216 if self._IsKeyword("PCI_REVISION"):\r
4217 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4218 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4219 if not self._GetNextHexNumber():\r
ca957eb5 4220 raise Warning.Expected("Hex revision", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4221 Overrides.PciRevision = self._Token\r
fd171542 4222 continue\r
4223\r
9e47e6f9
CJ
4224 if self._IsKeyword("PCI_COMPRESS"):\r
4225 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4226 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4227 if not self._GetNextToken():\r
ca957eb5 4228 raise Warning.Expected("TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4229 Overrides.NeedCompress = self._Token.upper() == 'TRUE'\r
fd171542 4230 continue\r
4231\r
ea98a825 4232 if self._IsToken(T_CHAR_BRACE_R):\r
fd171542 4233 break\r
4234 else:\r
4235 EdkLogger.error("FdfParser", FORMAT_INVALID, File=self.FileName, Line=self.CurrentLineNumber)\r
4236\r
30fdf114 4237 Obj.OverrideAttribs = Overrides\r
f7496d71 4238\r
9e47e6f9 4239 ## _GetOptRomFileStatement() method\r
30fdf114
LG
4240 #\r
4241 # Get FILE statements\r
4242 #\r
4243 # @param self The object pointer\r
4244 # @param Obj for whom FILE statement is got\r
4245 # @retval True Successfully find FILE statement\r
4246 # @retval False Not able to find FILE statement\r
4247 #\r
9e47e6f9
CJ
4248 def _GetOptRomFileStatement(self, Obj):\r
4249 if not self._IsKeyword("FILE"):\r
30fdf114
LG
4250 return False\r
4251\r
9e47e6f9 4252 FfsFileObj = OptRomFileStatement()\r
30fdf114 4253\r
9e47e6f9 4254 if not self._IsKeyword("EFI") and not self._IsKeyword(BINARY_FILE_TYPE_BIN):\r
ca957eb5 4255 raise Warning.Expected("Binary type (EFI/BIN)", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4256 FfsFileObj.FileType = self._Token\r
30fdf114 4257\r
9e47e6f9 4258 if not self._GetNextToken():\r
ca957eb5 4259 raise Warning.Expected("File path", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
4260 FfsFileObj.FileName = self._Token\r
4261 if FfsFileObj.FileName.replace(TAB_WORKSPACE, '').find('$') == -1:\r
6310ffd7 4262 #check for file path\r
4263 ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4264 if ErrorCode != 0:\r
4265 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114
LG
4266\r
4267 if FfsFileObj.FileType == 'EFI':\r
9e47e6f9 4268 self._GetOptRomOverrides(FfsFileObj)\r
f7496d71 4269\r
30fdf114
LG
4270 Obj.FfsList.append(FfsFileObj)\r
4271\r
4272 return True\r
fd171542 4273\r
9e47e6f9 4274 ## _GetCapInFd() method\r
fd171542 4275 #\r
4276 # Get Cap list contained in FD\r
4277 #\r
4278 # @param self The object pointer\r
4279 # @param FdName FD name\r
4280 # @retval CapList List of Capsule in FD\r
4281 #\r
9e47e6f9 4282 def _GetCapInFd (self, FdName):\r
fd171542 4283 CapList = []\r
9eb87141 4284 if FdName.upper() in self.Profile.FdDict:\r
fd171542 4285 FdObj = self.Profile.FdDict[FdName.upper()]\r
4286 for elementRegion in FdObj.RegionList:\r
4287 if elementRegion.RegionType == 'CAPSULE':\r
4288 for elementRegionData in elementRegion.RegionDataList:\r
4289 if elementRegionData.endswith(".cap"):\r
4290 continue\r
4231a819 4291 if elementRegionData is not None and elementRegionData.upper() not in CapList:\r
fd171542 4292 CapList.append(elementRegionData.upper())\r
4293 return CapList\r
4294\r
9e47e6f9 4295 ## _GetReferencedFdCapTuple() method\r
fd171542 4296 #\r
4297 # Get FV and FD list referenced by a capsule image\r
4298 #\r
4299 # @param self The object pointer\r
4300 # @param CapObj Capsule section to be searched\r
4301 # @param RefFdList referenced FD by section\r
4302 # @param RefFvList referenced FV by section\r
4303 #\r
9e47e6f9
CJ
4304 def _GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []):\r
4305 for CapsuleDataObj in CapObj.CapsuleDataList:\r
4231a819 4306 if hasattr(CapsuleDataObj, 'FvName') and CapsuleDataObj.FvName is not None and CapsuleDataObj.FvName.upper() not in RefFvList:\r
fd171542 4307 RefFvList.append (CapsuleDataObj.FvName.upper())\r
4231a819 4308 elif hasattr(CapsuleDataObj, 'FdName') and CapsuleDataObj.FdName is not None and CapsuleDataObj.FdName.upper() not in RefFdList:\r
f7496d71 4309 RefFdList.append (CapsuleDataObj.FdName.upper())\r
4231a819 4310 elif CapsuleDataObj.Ffs is not None:\r
9e47e6f9 4311 if isinstance(CapsuleDataObj.Ffs, FileStatement):\r
4231a819 4312 if CapsuleDataObj.Ffs.FvName is not None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList:\r
b36d134f 4313 RefFvList.append(CapsuleDataObj.Ffs.FvName.upper())\r
4231a819 4314 elif CapsuleDataObj.Ffs.FdName is not None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList:\r
b36d134f
LG
4315 RefFdList.append(CapsuleDataObj.Ffs.FdName.upper())\r
4316 else:\r
9e47e6f9 4317 self._GetReferencedFdFvTupleFromSection(CapsuleDataObj.Ffs, RefFdList, RefFvList)\r
fd171542 4318\r
9e47e6f9 4319 ## _GetFvInFd() method\r
30fdf114
LG
4320 #\r
4321 # Get FV list contained in FD\r
4322 #\r
4323 # @param self The object pointer\r
4324 # @param FdName FD name\r
4325 # @retval FvList list of FV in FD\r
4326 #\r
9e47e6f9 4327 def _GetFvInFd (self, FdName):\r
30fdf114 4328 FvList = []\r
9eb87141 4329 if FdName.upper() in self.Profile.FdDict:\r
30fdf114
LG
4330 FdObj = self.Profile.FdDict[FdName.upper()]\r
4331 for elementRegion in FdObj.RegionList:\r
91fa33ee 4332 if elementRegion.RegionType == BINARY_FILE_TYPE_FV:\r
30fdf114 4333 for elementRegionData in elementRegion.RegionDataList:\r
fd171542 4334 if elementRegionData.endswith(".fv"):\r
4335 continue\r
4231a819 4336 if elementRegionData is not None and elementRegionData.upper() not in FvList:\r
30fdf114
LG
4337 FvList.append(elementRegionData.upper())\r
4338 return FvList\r
4339\r
9e47e6f9 4340 ## _GetReferencedFdFvTuple() method\r
30fdf114
LG
4341 #\r
4342 # Get FD and FV list referenced by a FFS file\r
4343 #\r
4344 # @param self The object pointer\r
4345 # @param FfsFile contains sections to be searched\r
4346 # @param RefFdList referenced FD by section\r
4347 # @param RefFvList referenced FV by section\r
4348 #\r
9e47e6f9 4349 def _GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []):\r
30fdf114 4350 for FfsObj in FvObj.FfsList:\r
9e47e6f9 4351 if isinstance(FfsObj, FileStatement):\r
4231a819 4352 if FfsObj.FvName is not None and FfsObj.FvName.upper() not in RefFvList:\r
30fdf114 4353 RefFvList.append(FfsObj.FvName.upper())\r
4231a819 4354 elif FfsObj.FdName is not None and FfsObj.FdName.upper() not in RefFdList:\r
30fdf114
LG
4355 RefFdList.append(FfsObj.FdName.upper())\r
4356 else:\r
9e47e6f9 4357 self._GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList)\r
30fdf114 4358\r
9e47e6f9 4359 ## _GetReferencedFdFvTupleFromSection() method\r
30fdf114
LG
4360 #\r
4361 # Get FD and FV list referenced by a FFS section\r
4362 #\r
4363 # @param self The object pointer\r
4364 # @param FfsFile contains sections to be searched\r
4365 # @param FdList referenced FD by section\r
4366 # @param FvList referenced FV by section\r
4367 #\r
9e47e6f9 4368 def _GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []):\r
5a264f28 4369 SectionStack = list(FfsFile.SectionList)\r
30fdf114
LG
4370 while SectionStack != []:\r
4371 SectionObj = SectionStack.pop()\r
9e47e6f9 4372 if isinstance(SectionObj, FvImageSection):\r
4231a819 4373 if SectionObj.FvName is not None and SectionObj.FvName.upper() not in FvList:\r
30fdf114 4374 FvList.append(SectionObj.FvName.upper())\r
4231a819 4375 if SectionObj.Fv is not None and SectionObj.Fv.UiFvName is not None and SectionObj.Fv.UiFvName.upper() not in FvList:\r
30fdf114 4376 FvList.append(SectionObj.Fv.UiFvName.upper())\r
9e47e6f9 4377 self._GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList)\r
30fdf114 4378\r
9e47e6f9 4379 if isinstance(SectionObj, CompressSection) or isinstance(SectionObj, GuidSection):\r
30fdf114
LG
4380 SectionStack.extend(SectionObj.SectionList)\r
4381\r
4382 ## CycleReferenceCheck() method\r
4383 #\r
4384 # Check whether cycle reference exists in FDF\r
4385 #\r
4386 # @param self The object pointer\r
4387 # @retval True cycle reference exists\r
4388 # @retval False Not exists cycle reference\r
4389 #\r
4390 def CycleReferenceCheck(self):\r
fd171542 4391 #\r
4392 # Check the cycle between FV and FD image\r
4393 #\r
4394 MaxLength = len (self.Profile.FvDict)\r
9eb87141 4395 for FvName in self.Profile.FvDict:\r
fd171542 4396 LogStr = "\nCycle Reference Checking for FV: %s\n" % FvName\r
5a264f28
CJ
4397 RefFvStack = set(FvName)\r
4398 FdAnalyzedList = set()\r
f7496d71 4399\r
fd171542 4400 Index = 0\r
9e47e6f9 4401 while RefFvStack and Index < MaxLength:\r
fd171542 4402 Index = Index + 1\r
4403 FvNameFromStack = RefFvStack.pop()\r
9eb87141 4404 if FvNameFromStack.upper() in self.Profile.FvDict:\r
fd171542 4405 FvObj = self.Profile.FvDict[FvNameFromStack.upper()]\r
4406 else:\r
4407 continue\r
30fdf114 4408\r
fd171542 4409 RefFdList = []\r
4410 RefFvList = []\r
9e47e6f9 4411 self._GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)\r
30fdf114 4412\r
fd171542 4413 for RefFdName in RefFdList:\r
4414 if RefFdName in FdAnalyzedList:\r
30fdf114
LG
4415 continue\r
4416\r
fd171542 4417 LogStr += "FV %s contains FD %s\n" % (FvNameFromStack, RefFdName)\r
9e47e6f9 4418 FvInFdList = self._GetFvInFd(RefFdName)\r
fd171542 4419 if FvInFdList != []:\r
4420 for FvNameInFd in FvInFdList:\r
ccaa7754 4421 LogStr += "FD %s contains FV %s\n" % (RefFdName, FvNameInFd)\r
fd171542 4422 if FvNameInFd not in RefFvStack:\r
5a264f28 4423 RefFvStack.add(FvNameInFd)\r
fd171542 4424\r
4425 if FvName in RefFvStack or FvNameFromStack in RefFvStack:\r
4426 EdkLogger.info(LogStr)\r
4427 return True\r
5a264f28 4428 FdAnalyzedList.add(RefFdName)\r
30fdf114 4429\r
fd171542 4430 for RefFvName in RefFvList:\r
4431 LogStr += "FV %s contains FV %s\n" % (FvNameFromStack, RefFvName)\r
4432 if RefFvName not in RefFvStack:\r
5a264f28 4433 RefFvStack.add(RefFvName)\r
fd171542 4434\r
4435 if FvName in RefFvStack or FvNameFromStack in RefFvStack:\r
4436 EdkLogger.info(LogStr)\r
4437 return True\r
4438\r
4439 #\r
4440 # Check the cycle between Capsule and FD image\r
4441 #\r
4442 MaxLength = len (self.Profile.CapsuleDict)\r
9eb87141 4443 for CapName in self.Profile.CapsuleDict:\r
fd171542 4444 #\r
4445 # Capsule image to be checked.\r
4446 #\r
4447 LogStr = "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName\r
5a264f28
CJ
4448 RefCapStack = {CapName}\r
4449 FdAnalyzedList = set()\r
4450 FvAnalyzedList = set()\r
f7496d71 4451\r
fd171542 4452 Index = 0\r
5a264f28 4453 while RefCapStack and Index < MaxLength:\r
fd171542 4454 Index = Index + 1\r
4455 CapNameFromStack = RefCapStack.pop()\r
9eb87141 4456 if CapNameFromStack.upper() in self.Profile.CapsuleDict:\r
fd171542 4457 CapObj = self.Profile.CapsuleDict[CapNameFromStack.upper()]\r
4458 else:\r
4459 continue\r
4460\r
4461 RefFvList = []\r
4462 RefFdList = []\r
9e47e6f9 4463 self._GetReferencedFdCapTuple(CapObj, RefFdList, RefFvList)\r
fd171542 4464\r
4465 FvListLength = 0\r
4466 FdListLength = 0\r
4467 while FvListLength < len (RefFvList) or FdListLength < len (RefFdList):\r
30fdf114
LG
4468 for RefFdName in RefFdList:\r
4469 if RefFdName in FdAnalyzedList:\r
4470 continue\r
4471\r
fd171542 4472 LogStr += "Capsule %s contains FD %s\n" % (CapNameFromStack, RefFdName)\r
5a264f28
CJ
4473 for CapNameInFd in self._GetCapInFd(RefFdName):\r
4474 LogStr += "FD %s contains Capsule %s\n" % (RefFdName, CapNameInFd)\r
4475 if CapNameInFd not in RefCapStack:\r
4476 RefCapStack.append(CapNameInFd)\r
4477\r
4478 if CapName in RefCapStack or CapNameFromStack in RefCapStack:\r
4479 EdkLogger.info(LogStr)\r
4480 return True\r
4481\r
4482 for FvNameInFd in self._GetFvInFd(RefFdName):\r
4483 LogStr += "FD %s contains FV %s\n" % (RefFdName, FvNameInFd)\r
4484 if FvNameInFd not in RefFvList:\r
4485 RefFvList.append(FvNameInFd)\r
4486\r
4487 FdAnalyzedList.add(RefFdName)\r
fd171542 4488 #\r
4489 # the number of the parsed FV and FD image\r
4490 #\r
4491 FvListLength = len (RefFvList)\r
4492 FdListLength = len (RefFdList)\r
30fdf114 4493 for RefFvName in RefFvList:\r
fd171542 4494 if RefFvName in FvAnalyzedList:\r
4495 continue\r
4496 LogStr += "Capsule %s contains FV %s\n" % (CapNameFromStack, RefFvName)\r
9eb87141 4497 if RefFvName.upper() in self.Profile.FvDict:\r
fd171542 4498 FvObj = self.Profile.FvDict[RefFvName.upper()]\r
4499 else:\r
4500 continue\r
9e47e6f9 4501 self._GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)\r
5a264f28 4502 FvAnalyzedList.add(RefFvName)\r
30fdf114 4503\r
fd171542 4504 return False\r
30fdf114 4505\r
c17956e0
DL
4506 def GetAllIncludedFile (self):\r
4507 global AllIncludeFileList\r
4508 return AllIncludeFileList\r
4509\r
30fdf114 4510if __name__ == "__main__":\r
b36d134f
LG
4511 import sys\r
4512 try:\r
4513 test_file = sys.argv[1]\r
5b0671c1 4514 except IndexError as v:\r
72443dd2 4515 print("Usage: %s filename" % sys.argv[0])\r
b36d134f
LG
4516 sys.exit(1)\r
4517\r
4518 parser = FdfParser(test_file)\r
30fdf114
LG
4519 try:\r
4520 parser.ParseFile()\r
4521 parser.CycleReferenceCheck()\r
5b0671c1 4522 except Warning as X:\r
72443dd2 4523 print(str(X))\r
30fdf114 4524 else:\r
72443dd2 4525 print("Success!")\r
30fdf114 4526\r