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