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