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