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