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