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