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