4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 # Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>
7 # This program and the accompanying materials
8 # are licensed and made available under the terms and conditions of the BSD License
9 # which accompanies this distribution. The full text of the license may be found at
10 # http://opensource.org/licenses/bsd-license.php
12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
25 import FfsInfStatement
26 import FfsFileStatement
32 import CompressSection
37 import RuleComplexFile
41 import ComponentStatement
43 import OptRomInfStatement
44 import OptRomFileStatement
46 from GenFdsGlobalVariable
import GenFdsGlobalVariable
47 from Common
.BuildToolError
import *
48 from Common
import EdkLogger
49 from Common
.Misc
import PathClass
50 from Common
.String
import NormPath
51 import Common
.GlobalData
as GlobalData
52 from Common
.Expression
import *
53 from Common
import GlobalData
54 from Common
.String
import ReplaceMacro
56 from Common
.Misc
import tdict
57 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
58 import Common
.LongFilePathOs
as os
59 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
60 from Capsule
import EFI_CERT_TYPE_PKCS7_GUID
61 from Capsule
import EFI_CERT_TYPE_RSA2048_SHA256_GUID
62 from Common
.RangeExpression
import RangeExpression
63 from Common
.FdfParserLite
import FileExtensionPattern
65 ##define T_CHAR_SPACE ' '
66 ##define T_CHAR_NULL '\0'
67 ##define T_CHAR_CR '\r'
68 ##define T_CHAR_TAB '\t'
69 ##define T_CHAR_LF '\n'
70 ##define T_CHAR_SLASH '/'
71 ##define T_CHAR_BACKSLASH '\\'
72 ##define T_CHAR_DOUBLE_QUOTE '\"'
73 ##define T_CHAR_SINGLE_QUOTE '\''
74 ##define T_CHAR_STAR '*'
75 ##define T_CHAR_HASH '#'
77 (T_CHAR_SPACE
, T_CHAR_NULL
, T_CHAR_CR
, T_CHAR_TAB
, T_CHAR_LF
, T_CHAR_SLASH
, \
78 T_CHAR_BACKSLASH
, T_CHAR_DOUBLE_QUOTE
, T_CHAR_SINGLE_QUOTE
, T_CHAR_STAR
, T_CHAR_HASH
) = \
79 (' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#')
81 SEPERATOR_TUPLE
= ('=', '|', ',', '{', '}')
83 RegionSizePattern
= re
.compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
84 RegionSizeGuidPattern
= re
.compile("\s*(?P<base>\w+\.\w+)\s*\|\s*(?P<size>\w+\.\w+)\s*")
85 RegionOffsetPcdPattern
= re
.compile("\s*(?P<base>\w+\.\w+)\s*$")
86 ShortcutPcdPattern
= re
.compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
88 AllIncludeFileList
= []
90 # Get the closest parent
91 def GetParentAtLine (Line
):
92 for Profile
in AllIncludeFileList
:
93 if Profile
.IsLineInFile(Line
):
98 def IsValidInclude (File
, Line
):
99 for Profile
in AllIncludeFileList
:
100 if Profile
.IsLineInFile(Line
) and Profile
.FileName
== File
:
105 def GetRealFileLine (File
, Line
):
108 for Profile
in AllIncludeFileList
:
109 if Profile
.IsLineInFile(Line
):
110 return Profile
.GetLineInFile(Line
)
111 elif Line
>= Profile
.InsertStartLineNumber
and Profile
.Level
== 1:
112 InsertedLines
+= Profile
.GetTotalLines()
114 return (File
, Line
- InsertedLines
)
116 ## The exception class that used to report error messages when parsing FDF
118 # Currently the "ToolName" is set to be "FDF Parser".
120 class Warning (Exception):
123 # @param self The object pointer
124 # @param Str The message to record
125 # @param File The FDF name
126 # @param Line The Line number that error occurs
128 def __init__(self
, Str
, File
= None, Line
= None):
130 FileLineTuple
= GetRealFileLine(File
, Line
)
131 self
.FileName
= FileLineTuple
[0]
132 self
.LineNumber
= FileLineTuple
[1]
133 self
.OriginalLineNumber
= Line
135 self
.ToolName
= 'FdfParser'
140 ## The Include file content class that used to record file data when parsing include file
142 # May raise Exception when opening file.
144 class IncludeFileProfile
:
147 # @param self The object pointer
148 # @param FileName The file that to be parsed
150 def __init__(self
, FileName
):
151 self
.FileName
= FileName
152 self
.FileLinesList
= []
154 fsock
= open(FileName
, "rb", 0)
156 self
.FileLinesList
= fsock
.readlines()
157 for index
, line
in enumerate(self
.FileLinesList
):
158 if not line
.endswith('\n'):
159 self
.FileLinesList
[index
] += '\n'
165 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
167 self
.InsertStartLineNumber
= None
168 self
.InsertAdjust
= 0
169 self
.IncludeFileList
= []
170 self
.Level
= 1 # first level include file
172 def GetTotalLines(self
):
173 TotalLines
= self
.InsertAdjust
+ len(self
.FileLinesList
)
175 for Profile
in self
.IncludeFileList
:
176 TotalLines
+= Profile
.GetTotalLines()
180 def IsLineInFile(self
, Line
):
181 if Line
>= self
.InsertStartLineNumber
and Line
< self
.InsertStartLineNumber
+ self
.GetTotalLines():
186 def GetLineInFile(self
, Line
):
187 if not self
.IsLineInFile (Line
):
188 return (self
.FileName
, -1)
190 InsertedLines
= self
.InsertStartLineNumber
192 for Profile
in self
.IncludeFileList
:
193 if Profile
.IsLineInFile(Line
):
194 return Profile
.GetLineInFile(Line
)
195 elif Line
>= Profile
.InsertStartLineNumber
:
196 InsertedLines
+= Profile
.GetTotalLines()
198 return (self
.FileName
, Line
- InsertedLines
+ 1)
202 ## The FDF content class that used to record file data when parsing FDF
204 # May raise Exception when opening file.
209 # @param self The object pointer
210 # @param FileName The file that to be parsed
212 def __init__(self
, FileName
):
213 self
.FileLinesList
= []
215 fsock
= open(FileName
, "rb", 0)
217 self
.FileLinesList
= fsock
.readlines()
222 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
227 self
.InfDict
= {'ArchTBD':[]}
228 # ECC will use this Dict and List information
229 self
.PcdFileLineDict
= {}
230 self
.InfFileLineList
= []
233 self
.FdNameNotSet
= False
235 self
.CapsuleDict
= {}
239 self
.FmpPayloadDict
= {}
241 ## The syntax parser for FDF
243 # PreprocessFile method should be called prior to ParseFile
244 # CycleReferenceCheck method can detect cycles in FDF contents
246 # GetNext*** procedures mean these procedures will get next token first, then make judgement.
247 # Get*** procedures mean these procedures will make judgement on current token only.
252 # @param self The object pointer
253 # @param FileName The file that to be parsed
255 def __init__(self
, FileName
):
256 self
.Profile
= FileProfile(FileName
)
257 self
.FileName
= FileName
258 self
.CurrentLineNumber
= 1
259 self
.CurrentOffsetWithinLine
= 0
260 self
.CurrentFdName
= None
261 self
.CurrentFvName
= None
263 self
.__SkippedChars
= ""
264 GlobalData
.gFdfParser
= self
266 # Used to section info
267 self
.__CurSection
= []
268 # Key: [section name, UI name, arch]
269 # Value: {MACRO_NAME : MACRO_VALUE}
270 self
.__MacroDict
= tdict(True, 3)
273 self
.__WipeOffArea
= []
274 if GenFdsGlobalVariable
.WorkSpaceDir
== '':
275 GenFdsGlobalVariable
.WorkSpaceDir
= os
.getenv("WORKSPACE")
277 ## __IsWhiteSpace() method
279 # Whether char at current FileBufferPos is whitespace
281 # @param self The object pointer
282 # @param Char The char to test
283 # @retval True The char is a kind of white space
284 # @retval False The char is NOT a kind of white space
286 def __IsWhiteSpace(self
, Char
):
287 if Char
in (T_CHAR_NULL
, T_CHAR_CR
, T_CHAR_SPACE
, T_CHAR_TAB
, T_CHAR_LF
):
292 ## __SkipWhiteSpace() method
294 # Skip white spaces from current char, return number of chars skipped
296 # @param self The object pointer
297 # @retval Count The number of chars skipped
299 def __SkipWhiteSpace(self
):
301 while not self
.__EndOfFile
():
303 if self
.__CurrentChar
() in (T_CHAR_NULL
, T_CHAR_CR
, T_CHAR_LF
, T_CHAR_SPACE
, T_CHAR_TAB
):
304 self
.__SkippedChars
+= str(self
.__CurrentChar
())
311 ## __EndOfFile() method
313 # Judge current buffer pos is at file end
315 # @param self The object pointer
316 # @retval True Current File buffer position is at file end
317 # @retval False Current File buffer position is NOT at file end
319 def __EndOfFile(self
):
320 NumberOfLines
= len(self
.Profile
.FileLinesList
)
321 SizeOfLastLine
= len(self
.Profile
.FileLinesList
[-1])
322 if self
.CurrentLineNumber
== NumberOfLines
and self
.CurrentOffsetWithinLine
>= SizeOfLastLine
- 1:
324 elif self
.CurrentLineNumber
> NumberOfLines
:
329 ## __EndOfLine() method
331 # Judge current buffer pos is at line end
333 # @param self The object pointer
334 # @retval True Current File buffer position is at line end
335 # @retval False Current File buffer position is NOT at line end
337 def __EndOfLine(self
):
338 if self
.CurrentLineNumber
> len(self
.Profile
.FileLinesList
):
340 SizeOfCurrentLine
= len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
341 if self
.CurrentOffsetWithinLine
>= SizeOfCurrentLine
:
348 # Reset file data buffer to the initial state
350 # @param self The object pointer
351 # @param DestLine Optional new destination line number.
352 # @param DestOffset Optional new destination offset.
354 def Rewind(self
, DestLine
= 1, DestOffset
= 0):
355 self
.CurrentLineNumber
= DestLine
356 self
.CurrentOffsetWithinLine
= DestOffset
358 ## __UndoOneChar() method
360 # Go back one char in the file buffer
362 # @param self The object pointer
363 # @retval True Successfully go back one char
364 # @retval False Not able to go back one char as file beginning reached
366 def __UndoOneChar(self
):
368 if self
.CurrentLineNumber
== 1 and self
.CurrentOffsetWithinLine
== 0:
370 elif self
.CurrentOffsetWithinLine
== 0:
371 self
.CurrentLineNumber
-= 1
372 self
.CurrentOffsetWithinLine
= len(self
.__CurrentLine
()) - 1
374 self
.CurrentOffsetWithinLine
-= 1
377 ## __GetOneChar() method
379 # Move forward one char in the file buffer
381 # @param self The object pointer
383 def __GetOneChar(self
):
384 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
385 self
.CurrentLineNumber
+= 1
386 self
.CurrentOffsetWithinLine
= 0
388 self
.CurrentOffsetWithinLine
+= 1
390 ## __CurrentChar() method
392 # Get the char pointed to by the file buffer pointer
394 # @param self The object pointer
395 # @retval Char Current char
397 def __CurrentChar(self
):
398 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
]
400 ## __NextChar() method
402 # Get the one char pass the char pointed to by the file buffer pointer
404 # @param self The object pointer
405 # @retval Char Next char
407 def __NextChar(self
):
408 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
409 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
][0]
411 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
+ 1]
413 ## __SetCurrentCharValue() method
415 # Modify the value of current char
417 # @param self The object pointer
418 # @param Value The new value of current char
420 def __SetCurrentCharValue(self
, Value
):
421 self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
] = Value
423 ## __CurrentLine() method
425 # Get the list that contains current line contents
427 # @param self The object pointer
428 # @retval List current line contents
430 def __CurrentLine(self
):
431 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
433 def __StringToList(self
):
434 self
.Profile
.FileLinesList
= [list(s
) for s
in self
.Profile
.FileLinesList
]
435 self
.Profile
.FileLinesList
[-1].append(' ')
437 def __ReplaceFragment(self
, StartPos
, EndPos
, Value
= ' '):
438 if StartPos
[0] == EndPos
[0]:
440 while Offset
<= EndPos
[1]:
441 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
446 while self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] not in ('\r', '\n'):
447 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
451 while Line
< EndPos
[0]:
453 while self
.Profile
.FileLinesList
[Line
][Offset
] not in ('\r', '\n'):
454 self
.Profile
.FileLinesList
[Line
][Offset
] = Value
459 while Offset
<= EndPos
[1]:
460 self
.Profile
.FileLinesList
[EndPos
[0]][Offset
] = Value
464 def __GetMacroName(self
):
465 if not self
.__GetNextToken
():
466 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
467 MacroName
= self
.__Token
469 if MacroName
.startswith('!'):
471 MacroName
= MacroName
[1:].strip()
473 if not MacroName
.startswith('$(') or not MacroName
.endswith(')'):
474 raise Warning("Macro name expected(Please use '$(%(Token)s)' if '%(Token)s' is a macro.)" % {"Token" : MacroName
},
475 self
.FileName
, self
.CurrentLineNumber
)
476 MacroName
= MacroName
[2:-1]
477 return MacroName
, NotFlag
479 def __SetMacroValue(self
, Macro
, Value
):
480 if not self
.__CurSection
:
484 if not self
.__MacroDict
[self
.__CurSection
[0], self
.__CurSection
[1], self
.__CurSection
[2]]:
485 self
.__MacroDict
[self
.__CurSection
[0], self
.__CurSection
[1], self
.__CurSection
[2]] = MacroDict
487 MacroDict
= self
.__MacroDict
[self
.__CurSection
[0], self
.__CurSection
[1], self
.__CurSection
[2]]
488 MacroDict
[Macro
] = Value
490 def __GetMacroValue(self
, Macro
):
492 if Macro
in GlobalData
.gCommandLineDefines
:
493 return GlobalData
.gCommandLineDefines
[Macro
]
494 if Macro
in GlobalData
.gGlobalDefines
:
495 return GlobalData
.gGlobalDefines
[Macro
]
497 if self
.__CurSection
:
498 MacroDict
= self
.__MacroDict
[
499 self
.__CurSection
[0],
500 self
.__CurSection
[1],
503 if MacroDict
and Macro
in MacroDict
:
504 return MacroDict
[Macro
]
507 if Macro
in GlobalData
.gPlatformDefines
:
508 return GlobalData
.gPlatformDefines
[Macro
]
511 def __SectionHeaderParser(self
, Section
):
513 # [FD.UiName]: use dummy instead if UI name is optional
516 # [Rule]: don't take rule section into account, macro is not allowed in this section
517 # [VTF.arch.UiName, arch]
518 # [OptionRom.DriverName]
519 self
.__CurSection
= []
520 Section
= Section
.strip()[1:-1].upper().replace(' ', '').strip('.')
521 ItemList
= Section
.split('.')
523 if Item
== '' or Item
== 'RULE':
526 if Item
== 'DEFINES':
527 self
.__CurSection
= ['COMMON', 'COMMON', 'COMMON']
528 elif Item
== 'VTF' and len(ItemList
) == 3:
530 Pos
= UiName
.find(',')
532 UiName
= UiName
[:Pos
]
533 self
.__CurSection
= ['VTF', UiName
, ItemList
[1]]
534 elif len(ItemList
) > 1:
535 self
.__CurSection
= [ItemList
[0], ItemList
[1], 'COMMON']
536 elif len(ItemList
) > 0:
537 self
.__CurSection
= [ItemList
[0], 'DUMMY', 'COMMON']
539 ## PreprocessFile() method
541 # Preprocess file contents, replace comments with spaces.
542 # In the end, rewind the file buffer pointer to the beginning
543 # BUGBUG: No !include statement processing contained in this procedure
544 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
546 # @param self The object pointer
548 def PreprocessFile(self
):
552 DoubleSlashComment
= False
554 # HashComment in quoted string " " is ignored.
557 while not self
.__EndOfFile
():
559 if self
.__CurrentChar
() == T_CHAR_DOUBLE_QUOTE
and not InComment
:
560 InString
= not InString
561 # meet new line, then no longer in a comment for // and '#'
562 if self
.__CurrentChar
() == T_CHAR_LF
:
563 self
.CurrentLineNumber
+= 1
564 self
.CurrentOffsetWithinLine
= 0
565 if InComment
and DoubleSlashComment
:
567 DoubleSlashComment
= False
568 if InComment
and HashComment
:
571 # check for */ comment end
572 elif InComment
and not DoubleSlashComment
and not HashComment
and self
.__CurrentChar
() == T_CHAR_STAR
and self
.__NextChar
() == T_CHAR_SLASH
:
573 self
.__SetCurrentCharValue
(T_CHAR_SPACE
)
575 self
.__SetCurrentCharValue
(T_CHAR_SPACE
)
578 # set comments to spaces
580 self
.__SetCurrentCharValue
(T_CHAR_SPACE
)
582 # check for // comment
583 elif self
.__CurrentChar
() == T_CHAR_SLASH
and self
.__NextChar
() == T_CHAR_SLASH
and not self
.__EndOfLine
():
585 DoubleSlashComment
= True
586 # check for '#' comment
587 elif self
.__CurrentChar
() == T_CHAR_HASH
and not self
.__EndOfLine
() and not InString
:
590 # check for /* comment start
591 elif self
.__CurrentChar
() == T_CHAR_SLASH
and self
.__NextChar
() == T_CHAR_STAR
:
592 self
.__SetCurrentCharValue
( T_CHAR_SPACE
)
594 self
.__SetCurrentCharValue
( T_CHAR_SPACE
)
600 # restore from ListOfList to ListOfString
601 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
604 ## PreprocessIncludeFile() method
606 # Preprocess file contents, replace !include statements with file contents.
607 # In the end, rewind the file buffer pointer to the beginning
609 # @param self The object pointer
611 def PreprocessIncludeFile(self
):
612 # nested include support
615 while self
.__GetNextToken
():
617 if self
.__Token
== 'DEFINE':
618 if not self
.__GetNextToken
():
619 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
621 if not self
.__IsToken
( "="):
622 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
623 Value
= self
.__GetExpression
()
624 MacroDict
[Macro
] = Value
626 elif self
.__Token
== '!include':
628 IncludeLine
= self
.CurrentLineNumber
629 IncludeOffset
= self
.CurrentOffsetWithinLine
- len('!include')
630 if not self
.__GetNextToken
():
631 raise Warning("expected include file name", self
.FileName
, self
.CurrentLineNumber
)
632 IncFileName
= self
.__Token
634 StartPos
= IncFileName
.find('$(', PreIndex
)
635 EndPos
= IncFileName
.find(')', StartPos
+2)
636 while StartPos
!= -1 and EndPos
!= -1:
637 Macro
= IncFileName
[StartPos
+2 : EndPos
]
638 MacroVal
= self
.__GetMacroValue
(Macro
)
640 if Macro
in MacroDict
:
641 MacroVal
= MacroDict
[Macro
]
642 if MacroVal
is not None:
643 IncFileName
= IncFileName
.replace('$(' + Macro
+ ')', MacroVal
, 1)
644 if MacroVal
.find('$(') != -1:
647 PreIndex
= StartPos
+ len(MacroVal
)
649 raise Warning("The Macro %s is not defined" %Macro
, self
.FileName
, self
.CurrentLineNumber
)
650 StartPos
= IncFileName
.find('$(', PreIndex
)
651 EndPos
= IncFileName
.find(')', StartPos
+2)
653 IncludedFile
= NormPath(IncFileName
)
655 # First search the include file under the same directory as FDF file
657 IncludedFile1
= PathClass(IncludedFile
, os
.path
.dirname(self
.FileName
))
658 ErrorCode
= IncludedFile1
.Validate()[0]
661 # Then search the include file under the same directory as DSC file
664 if GenFdsGlobalVariable
.ActivePlatform
:
665 PlatformDir
= GenFdsGlobalVariable
.ActivePlatform
.Dir
666 elif GlobalData
.gActivePlatform
:
667 PlatformDir
= GlobalData
.gActivePlatform
.MetaFile
.Dir
668 IncludedFile1
= PathClass(IncludedFile
, PlatformDir
)
669 ErrorCode
= IncludedFile1
.Validate()[0]
672 # Also search file under the WORKSPACE directory
674 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
675 ErrorCode
= IncludedFile1
.Validate()[0]
677 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
),
678 self
.FileName
, self
.CurrentLineNumber
)
680 if not IsValidInclude (IncludedFile1
.Path
, self
.CurrentLineNumber
):
681 raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1
.Path
), self
.FileName
, self
.CurrentLineNumber
)
683 IncFileProfile
= IncludeFileProfile(IncludedFile1
.Path
)
685 CurrentLine
= self
.CurrentLineNumber
686 CurrentOffset
= self
.CurrentOffsetWithinLine
687 # list index of the insertion, note that line number is 'CurrentLine + 1'
688 InsertAtLine
= CurrentLine
689 ParentProfile
= GetParentAtLine (CurrentLine
)
690 if ParentProfile
is not None:
691 ParentProfile
.IncludeFileList
.insert(0, IncFileProfile
)
692 IncFileProfile
.Level
= ParentProfile
.Level
+ 1
693 IncFileProfile
.InsertStartLineNumber
= InsertAtLine
+ 1
694 # deal with remaining portions after "!include filename", if exists.
695 if self
.__GetNextToken
():
696 if self
.CurrentLineNumber
== CurrentLine
:
697 RemainingLine
= self
.__CurrentLine
()[CurrentOffset
:]
698 self
.Profile
.FileLinesList
.insert(self
.CurrentLineNumber
, RemainingLine
)
699 IncFileProfile
.InsertAdjust
+= 1
700 self
.CurrentLineNumber
+= 1
701 self
.CurrentOffsetWithinLine
= 0
703 for Line
in IncFileProfile
.FileLinesList
:
704 self
.Profile
.FileLinesList
.insert(InsertAtLine
, Line
)
705 self
.CurrentLineNumber
+= 1
708 # reversely sorted to better determine error in file
709 AllIncludeFileList
.insert(0, IncFileProfile
)
711 # comment out the processed include file statement
712 TempList
= list(self
.Profile
.FileLinesList
[IncludeLine
- 1])
713 TempList
.insert(IncludeOffset
, '#')
714 self
.Profile
.FileLinesList
[IncludeLine
- 1] = ''.join(TempList
)
715 if Processed
: # Nested and back-to-back support
716 self
.Rewind(DestLine
= IncFileProfile
.InsertStartLineNumber
- 1)
721 def __GetIfListCurrentItemStat(self
, IfList
):
731 ## PreprocessConditionalStatement() method
733 # Preprocess conditional statement.
734 # In the end, rewind the file buffer pointer to the beginning
736 # @param self The object pointer
738 def PreprocessConditionalStatement(self
):
739 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
743 while self
.__GetNextToken
():
744 # Determine section name and the location dependent macro
745 if self
.__GetIfListCurrentItemStat
(IfList
):
746 if self
.__Token
.startswith('['):
747 Header
= self
.__Token
748 if not self
.__Token
.endswith(']'):
749 self
.__SkipToToken
(']')
750 Header
+= self
.__SkippedChars
751 if Header
.find('$(') != -1:
752 raise Warning("macro cannot be used in section header", self
.FileName
, self
.CurrentLineNumber
)
753 self
.__SectionHeaderParser
(Header
)
755 # Replace macros except in RULE section or out of section
756 elif self
.__CurSection
and ReplacedLine
!= self
.CurrentLineNumber
:
757 ReplacedLine
= self
.CurrentLineNumber
759 CurLine
= self
.Profile
.FileLinesList
[ReplacedLine
- 1]
761 StartPos
= CurLine
.find('$(', PreIndex
)
762 EndPos
= CurLine
.find(')', StartPos
+2)
763 while StartPos
!= -1 and EndPos
!= -1 and self
.__Token
not in ['!ifdef', '!ifndef', '!if', '!elseif']:
764 MacroName
= CurLine
[StartPos
+2 : EndPos
]
765 MacorValue
= self
.__GetMacroValue
(MacroName
)
766 if MacorValue
is not None:
767 CurLine
= CurLine
.replace('$(' + MacroName
+ ')', MacorValue
, 1)
768 if MacorValue
.find('$(') != -1:
771 PreIndex
= StartPos
+ len(MacorValue
)
773 PreIndex
= EndPos
+ 1
774 StartPos
= CurLine
.find('$(', PreIndex
)
775 EndPos
= CurLine
.find(')', StartPos
+2)
776 self
.Profile
.FileLinesList
[ReplacedLine
- 1] = CurLine
779 if self
.__Token
== 'DEFINE':
780 if self
.__GetIfListCurrentItemStat
(IfList
):
781 if not self
.__CurSection
:
782 raise Warning("macro cannot be defined in Rule section or out of section", self
.FileName
, self
.CurrentLineNumber
)
783 DefineLine
= self
.CurrentLineNumber
- 1
784 DefineOffset
= self
.CurrentOffsetWithinLine
- len('DEFINE')
785 if not self
.__GetNextToken
():
786 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
788 if not self
.__IsToken
( "="):
789 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
791 Value
= self
.__GetExpression
()
792 self
.__SetMacroValue
(Macro
, Value
)
793 self
.__WipeOffArea
.append(((DefineLine
, DefineOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
794 elif self
.__Token
== 'SET':
795 if not self
.__GetIfListCurrentItemStat
(IfList
):
797 SetLine
= self
.CurrentLineNumber
- 1
798 SetOffset
= self
.CurrentOffsetWithinLine
- len('SET')
799 PcdPair
= self
.__GetNextPcdName
()
800 PcdName
= "%s.%s" % (PcdPair
[1], PcdPair
[0])
801 if not self
.__IsToken
( "="):
802 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
804 Value
= self
.__GetExpression
()
805 Value
= self
.__EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
807 self
.__PcdDict
[PcdName
] = Value
809 self
.Profile
.PcdDict
[PcdPair
] = Value
810 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
811 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
813 self
.__WipeOffArea
.append(((SetLine
, SetOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
814 elif self
.__Token
in ('!ifdef', '!ifndef', '!if'):
815 IfStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
.__Token
))
816 IfList
.append([IfStartPos
, None, None])
818 CondLabel
= self
.__Token
819 Expression
= self
.__GetExpression
()
821 if CondLabel
== '!if':
822 ConditionSatisfied
= self
.__EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
824 ConditionSatisfied
= self
.__EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'in')
825 if CondLabel
== '!ifndef':
826 ConditionSatisfied
= not ConditionSatisfied
828 BranchDetermined
= ConditionSatisfied
829 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, BranchDetermined
]
830 if ConditionSatisfied
:
831 self
.__WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
832 elif self
.__Token
in ('!elseif', '!else'):
833 ElseStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
.__Token
))
835 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
838 IfList
[-1] = [ElseStartPos
, False, True]
839 self
.__WipeOffArea
.append((ElseStartPos
, (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
841 self
.__WipeOffArea
.append((IfList
[-1][0], ElseStartPos
))
842 IfList
[-1] = [ElseStartPos
, True, IfList
[-1][2]]
843 if self
.__Token
== '!elseif':
844 Expression
= self
.__GetExpression
()
845 ConditionSatisfied
= self
.__EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
846 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, IfList
[-1][2]]
850 IfList
[-1][1] = False
853 self
.__WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
854 elif self
.__Token
== '!endif':
856 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
858 self
.__WipeOffArea
.append(((self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len('!endif')), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
860 self
.__WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
863 elif not IfList
: # Don't use PCDs inside conditional directive
864 if self
.CurrentLineNumber
<= RegionLayoutLine
:
865 # Don't try the same line twice
867 SetPcd
= ShortcutPcdPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
869 self
.__PcdDict
[SetPcd
.group('name')] = SetPcd
.group('value')
870 RegionLayoutLine
= self
.CurrentLineNumber
872 RegionSize
= RegionSizePattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
874 RegionLayoutLine
= self
.CurrentLineNumber
876 RegionSizeGuid
= RegionSizeGuidPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
])
877 if not RegionSizeGuid
:
878 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
880 self
.__PcdDict
[RegionSizeGuid
.group('base')] = RegionSize
.group('base')
881 self
.__PcdDict
[RegionSizeGuid
.group('size')] = RegionSize
.group('size')
882 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
885 raise Warning("Missing !endif", self
.FileName
, self
.CurrentLineNumber
)
888 def __CollectMacroPcd(self
):
892 MacroDict
.update(GlobalData
.gPlatformPcds
)
893 MacroDict
.update(self
.__PcdDict
)
896 MacroDict
.update(GlobalData
.gPlatformDefines
)
898 if self
.__CurSection
:
900 ScopeMacro
= self
.__MacroDict
['COMMON', 'COMMON', 'COMMON']
902 MacroDict
.update(ScopeMacro
)
905 ScopeMacro
= self
.__MacroDict
[
906 self
.__CurSection
[0],
907 self
.__CurSection
[1],
911 MacroDict
.update(ScopeMacro
)
913 MacroDict
.update(GlobalData
.gGlobalDefines
)
914 MacroDict
.update(GlobalData
.gCommandLineDefines
)
915 if GlobalData
.BuildOptionPcd
:
916 for Item
in GlobalData
.BuildOptionPcd
:
917 if type(Item
) is tuple:
919 PcdName
, TmpValue
= Item
.split("=")
920 TmpValue
= BuildOptionValue(TmpValue
, {})
921 MacroDict
[PcdName
.strip()] = TmpValue
926 def __EvaluateConditional(self
, Expression
, Line
, Op
= None, Value
= None):
927 FileLineTuple
= GetRealFileLine(self
.FileName
, Line
)
928 MacroPcdDict
= self
.__CollectMacroPcd
()
932 return ValueExpression(Expression
, MacroPcdDict
)(True)
934 return ValueExpression(Expression
, MacroPcdDict
)()
935 except WrnExpression
, Excpt
:
937 # Catch expression evaluation warning here. We need to report
938 # the precise number of line and return the evaluation result
940 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
941 File
=self
.FileName
, ExtraData
=self
.__CurrentLine
(),
944 except Exception, Excpt
:
945 if hasattr(Excpt
, 'Pcd'):
946 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
947 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
948 raise Warning("Cannot use this PCD (%s) in an expression as"
949 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
950 " of the DSC file (%s), and it is currently defined in this section:"
951 " %s, line #: %d." % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE'], Info
[0], Info
[1]),
954 raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE']),
957 raise Warning(str(Excpt
), *FileLineTuple
)
959 if Expression
.startswith('$(') and Expression
[-1] == ')':
960 Expression
= Expression
[2:-1]
961 return Expression
in MacroPcdDict
963 ## __IsToken() method
965 # Check whether input string is found from current char position along
966 # If found, the string value is put into self.__Token
968 # @param self The object pointer
969 # @param String The string to search
970 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
971 # @retval True Successfully find string, file buffer pointer moved forward
972 # @retval False Not able to find string, file buffer pointer not changed
974 def __IsToken(self
, String
, IgnoreCase
= False):
975 self
.__SkipWhiteSpace
()
977 # Only consider the same line, no multi-line token allowed
978 StartPos
= self
.CurrentOffsetWithinLine
981 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
983 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
985 self
.CurrentOffsetWithinLine
+= len(String
)
986 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
990 ## __IsKeyword() method
992 # Check whether input keyword is found from current char position along, whole word only!
993 # If found, the string value is put into self.__Token
995 # @param self The object pointer
996 # @param Keyword The string to search
997 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
998 # @retval True Successfully find string, file buffer pointer moved forward
999 # @retval False Not able to find string, file buffer pointer not changed
1001 def __IsKeyword(self
, KeyWord
, IgnoreCase
= False):
1002 self
.__SkipWhiteSpace
()
1004 # Only consider the same line, no multi-line token allowed
1005 StartPos
= self
.CurrentOffsetWithinLine
1008 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(KeyWord
.upper())
1010 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(KeyWord
)
1012 followingChar
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
+ len(KeyWord
)]
1013 if not str(followingChar
).isspace() and followingChar
not in SEPERATOR_TUPLE
:
1015 self
.CurrentOffsetWithinLine
+= len(KeyWord
)
1016 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1020 def __GetExpression(self
):
1021 Line
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
1022 Index
= len(Line
) - 1
1023 while Line
[Index
] in ['\r', '\n']:
1025 ExpressionString
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:Index
+1]
1026 self
.CurrentOffsetWithinLine
+= len(ExpressionString
)
1027 ExpressionString
= ExpressionString
.strip()
1028 return ExpressionString
1030 ## __GetNextWord() method
1032 # Get next C name from file lines
1033 # If found, the string value is put into self.__Token
1035 # @param self The object pointer
1036 # @retval True Successfully find a C name string, file buffer pointer moved forward
1037 # @retval False Not able to find a C name string, file buffer pointer not changed
1039 def __GetNextWord(self
):
1040 self
.__SkipWhiteSpace
()
1041 if self
.__EndOfFile
():
1044 TempChar
= self
.__CurrentChar
()
1045 StartPos
= self
.CurrentOffsetWithinLine
1046 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_':
1048 while not self
.__EndOfLine
():
1049 TempChar
= self
.__CurrentChar
()
1050 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
1051 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-':
1057 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1062 ## __GetNextToken() method
1064 # Get next token unit before a seperator
1065 # If found, the string value is put into self.__Token
1067 # @param self The object pointer
1068 # @retval True Successfully find a token unit, file buffer pointer moved forward
1069 # @retval False Not able to find a token unit, file buffer pointer not changed
1071 def __GetNextToken(self
):
1072 # Skip leading spaces, if exist.
1073 self
.__SkipWhiteSpace
()
1074 if self
.__EndOfFile
():
1076 # Record the token start position, the position of the first non-space char.
1077 StartPos
= self
.CurrentOffsetWithinLine
1078 StartLine
= self
.CurrentLineNumber
1079 while StartLine
== self
.CurrentLineNumber
:
1080 TempChar
= self
.__CurrentChar
()
1081 # Try to find the end char that is not a space and not in seperator tuple.
1082 # That is, when we got a space or any char in the tuple, we got the end of token.
1083 if not str(TempChar
).isspace() and TempChar
not in SEPERATOR_TUPLE
:
1085 # if we happen to meet a seperator as the first char, we must proceed to get it.
1086 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1087 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPERATOR_TUPLE
:
1095 EndPos
= self
.CurrentOffsetWithinLine
1096 if self
.CurrentLineNumber
!= StartLine
:
1097 EndPos
= len(self
.Profile
.FileLinesList
[StartLine
-1])
1098 self
.__Token
= self
.Profile
.FileLinesList
[StartLine
-1][StartPos
: EndPos
]
1099 if StartPos
!= self
.CurrentOffsetWithinLine
:
1104 def __GetNextOp(self
):
1105 # Skip leading spaces, if exist.
1106 self
.__SkipWhiteSpace
()
1107 if self
.__EndOfFile
():
1109 # Record the token start position, the position of the first non-space char.
1110 StartPos
= self
.CurrentOffsetWithinLine
1111 while not self
.__EndOfLine
():
1112 TempChar
= self
.__CurrentChar
()
1113 # Try to find the end char that is not a space
1114 if not str(TempChar
).isspace():
1121 if StartPos
!= self
.CurrentOffsetWithinLine
:
1122 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1126 ## __GetNextGuid() method
1128 # Get next token unit before a seperator
1129 # If found, the GUID string is put into self.__Token
1131 # @param self The object pointer
1132 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward
1133 # @retval False Not able to find a registry format GUID, file buffer pointer not changed
1135 def __GetNextGuid(self
):
1137 if not self
.__GetNextToken
():
1139 if gGuidPattern
.match(self
.__Token
) is not None:
1145 def __Verify(self
, Name
, Value
, Scope
):
1146 if Scope
in ['UINT64', 'UINT8']:
1149 ValueNumber
= int (Value
, 0)
1151 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value is not valid dec or hex number for %s." % Name
)
1153 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value can't be set to negative value for %s." % Name
)
1154 if Scope
== 'UINT64':
1155 if ValueNumber
>= 0x10000000000000000:
1156 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "Too large value for %s." % Name
)
1157 if Scope
== 'UINT8':
1158 if ValueNumber
>= 0x100:
1159 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "Too large value for %s." % Name
)
1162 ## __UndoToken() method
1164 # Go back one token unit in file buffer
1166 # @param self The object pointer
1168 def __UndoToken(self
):
1169 self
.__UndoOneChar
()
1170 while self
.__CurrentChar
().isspace():
1171 if not self
.__UndoOneChar
():
1176 StartPos
= self
.CurrentOffsetWithinLine
1177 CurrentLine
= self
.CurrentLineNumber
1178 while CurrentLine
== self
.CurrentLineNumber
:
1180 TempChar
= self
.__CurrentChar
()
1181 # Try to find the end char that is not a space and not in seperator tuple.
1182 # That is, when we got a space or any char in the tuple, we got the end of token.
1183 if not str(TempChar
).isspace() and not TempChar
in SEPERATOR_TUPLE
:
1184 if not self
.__UndoOneChar
():
1186 # if we happen to meet a seperator as the first char, we must proceed to get it.
1187 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1188 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPERATOR_TUPLE
:
1195 ## __HexDigit() method
1197 # Whether char input is a Hex data bit
1199 # @param self The object pointer
1200 # @param TempChar The char to test
1201 # @retval True The char is a Hex data bit
1202 # @retval False The char is NOT a Hex data bit
1204 def __HexDigit(self
, TempChar
):
1205 if (TempChar
>= 'a' and TempChar
<= 'f') or (TempChar
>= 'A' and TempChar
<= 'F') \
1206 or (TempChar
>= '0' and TempChar
<= '9'):
1211 def __IsHex(self
, HexStr
):
1212 if not HexStr
.upper().startswith("0X"):
1214 if len(self
.__Token
) <= 2:
1216 charList
= [c
for c
in HexStr
[2 : ] if not self
.__HexDigit
( c
)]
1217 if len(charList
) == 0:
1221 ## __GetNextHexNumber() method
1223 # Get next HEX data before a seperator
1224 # If found, the HEX data is put into self.__Token
1226 # @param self The object pointer
1227 # @retval True Successfully find a HEX data, file buffer pointer moved forward
1228 # @retval False Not able to find a HEX data, file buffer pointer not changed
1230 def __GetNextHexNumber(self
):
1231 if not self
.__GetNextToken
():
1233 if self
.__IsHex
(self
.__Token
):
1239 ## __GetNextDecimalNumber() method
1241 # Get next decimal data before a seperator
1242 # If found, the decimal data is put into self.__Token
1244 # @param self The object pointer
1245 # @retval True Successfully find a decimal data, file buffer pointer moved forward
1246 # @retval False Not able to find a decimal data, file buffer pointer not changed
1248 def __GetNextDecimalNumber(self
):
1249 if not self
.__GetNextToken
():
1251 if self
.__Token
.isdigit():
1257 ## __GetNextPcdName() method
1259 # Get next PCD token space C name and PCD C name pair before a seperator
1260 # If found, the decimal data is put into self.__Token
1262 # @param self The object pointer
1263 # @retval Tuple PCD C name and PCD token space C name pair
1265 def __GetNextPcdName(self
):
1266 if not self
.__GetNextWord
():
1267 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1268 pcdTokenSpaceCName
= self
.__Token
1270 if not self
.__IsToken
( "."):
1271 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1273 if not self
.__GetNextWord
():
1274 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1275 pcdCName
= self
.__Token
1277 return (pcdCName
, pcdTokenSpaceCName
)
1279 ## __GetStringData() method
1281 # Get string contents quoted in ""
1282 # If found, the decimal data is put into self.__Token
1284 # @param self The object pointer
1285 # @retval True Successfully find a string data, file buffer pointer moved forward
1286 # @retval False Not able to find a string data, file buffer pointer not changed
1288 def __GetStringData(self
):
1289 if self
.__Token
.startswith("\"") or self
.__Token
.startswith("L\""):
1291 self
.__SkipToToken
("\"")
1292 currentLineNumber
= self
.CurrentLineNumber
1294 if not self
.__SkipToToken
("\""):
1295 raise Warning("Missing Quote \" for String", self
.FileName
, self
.CurrentLineNumber
)
1296 if currentLineNumber
!= self
.CurrentLineNumber
:
1297 raise Warning("Missing Quote \" for String", self
.FileName
, self
.CurrentLineNumber
)
1298 self
.__Token
= self
.__SkippedChars
.rstrip('\"')
1301 elif self
.__Token
.startswith("\'") or self
.__Token
.startswith("L\'"):
1303 self
.__SkipToToken
("\'")
1304 currentLineNumber
= self
.CurrentLineNumber
1306 if not self
.__SkipToToken
("\'"):
1307 raise Warning("Missing Quote \' for String", self
.FileName
, self
.CurrentLineNumber
)
1308 if currentLineNumber
!= self
.CurrentLineNumber
:
1309 raise Warning("Missing Quote \' for String", self
.FileName
, self
.CurrentLineNumber
)
1310 self
.__Token
= self
.__SkippedChars
.rstrip('\'')
1316 ## __SkipToToken() method
1318 # Search forward in file buffer for the string
1319 # The skipped chars are put into self.__SkippedChars
1321 # @param self The object pointer
1322 # @param String The string to search
1323 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
1324 # @retval True Successfully find the string, file buffer pointer moved forward
1325 # @retval False Not able to find the string, file buffer pointer not changed
1327 def __SkipToToken(self
, String
, IgnoreCase
= False):
1328 StartPos
= self
.GetFileBufferPos()
1330 self
.__SkippedChars
= ""
1331 while not self
.__EndOfFile
():
1334 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
1336 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
1338 self
.CurrentOffsetWithinLine
+= len(String
)
1339 self
.__SkippedChars
+= String
1341 self
.__SkippedChars
+= str(self
.__CurrentChar
())
1344 self
.SetFileBufferPos( StartPos
)
1345 self
.__SkippedChars
= ""
1348 ## GetFileBufferPos() method
1350 # Return the tuple of current line and offset within the line
1352 # @param self The object pointer
1353 # @retval Tuple Line number and offset pair
1355 def GetFileBufferPos(self
):
1356 return (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
)
1358 ## SetFileBufferPos() method
1360 # Restore the file buffer position
1362 # @param self The object pointer
1363 # @param Pos The new file buffer position
1365 def SetFileBufferPos(self
, Pos
):
1366 (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
) = Pos
1368 ## Preprocess() method
1370 # Preprocess comment, conditional directive, include directive, replace macro.
1371 # Exception will be raised if syntax error found
1373 # @param self The object pointer
1375 def Preprocess(self
):
1376 self
.__StringToList
()
1377 self
.PreprocessFile()
1378 self
.PreprocessIncludeFile()
1379 self
.__StringToList
()
1380 self
.PreprocessFile()
1381 self
.PreprocessConditionalStatement()
1382 self
.__StringToList
()
1383 for Pos
in self
.__WipeOffArea
:
1384 self
.__ReplaceFragment
(Pos
[0], Pos
[1])
1385 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
1387 while self
.__GetDefines
():
1390 ## ParseFile() method
1392 # Parse the file profile buffer to extract fd, fv ... information
1393 # Exception will be raised if syntax error found
1395 # @param self The object pointer
1397 def ParseFile(self
):
1402 # Keep processing sections of the FDF until no new sections or a syntax error is found
1404 while self
.__GetFd
() or self
.__GetFv
() or self
.__GetFmp
() or self
.__GetCapsule
() or self
.__GetVtf
() or self
.__GetRule
() or self
.__GetOptionRom
():
1409 #'\n\tGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \
1410 # At this point, the closest parent would be the included file itself
1411 Profile
= GetParentAtLine(X
.OriginalLineNumber
)
1412 if Profile
is not None:
1413 X
.Message
+= ' near line %d, column %d: %s' \
1414 % (X
.LineNumber
, 0, Profile
.FileLinesList
[X
.LineNumber
-1])
1416 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1417 X
.Message
+= ' near line %d, column %d: %s' \
1418 % (FileLineTuple
[1], self
.CurrentOffsetWithinLine
+ 1, self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:].rstrip('\n').rstrip('\r'))
1421 ## SectionParser() method
1423 # Parse the file section info
1424 # Exception will be raised if syntax error found
1426 # @param self The object pointer
1427 # @param section The section string
1429 def SectionParser(self
, section
):
1431 if not S
.startswith("[DEFINES") and not S
.startswith("[FD.") and not S
.startswith("[FV.") and not S
.startswith("[CAPSULE.") \
1432 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM.") and not S
.startswith('[FMPPAYLOAD.'):
1433 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.], [FMPPAYLOAD.])", self
.FileName
, self
.CurrentLineNumber
)
1435 ## __GetDefines() method
1437 # Get Defines section contents and store its data into AllMacrosList
1439 # @param self The object pointer
1440 # @retval True Successfully find a Defines
1441 # @retval False Not able to find a Defines
1443 def __GetDefines(self
):
1445 if not self
.__GetNextToken
():
1448 S
= self
.__Token
.upper()
1449 if S
.startswith("[") and not S
.startswith("[DEFINES"):
1450 self
.SectionParser(S
)
1455 if not self
.__IsToken
("[DEFINES", True):
1456 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1457 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1458 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1459 raise Warning("expected [DEFINES", self
.FileName
, self
.CurrentLineNumber
)
1461 if not self
.__IsToken
( "]"):
1462 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
1464 while self
.__GetNextWord
():
1465 # handle the SET statement
1466 if self
.__Token
== 'SET':
1468 self
.__GetSetStatement
(None)
1471 Macro
= self
.__Token
1473 if not self
.__IsToken
("="):
1474 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1475 if not self
.__GetNextToken
() or self
.__Token
.startswith('['):
1476 raise Warning("expected MACRO value", self
.FileName
, self
.CurrentLineNumber
)
1477 Value
= self
.__Token
1483 # Get FD section contents and store its data into FD dictionary of self.Profile
1485 # @param self The object pointer
1486 # @retval True Successfully find a FD
1487 # @retval False Not able to find a FD
1491 if not self
.__GetNextToken
():
1494 S
= self
.__Token
.upper()
1495 if S
.startswith("[") and not S
.startswith("[FD."):
1496 if not S
.startswith("[FV.") and not S
.startswith('[FMPPAYLOAD.') and not S
.startswith("[CAPSULE.") \
1497 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM."):
1498 raise Warning("Unknown section", self
.FileName
, self
.CurrentLineNumber
)
1503 if not self
.__IsToken
("[FD.", True):
1504 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1505 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1506 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1507 raise Warning("expected [FD.]", self
.FileName
, self
.CurrentLineNumber
)
1509 FdName
= self
.__GetUiName
()
1511 if len (self
.Profile
.FdDict
) == 0:
1512 FdName
= GenFdsGlobalVariable
.PlatformName
1513 if FdName
== "" and GlobalData
.gActivePlatform
:
1514 FdName
= GlobalData
.gActivePlatform
.PlatformName
1515 self
.Profile
.FdNameNotSet
= True
1517 raise Warning("expected FdName in [FD.] section", self
.FileName
, self
.CurrentLineNumber
)
1518 self
.CurrentFdName
= FdName
.upper()
1520 if self
.CurrentFdName
in self
.Profile
.FdDict
:
1521 raise Warning("Unexpected the same FD name", self
.FileName
, self
.CurrentLineNumber
)
1523 if not self
.__IsToken
( "]"):
1524 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
1527 FdObj
.FdUiName
= self
.CurrentFdName
1528 self
.Profile
.FdDict
[self
.CurrentFdName
] = FdObj
1530 if len (self
.Profile
.FdDict
) > 1 and self
.Profile
.FdNameNotSet
:
1531 raise Warning("expected all FDs have their name", self
.FileName
, self
.CurrentLineNumber
)
1533 Status
= self
.__GetCreateFile
(FdObj
)
1535 raise Warning("FD name error", self
.FileName
, self
.CurrentLineNumber
)
1537 while self
.__GetTokenStatements
(FdObj
):
1539 for Attr
in ("BaseAddress", "Size", "ErasePolarity"):
1540 if getattr(FdObj
, Attr
) is None:
1541 self
.__GetNextToken
()
1542 raise Warning("Keyword %s missing" % Attr
, self
.FileName
, self
.CurrentLineNumber
)
1544 if not FdObj
.BlockSizeList
:
1545 FdObj
.BlockSizeList
.append((1, FdObj
.Size
, None))
1547 self
.__GetDefineStatements
(FdObj
)
1549 self
.__GetSetStatements
(FdObj
)
1551 if not self
.__GetRegionLayout
(FdObj
):
1552 raise Warning("expected region layout", self
.FileName
, self
.CurrentLineNumber
)
1554 while self
.__GetRegionLayout
(FdObj
):
1558 ## __GetUiName() method
1560 # Return the UI name of a section
1562 # @param self The object pointer
1563 # @retval FdName UI name
1565 def __GetUiName(self
):
1567 if self
.__GetNextWord
():
1572 ## __GetCreateFile() method
1574 # Return the output file name of object
1576 # @param self The object pointer
1577 # @param Obj object whose data will be stored in file
1578 # @retval FdName UI name
1580 def __GetCreateFile(self
, Obj
):
1582 if self
.__IsKeyword
( "CREATE_FILE"):
1583 if not self
.__IsToken
( "="):
1584 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1586 if not self
.__GetNextToken
():
1587 raise Warning("expected file name", self
.FileName
, self
.CurrentLineNumber
)
1589 FileName
= self
.__Token
1590 Obj
.CreateFileName
= FileName
1594 ## __GetTokenStatements() method
1596 # Get token statements
1598 # @param self The object pointer
1599 # @param Obj for whom token statement is got
1601 def __GetTokenStatements(self
, Obj
):
1602 if self
.__IsKeyword
( "BaseAddress"):
1603 if not self
.__IsToken
( "="):
1604 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1606 if not self
.__GetNextHexNumber
():
1607 raise Warning("expected Hex base address", self
.FileName
, self
.CurrentLineNumber
)
1609 Obj
.BaseAddress
= self
.__Token
1611 if self
.__IsToken
( "|"):
1612 pcdPair
= self
.__GetNextPcdName
()
1613 Obj
.BaseAddressPcd
= pcdPair
1614 self
.Profile
.PcdDict
[pcdPair
] = Obj
.BaseAddress
1615 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1616 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1619 if self
.__IsKeyword
( "Size"):
1620 if not self
.__IsToken
( "="):
1621 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1623 if not self
.__GetNextHexNumber
():
1624 raise Warning("expected Hex size", self
.FileName
, self
.CurrentLineNumber
)
1627 if self
.__IsToken
( "|"):
1628 pcdPair
= self
.__GetNextPcdName
()
1629 Obj
.SizePcd
= pcdPair
1630 self
.Profile
.PcdDict
[pcdPair
] = Size
1631 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1632 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1633 Obj
.Size
= long(Size
, 0)
1636 if self
.__IsKeyword
( "ErasePolarity"):
1637 if not self
.__IsToken
( "="):
1638 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1640 if not self
.__GetNextToken
():
1641 raise Warning("expected Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1643 if self
.__Token
!= "1" and self
.__Token
!= "0":
1644 raise Warning("expected 1 or 0 Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1646 Obj
.ErasePolarity
= self
.__Token
1649 return self
.__GetBlockStatements
(Obj
)
1651 ## __GetAddressStatements() method
1653 # Get address statements
1655 # @param self The object pointer
1656 # @param Obj for whom address statement is got
1657 # @retval True Successfully find
1658 # @retval False Not able to find
1660 def __GetAddressStatements(self
, Obj
):
1662 if self
.__IsKeyword
("BsBaseAddress"):
1663 if not self
.__IsToken
( "="):
1664 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1666 if not self
.__GetNextDecimalNumber
() and not self
.__GetNextHexNumber
():
1667 raise Warning("expected address", self
.FileName
, self
.CurrentLineNumber
)
1669 BsAddress
= long(self
.__Token
, 0)
1670 Obj
.BsBaseAddress
= BsAddress
1672 if self
.__IsKeyword
("RtBaseAddress"):
1673 if not self
.__IsToken
( "="):
1674 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1676 if not self
.__GetNextDecimalNumber
() and not self
.__GetNextHexNumber
():
1677 raise Warning("expected address", self
.FileName
, self
.CurrentLineNumber
)
1679 RtAddress
= long(self
.__Token
, 0)
1680 Obj
.RtBaseAddress
= RtAddress
1682 ## __GetBlockStatements() method
1684 # Get block statements
1686 # @param self The object pointer
1687 # @param Obj for whom block statement is got
1689 def __GetBlockStatements(self
, Obj
):
1691 while self
.__GetBlockStatement
(Obj
):
1694 Item
= Obj
.BlockSizeList
[-1]
1695 if Item
[0] is None or Item
[1] is None:
1696 raise Warning("expected block statement", self
.FileName
, self
.CurrentLineNumber
)
1699 ## __GetBlockStatement() method
1701 # Get block statement
1703 # @param self The object pointer
1704 # @param Obj for whom block statement is got
1705 # @retval True Successfully find
1706 # @retval False Not able to find
1708 def __GetBlockStatement(self
, Obj
):
1709 if not self
.__IsKeyword
( "BlockSize"):
1712 if not self
.__IsToken
( "="):
1713 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1715 if not self
.__GetNextHexNumber
() and not self
.__GetNextDecimalNumber
():
1716 raise Warning("expected Hex or Integer block size", self
.FileName
, self
.CurrentLineNumber
)
1718 BlockSize
= self
.__Token
1720 if self
.__IsToken
( "|"):
1721 PcdPair
= self
.__GetNextPcdName
()
1722 BlockSizePcd
= PcdPair
1723 self
.Profile
.PcdDict
[PcdPair
] = BlockSize
1724 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1725 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1726 BlockSize
= long(BlockSize
, 0)
1729 if self
.__IsKeyword
( "NumBlocks"):
1730 if not self
.__IsToken
( "="):
1731 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1733 if not self
.__GetNextDecimalNumber
() and not self
.__GetNextHexNumber
():
1734 raise Warning("expected block numbers", self
.FileName
, self
.CurrentLineNumber
)
1736 BlockNumber
= long(self
.__Token
, 0)
1738 Obj
.BlockSizeList
.append((BlockSize
, BlockNumber
, BlockSizePcd
))
1741 ## __GetDefineStatements() method
1743 # Get define statements
1745 # @param self The object pointer
1746 # @param Obj for whom define statement is got
1747 # @retval True Successfully find
1748 # @retval False Not able to find
1750 def __GetDefineStatements(self
, Obj
):
1751 while self
.__GetDefineStatement
( Obj
):
1754 ## __GetDefineStatement() method
1756 # Get define statement
1758 # @param self The object pointer
1759 # @param Obj for whom define statement is got
1760 # @retval True Successfully find
1761 # @retval False Not able to find
1763 def __GetDefineStatement(self
, Obj
):
1764 if self
.__IsKeyword
("DEFINE"):
1765 self
.__GetNextToken
()
1766 Macro
= self
.__Token
1767 if not self
.__IsToken
( "="):
1768 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1770 if not self
.__GetNextToken
():
1771 raise Warning("expected value", self
.FileName
, self
.CurrentLineNumber
)
1773 Value
= self
.__Token
1774 Macro
= '$(' + Macro
+ ')'
1775 Obj
.DefineVarDict
[Macro
] = Value
1780 ## __GetSetStatements() method
1782 # Get set statements
1784 # @param self The object pointer
1785 # @param Obj for whom set statement is got
1786 # @retval True Successfully find
1787 # @retval False Not able to find
1789 def __GetSetStatements(self
, Obj
):
1790 while self
.__GetSetStatement
(Obj
):
1793 ## __GetSetStatement() method
1797 # @param self The object pointer
1798 # @param Obj for whom set statement is got
1799 # @retval True Successfully find
1800 # @retval False Not able to find
1802 def __GetSetStatement(self
, Obj
):
1803 if self
.__IsKeyword
("SET"):
1804 PcdPair
= self
.__GetNextPcdName
()
1806 if not self
.__IsToken
( "="):
1807 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1809 Value
= self
.__GetExpression
()
1810 Value
= self
.__EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
1813 Obj
.SetVarDict
[PcdPair
] = Value
1814 self
.Profile
.PcdDict
[PcdPair
] = Value
1815 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1816 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1821 ## __CalcRegionExpr(self)
1823 # Calculate expression for offset or size of a region
1825 # @return: None if invalid expression
1826 # Calculated number if successfully
1828 def __CalcRegionExpr(self
):
1829 StartPos
= self
.GetFileBufferPos()
1832 while not self
.__EndOfFile
():
1833 CurCh
= self
.__CurrentChar
()
1839 if CurCh
in '|\r\n' and PairCount
== 0:
1845 ValueExpression(Expr
,
1846 self
.__CollectMacroPcd
()
1849 self
.SetFileBufferPos(StartPos
)
1852 ## __GetRegionLayout() method
1854 # Get region layout for FD
1856 # @param self The object pointer
1857 # @param Fd for whom region is got
1858 # @retval True Successfully find
1859 # @retval False Not able to find
1861 def __GetRegionLayout(self
, Fd
):
1862 Offset
= self
.__CalcRegionExpr
()
1866 RegionObj
= Region
.Region()
1867 RegionObj
.Offset
= Offset
1868 Fd
.RegionList
.append(RegionObj
)
1870 if not self
.__IsToken
( "|"):
1871 raise Warning("expected '|'", self
.FileName
, self
.CurrentLineNumber
)
1873 Size
= self
.__CalcRegionExpr
()
1875 raise Warning("expected Region Size", self
.FileName
, self
.CurrentLineNumber
)
1876 RegionObj
.Size
= Size
1878 if not self
.__GetNextWord
():
1881 if not self
.__Token
in ("SET", "FV", "FILE", "DATA", "CAPSULE", "INF"):
1883 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]
1884 # Or it might be next region's offset described by an expression which starts with a PCD.
1885 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size
1888 IsRegionPcd
= (RegionSizeGuidPattern
.match(self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
:]) or
1889 RegionOffsetPcdPattern
.match(self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
:]))
1891 RegionObj
.PcdOffset
= self
.__GetNextPcdName
()
1892 self
.Profile
.PcdDict
[RegionObj
.PcdOffset
] = "0x%08X" % (RegionObj
.Offset
+ long(Fd
.BaseAddress
, 0))
1893 self
.__PcdDict
['%s.%s' % (RegionObj
.PcdOffset
[1], RegionObj
.PcdOffset
[0])] = "0x%x" % RegionObj
.Offset
1894 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1895 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdOffset
] = FileLineTuple
1896 if self
.__IsToken
( "|"):
1897 RegionObj
.PcdSize
= self
.__GetNextPcdName
()
1898 self
.Profile
.PcdDict
[RegionObj
.PcdSize
] = "0x%08X" % RegionObj
.Size
1899 self
.__PcdDict
['%s.%s' % (RegionObj
.PcdSize
[1], RegionObj
.PcdSize
[0])] = "0x%x" % RegionObj
.Size
1900 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1901 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdSize
] = FileLineTuple
1903 if not self
.__GetNextWord
():
1906 if self
.__Token
== "SET":
1908 self
.__GetSetStatements
( RegionObj
)
1909 if not self
.__GetNextWord
():
1912 elif self
.__Token
== "FV":
1914 self
.__GetRegionFvType
( RegionObj
)
1916 elif self
.__Token
== "CAPSULE":
1918 self
.__GetRegionCapType
( RegionObj
)
1920 elif self
.__Token
== "FILE":
1922 self
.__GetRegionFileType
(RegionObj
)
1924 elif self
.__Token
== "INF":
1926 RegionObj
.RegionType
= "INF"
1927 while self
.__IsKeyword
("INF"):
1929 ffsInf
= self
.__ParseInfStatement
()
1932 RegionObj
.RegionDataList
.append(ffsInf
)
1934 elif self
.__Token
== "DATA":
1936 self
.__GetRegionDataType
(RegionObj
)
1939 if self
.__GetRegionLayout
(Fd
):
1941 raise Warning("A valid region type was not found. "
1942 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
1943 self
.FileName
, self
.CurrentLineNumber
)
1947 ## __GetRegionFvType() method
1949 # Get region fv data for region
1951 # @param self The object pointer
1952 # @param RegionObj for whom region data is got
1954 def __GetRegionFvType(self
, RegionObj
):
1956 if not self
.__IsKeyword
( "FV"):
1957 raise Warning("expected Keyword 'FV'", self
.FileName
, self
.CurrentLineNumber
)
1959 if not self
.__IsToken
( "="):
1960 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1962 if not self
.__GetNextToken
():
1963 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
1965 RegionObj
.RegionType
= "FV"
1966 RegionObj
.RegionDataList
.append((self
.__Token
).upper())
1968 while self
.__IsKeyword
( "FV"):
1970 if not self
.__IsToken
( "="):
1971 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1973 if not self
.__GetNextToken
():
1974 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
1976 RegionObj
.RegionDataList
.append((self
.__Token
).upper())
1978 ## __GetRegionCapType() method
1980 # Get region capsule data for region
1982 # @param self The object pointer
1983 # @param RegionObj for whom region data is got
1985 def __GetRegionCapType(self
, RegionObj
):
1987 if not self
.__IsKeyword
("CAPSULE"):
1988 raise Warning("expected Keyword 'CAPSULE'", self
.FileName
, self
.CurrentLineNumber
)
1990 if not self
.__IsToken
("="):
1991 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1993 if not self
.__GetNextToken
():
1994 raise Warning("expected CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1996 RegionObj
.RegionType
= "CAPSULE"
1997 RegionObj
.RegionDataList
.append(self
.__Token
)
1999 while self
.__IsKeyword
("CAPSULE"):
2001 if not self
.__IsToken
("="):
2002 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2004 if not self
.__GetNextToken
():
2005 raise Warning("expected CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
2007 RegionObj
.RegionDataList
.append(self
.__Token
)
2009 ## __GetRegionFileType() method
2011 # Get region file data for region
2013 # @param self The object pointer
2014 # @param RegionObj for whom region data is got
2016 def __GetRegionFileType(self
, RegionObj
):
2018 if not self
.__IsKeyword
( "FILE"):
2019 raise Warning("expected Keyword 'FILE'", self
.FileName
, self
.CurrentLineNumber
)
2021 if not self
.__IsToken
( "="):
2022 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2024 if not self
.__GetNextToken
():
2025 raise Warning("expected File name", self
.FileName
, self
.CurrentLineNumber
)
2027 RegionObj
.RegionType
= "FILE"
2028 RegionObj
.RegionDataList
.append( self
.__Token
)
2030 while self
.__IsKeyword
( "FILE"):
2032 if not self
.__IsToken
( "="):
2033 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2035 if not self
.__GetNextToken
():
2036 raise Warning("expected FILE name", self
.FileName
, self
.CurrentLineNumber
)
2038 RegionObj
.RegionDataList
.append(self
.__Token
)
2040 ## __GetRegionDataType() method
2042 # Get region array data for region
2044 # @param self The object pointer
2045 # @param RegionObj for whom region data is got
2047 def __GetRegionDataType(self
, RegionObj
):
2049 if not self
.__IsKeyword
( "DATA"):
2050 raise Warning("expected Region Data type", self
.FileName
, self
.CurrentLineNumber
)
2052 if not self
.__IsToken
( "="):
2053 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2055 if not self
.__IsToken
( "{"):
2056 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2058 if not self
.__GetNextHexNumber
():
2059 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2061 if len(self
.__Token
) > 18:
2062 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2064 # convert hex string value to byte hex string array
2065 AllString
= self
.__Token
2066 AllStrLen
= len (AllString
)
2068 while AllStrLen
> 4:
2069 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + ","
2070 AllStrLen
= AllStrLen
- 2
2071 DataString
= DataString
+ AllString
[:AllStrLen
] + ","
2074 if len (self
.__Token
) <= 4:
2075 while self
.__IsToken
(","):
2076 if not self
.__GetNextHexNumber
():
2077 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2078 if len(self
.__Token
) > 4:
2079 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2080 DataString
+= self
.__Token
2083 if not self
.__IsToken
( "}"):
2084 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2086 DataString
= DataString
.rstrip(",")
2087 RegionObj
.RegionType
= "DATA"
2088 RegionObj
.RegionDataList
.append( DataString
)
2090 while self
.__IsKeyword
( "DATA"):
2092 if not self
.__IsToken
( "="):
2093 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2095 if not self
.__IsToken
( "{"):
2096 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2098 if not self
.__GetNextHexNumber
():
2099 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2101 if len(self
.__Token
) > 18:
2102 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2104 # convert hex string value to byte hex string array
2105 AllString
= self
.__Token
2106 AllStrLen
= len (AllString
)
2108 while AllStrLen
> 4:
2109 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + ","
2110 AllStrLen
= AllStrLen
- 2
2111 DataString
= DataString
+ AllString
[:AllStrLen
] + ","
2114 if len (self
.__Token
) <= 4:
2115 while self
.__IsToken
(","):
2116 if not self
.__GetNextHexNumber
():
2117 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2118 if len(self
.__Token
) > 4:
2119 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2120 DataString
+= self
.__Token
2123 if not self
.__IsToken
( "}"):
2124 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2126 DataString
= DataString
.rstrip(",")
2127 RegionObj
.RegionDataList
.append( DataString
)
2131 # Get FV section contents and store its data into FV dictionary of self.Profile
2133 # @param self The object pointer
2134 # @retval True Successfully find a FV
2135 # @retval False Not able to find a FV
2138 if not self
.__GetNextToken
():
2141 S
= self
.__Token
.upper()
2142 if S
.startswith("[") and not S
.startswith("[FV."):
2143 self
.SectionParser(S
)
2148 if not self
.__IsToken
("[FV.", True):
2149 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2150 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2151 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2152 raise Warning("Unknown Keyword '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2154 FvName
= self
.__GetUiName
()
2155 self
.CurrentFvName
= FvName
.upper()
2157 if not self
.__IsToken
( "]"):
2158 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
2161 FvObj
.UiFvName
= self
.CurrentFvName
2162 self
.Profile
.FvDict
[self
.CurrentFvName
] = FvObj
2164 Status
= self
.__GetCreateFile
(FvObj
)
2166 raise Warning("FV name error", self
.FileName
, self
.CurrentLineNumber
)
2168 self
.__GetDefineStatements
(FvObj
)
2170 self
.__GetAddressStatements
(FvObj
)
2172 FvObj
.FvExtEntryTypeValue
= []
2173 FvObj
.FvExtEntryType
= []
2174 FvObj
.FvExtEntryData
= []
2176 self
.__GetSetStatements
(FvObj
)
2178 if not (self
.__GetBlockStatement
(FvObj
) or self
.__GetFvBaseAddress
(FvObj
) or
2179 self
.__GetFvForceRebase
(FvObj
) or self
.__GetFvAlignment
(FvObj
) or
2180 self
.__GetFvAttributes
(FvObj
) or self
.__GetFvNameGuid
(FvObj
) or
2181 self
.__GetFvExtEntryStatement
(FvObj
) or self
.__GetFvNameString
(FvObj
)):
2184 if FvObj
.FvNameString
== 'TRUE' and not FvObj
.FvNameGuid
:
2185 raise Warning("FvNameString found but FvNameGuid was not found", self
.FileName
, self
.CurrentLineNumber
)
2187 self
.__GetAprioriSection
(FvObj
, FvObj
.DefineVarDict
.copy())
2188 self
.__GetAprioriSection
(FvObj
, FvObj
.DefineVarDict
.copy())
2191 isInf
= self
.__GetInfStatement
(FvObj
, MacroDict
= FvObj
.DefineVarDict
.copy())
2192 isFile
= self
.__GetFileStatement
(FvObj
, MacroDict
= FvObj
.DefineVarDict
.copy())
2193 if not isInf
and not isFile
:
2198 ## __GetFvAlignment() method
2200 # Get alignment for FV
2202 # @param self The object pointer
2203 # @param Obj for whom alignment is got
2204 # @retval True Successfully find a alignment statement
2205 # @retval False Not able to find a alignment statement
2207 def __GetFvAlignment(self
, Obj
):
2209 if not self
.__IsKeyword
( "FvAlignment"):
2212 if not self
.__IsToken
( "="):
2213 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2215 if not self
.__GetNextToken
():
2216 raise Warning("expected alignment value", self
.FileName
, self
.CurrentLineNumber
)
2218 if self
.__Token
.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
2219 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
2220 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
2222 raise Warning("Unknown alignment value '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2223 Obj
.FvAlignment
= self
.__Token
2226 ## __GetFvBaseAddress() method
2228 # Get BaseAddress for FV
2230 # @param self The object pointer
2231 # @param Obj for whom FvBaseAddress is got
2232 # @retval True Successfully find a FvBaseAddress statement
2233 # @retval False Not able to find a FvBaseAddress statement
2235 def __GetFvBaseAddress(self
, Obj
):
2237 if not self
.__IsKeyword
("FvBaseAddress"):
2240 if not self
.__IsToken
( "="):
2241 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2243 if not self
.__GetNextToken
():
2244 raise Warning("expected FV base address value", self
.FileName
, self
.CurrentLineNumber
)
2246 IsValidBaseAddrValue
= re
.compile('^0[x|X][0-9a-fA-F]+')
2248 if not IsValidBaseAddrValue
.match(self
.__Token
.upper()):
2249 raise Warning("Unknown FV base address value '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2250 Obj
.FvBaseAddress
= self
.__Token
2253 ## __GetFvForceRebase() method
2255 # Get FvForceRebase for FV
2257 # @param self The object pointer
2258 # @param Obj for whom FvForceRebase is got
2259 # @retval True Successfully find a FvForceRebase statement
2260 # @retval False Not able to find a FvForceRebase statement
2262 def __GetFvForceRebase(self
, Obj
):
2264 if not self
.__IsKeyword
("FvForceRebase"):
2267 if not self
.__IsToken
( "="):
2268 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2270 if not self
.__GetNextToken
():
2271 raise Warning("expected FvForceRebase value", self
.FileName
, self
.CurrentLineNumber
)
2273 if self
.__Token
.upper() not in ["TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"]:
2274 raise Warning("Unknown FvForceRebase value '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2276 if self
.__Token
.upper() in ["TRUE", "1", "0X1", "0X01"]:
2277 Obj
.FvForceRebase
= True
2278 elif self
.__Token
.upper() in ["FALSE", "0", "0X0", "0X00"]:
2279 Obj
.FvForceRebase
= False
2281 Obj
.FvForceRebase
= None
2286 ## __GetFvAttributes() method
2288 # Get attributes for FV
2290 # @param self The object pointer
2291 # @param Obj for whom attribute is got
2294 def __GetFvAttributes(self
, FvObj
):
2296 while self
.__GetNextWord
():
2299 if name
not in ("ERASE_POLARITY", "MEMORY_MAPPED", \
2300 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
2301 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
2302 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
2303 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
2304 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"):
2308 if not self
.__IsToken
( "="):
2309 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2311 if not self
.__GetNextToken
() or self
.__Token
.upper() not in ("TRUE", "FALSE", "1", "0"):
2312 raise Warning("expected TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
2314 FvObj
.FvAttributeDict
[name
] = self
.__Token
2318 ## __GetFvNameGuid() method
2320 # Get FV GUID for FV
2322 # @param self The object pointer
2323 # @param Obj for whom GUID is got
2326 def __GetFvNameGuid(self
, FvObj
):
2328 if not self
.__IsKeyword
( "FvNameGuid"):
2331 if not self
.__IsToken
( "="):
2332 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2334 if not self
.__GetNextGuid
():
2335 raise Warning("expected FV GUID value", self
.FileName
, self
.CurrentLineNumber
)
2337 FvObj
.FvNameGuid
= self
.__Token
2341 def __GetFvNameString(self
, FvObj
):
2343 if not self
.__IsKeyword
( "FvNameString"):
2346 if not self
.__IsToken
( "="):
2347 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2349 if not self
.__GetNextToken
() or self
.__Token
not in ('TRUE', 'FALSE'):
2350 raise Warning("expected TRUE or FALSE for FvNameString", self
.FileName
, self
.CurrentLineNumber
)
2352 FvObj
.FvNameString
= self
.__Token
2356 def __GetFvExtEntryStatement(self
, FvObj
):
2358 if not (self
.__IsKeyword
( "FV_EXT_ENTRY") or self
.__IsKeyword
( "FV_EXT_ENTRY_TYPE")):
2361 if not self
.__IsKeyword
("TYPE"):
2362 raise Warning("expected 'TYPE'", self
.FileName
, self
.CurrentLineNumber
)
2364 if not self
.__IsToken
( "="):
2365 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2367 if not self
.__GetNextHexNumber
() and not self
.__GetNextDecimalNumber
():
2368 raise Warning("expected Hex FV extension entry type value At Line ", self
.FileName
, self
.CurrentLineNumber
)
2370 FvObj
.FvExtEntryTypeValue
+= [self
.__Token
]
2372 if not self
.__IsToken
( "{"):
2373 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2375 if not self
.__IsKeyword
("FILE") and not self
.__IsKeyword
("DATA"):
2376 raise Warning("expected 'FILE' or 'DATA'", self
.FileName
, self
.CurrentLineNumber
)
2378 FvObj
.FvExtEntryType
+= [self
.__Token
]
2380 if self
.__Token
== 'DATA':
2382 if not self
.__IsToken
( "="):
2383 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2385 if not self
.__IsToken
( "{"):
2386 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2388 if not self
.__GetNextHexNumber
():
2389 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2391 if len(self
.__Token
) > 4:
2392 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2394 DataString
= self
.__Token
2397 while self
.__IsToken
(","):
2398 if not self
.__GetNextHexNumber
():
2399 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2400 if len(self
.__Token
) > 4:
2401 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2402 DataString
+= self
.__Token
2405 if not self
.__IsToken
( "}"):
2406 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2408 if not self
.__IsToken
( "}"):
2409 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2411 DataString
= DataString
.rstrip(",")
2412 FvObj
.FvExtEntryData
+= [DataString
]
2414 if self
.__Token
== 'FILE':
2416 if not self
.__IsToken
( "="):
2417 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2419 if not self
.__GetNextToken
():
2420 raise Warning("expected FV Extension Entry file path At Line ", self
.FileName
, self
.CurrentLineNumber
)
2422 FvObj
.FvExtEntryData
+= [self
.__Token
]
2424 if not self
.__IsToken
( "}"):
2425 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2429 ## __GetAprioriSection() method
2431 # Get token statements
2433 # @param self The object pointer
2434 # @param FvObj for whom apriori is got
2435 # @param MacroDict dictionary used to replace macro
2436 # @retval True Successfully find apriori statement
2437 # @retval False Not able to find apriori statement
2439 def __GetAprioriSection(self
, FvObj
, MacroDict
= {}):
2441 if not self
.__IsKeyword
( "APRIORI"):
2444 if not self
.__IsKeyword
("PEI") and not self
.__IsKeyword
("DXE"):
2445 raise Warning("expected Apriori file type", self
.FileName
, self
.CurrentLineNumber
)
2446 AprType
= self
.__Token
2448 if not self
.__IsToken
( "{"):
2449 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2451 AprSectionObj
= AprioriSection
.AprioriSection()
2452 AprSectionObj
.AprioriType
= AprType
2454 self
.__GetDefineStatements
(AprSectionObj
)
2455 MacroDict
.update(AprSectionObj
.DefineVarDict
)
2458 IsInf
= self
.__GetInfStatement
( AprSectionObj
, MacroDict
= MacroDict
)
2459 IsFile
= self
.__GetFileStatement
( AprSectionObj
)
2460 if not IsInf
and not IsFile
:
2463 if not self
.__IsToken
( "}"):
2464 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2466 FvObj
.AprioriSectionList
.append(AprSectionObj
)
2469 def __ParseInfStatement(self
):
2470 if not self
.__IsKeyword
("INF"):
2473 ffsInf
= FfsInfStatement
.FfsInfStatement()
2474 self
.__GetInfOptions
(ffsInf
)
2476 if not self
.__GetNextToken
():
2477 raise Warning("expected INF file path", self
.FileName
, self
.CurrentLineNumber
)
2478 ffsInf
.InfFileName
= self
.__Token
2479 if not ffsInf
.InfFileName
.endswith('.inf'):
2480 raise Warning("expected .inf file path", self
.FileName
, self
.CurrentLineNumber
)
2482 ffsInf
.CurrentLineNum
= self
.CurrentLineNumber
2483 ffsInf
.CurrentLineContent
= self
.__CurrentLine
()
2485 #Replace $(SAPCE) with real space
2486 ffsInf
.InfFileName
= ffsInf
.InfFileName
.replace('$(SPACE)', ' ')
2488 if ffsInf
.InfFileName
.replace('$(WORKSPACE)', '').find('$') == -1:
2489 #do case sensitive check for file path
2490 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2492 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2494 if not ffsInf
.InfFileName
in self
.Profile
.InfList
:
2495 self
.Profile
.InfList
.append(ffsInf
.InfFileName
)
2496 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2497 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
2499 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
2500 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
2502 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
2504 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
2506 if self
.__IsToken
('|'):
2507 if self
.__IsKeyword
('RELOCS_STRIPPED'):
2508 ffsInf
.KeepReloc
= False
2509 elif self
.__IsKeyword
('RELOCS_RETAINED'):
2510 ffsInf
.KeepReloc
= True
2512 raise Warning("Unknown reloc strip flag '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2515 ## __GetInfStatement() method
2517 # Get INF statements
2519 # @param self The object pointer
2520 # @param Obj for whom inf statement is got
2521 # @param MacroDict dictionary used to replace macro
2522 # @retval True Successfully find inf statement
2523 # @retval False Not able to find inf statement
2525 def __GetInfStatement(self
, Obj
, ForCapsule
=False, MacroDict
={}):
2526 ffsInf
= self
.__ParseInfStatement
()
2531 capsuleFfs
= CapsuleData
.CapsuleFfs()
2532 capsuleFfs
.Ffs
= ffsInf
2533 Obj
.CapsuleDataList
.append(capsuleFfs
)
2535 Obj
.FfsList
.append(ffsInf
)
2538 ## __GetInfOptions() method
2540 # Get options for INF
2542 # @param self The object pointer
2543 # @param FfsInfObj for whom option is got
2545 def __GetInfOptions(self
, FfsInfObj
):
2546 if self
.__IsKeyword
("FILE_GUID"):
2547 if not self
.__IsToken
("="):
2548 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2549 if not self
.__GetNextGuid
():
2550 raise Warning("expected GUID value", self
.FileName
, self
.CurrentLineNumber
)
2551 FfsInfObj
.OverrideGuid
= self
.__Token
2553 if self
.__IsKeyword
( "RuleOverride"):
2554 if not self
.__IsToken
( "="):
2555 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2556 if not self
.__GetNextToken
():
2557 raise Warning("expected Rule name", self
.FileName
, self
.CurrentLineNumber
)
2558 FfsInfObj
.Rule
= self
.__Token
2560 if self
.__IsKeyword
( "VERSION"):
2561 if not self
.__IsToken
( "="):
2562 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2563 if not self
.__GetNextToken
():
2564 raise Warning("expected Version", self
.FileName
, self
.CurrentLineNumber
)
2566 if self
.__GetStringData
():
2567 FfsInfObj
.Version
= self
.__Token
2569 if self
.__IsKeyword
( "UI"):
2570 if not self
.__IsToken
( "="):
2571 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2572 if not self
.__GetNextToken
():
2573 raise Warning("expected UI name", self
.FileName
, self
.CurrentLineNumber
)
2575 if self
.__GetStringData
():
2576 FfsInfObj
.Ui
= self
.__Token
2578 if self
.__IsKeyword
( "USE"):
2579 if not self
.__IsToken
( "="):
2580 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2581 if not self
.__GetNextToken
():
2582 raise Warning("expected ARCH name", self
.FileName
, self
.CurrentLineNumber
)
2583 FfsInfObj
.UseArch
= self
.__Token
2586 if self
.__GetNextToken
():
2587 p
= re
.compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
2588 if p
.match(self
.__Token
) and p
.match(self
.__Token
).span()[1] == len(self
.__Token
):
2589 FfsInfObj
.KeyStringList
.append(self
.__Token
)
2590 if not self
.__IsToken
(","):
2596 while self
.__GetNextToken
():
2597 if not p
.match(self
.__Token
):
2598 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2599 FfsInfObj
.KeyStringList
.append(self
.__Token
)
2601 if not self
.__IsToken
(","):
2604 ## __GetFileStatement() method
2606 # Get FILE statements
2608 # @param self The object pointer
2609 # @param Obj for whom FILE statement is got
2610 # @param MacroDict dictionary used to replace macro
2611 # @retval True Successfully find FILE statement
2612 # @retval False Not able to find FILE statement
2614 def __GetFileStatement(self
, Obj
, ForCapsule
= False, MacroDict
= {}):
2616 if not self
.__IsKeyword
( "FILE"):
2619 if not self
.__GetNextWord
():
2620 raise Warning("expected FFS type", self
.FileName
, self
.CurrentLineNumber
)
2622 if ForCapsule
and self
.__Token
== 'DATA':
2627 FfsFileObj
= FfsFileStatement
.FileStatement()
2628 FfsFileObj
.FvFileType
= self
.__Token
2630 if not self
.__IsToken
( "="):
2631 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2633 if not self
.__GetNextGuid
():
2634 if not self
.__GetNextWord
():
2635 raise Warning("expected File GUID", self
.FileName
, self
.CurrentLineNumber
)
2636 if self
.__Token
== 'PCD':
2637 if not self
.__IsToken
( "("):
2638 raise Warning("expected '('", self
.FileName
, self
.CurrentLineNumber
)
2639 PcdPair
= self
.__GetNextPcdName
()
2640 if not self
.__IsToken
( ")"):
2641 raise Warning("expected ')'", self
.FileName
, self
.CurrentLineNumber
)
2642 self
.__Token
= 'PCD('+PcdPair
[1]+'.'+PcdPair
[0]+')'
2644 FfsFileObj
.NameGuid
= self
.__Token
2646 self
.__GetFilePart
( FfsFileObj
, MacroDict
.copy())
2649 capsuleFfs
= CapsuleData
.CapsuleFfs()
2650 capsuleFfs
.Ffs
= FfsFileObj
2651 Obj
.CapsuleDataList
.append(capsuleFfs
)
2653 Obj
.FfsList
.append(FfsFileObj
)
2657 ## __FileCouldHaveRelocFlag() method
2659 # Check whether reloc strip flag can be set for a file type.
2661 # @param self The object pointer
2662 # @param FileType The file type to check with
2663 # @retval True This type could have relocation strip flag
2664 # @retval False No way to have it
2667 def __FileCouldHaveRelocFlag (self
, FileType
):
2668 if FileType
in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'):
2673 ## __SectionCouldHaveRelocFlag() method
2675 # Check whether reloc strip flag can be set for a section type.
2677 # @param self The object pointer
2678 # @param SectionType The section type to check with
2679 # @retval True This type could have relocation strip flag
2680 # @retval False No way to have it
2683 def __SectionCouldHaveRelocFlag (self
, SectionType
):
2684 if SectionType
in ('TE', 'PE32'):
2689 ## __GetFilePart() method
2691 # Get components for FILE statement
2693 # @param self The object pointer
2694 # @param FfsFileObj for whom component is got
2695 # @param MacroDict dictionary used to replace macro
2697 def __GetFilePart(self
, FfsFileObj
, MacroDict
= {}):
2699 self
.__GetFileOpts
( FfsFileObj
)
2701 if not self
.__IsToken
("{"):
2702 if self
.__IsKeyword
('RELOCS_STRIPPED') or self
.__IsKeyword
('RELOCS_RETAINED'):
2703 if self
.__FileCouldHaveRelocFlag
(FfsFileObj
.FvFileType
):
2704 if self
.__Token
== 'RELOCS_STRIPPED':
2705 FfsFileObj
.KeepReloc
= False
2707 FfsFileObj
.KeepReloc
= True
2709 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj
.FvFileType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
2711 if not self
.__IsToken
("{"):
2712 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2714 if not self
.__GetNextToken
():
2715 raise Warning("expected File name or section data", self
.FileName
, self
.CurrentLineNumber
)
2717 if self
.__Token
== "FV":
2718 if not self
.__IsToken
( "="):
2719 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2720 if not self
.__GetNextToken
():
2721 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
2722 FfsFileObj
.FvName
= self
.__Token
2724 elif self
.__Token
== "FD":
2725 if not self
.__IsToken
( "="):
2726 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2727 if not self
.__GetNextToken
():
2728 raise Warning("expected FD name", self
.FileName
, self
.CurrentLineNumber
)
2729 FfsFileObj
.FdName
= self
.__Token
2731 elif self
.__Token
in ("DEFINE", "APRIORI", "SECTION"):
2733 self
.__GetSectionData
( FfsFileObj
, MacroDict
)
2735 elif hasattr(FfsFileObj
, 'FvFileType') and FfsFileObj
.FvFileType
== 'RAW':
2737 self
.__GetRAWData
(FfsFileObj
, MacroDict
)
2740 FfsFileObj
.CurrentLineNum
= self
.CurrentLineNumber
2741 FfsFileObj
.CurrentLineContent
= self
.__CurrentLine
()
2742 FfsFileObj
.FileName
= self
.__Token
.replace('$(SPACE)', ' ')
2743 self
.__VerifyFile
(FfsFileObj
.FileName
)
2745 if not self
.__IsToken
( "}"):
2746 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2748 ## __GetRAWData() method
2750 # Get RAW data for FILE statement
2752 # @param self The object pointer
2753 # @param FfsFileObj for whom section is got
2754 # @param MacroDict dictionary used to replace macro
2756 def __GetRAWData(self
, FfsFileObj
, MacroDict
= {}):
2757 FfsFileObj
.FileName
= []
2758 FfsFileObj
.SubAlignment
= []
2761 if self
.__GetAlignment
():
2762 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
2763 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
2764 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2765 #For FFS, Auto is default option same to ""
2766 if not self
.__Token
== "Auto":
2767 AlignValue
= self
.__Token
2768 if not self
.__GetNextToken
():
2769 raise Warning("expected Filename value", self
.FileName
, self
.CurrentLineNumber
)
2771 FileName
= self
.__Token
.replace('$(SPACE)', ' ')
2774 raise Warning("expected Filename value", self
.FileName
, self
.CurrentLineNumber
)
2776 self
.__VerifyFile
(FileName
)
2777 File
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
)
2778 FfsFileObj
.FileName
.append(File
.Path
)
2779 FfsFileObj
.SubAlignment
.append(AlignValue
)
2781 if self
.__IsToken
( "}"):
2785 if len(FfsFileObj
.SubAlignment
) == 1:
2786 FfsFileObj
.SubAlignment
= FfsFileObj
.SubAlignment
[0]
2787 if len(FfsFileObj
.FileName
) == 1:
2788 FfsFileObj
.FileName
= FfsFileObj
.FileName
[0]
2790 ## __GetFileOpts() method
2792 # Get options for FILE statement
2794 # @param self The object pointer
2795 # @param FfsFileObj for whom options is got
2797 def __GetFileOpts(self
, FfsFileObj
):
2799 if self
.__GetNextToken
():
2800 Pattern
= re
.compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
2801 if Pattern
.match(self
.__Token
):
2802 FfsFileObj
.KeyStringList
.append(self
.__Token
)
2803 if self
.__IsToken
(","):
2804 while self
.__GetNextToken
():
2805 if not Pattern
.match(self
.__Token
):
2806 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2807 FfsFileObj
.KeyStringList
.append(self
.__Token
)
2809 if not self
.__IsToken
(","):
2815 if self
.__IsKeyword
( "FIXED", True):
2816 FfsFileObj
.Fixed
= True
2818 if self
.__IsKeyword
( "CHECKSUM", True):
2819 FfsFileObj
.CheckSum
= True
2821 if self
.__GetAlignment
():
2822 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
2823 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
2824 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2825 #For FFS, Auto is default option same to ""
2826 if not self
.__Token
== "Auto":
2827 FfsFileObj
.Alignment
= self
.__Token
2829 ## __GetAlignment() method
2831 # Return the alignment value
2833 # @param self The object pointer
2834 # @retval True Successfully find alignment
2835 # @retval False Not able to find alignment
2837 def __GetAlignment(self
):
2838 if self
.__IsKeyword
( "Align", True):
2839 if not self
.__IsToken
( "="):
2840 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2842 if not self
.__GetNextToken
():
2843 raise Warning("expected alignment value", self
.FileName
, self
.CurrentLineNumber
)
2848 ## __GetFilePart() method
2850 # Get section data for FILE statement
2852 # @param self The object pointer
2853 # @param FfsFileObj for whom section is got
2854 # @param MacroDict dictionary used to replace macro
2856 def __GetSectionData(self
, FfsFileObj
, MacroDict
= {}):
2858 Dict
.update(MacroDict
)
2860 self
.__GetDefineStatements
(FfsFileObj
)
2862 Dict
.update(FfsFileObj
.DefineVarDict
)
2863 self
.__GetAprioriSection
(FfsFileObj
, Dict
.copy())
2864 self
.__GetAprioriSection
(FfsFileObj
, Dict
.copy())
2867 IsLeafSection
= self
.__GetLeafSection
(FfsFileObj
, Dict
)
2868 IsEncapSection
= self
.__GetEncapsulationSec
(FfsFileObj
)
2869 if not IsLeafSection
and not IsEncapSection
:
2872 ## __GetLeafSection() method
2874 # Get leaf section for Obj
2876 # @param self The object pointer
2877 # @param Obj for whom leaf section is got
2878 # @param MacroDict dictionary used to replace macro
2879 # @retval True Successfully find section statement
2880 # @retval False Not able to find section statement
2882 def __GetLeafSection(self
, Obj
, MacroDict
= {}):
2884 OldPos
= self
.GetFileBufferPos()
2886 if not self
.__IsKeyword
( "SECTION"):
2887 if len(Obj
.SectionList
) == 0:
2888 raise Warning("expected SECTION", self
.FileName
, self
.CurrentLineNumber
)
2893 if self
.__GetAlignment
():
2894 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
2895 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
2896 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2897 AlignValue
= self
.__Token
2900 if self
.__IsKeyword
( "BUILD_NUM"):
2901 if not self
.__IsToken
( "="):
2902 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2904 if not self
.__GetNextToken
():
2905 raise Warning("expected Build number value", self
.FileName
, self
.CurrentLineNumber
)
2907 BuildNum
= self
.__Token
2909 if self
.__IsKeyword
( "VERSION"):
2910 if AlignValue
== 'Auto':
2911 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2912 if not self
.__IsToken
( "="):
2913 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2914 if not self
.__GetNextToken
():
2915 raise Warning("expected version", self
.FileName
, self
.CurrentLineNumber
)
2916 VerSectionObj
= VerSection
.VerSection()
2917 VerSectionObj
.Alignment
= AlignValue
2918 VerSectionObj
.BuildNum
= BuildNum
2919 if self
.__GetStringData
():
2920 VerSectionObj
.StringData
= self
.__Token
2922 VerSectionObj
.FileName
= self
.__Token
2923 Obj
.SectionList
.append(VerSectionObj
)
2925 elif self
.__IsKeyword
( "UI"):
2926 if AlignValue
== 'Auto':
2927 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2928 if not self
.__IsToken
( "="):
2929 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2930 if not self
.__GetNextToken
():
2931 raise Warning("expected UI", self
.FileName
, self
.CurrentLineNumber
)
2932 UiSectionObj
= UiSection
.UiSection()
2933 UiSectionObj
.Alignment
= AlignValue
2934 if self
.__GetStringData
():
2935 UiSectionObj
.StringData
= self
.__Token
2937 UiSectionObj
.FileName
= self
.__Token
2938 Obj
.SectionList
.append(UiSectionObj
)
2940 elif self
.__IsKeyword
( "FV_IMAGE"):
2941 if AlignValue
== 'Auto':
2942 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2943 if not self
.__IsToken
( "="):
2944 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2945 if not self
.__GetNextToken
():
2946 raise Warning("expected FV name or FV file path", self
.FileName
, self
.CurrentLineNumber
)
2948 FvName
= self
.__Token
2951 if self
.__IsToken
( "{"):
2953 FvObj
.UiFvName
= FvName
.upper()
2954 self
.__GetDefineStatements
(FvObj
)
2955 MacroDict
.update(FvObj
.DefineVarDict
)
2956 self
.__GetBlockStatement
(FvObj
)
2957 self
.__GetSetStatements
(FvObj
)
2958 self
.__GetFvAlignment
(FvObj
)
2959 self
.__GetFvAttributes
(FvObj
)
2960 self
.__GetAprioriSection
(FvObj
, MacroDict
.copy())
2961 self
.__GetAprioriSection
(FvObj
, MacroDict
.copy())
2964 IsInf
= self
.__GetInfStatement
(FvObj
, MacroDict
.copy())
2965 IsFile
= self
.__GetFileStatement
(FvObj
, MacroDict
.copy())
2966 if not IsInf
and not IsFile
:
2969 if not self
.__IsToken
( "}"):
2970 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2972 FvImageSectionObj
= FvImageSection
.FvImageSection()
2973 FvImageSectionObj
.Alignment
= AlignValue
2974 if FvObj
is not None:
2975 FvImageSectionObj
.Fv
= FvObj
2976 FvImageSectionObj
.FvName
= None
2978 FvImageSectionObj
.FvName
= FvName
.upper()
2979 FvImageSectionObj
.FvFileName
= FvName
2981 Obj
.SectionList
.append(FvImageSectionObj
)
2983 elif self
.__IsKeyword
("PEI_DEPEX_EXP") or self
.__IsKeyword
("DXE_DEPEX_EXP") or self
.__IsKeyword
("SMM_DEPEX_EXP"):
2984 if AlignValue
== 'Auto':
2985 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2986 DepexSectionObj
= DepexSection
.DepexSection()
2987 DepexSectionObj
.Alignment
= AlignValue
2988 DepexSectionObj
.DepexType
= self
.__Token
2990 if not self
.__IsToken
( "="):
2991 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2992 if not self
.__IsToken
( "{"):
2993 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2994 if not self
.__SkipToToken
( "}"):
2995 raise Warning("expected Depex expression ending '}'", self
.FileName
, self
.CurrentLineNumber
)
2997 DepexSectionObj
.Expression
= self
.__SkippedChars
.rstrip('}')
2998 Obj
.SectionList
.append(DepexSectionObj
)
3001 if not self
.__GetNextWord
():
3002 raise Warning("expected section type", self
.FileName
, self
.CurrentLineNumber
)
3004 # Encapsulation section appear, UndoToken and return
3005 if self
.__Token
== "COMPRESS" or self
.__Token
== "GUIDED":
3006 self
.SetFileBufferPos(OldPos
)
3009 if self
.__Token
not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3010 "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"):
3011 raise Warning("Unknown section type '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3012 if AlignValue
== 'Auto'and (not self
.__Token
== 'PE32') and (not self
.__Token
== 'TE'):
3013 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3016 DataSectionObj
= DataSection
.DataSection()
3017 DataSectionObj
.Alignment
= AlignValue
3018 DataSectionObj
.SecType
= self
.__Token
3020 if self
.__IsKeyword
('RELOCS_STRIPPED') or self
.__IsKeyword
('RELOCS_RETAINED'):
3021 if self
.__FileCouldHaveRelocFlag
(Obj
.FvFileType
) and self
.__SectionCouldHaveRelocFlag
(DataSectionObj
.SecType
):
3022 if self
.__Token
== 'RELOCS_STRIPPED':
3023 DataSectionObj
.KeepReloc
= False
3025 DataSectionObj
.KeepReloc
= True
3027 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
)
3029 if self
.__IsToken
("="):
3030 if not self
.__GetNextToken
():
3031 raise Warning("expected section file path", self
.FileName
, self
.CurrentLineNumber
)
3032 DataSectionObj
.SectFileName
= self
.__Token
3033 self
.__VerifyFile
(DataSectionObj
.SectFileName
)
3035 if not self
.__GetCglSection
(DataSectionObj
):
3038 Obj
.SectionList
.append(DataSectionObj
)
3044 # Check if file exists or not:
3045 # If current phase if GenFds, the file must exist;
3046 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist
3047 # @param FileName: File path to be verified.
3049 def __VerifyFile(self
, FileName
):
3050 if FileName
.replace('$(WORKSPACE)', '').find('$') != -1:
3052 if not GlobalData
.gAutoGenPhase
or not self
.__GetMacroValue
("OUTPUT_DIRECTORY") in FileName
:
3053 ErrorCode
, ErrorInfo
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
3055 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
3057 ## __GetCglSection() method
3059 # Get compressed or GUIDed section for Obj
3061 # @param self The object pointer
3062 # @param Obj for whom leaf section is got
3063 # @param AlignValue alignment value for complex section
3064 # @retval True Successfully find section statement
3065 # @retval False Not able to find section statement
3067 def __GetCglSection(self
, Obj
, AlignValue
= None):
3069 if self
.__IsKeyword
( "COMPRESS"):
3071 if self
.__IsKeyword
("PI_STD") or self
.__IsKeyword
("PI_NONE"):
3074 if not self
.__IsToken
("{"):
3075 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
3077 CompressSectionObj
= CompressSection
.CompressSection()
3078 CompressSectionObj
.Alignment
= AlignValue
3079 CompressSectionObj
.CompType
= type
3080 # Recursive sections...
3082 IsLeafSection
= self
.__GetLeafSection
(CompressSectionObj
)
3083 IsEncapSection
= self
.__GetEncapsulationSec
(CompressSectionObj
)
3084 if not IsLeafSection
and not IsEncapSection
:
3088 if not self
.__IsToken
( "}"):
3089 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
3090 Obj
.SectionList
.append(CompressSectionObj
)
3093 # raise Warning("Compress type not known")
3097 elif self
.__IsKeyword
( "GUIDED"):
3099 if self
.__GetNextGuid
():
3100 GuidValue
= self
.__Token
3102 AttribDict
= self
.__GetGuidAttrib
()
3103 if not self
.__IsToken
("{"):
3104 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
3105 GuidSectionObj
= GuidSection
.GuidSection()
3106 GuidSectionObj
.Alignment
= AlignValue
3107 GuidSectionObj
.NameGuid
= GuidValue
3108 GuidSectionObj
.SectionType
= "GUIDED"
3109 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
3110 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
3111 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
3112 # Recursive sections...
3114 IsLeafSection
= self
.__GetLeafSection
(GuidSectionObj
)
3115 IsEncapSection
= self
.__GetEncapsulationSec
(GuidSectionObj
)
3116 if not IsLeafSection
and not IsEncapSection
:
3119 if not self
.__IsToken
( "}"):
3120 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
3121 Obj
.SectionList
.append(GuidSectionObj
)
3127 ## __GetGuidAttri() method
3129 # Get attributes for GUID section
3131 # @param self The object pointer
3132 # @retval AttribDict Dictionary of key-value pair of section attributes
3134 def __GetGuidAttrib(self
):
3137 AttribDict
["PROCESSING_REQUIRED"] = "NONE"
3138 AttribDict
["AUTH_STATUS_VALID"] = "NONE"
3139 AttribDict
["EXTRA_HEADER_SIZE"] = -1
3140 while self
.__IsKeyword
("PROCESSING_REQUIRED") or self
.__IsKeyword
("AUTH_STATUS_VALID") \
3141 or self
.__IsKeyword
("EXTRA_HEADER_SIZE"):
3142 AttribKey
= self
.__Token
3144 if not self
.__IsToken
("="):
3145 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3147 if not self
.__GetNextToken
():
3148 raise Warning("expected TRUE(1)/FALSE(0)/Number", self
.FileName
, self
.CurrentLineNumber
)
3149 elif AttribKey
== "EXTRA_HEADER_SIZE":
3151 if self
.__Token
[0:2].upper() == "0X":
3154 AttribDict
[AttribKey
] = int(self
.__Token
, Base
)
3157 raise Warning("expected Number", self
.FileName
, self
.CurrentLineNumber
)
3158 elif self
.__Token
.upper() not in ("TRUE", "FALSE", "1", "0"):
3159 raise Warning("expected TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
3160 AttribDict
[AttribKey
] = self
.__Token
3164 ## __GetEncapsulationSec() method
3166 # Get encapsulation section for FILE
3168 # @param self The object pointer
3169 # @param FfsFile for whom section is got
3170 # @retval True Successfully find section statement
3171 # @retval False Not able to find section statement
3173 def __GetEncapsulationSec(self
, FfsFileObj
):
3175 OldPos
= self
.GetFileBufferPos()
3176 if not self
.__IsKeyword
( "SECTION"):
3177 if len(FfsFileObj
.SectionList
) == 0:
3178 raise Warning("expected SECTION", self
.FileName
, self
.CurrentLineNumber
)
3183 if self
.__GetAlignment
():
3184 if self
.__Token
not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
3185 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
3186 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3187 AlignValue
= self
.__Token
3189 if not self
.__GetCglSection
(FfsFileObj
, AlignValue
):
3190 self
.SetFileBufferPos(OldPos
)
3196 if not self
.__GetNextToken
():
3198 S
= self
.__Token
.upper()
3199 if S
.startswith("[") and not S
.startswith("[FMPPAYLOAD."):
3200 self
.SectionParser(S
)
3205 self
.__SkipToToken
("[FMPPAYLOAD.", True)
3206 FmpUiName
= self
.__GetUiName
().upper()
3207 if FmpUiName
in self
.Profile
.FmpPayloadDict
: