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