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