4 # Copyright (c) 2007 - 2016, 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
58 import Common
.LongFilePathOs
as os
59 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
61 ##define T_CHAR_SPACE ' '
62 ##define T_CHAR_NULL '\0'
63 ##define T_CHAR_CR '\r'
64 ##define T_CHAR_TAB '\t'
65 ##define T_CHAR_LF '\n'
66 ##define T_CHAR_SLASH '/'
67 ##define T_CHAR_BACKSLASH '\\'
68 ##define T_CHAR_DOUBLE_QUOTE '\"'
69 ##define T_CHAR_SINGLE_QUOTE '\''
70 ##define T_CHAR_STAR '*'
71 ##define T_CHAR_HASH '#'
73 (T_CHAR_SPACE
, T_CHAR_NULL
, T_CHAR_CR
, T_CHAR_TAB
, T_CHAR_LF
, T_CHAR_SLASH
, \
74 T_CHAR_BACKSLASH
, T_CHAR_DOUBLE_QUOTE
, T_CHAR_SINGLE_QUOTE
, T_CHAR_STAR
, T_CHAR_HASH
) = \
75 (' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#')
77 SEPERATOR_TUPLE
= ('=', '|', ',', '{', '}')
79 RegionSizePattern
= re
.compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
80 RegionSizeGuidPattern
= re
.compile("\s*(?P<base>\w+\.\w+)\s*\|\s*(?P<size>\w+\.\w+)\s*")
81 RegionOffsetPcdPattern
= re
.compile("\s*(?P<base>\w+\.\w+)\s*$")
82 ShortcutPcdPattern
= re
.compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
84 AllIncludeFileList
= []
86 # Get the closest parent
87 def GetParentAtLine (Line
):
88 for Profile
in AllIncludeFileList
:
89 if Profile
.IsLineInFile(Line
):
94 def IsValidInclude (File
, Line
):
95 for Profile
in AllIncludeFileList
:
96 if Profile
.IsLineInFile(Line
) and Profile
.FileName
== File
:
101 def GetRealFileLine (File
, Line
):
104 for Profile
in AllIncludeFileList
:
105 if Profile
.IsLineInFile(Line
):
106 return Profile
.GetLineInFile(Line
)
107 elif Line
>= Profile
.InsertStartLineNumber
and Profile
.Level
== 1:
108 InsertedLines
+= Profile
.GetTotalLines()
110 return (File
, Line
- InsertedLines
)
112 ## The exception class that used to report error messages when parsing FDF
114 # Currently the "ToolName" is set to be "FDF Parser".
116 class Warning (Exception):
119 # @param self The object pointer
120 # @param Str The message to record
121 # @param File The FDF name
122 # @param Line The Line number that error occurs
124 def __init__(self
, Str
, File
= None, Line
= None):
126 FileLineTuple
= GetRealFileLine(File
, Line
)
127 self
.FileName
= FileLineTuple
[0]
128 self
.LineNumber
= FileLineTuple
[1]
129 self
.OriginalLineNumber
= Line
131 self
.ToolName
= 'FdfParser'
136 ## The MACRO class that used to record macro value data when parsing include file
142 # @param self The object pointer
143 # @param FileName The file that to be parsed
145 def __init__(self
, FileName
, Line
):
146 self
.FileName
= FileName
147 self
.DefinedAtLine
= Line
148 self
.MacroName
= None
149 self
.MacroValue
= None
151 ## The Include file content class that used to record file data when parsing include file
153 # May raise Exception when opening file.
155 class IncludeFileProfile
:
158 # @param self The object pointer
159 # @param FileName The file that to be parsed
161 def __init__(self
, FileName
):
162 self
.FileName
= FileName
163 self
.FileLinesList
= []
165 fsock
= open(FileName
, "rb", 0)
167 self
.FileLinesList
= fsock
.readlines()
172 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
174 self
.InsertStartLineNumber
= None
175 self
.InsertAdjust
= 0
176 self
.IncludeFileList
= []
177 self
.Level
= 1 # first level include file
179 def GetTotalLines(self
):
180 TotalLines
= self
.InsertAdjust
+ len(self
.FileLinesList
)
182 for Profile
in self
.IncludeFileList
:
183 TotalLines
+= Profile
.GetTotalLines()
187 def IsLineInFile(self
, Line
):
188 if Line
>= self
.InsertStartLineNumber
and Line
< self
.InsertStartLineNumber
+ self
.GetTotalLines():
193 def GetLineInFile(self
, Line
):
194 if not self
.IsLineInFile (Line
):
195 return (self
.FileName
, -1)
197 InsertedLines
= self
.InsertStartLineNumber
199 for Profile
in self
.IncludeFileList
:
200 if Profile
.IsLineInFile(Line
):
201 return Profile
.GetLineInFile(Line
)
202 elif Line
>= Profile
.InsertStartLineNumber
:
203 InsertedLines
+= Profile
.GetTotalLines()
205 return (self
.FileName
, Line
- InsertedLines
+ 1)
209 ## The FDF content class that used to record file data when parsing FDF
211 # May raise Exception when opening file.
216 # @param self The object pointer
217 # @param FileName The file that to be parsed
219 def __init__(self
, FileName
):
220 self
.FileLinesList
= []
222 fsock
= open(FileName
, "rb", 0)
224 self
.FileLinesList
= fsock
.readlines()
229 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
234 # ECC will use this Dict and List information
235 self
.PcdFileLineDict
= {}
236 self
.InfFileLineList
= []
239 self
.FdNameNotSet
= False
241 self
.CapsuleDict
= {}
245 self
.FmpPayloadDict
= {}
247 ## The syntax parser for FDF
249 # PreprocessFile method should be called prior to ParseFile
250 # CycleReferenceCheck method can detect cycles in FDF contents
252 # GetNext*** procedures mean these procedures will get next token first, then make judgement.
253 # Get*** procedures mean these procedures will make judgement on current token only.
258 # @param self The object pointer
259 # @param FileName The file that to be parsed
261 def __init__(self
, FileName
):
262 self
.Profile
= FileProfile(FileName
)
263 self
.FileName
= FileName
264 self
.CurrentLineNumber
= 1
265 self
.CurrentOffsetWithinLine
= 0
266 self
.CurrentFdName
= None
267 self
.CurrentFvName
= None
269 self
.__SkippedChars
= ""
270 GlobalData
.gFdfParser
= self
272 # Used to section info
273 self
.__CurSection
= []
274 # Key: [section name, UI name, arch]
275 # Value: {MACRO_NAME : MACRO_VALUE}
276 self
.__MacroDict
= tdict(True, 3)
279 self
.__WipeOffArea
= []
280 if GenFdsGlobalVariable
.WorkSpaceDir
== '':
281 GenFdsGlobalVariable
.WorkSpaceDir
= os
.getenv("WORKSPACE")
283 ## __IsWhiteSpace() method
285 # Whether char at current FileBufferPos is whitespace
287 # @param self The object pointer
288 # @param Char The char to test
289 # @retval True The char is a kind of white space
290 # @retval False The char is NOT a kind of white space
292 def __IsWhiteSpace(self
, Char
):
293 if Char
in (T_CHAR_NULL
, T_CHAR_CR
, T_CHAR_SPACE
, T_CHAR_TAB
, T_CHAR_LF
):
298 ## __SkipWhiteSpace() method
300 # Skip white spaces from current char, return number of chars skipped
302 # @param self The object pointer
303 # @retval Count The number of chars skipped
305 def __SkipWhiteSpace(self
):
307 while not self
.__EndOfFile
():
309 if self
.__CurrentChar
() in (T_CHAR_NULL
, T_CHAR_CR
, T_CHAR_LF
, T_CHAR_SPACE
, T_CHAR_TAB
):
310 self
.__SkippedChars
+= str(self
.__CurrentChar
())
317 ## __EndOfFile() method
319 # Judge current buffer pos is at file end
321 # @param self The object pointer
322 # @retval True Current File buffer position is at file end
323 # @retval False Current File buffer position is NOT at file end
325 def __EndOfFile(self
):
326 NumberOfLines
= len(self
.Profile
.FileLinesList
)
327 SizeOfLastLine
= len(self
.Profile
.FileLinesList
[-1])
328 if self
.CurrentLineNumber
== NumberOfLines
and self
.CurrentOffsetWithinLine
>= SizeOfLastLine
- 1:
330 elif self
.CurrentLineNumber
> NumberOfLines
:
335 ## __EndOfLine() method
337 # Judge current buffer pos is at line end
339 # @param self The object pointer
340 # @retval True Current File buffer position is at line end
341 # @retval False Current File buffer position is NOT at line end
343 def __EndOfLine(self
):
344 if self
.CurrentLineNumber
> len(self
.Profile
.FileLinesList
):
346 SizeOfCurrentLine
= len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
347 if self
.CurrentOffsetWithinLine
>= SizeOfCurrentLine
:
354 # Reset file data buffer to the initial state
356 # @param self The object pointer
357 # @param DestLine Optional new destination line number.
358 # @param DestOffset Optional new destination offset.
360 def Rewind(self
, DestLine
= 1, DestOffset
= 0):
361 self
.CurrentLineNumber
= DestLine
362 self
.CurrentOffsetWithinLine
= DestOffset
364 ## __UndoOneChar() method
366 # Go back one char in the file buffer
368 # @param self The object pointer
369 # @retval True Successfully go back one char
370 # @retval False Not able to go back one char as file beginning reached
372 def __UndoOneChar(self
):
374 if self
.CurrentLineNumber
== 1 and self
.CurrentOffsetWithinLine
== 0:
376 elif self
.CurrentOffsetWithinLine
== 0:
377 self
.CurrentLineNumber
-= 1
378 self
.CurrentOffsetWithinLine
= len(self
.__CurrentLine
()) - 1
380 self
.CurrentOffsetWithinLine
-= 1
383 ## __GetOneChar() method
385 # Move forward one char in the file buffer
387 # @param self The object pointer
389 def __GetOneChar(self
):
390 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
391 self
.CurrentLineNumber
+= 1
392 self
.CurrentOffsetWithinLine
= 0
394 self
.CurrentOffsetWithinLine
+= 1
396 ## __CurrentChar() method
398 # Get the char pointed to by the file buffer pointer
400 # @param self The object pointer
401 # @retval Char Current char
403 def __CurrentChar(self
):
404 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
]
406 ## __NextChar() method
408 # Get the one char pass the char pointed to by the file buffer pointer
410 # @param self The object pointer
411 # @retval Char Next char
413 def __NextChar(self
):
414 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
415 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
][0]
417 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
+ 1]
419 ## __SetCurrentCharValue() method
421 # Modify the value of current char
423 # @param self The object pointer
424 # @param Value The new value of current char
426 def __SetCurrentCharValue(self
, Value
):
427 self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
] = Value
429 ## __CurrentLine() method
431 # Get the list that contains current line contents
433 # @param self The object pointer
434 # @retval List current line contents
436 def __CurrentLine(self
):
437 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
439 def __StringToList(self
):
440 self
.Profile
.FileLinesList
= [list(s
) for s
in self
.Profile
.FileLinesList
]
441 self
.Profile
.FileLinesList
[-1].append(' ')
443 def __ReplaceFragment(self
, StartPos
, EndPos
, Value
= ' '):
444 if StartPos
[0] == EndPos
[0]:
446 while Offset
<= EndPos
[1]:
447 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
452 while self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] not in ('\r', '\n'):
453 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
457 while Line
< EndPos
[0]:
459 while self
.Profile
.FileLinesList
[Line
][Offset
] not in ('\r', '\n'):
460 self
.Profile
.FileLinesList
[Line
][Offset
] = Value
465 while Offset
<= EndPos
[1]:
466 self
.Profile
.FileLinesList
[EndPos
[0]][Offset
] = Value
470 def __GetMacroName(self
):
471 if not self
.__GetNextToken
():
472 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
473 MacroName
= self
.__Token
475 if MacroName
.startswith('!'):
477 MacroName
= MacroName
[1:].strip()
479 if not MacroName
.startswith('$(') or not MacroName
.endswith(')'):
480 raise Warning("Macro name expected(Please use '$(%(Token)s)' if '%(Token)s' is a macro.)" % {"Token" : MacroName
},
481 self
.FileName
, self
.CurrentLineNumber
)
482 MacroName
= MacroName
[2:-1]
483 return MacroName
, NotFlag
485 def __SetMacroValue(self
, Macro
, Value
):
486 if not self
.__CurSection
:
490 if not self
.__MacroDict
[self
.__CurSection
[0], self
.__CurSection
[1], self
.__CurSection
[2]]:
491 self
.__MacroDict
[self
.__CurSection
[0], self
.__CurSection
[1], self
.__CurSection
[2]] = MacroDict
493 MacroDict
= self
.__MacroDict
[self
.__CurSection
[0], self
.__CurSection
[1], self
.__CurSection
[2]]
494 MacroDict
[Macro
] = Value
496 def __GetMacroValue(self
, Macro
):
498 if Macro
in GlobalData
.gCommandLineDefines
:
499 return GlobalData
.gCommandLineDefines
[Macro
]
500 if Macro
in GlobalData
.gGlobalDefines
:
501 return GlobalData
.gGlobalDefines
[Macro
]
503 if self
.__CurSection
:
504 MacroDict
= self
.__MacroDict
[
505 self
.__CurSection
[0],
506 self
.__CurSection
[1],
509 if MacroDict
and Macro
in MacroDict
:
510 return MacroDict
[Macro
]
513 if Macro
in GlobalData
.gPlatformDefines
:
514 return GlobalData
.gPlatformDefines
[Macro
]
517 def __SectionHeaderParser(self
, Section
):
519 # [FD.UiName]: use dummy instead if UI name is optional
522 # [Rule]: don't take rule section into account, macro is not allowed in this section
523 # [VTF.arch.UiName, arch]
524 # [OptionRom.DriverName]
525 self
.__CurSection
= []
526 Section
= Section
.strip()[1:-1].upper().replace(' ', '').strip('.')
527 ItemList
= Section
.split('.')
529 if Item
== '' or Item
== 'RULE':
532 if Item
== 'DEFINES':
533 self
.__CurSection
= ['COMMON', 'COMMON', 'COMMON']
534 elif Item
== 'VTF' and len(ItemList
) == 3:
536 Pos
= UiName
.find(',')
538 UiName
= UiName
[:Pos
]
539 self
.__CurSection
= ['VTF', UiName
, ItemList
[1]]
540 elif len(ItemList
) > 1:
541 self
.__CurSection
= [ItemList
[0], ItemList
[1], 'COMMON']
542 elif len(ItemList
) > 0:
543 self
.__CurSection
= [ItemList
[0], 'DUMMY', 'COMMON']
545 ## PreprocessFile() method
547 # Preprocess file contents, replace comments with spaces.
548 # In the end, rewind the file buffer pointer to the beginning
549 # BUGBUG: No !include statement processing contained in this procedure
550 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
552 # @param self The object pointer
554 def PreprocessFile(self
):
558 DoubleSlashComment
= False
560 # HashComment in quoted string " " is ignored.
563 while not self
.__EndOfFile
():
565 if self
.__CurrentChar
() == T_CHAR_DOUBLE_QUOTE
and not InComment
:
566 InString
= not InString
567 # meet new line, then no longer in a comment for // and '#'
568 if self
.__CurrentChar
() == T_CHAR_LF
:
569 self
.CurrentLineNumber
+= 1
570 self
.CurrentOffsetWithinLine
= 0
571 if InComment
and DoubleSlashComment
:
573 DoubleSlashComment
= False
574 if InComment
and HashComment
:
577 # check for */ comment end
578 elif InComment
and not DoubleSlashComment
and not HashComment
and self
.__CurrentChar
() == T_CHAR_STAR
and self
.__NextChar
() == T_CHAR_SLASH
:
579 self
.__SetCurrentCharValue
(T_CHAR_SPACE
)
581 self
.__SetCurrentCharValue
(T_CHAR_SPACE
)
584 # set comments to spaces
586 self
.__SetCurrentCharValue
(T_CHAR_SPACE
)
588 # check for // comment
589 elif self
.__CurrentChar
() == T_CHAR_SLASH
and self
.__NextChar
() == T_CHAR_SLASH
and not self
.__EndOfLine
():
591 DoubleSlashComment
= True
592 # check for '#' comment
593 elif self
.__CurrentChar
() == T_CHAR_HASH
and not self
.__EndOfLine
() and not InString
:
596 # check for /* comment start
597 elif self
.__CurrentChar
() == T_CHAR_SLASH
and self
.__NextChar
() == T_CHAR_STAR
:
598 self
.__SetCurrentCharValue
( T_CHAR_SPACE
)
600 self
.__SetCurrentCharValue
( T_CHAR_SPACE
)
606 # restore from ListOfList to ListOfString
607 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
610 ## PreprocessIncludeFile() method
612 # Preprocess file contents, replace !include statements with file contents.
613 # In the end, rewind the file buffer pointer to the beginning
615 # @param self The object pointer
617 def PreprocessIncludeFile(self
):
618 # nested include support
620 while self
.__GetNextToken
():
622 if self
.__Token
== '!include':
624 IncludeLine
= self
.CurrentLineNumber
625 IncludeOffset
= self
.CurrentOffsetWithinLine
- len('!include')
626 if not self
.__GetNextToken
():
627 raise Warning("expected include file name", self
.FileName
, self
.CurrentLineNumber
)
628 IncFileName
= self
.__Token
630 for Macro
in ['WORKSPACE', 'ECP_SOURCE', 'EFI_SOURCE', 'EDK_SOURCE']:
631 MacroVal
= self
.__GetMacroValue
(Macro
)
633 __IncludeMacros
[Macro
] = MacroVal
636 IncludedFile
= NormPath(ReplaceMacro(IncFileName
, __IncludeMacros
, RaiseError
=True))
638 raise Warning("only these system environment variables are permitted to start the path of the included file: "
639 "$(WORKSPACE), $(ECP_SOURCE), $(EFI_SOURCE), $(EDK_SOURCE)",
640 self
.FileName
, self
.CurrentLineNumber
)
642 # First search the include file under the same directory as FDF file
644 IncludedFile1
= PathClass(IncludedFile
, os
.path
.dirname(self
.FileName
))
645 ErrorCode
= IncludedFile1
.Validate()[0]
648 # Then search the include file under the same directory as DSC file
651 if GenFdsGlobalVariable
.ActivePlatform
:
652 PlatformDir
= GenFdsGlobalVariable
.ActivePlatform
.Dir
653 elif GlobalData
.gActivePlatform
:
654 PlatformDir
= GlobalData
.gActivePlatform
.MetaFile
.Dir
655 IncludedFile1
= PathClass(IncludedFile
, PlatformDir
)
656 ErrorCode
= IncludedFile1
.Validate()[0]
659 # Also search file under the WORKSPACE directory
661 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
662 ErrorCode
= IncludedFile1
.Validate()[0]
664 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
),
665 self
.FileName
, self
.CurrentLineNumber
)
667 if not IsValidInclude (IncludedFile1
.Path
, self
.CurrentLineNumber
):
668 raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1
.Path
), self
.FileName
, self
.CurrentLineNumber
)
670 IncFileProfile
= IncludeFileProfile(IncludedFile1
.Path
)
672 CurrentLine
= self
.CurrentLineNumber
673 CurrentOffset
= self
.CurrentOffsetWithinLine
674 # list index of the insertion, note that line number is 'CurrentLine + 1'
675 InsertAtLine
= CurrentLine
676 ParentProfile
= GetParentAtLine (CurrentLine
)
677 if ParentProfile
!= None:
678 ParentProfile
.IncludeFileList
.insert(0, IncFileProfile
)
679 IncFileProfile
.Level
= ParentProfile
.Level
+ 1
680 IncFileProfile
.InsertStartLineNumber
= InsertAtLine
+ 1
681 # deal with remaining portions after "!include filename", if exists.
682 if self
.__GetNextToken
():
683 if self
.CurrentLineNumber
== CurrentLine
:
684 RemainingLine
= self
.__CurrentLine
()[CurrentOffset
:]
685 self
.Profile
.FileLinesList
.insert(self
.CurrentLineNumber
, RemainingLine
)
686 IncFileProfile
.InsertAdjust
+= 1
687 self
.CurrentLineNumber
+= 1
688 self
.CurrentOffsetWithinLine
= 0
690 for Line
in IncFileProfile
.FileLinesList
:
691 self
.Profile
.FileLinesList
.insert(InsertAtLine
, Line
)
692 self
.CurrentLineNumber
+= 1
695 # reversely sorted to better determine error in file
696 AllIncludeFileList
.insert(0, IncFileProfile
)
698 # comment out the processed include file statement
699 TempList
= list(self
.Profile
.FileLinesList
[IncludeLine
- 1])
700 TempList
.insert(IncludeOffset
, '#')
701 self
.Profile
.FileLinesList
[IncludeLine
- 1] = ''.join(TempList
)
702 if Processed
: # Nested and back-to-back support
703 self
.Rewind(DestLine
= IncFileProfile
.InsertStartLineNumber
- 1)
708 def __GetIfListCurrentItemStat(self
, IfList
):
718 ## PreprocessConditionalStatement() method
720 # Preprocess conditional statement.
721 # In the end, rewind the file buffer pointer to the beginning
723 # @param self The object pointer
725 def PreprocessConditionalStatement(self
):
726 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
730 while self
.__GetNextToken
():
731 # Determine section name and the location dependent macro
732 if self
.__GetIfListCurrentItemStat
(IfList
):
733 if self
.__Token
.startswith('['):
734 Header
= self
.__Token
735 if not self
.__Token
.endswith(']'):
736 self
.__SkipToToken
(']')
737 Header
+= self
.__SkippedChars
738 if Header
.find('$(') != -1:
739 raise Warning("macro cannot be used in section header", self
.FileName
, self
.CurrentLineNumber
)
740 self
.__SectionHeaderParser
(Header
)
742 # Replace macros except in RULE section or out of section
743 elif self
.__CurSection
and ReplacedLine
!= self
.CurrentLineNumber
:
744 ReplacedLine
= self
.CurrentLineNumber
746 CurLine
= self
.Profile
.FileLinesList
[ReplacedLine
- 1]
748 StartPos
= CurLine
.find('$(', PreIndex
)
749 EndPos
= CurLine
.find(')', StartPos
+2)
750 while StartPos
!= -1 and EndPos
!= -1 and self
.__Token
not in ['!ifdef', '!ifndef', '!if', '!elseif']:
751 MacroName
= CurLine
[StartPos
+2 : EndPos
]
752 MacorValue
= self
.__GetMacroValue
(MacroName
)
753 if MacorValue
!= None:
754 CurLine
= CurLine
.replace('$(' + MacroName
+ ')', MacorValue
, 1)
755 if MacorValue
.find('$(') != -1:
758 PreIndex
= StartPos
+ len(MacorValue
)
760 PreIndex
= EndPos
+ 1
761 StartPos
= CurLine
.find('$(', PreIndex
)
762 EndPos
= CurLine
.find(')', StartPos
+2)
763 self
.Profile
.FileLinesList
[ReplacedLine
- 1] = CurLine
766 if self
.__Token
== 'DEFINE':
767 if self
.__GetIfListCurrentItemStat
(IfList
):
768 if not self
.__CurSection
:
769 raise Warning("macro cannot be defined in Rule section or out of section", self
.FileName
, self
.CurrentLineNumber
)
770 DefineLine
= self
.CurrentLineNumber
- 1
771 DefineOffset
= self
.CurrentOffsetWithinLine
- len('DEFINE')
772 if not self
.__GetNextToken
():
773 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
775 if not self
.__IsToken
( "="):
776 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
778 Value
= self
.__GetExpression
()
779 self
.__SetMacroValue
(Macro
, Value
)
780 self
.__WipeOffArea
.append(((DefineLine
, DefineOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
781 elif self
.__Token
== 'SET':
782 if not self
.__GetIfListCurrentItemStat
(IfList
):
784 SetLine
= self
.CurrentLineNumber
- 1
785 SetOffset
= self
.CurrentOffsetWithinLine
- len('SET')
786 PcdPair
= self
.__GetNextPcdName
()
787 PcdName
= "%s.%s" % (PcdPair
[1], PcdPair
[0])
788 if not self
.__IsToken
( "="):
789 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
791 Value
= self
.__GetExpression
()
792 Value
= self
.__EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
794 self
.__PcdDict
[PcdName
] = Value
796 self
.Profile
.PcdDict
[PcdPair
] = Value
797 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
798 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
800 self
.__WipeOffArea
.append(((SetLine
, SetOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
801 elif self
.__Token
in ('!ifdef', '!ifndef', '!if'):
802 IfStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
.__Token
))
803 IfList
.append([IfStartPos
, None, None])
805 CondLabel
= self
.__Token
806 Expression
= self
.__GetExpression
()
808 if CondLabel
== '!if':
809 ConditionSatisfied
= self
.__EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
811 ConditionSatisfied
= self
.__EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'in')
812 if CondLabel
== '!ifndef':
813 ConditionSatisfied
= not ConditionSatisfied
815 BranchDetermined
= ConditionSatisfied
816 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, BranchDetermined
]
817 if ConditionSatisfied
:
818 self
.__WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
819 elif self
.__Token
in ('!elseif', '!else'):
820 ElseStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
.__Token
))
822 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
825 IfList
[-1] = [ElseStartPos
, False, True]
826 self
.__WipeOffArea
.append((ElseStartPos
, (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
828 self
.__WipeOffArea
.append((IfList
[-1][0], ElseStartPos
))
829 IfList
[-1] = [ElseStartPos
, True, IfList
[-1][2]]
830 if self
.__Token
== '!elseif':
831 Expression
= self
.__GetExpression
()
832 ConditionSatisfied
= self
.__EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
833 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, IfList
[-1][2]]
837 IfList
[-1][1] = False
840 self
.__WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
841 elif self
.__Token
== '!endif':
843 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
845 self
.__WipeOffArea
.append(((self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len('!endif')), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
847 self
.__WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
850 elif not IfList
: # Don't use PCDs inside conditional directive
851 if self
.CurrentLineNumber
<= RegionLayoutLine
:
852 # Don't try the same line twice
854 SetPcd
= ShortcutPcdPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
856 self
.__PcdDict
[SetPcd
.group('name')] = SetPcd
.group('value')
857 RegionLayoutLine
= self
.CurrentLineNumber
859 RegionSize
= RegionSizePattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
861 RegionLayoutLine
= self
.CurrentLineNumber
863 RegionSizeGuid
= RegionSizeGuidPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
])
864 if not RegionSizeGuid
:
865 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
867 self
.__PcdDict
[RegionSizeGuid
.group('base')] = RegionSize
.group('base')
868 self
.__PcdDict
[RegionSizeGuid
.group('size')] = RegionSize
.group('size')
869 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
872 raise Warning("Missing !endif", self
.FileName
, self
.CurrentLineNumber
)
875 def __CollectMacroPcd(self
):
879 MacroDict
.update(GlobalData
.gPlatformPcds
)
880 MacroDict
.update(self
.__PcdDict
)
883 MacroDict
.update(GlobalData
.gPlatformDefines
)
885 if self
.__CurSection
:
887 ScopeMacro
= self
.__MacroDict
['COMMON', 'COMMON', 'COMMON']
889 MacroDict
.update(ScopeMacro
)
892 ScopeMacro
= self
.__MacroDict
[
893 self
.__CurSection
[0],
894 self
.__CurSection
[1],
898 MacroDict
.update(ScopeMacro
)
900 MacroDict
.update(GlobalData
.gGlobalDefines
)
901 MacroDict
.update(GlobalData
.gCommandLineDefines
)
906 def __EvaluateConditional(self
, Expression
, Line
, Op
= None, Value
= None):
907 FileLineTuple
= GetRealFileLine(self
.FileName
, Line
)
908 MacroPcdDict
= self
.__CollectMacroPcd
()
912 return ValueExpression(Expression
, MacroPcdDict
)(True)
914 return ValueExpression(Expression
, MacroPcdDict
)()
915 except WrnExpression
, Excpt
:
917 # Catch expression evaluation warning here. We need to report
918 # the precise number of line and return the evaluation result
920 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
921 File
=self
.FileName
, ExtraData
=self
.__CurrentLine
(),
924 except Exception, Excpt
:
925 if hasattr(Excpt
, 'Pcd'):
926 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
927 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
928 raise Warning("Cannot use this PCD (%s) in an expression as"
929 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
930 " of the DSC file (%s), and it is currently defined in this section:"
931 " %s, line #: %d." % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE'], Info
[0], Info
[1]),
934 raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE']),
937 raise Warning(str(Excpt
), *FileLineTuple
)
939 if Expression
.startswith('$(') and Expression
[-1] == ')':
940 Expression
= Expression
[2:-1]
941 return Expression
in MacroPcdDict
943 ## __IsToken() method
945 # Check whether input string is found from current char position along
946 # If found, the string value is put into self.__Token
948 # @param self The object pointer
949 # @param String The string to search
950 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
951 # @retval True Successfully find string, file buffer pointer moved forward
952 # @retval False Not able to find string, file buffer pointer not changed
954 def __IsToken(self
, String
, IgnoreCase
= False):
955 self
.__SkipWhiteSpace
()
957 # Only consider the same line, no multi-line token allowed
958 StartPos
= self
.CurrentOffsetWithinLine
961 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
963 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
965 self
.CurrentOffsetWithinLine
+= len(String
)
966 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
970 ## __IsKeyword() method
972 # Check whether input keyword is found from current char position along, whole word only!
973 # If found, the string value is put into self.__Token
975 # @param self The object pointer
976 # @param Keyword The string to search
977 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
978 # @retval True Successfully find string, file buffer pointer moved forward
979 # @retval False Not able to find string, file buffer pointer not changed
981 def __IsKeyword(self
, KeyWord
, IgnoreCase
= False):
982 self
.__SkipWhiteSpace
()
984 # Only consider the same line, no multi-line token allowed
985 StartPos
= self
.CurrentOffsetWithinLine
988 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(KeyWord
.upper())
990 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(KeyWord
)
992 followingChar
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
+ len(KeyWord
)]
993 if not str(followingChar
).isspace() and followingChar
not in SEPERATOR_TUPLE
:
995 self
.CurrentOffsetWithinLine
+= len(KeyWord
)
996 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1000 def __GetExpression(self
):
1001 Line
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
1002 Index
= len(Line
) - 1
1003 while Line
[Index
] in ['\r', '\n']:
1005 ExpressionString
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:Index
+1]
1006 self
.CurrentOffsetWithinLine
+= len(ExpressionString
)
1007 ExpressionString
= ExpressionString
.strip()
1008 return ExpressionString
1010 ## __GetNextWord() method
1012 # Get next C name from file lines
1013 # If found, the string value is put into self.__Token
1015 # @param self The object pointer
1016 # @retval True Successfully find a C name string, file buffer pointer moved forward
1017 # @retval False Not able to find a C name string, file buffer pointer not changed
1019 def __GetNextWord(self
):
1020 self
.__SkipWhiteSpace
()
1021 if self
.__EndOfFile
():
1024 TempChar
= self
.__CurrentChar
()
1025 StartPos
= self
.CurrentOffsetWithinLine
1026 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_':
1028 while not self
.__EndOfLine
():
1029 TempChar
= self
.__CurrentChar
()
1030 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
1031 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-':
1037 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1042 ## __GetNextToken() method
1044 # Get next token unit before a seperator
1045 # If found, the string value is put into self.__Token
1047 # @param self The object pointer
1048 # @retval True Successfully find a token unit, file buffer pointer moved forward
1049 # @retval False Not able to find a token unit, file buffer pointer not changed
1051 def __GetNextToken(self
):
1052 # Skip leading spaces, if exist.
1053 self
.__SkipWhiteSpace
()
1054 if self
.__EndOfFile
():
1056 # Record the token start position, the position of the first non-space char.
1057 StartPos
= self
.CurrentOffsetWithinLine
1058 StartLine
= self
.CurrentLineNumber
1059 while StartLine
== self
.CurrentLineNumber
:
1060 TempChar
= self
.__CurrentChar
()
1061 # Try to find the end char that is not a space and not in seperator tuple.
1062 # That is, when we got a space or any char in the tuple, we got the end of token.
1063 if not str(TempChar
).isspace() and TempChar
not in SEPERATOR_TUPLE
:
1065 # if we happen to meet a seperator as the first char, we must proceed to get it.
1066 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1067 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPERATOR_TUPLE
:
1075 EndPos
= self
.CurrentOffsetWithinLine
1076 if self
.CurrentLineNumber
!= StartLine
:
1077 EndPos
= len(self
.Profile
.FileLinesList
[StartLine
-1])
1078 self
.__Token
= self
.Profile
.FileLinesList
[StartLine
-1][StartPos
: EndPos
]
1079 if StartPos
!= self
.CurrentOffsetWithinLine
:
1084 def __GetNextOp(self
):
1085 # Skip leading spaces, if exist.
1086 self
.__SkipWhiteSpace
()
1087 if self
.__EndOfFile
():
1089 # Record the token start position, the position of the first non-space char.
1090 StartPos
= self
.CurrentOffsetWithinLine
1091 while not self
.__EndOfLine
():
1092 TempChar
= self
.__CurrentChar
()
1093 # Try to find the end char that is not a space
1094 if not str(TempChar
).isspace():
1101 if StartPos
!= self
.CurrentOffsetWithinLine
:
1102 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1106 ## __GetNextGuid() method
1108 # Get next token unit before a seperator
1109 # If found, the GUID string is put into self.__Token
1111 # @param self The object pointer
1112 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward
1113 # @retval False Not able to find a registry format GUID, file buffer pointer not changed
1115 def __GetNextGuid(self
):
1117 if not self
.__GetNextToken
():
1119 p
= re
.compile('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}')
1120 if p
.match(self
.__Token
) != None:
1126 ## __UndoToken() method
1128 # Go back one token unit in file buffer
1130 # @param self The object pointer
1132 def __UndoToken(self
):
1133 self
.__UndoOneChar
()
1134 while self
.__CurrentChar
().isspace():
1135 if not self
.__UndoOneChar
():
1140 StartPos
= self
.CurrentOffsetWithinLine
1141 CurrentLine
= self
.CurrentLineNumber
1142 while CurrentLine
== self
.CurrentLineNumber
:
1144 TempChar
= self
.__CurrentChar
()
1145 # Try to find the end char that is not a space and not in seperator tuple.
1146 # That is, when we got a space or any char in the tuple, we got the end of token.
1147 if not str(TempChar
).isspace() and not TempChar
in SEPERATOR_TUPLE
:
1148 if not self
.__UndoOneChar
():
1150 # if we happen to meet a seperator as the first char, we must proceed to get it.
1151 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1152 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPERATOR_TUPLE
:
1159 ## __HexDigit() method
1161 # Whether char input is a Hex data bit
1163 # @param self The object pointer
1164 # @param TempChar The char to test
1165 # @retval True The char is a Hex data bit
1166 # @retval False The char is NOT a Hex data bit
1168 def __HexDigit(self
, TempChar
):
1169 if (TempChar
>= 'a' and TempChar
<= 'f') or (TempChar
>= 'A' and TempChar
<= 'F') \
1170 or (TempChar
>= '0' and TempChar
<= '9'):
1175 def __IsHex(self
, HexStr
):
1176 if not HexStr
.upper().startswith("0X"):
1178 if len(self
.__Token
) <= 2:
1180 charList
= [c
for c
in HexStr
[2 : ] if not self
.__HexDigit
( c
)]
1181 if len(charList
) == 0:
1185 ## __GetNextHexNumber() method
1187 # Get next HEX data before a seperator
1188 # If found, the HEX data is put into self.__Token
1190 # @param self The object pointer
1191 # @retval True Successfully find a HEX data, file buffer pointer moved forward
1192 # @retval False Not able to find a HEX data, file buffer pointer not changed
1194 def __GetNextHexNumber(self
):
1195 if not self
.__GetNextToken
():
1197 if self
.__IsHex
(self
.__Token
):
1203 ## __GetNextDecimalNumber() method
1205 # Get next decimal data before a seperator
1206 # If found, the decimal data is put into self.__Token
1208 # @param self The object pointer
1209 # @retval True Successfully find a decimal data, file buffer pointer moved forward
1210 # @retval False Not able to find a decimal data, file buffer pointer not changed
1212 def __GetNextDecimalNumber(self
):
1213 if not self
.__GetNextToken
():
1215 if self
.__Token
.isdigit():
1221 ## __GetNextPcdName() method
1223 # Get next PCD token space C name and PCD C name pair before a seperator
1224 # If found, the decimal data is put into self.__Token
1226 # @param self The object pointer
1227 # @retval Tuple PCD C name and PCD token space C name pair
1229 def __GetNextPcdName(self
):
1230 if not self
.__GetNextWord
():
1231 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1232 pcdTokenSpaceCName
= self
.__Token
1234 if not self
.__IsToken
( "."):
1235 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1237 if not self
.__GetNextWord
():
1238 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1239 pcdCName
= self
.__Token
1241 return (pcdCName
, pcdTokenSpaceCName
)
1243 ## __GetStringData() method
1245 # Get string contents quoted in ""
1246 # If found, the decimal data is put into self.__Token
1248 # @param self The object pointer
1249 # @retval True Successfully find a string data, file buffer pointer moved forward
1250 # @retval False Not able to find a string data, file buffer pointer not changed
1252 def __GetStringData(self
):
1253 if self
.__Token
.startswith("\"") or self
.__Token
.startswith("L\""):
1255 self
.__SkipToToken
("\"")
1256 currentLineNumber
= self
.CurrentLineNumber
1258 if not self
.__SkipToToken
("\""):
1259 raise Warning("Missing Quote \" for String", self
.FileName
, self
.CurrentLineNumber
)
1260 if currentLineNumber
!= self
.CurrentLineNumber
:
1261 raise Warning("Missing Quote \" for String", self
.FileName
, self
.CurrentLineNumber
)
1262 self
.__Token
= self
.__SkippedChars
.rstrip('\"')
1265 elif self
.__Token
.startswith("\'") or self
.__Token
.startswith("L\'"):
1267 self
.__SkipToToken
("\'")
1268 currentLineNumber
= self
.CurrentLineNumber
1270 if not self
.__SkipToToken
("\'"):
1271 raise Warning("Missing Quote \' for String", self
.FileName
, self
.CurrentLineNumber
)
1272 if currentLineNumber
!= self
.CurrentLineNumber
:
1273 raise Warning("Missing Quote \' for String", self
.FileName
, self
.CurrentLineNumber
)
1274 self
.__Token
= self
.__SkippedChars
.rstrip('\'')
1280 ## __SkipToToken() method
1282 # Search forward in file buffer for the string
1283 # The skipped chars are put into self.__SkippedChars
1285 # @param self The object pointer
1286 # @param String The string to search
1287 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
1288 # @retval True Successfully find the string, file buffer pointer moved forward
1289 # @retval False Not able to find the string, file buffer pointer not changed
1291 def __SkipToToken(self
, String
, IgnoreCase
= False):
1292 StartPos
= self
.GetFileBufferPos()
1294 self
.__SkippedChars
= ""
1295 while not self
.__EndOfFile
():
1298 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
1300 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
1302 self
.CurrentOffsetWithinLine
+= len(String
)
1303 self
.__SkippedChars
+= String
1305 self
.__SkippedChars
+= str(self
.__CurrentChar
())
1308 self
.SetFileBufferPos( StartPos
)
1309 self
.__SkippedChars
= ""
1312 ## GetFileBufferPos() method
1314 # Return the tuple of current line and offset within the line
1316 # @param self The object pointer
1317 # @retval Tuple Line number and offset pair
1319 def GetFileBufferPos(self
):
1320 return (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
)
1322 ## SetFileBufferPos() method
1324 # Restore the file buffer position
1326 # @param self The object pointer
1327 # @param Pos The new file buffer position
1329 def SetFileBufferPos(self
, Pos
):
1330 (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
) = Pos
1332 ## Preprocess() method
1334 # Preprocess comment, conditional directive, include directive, replace macro.
1335 # Exception will be raised if syntax error found
1337 # @param self The object pointer
1339 def Preprocess(self
):
1340 self
.__StringToList
()
1341 self
.PreprocessFile()
1342 self
.PreprocessIncludeFile()
1343 self
.__StringToList
()
1344 self
.PreprocessFile()
1345 self
.PreprocessConditionalStatement()
1346 self
.__StringToList
()
1347 for Pos
in self
.__WipeOffArea
:
1348 self
.__ReplaceFragment
(Pos
[0], Pos
[1])
1349 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
1351 while self
.__GetDefines
():
1354 ## ParseFile() method
1356 # Parse the file profile buffer to extract fd, fv ... information
1357 # Exception will be raised if syntax error found
1359 # @param self The object pointer
1361 def ParseFile(self
):
1365 while self
.__GetFd
():
1368 while self
.__GetFv
():
1371 while self
.__GetFmp
():
1374 while self
.__GetCapsule
():
1377 while self
.__GetVtf
():
1380 while self
.__GetRule
():
1383 while self
.__GetOptionRom
():
1388 #'\n\tGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \
1389 # At this point, the closest parent would be the included file itself
1390 Profile
= GetParentAtLine(X
.OriginalLineNumber
)
1392 X
.Message
+= ' near line %d, column %d: %s' \
1393 % (X
.LineNumber
, 0, Profile
.FileLinesList
[X
.LineNumber
-1])
1395 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1396 X
.Message
+= ' near line %d, column %d: %s' \
1397 % (FileLineTuple
[1], self
.CurrentOffsetWithinLine
+ 1, self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:].rstrip('\n').rstrip('\r'))
1400 ## SectionParser() method
1402 # Parse the file section info
1403 # Exception will be raised if syntax error found
1405 # @param self The object pointer
1406 # @param section The section string
1408 def SectionParser(self
, section
):
1410 if not S
.startswith("[DEFINES") and not S
.startswith("[FD.") and not S
.startswith("[FV.") and not S
.startswith("[CAPSULE.") \
1411 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM.") and not S
.startswith('[FMPPAYLOAD.'):
1412 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
)
1414 ## __GetDefines() method
1416 # Get Defines section contents and store its data into AllMacrosList
1418 # @param self The object pointer
1419 # @retval True Successfully find a Defines
1420 # @retval False Not able to find a Defines
1422 def __GetDefines(self
):
1424 if not self
.__GetNextToken
():
1427 S
= self
.__Token
.upper()
1428 if S
.startswith("[") and not S
.startswith("[DEFINES"):
1429 self
.SectionParser(S
)
1434 if not self
.__IsToken
("[DEFINES", True):
1435 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1436 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1437 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1438 raise Warning("expected [DEFINES", self
.FileName
, self
.CurrentLineNumber
)
1440 if not self
.__IsToken
( "]"):
1441 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
1443 while self
.__GetNextWord
():
1444 # handle the SET statement
1445 if self
.__Token
== 'SET':
1447 self
.__GetSetStatement
(None)
1450 Macro
= self
.__Token
1452 if not self
.__IsToken
("="):
1453 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1454 if not self
.__GetNextToken
() or self
.__Token
.startswith('['):
1455 raise Warning("expected MACRO value", self
.FileName
, self
.CurrentLineNumber
)
1456 Value
= self
.__Token
1462 # Get FD section contents and store its data into FD dictionary of self.Profile
1464 # @param self The object pointer
1465 # @retval True Successfully find a FD
1466 # @retval False Not able to find a FD
1470 if not self
.__GetNextToken
():
1473 S
= self
.__Token
.upper()
1474 if S
.startswith("[") and not S
.startswith("[FD."):
1475 if not S
.startswith("[FV.") and not S
.startswith('[FMPPAYLOAD.') and not S
.startswith("[CAPSULE.") \
1476 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM."):
1477 raise Warning("Unknown section", self
.FileName
, self
.CurrentLineNumber
)
1482 if not self
.__IsToken
("[FD.", True):
1483 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1484 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1485 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1486 raise Warning("expected [FD.]", self
.FileName
, self
.CurrentLineNumber
)
1488 FdName
= self
.__GetUiName
()
1490 if len (self
.Profile
.FdDict
) == 0:
1491 FdName
= GenFdsGlobalVariable
.PlatformName
1492 if FdName
== "" and GlobalData
.gActivePlatform
:
1493 FdName
= GlobalData
.gActivePlatform
.PlatformName
1494 self
.Profile
.FdNameNotSet
= True
1496 raise Warning("expected FdName in [FD.] section", self
.FileName
, self
.CurrentLineNumber
)
1497 self
.CurrentFdName
= FdName
.upper()
1499 if self
.CurrentFdName
in self
.Profile
.FdDict
:
1500 raise Warning("Unexpected the same FD name", self
.FileName
, self
.CurrentLineNumber
)
1502 if not self
.__IsToken
( "]"):
1503 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
1506 FdObj
.FdUiName
= self
.CurrentFdName
1507 self
.Profile
.FdDict
[self
.CurrentFdName
] = FdObj
1509 if len (self
.Profile
.FdDict
) > 1 and self
.Profile
.FdNameNotSet
:
1510 raise Warning("expected all FDs have their name", self
.FileName
, self
.CurrentLineNumber
)
1512 Status
= self
.__GetCreateFile
(FdObj
)
1514 raise Warning("FD name error", self
.FileName
, self
.CurrentLineNumber
)
1516 while self
.__GetTokenStatements
(FdObj
):
1518 for Attr
in ("BaseAddress", "Size", "ErasePolarity"):
1519 if getattr(FdObj
, Attr
) == None:
1520 self
.__GetNextToken
()
1521 raise Warning("Keyword %s missing" % Attr
, self
.FileName
, self
.CurrentLineNumber
)
1523 if not FdObj
.BlockSizeList
:
1524 FdObj
.BlockSizeList
.append((1, FdObj
.Size
, None))
1526 self
.__GetDefineStatements
(FdObj
)
1528 self
.__GetSetStatements
(FdObj
)
1530 if not self
.__GetRegionLayout
(FdObj
):
1531 raise Warning("expected region layout", self
.FileName
, self
.CurrentLineNumber
)
1533 while self
.__GetRegionLayout
(FdObj
):
1537 ## __GetUiName() method
1539 # Return the UI name of a section
1541 # @param self The object pointer
1542 # @retval FdName UI name
1544 def __GetUiName(self
):
1546 if self
.__GetNextWord
():
1551 ## __GetCreateFile() method
1553 # Return the output file name of object
1555 # @param self The object pointer
1556 # @param Obj object whose data will be stored in file
1557 # @retval FdName UI name
1559 def __GetCreateFile(self
, Obj
):
1561 if self
.__IsKeyword
( "CREATE_FILE"):
1562 if not self
.__IsToken
( "="):
1563 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1565 if not self
.__GetNextToken
():
1566 raise Warning("expected file name", self
.FileName
, self
.CurrentLineNumber
)
1568 FileName
= self
.__Token
1569 Obj
.CreateFileName
= FileName
1573 ## __GetTokenStatements() method
1575 # Get token statements
1577 # @param self The object pointer
1578 # @param Obj for whom token statement is got
1580 def __GetTokenStatements(self
, Obj
):
1581 if self
.__IsKeyword
( "BaseAddress"):
1582 if not self
.__IsToken
( "="):
1583 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1585 if not self
.__GetNextHexNumber
():
1586 raise Warning("expected Hex base address", self
.FileName
, self
.CurrentLineNumber
)
1588 Obj
.BaseAddress
= self
.__Token
1590 if self
.__IsToken
( "|"):
1591 pcdPair
= self
.__GetNextPcdName
()
1592 Obj
.BaseAddressPcd
= pcdPair
1593 self
.Profile
.PcdDict
[pcdPair
] = Obj
.BaseAddress
1594 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1595 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1598 if self
.__IsKeyword
( "Size"):
1599 if not self
.__IsToken
( "="):
1600 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1602 if not self
.__GetNextHexNumber
():
1603 raise Warning("expected Hex size", self
.FileName
, self
.CurrentLineNumber
)
1606 if self
.__IsToken
( "|"):
1607 pcdPair
= self
.__GetNextPcdName
()
1608 Obj
.SizePcd
= pcdPair
1609 self
.Profile
.PcdDict
[pcdPair
] = Size
1610 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1611 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1612 Obj
.Size
= long(Size
, 0)
1615 if self
.__IsKeyword
( "ErasePolarity"):
1616 if not self
.__IsToken
( "="):
1617 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1619 if not self
.__GetNextToken
():
1620 raise Warning("expected Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1622 if self
.__Token
!= "1" and self
.__Token
!= "0":
1623 raise Warning("expected 1 or 0 Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1625 Obj
.ErasePolarity
= self
.__Token
1628 return self
.__GetBlockStatements
(Obj
)
1630 ## __GetAddressStatements() method
1632 # Get address statements
1634 # @param self The object pointer
1635 # @param Obj for whom address statement is got
1636 # @retval True Successfully find
1637 # @retval False Not able to find
1639 def __GetAddressStatements(self
, Obj
):
1641 if self
.__IsKeyword
("BsBaseAddress"):
1642 if not self
.__IsToken
( "="):
1643 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1645 if not self
.__GetNextDecimalNumber
() and not self
.__GetNextHexNumber
():
1646 raise Warning("expected address", self
.FileName
, self
.CurrentLineNumber
)
1648 BsAddress
= long(self
.__Token
, 0)
1649 Obj
.BsBaseAddress
= BsAddress
1651 if self
.__IsKeyword
("RtBaseAddress"):
1652 if not self
.__IsToken
( "="):
1653 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1655 if not self
.__GetNextDecimalNumber
() and not self
.__GetNextHexNumber
():
1656 raise Warning("expected address", self
.FileName
, self
.CurrentLineNumber
)
1658 RtAddress
= long(self
.__Token
, 0)
1659 Obj
.RtBaseAddress
= RtAddress
1661 ## __GetBlockStatements() method
1663 # Get block statements
1665 # @param self The object pointer
1666 # @param Obj for whom block statement is got
1668 def __GetBlockStatements(self
, Obj
):
1670 while self
.__GetBlockStatement
(Obj
):
1673 Item
= Obj
.BlockSizeList
[-1]
1674 if Item
[0] == None or Item
[1] == None:
1675 raise Warning("expected block statement", self
.FileName
, self
.CurrentLineNumber
)
1678 ## __GetBlockStatement() method
1680 # Get block statement
1682 # @param self The object pointer
1683 # @param Obj for whom block statement is got
1684 # @retval True Successfully find
1685 # @retval False Not able to find
1687 def __GetBlockStatement(self
, Obj
):
1688 if not self
.__IsKeyword
( "BlockSize"):
1691 if not self
.__IsToken
( "="):
1692 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1694 if not self
.__GetNextHexNumber
() and not self
.__GetNextDecimalNumber
():
1695 raise Warning("expected Hex or Integer block size", self
.FileName
, self
.CurrentLineNumber
)
1697 BlockSize
= self
.__Token
1699 if self
.__IsToken
( "|"):
1700 PcdPair
= self
.__GetNextPcdName
()
1701 BlockSizePcd
= PcdPair
1702 self
.Profile
.PcdDict
[PcdPair
] = BlockSize
1703 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1704 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1705 BlockSize
= long(BlockSize
, 0)
1708 if self
.__IsKeyword
( "NumBlocks"):
1709 if not self
.__IsToken
( "="):
1710 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1712 if not self
.__GetNextDecimalNumber
() and not self
.__GetNextHexNumber
():
1713 raise Warning("expected block numbers", self
.FileName
, self
.CurrentLineNumber
)
1715 BlockNumber
= long(self
.__Token
, 0)
1717 Obj
.BlockSizeList
.append((BlockSize
, BlockNumber
, BlockSizePcd
))
1720 ## __GetDefineStatements() method
1722 # Get define statements
1724 # @param self The object pointer
1725 # @param Obj for whom define statement is got
1726 # @retval True Successfully find
1727 # @retval False Not able to find
1729 def __GetDefineStatements(self
, Obj
):
1730 while self
.__GetDefineStatement
( Obj
):
1733 ## __GetDefineStatement() method
1735 # Get define statement
1737 # @param self The object pointer
1738 # @param Obj for whom define statement is got
1739 # @retval True Successfully find
1740 # @retval False Not able to find
1742 def __GetDefineStatement(self
, Obj
):
1743 if self
.__IsKeyword
("DEFINE"):
1744 self
.__GetNextToken
()
1745 Macro
= self
.__Token
1746 if not self
.__IsToken
( "="):
1747 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1749 if not self
.__GetNextToken
():
1750 raise Warning("expected value", self
.FileName
, self
.CurrentLineNumber
)
1752 Value
= self
.__Token
1753 Macro
= '$(' + Macro
+ ')'
1754 Obj
.DefineVarDict
[Macro
] = Value
1759 ## __GetSetStatements() method
1761 # Get set statements
1763 # @param self The object pointer
1764 # @param Obj for whom set statement is got
1765 # @retval True Successfully find
1766 # @retval False Not able to find
1768 def __GetSetStatements(self
, Obj
):
1769 while self
.__GetSetStatement
(Obj
):
1772 ## __GetSetStatement() method
1776 # @param self The object pointer
1777 # @param Obj for whom set statement is got
1778 # @retval True Successfully find
1779 # @retval False Not able to find
1781 def __GetSetStatement(self
, Obj
):
1782 if self
.__IsKeyword
("SET"):
1783 PcdPair
= self
.__GetNextPcdName
()
1785 if not self
.__IsToken
( "="):
1786 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1788 Value
= self
.__GetExpression
()
1789 Value
= self
.__EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
1792 Obj
.SetVarDict
[PcdPair
] = Value
1793 self
.Profile
.PcdDict
[PcdPair
] = Value
1794 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1795 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1800 ## __CalcRegionExpr(self)
1802 # Calculate expression for offset or size of a region
1804 # @return: None if invalid expression
1805 # Calculated number if successfully
1807 def __CalcRegionExpr(self
):
1808 StartPos
= self
.GetFileBufferPos()
1811 while not self
.__EndOfFile
():
1812 CurCh
= self
.__CurrentChar
()
1818 if CurCh
in '|\r\n' and PairCount
== 0:
1824 ValueExpression(Expr
,
1825 self
.__CollectMacroPcd
()
1828 self
.SetFileBufferPos(StartPos
)
1831 ## __GetRegionLayout() method
1833 # Get region layout for FD
1835 # @param self The object pointer
1836 # @param Fd for whom region is got
1837 # @retval True Successfully find
1838 # @retval False Not able to find
1840 def __GetRegionLayout(self
, Fd
):
1841 Offset
= self
.__CalcRegionExpr
()
1845 RegionObj
= Region
.Region()
1846 RegionObj
.Offset
= Offset
1847 Fd
.RegionList
.append(RegionObj
)
1849 if not self
.__IsToken
( "|"):
1850 raise Warning("expected '|'", self
.FileName
, self
.CurrentLineNumber
)
1852 Size
= self
.__CalcRegionExpr
()
1854 raise Warning("expected Region Size", self
.FileName
, self
.CurrentLineNumber
)
1855 RegionObj
.Size
= Size
1857 if not self
.__GetNextWord
():
1860 if not self
.__Token
in ("SET", "FV", "FILE", "DATA", "CAPSULE", "INF"):
1862 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]
1863 # Or it might be next region's offset described by an expression which starts with a PCD.
1864 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size
1867 IsRegionPcd
= (RegionSizeGuidPattern
.match(self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
:]) or
1868 RegionOffsetPcdPattern
.match(self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
:]))
1870 RegionObj
.PcdOffset
= self
.__GetNextPcdName
()
1871 self
.Profile
.PcdDict
[RegionObj
.PcdOffset
] = "0x%08X" % (RegionObj
.Offset
+ long(Fd
.BaseAddress
, 0))
1872 self
.__PcdDict
['%s.%s' % (RegionObj
.PcdOffset
[1], RegionObj
.PcdOffset
[0])] = "0x%x" % RegionObj
.Offset
1873 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1874 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdOffset
] = FileLineTuple
1875 if self
.__IsToken
( "|"):
1876 RegionObj
.PcdSize
= self
.__GetNextPcdName
()
1877 self
.Profile
.PcdDict
[RegionObj
.PcdSize
] = "0x%08X" % RegionObj
.Size
1878 self
.__PcdDict
['%s.%s' % (RegionObj
.PcdSize
[1], RegionObj
.PcdSize
[0])] = "0x%x" % RegionObj
.Size
1879 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1880 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdSize
] = FileLineTuple
1882 if not self
.__GetNextWord
():
1885 if self
.__Token
== "SET":
1887 self
.__GetSetStatements
( RegionObj
)
1888 if not self
.__GetNextWord
():
1891 elif self
.__Token
== "FV":
1893 self
.__GetRegionFvType
( RegionObj
)
1895 elif self
.__Token
== "CAPSULE":
1897 self
.__GetRegionCapType
( RegionObj
)
1899 elif self
.__Token
== "FILE":
1901 self
.__GetRegionFileType
(RegionObj
)
1903 elif self
.__Token
== "INF":
1905 RegionObj
.RegionType
= "INF"
1906 while self
.__IsKeyword
("INF"):
1908 ffsInf
= self
.__ParseInfStatement
()
1911 RegionObj
.RegionDataList
.append(ffsInf
)
1913 elif self
.__Token
== "DATA":
1915 self
.__GetRegionDataType
(RegionObj
)
1918 if self
.__GetRegionLayout
(Fd
):
1920 raise Warning("A valid region type was not found. "
1921 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
1922 self
.FileName
, self
.CurrentLineNumber
)
1926 ## __GetRegionFvType() method
1928 # Get region fv data for region
1930 # @param self The object pointer
1931 # @param RegionObj for whom region data is got
1933 def __GetRegionFvType(self
, RegionObj
):
1935 if not self
.__IsKeyword
( "FV"):
1936 raise Warning("expected Keyword 'FV'", self
.FileName
, self
.CurrentLineNumber
)
1938 if not self
.__IsToken
( "="):
1939 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1941 if not self
.__GetNextToken
():
1942 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
1944 RegionObj
.RegionType
= "FV"
1945 RegionObj
.RegionDataList
.append(self
.__Token
)
1947 while self
.__IsKeyword
( "FV"):
1949 if not self
.__IsToken
( "="):
1950 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1952 if not self
.__GetNextToken
():
1953 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
1955 RegionObj
.RegionDataList
.append(self
.__Token
)
1957 ## __GetRegionCapType() method
1959 # Get region capsule data for region
1961 # @param self The object pointer
1962 # @param RegionObj for whom region data is got
1964 def __GetRegionCapType(self
, RegionObj
):
1966 if not self
.__IsKeyword
("CAPSULE"):
1967 raise Warning("expected Keyword 'CAPSULE'", self
.FileName
, self
.CurrentLineNumber
)
1969 if not self
.__IsToken
("="):
1970 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1972 if not self
.__GetNextToken
():
1973 raise Warning("expected CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1975 RegionObj
.RegionType
= "CAPSULE"
1976 RegionObj
.RegionDataList
.append(self
.__Token
)
1978 while self
.__IsKeyword
("CAPSULE"):
1980 if not self
.__IsToken
("="):
1981 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1983 if not self
.__GetNextToken
():
1984 raise Warning("expected CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1986 RegionObj
.RegionDataList
.append(self
.__Token
)
1988 ## __GetRegionFileType() method
1990 # Get region file data for region
1992 # @param self The object pointer
1993 # @param RegionObj for whom region data is got
1995 def __GetRegionFileType(self
, RegionObj
):
1997 if not self
.__IsKeyword
( "FILE"):
1998 raise Warning("expected Keyword 'FILE'", self
.FileName
, self
.CurrentLineNumber
)
2000 if not self
.__IsToken
( "="):
2001 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2003 if not self
.__GetNextToken
():
2004 raise Warning("expected File name", self
.FileName
, self
.CurrentLineNumber
)
2006 RegionObj
.RegionType
= "FILE"
2007 RegionObj
.RegionDataList
.append( self
.__Token
)
2009 while self
.__IsKeyword
( "FILE"):
2011 if not self
.__IsToken
( "="):
2012 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2014 if not self
.__GetNextToken
():
2015 raise Warning("expected FILE name", self
.FileName
, self
.CurrentLineNumber
)
2017 RegionObj
.RegionDataList
.append(self
.__Token
)
2019 ## __GetRegionDataType() method
2021 # Get region array data for region
2023 # @param self The object pointer
2024 # @param RegionObj for whom region data is got
2026 def __GetRegionDataType(self
, RegionObj
):
2028 if not self
.__IsKeyword
( "DATA"):
2029 raise Warning("expected Region Data type", self
.FileName
, self
.CurrentLineNumber
)
2031 if not self
.__IsToken
( "="):
2032 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2034 if not self
.__IsToken
( "{"):
2035 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2037 if not self
.__GetNextHexNumber
():
2038 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2040 if len(self
.__Token
) > 18:
2041 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2043 # convert hex string value to byte hex string array
2044 AllString
= self
.__Token
2045 AllStrLen
= len (AllString
)
2047 while AllStrLen
> 4:
2048 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + ","
2049 AllStrLen
= AllStrLen
- 2
2050 DataString
= DataString
+ AllString
[:AllStrLen
] + ","
2053 if len (self
.__Token
) <= 4:
2054 while self
.__IsToken
(","):
2055 if not self
.__GetNextHexNumber
():
2056 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2057 if len(self
.__Token
) > 4:
2058 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2059 DataString
+= self
.__Token
2062 if not self
.__IsToken
( "}"):
2063 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2065 DataString
= DataString
.rstrip(",")
2066 RegionObj
.RegionType
= "DATA"
2067 RegionObj
.RegionDataList
.append( DataString
)
2069 while self
.__IsKeyword
( "DATA"):
2071 if not self
.__IsToken
( "="):
2072 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2074 if not self
.__IsToken
( "{"):
2075 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2077 if not self
.__GetNextHexNumber
():
2078 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2080 if len(self
.__Token
) > 18:
2081 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2083 # convert hex string value to byte hex string array
2084 AllString
= self
.__Token
2085 AllStrLen
= len (AllString
)
2087 while AllStrLen
> 4:
2088 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + ","
2089 AllStrLen
= AllStrLen
- 2
2090 DataString
= DataString
+ AllString
[:AllStrLen
] + ","
2093 if len (self
.__Token
) <= 4:
2094 while self
.__IsToken
(","):
2095 if not self
.__GetNextHexNumber
():
2096 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2097 if len(self
.__Token
) > 4:
2098 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2099 DataString
+= self
.__Token
2102 if not self
.__IsToken
( "}"):
2103 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2105 DataString
= DataString
.rstrip(",")
2106 RegionObj
.RegionDataList
.append( DataString
)
2110 # Get FV section contents and store its data into FV dictionary of self.Profile
2112 # @param self The object pointer
2113 # @retval True Successfully find a FV
2114 # @retval False Not able to find a FV
2117 if not self
.__GetNextToken
():
2120 S
= self
.__Token
.upper()
2121 if S
.startswith("[") and not S
.startswith("[FV."):
2122 self
.SectionParser(S
)
2127 if not self
.__IsToken
("[FV.", True):
2128 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2129 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2130 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2131 raise Warning("Unknown Keyword '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2133 FvName
= self
.__GetUiName
()
2134 self
.CurrentFvName
= FvName
.upper()
2136 if not self
.__IsToken
( "]"):
2137 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
2140 FvObj
.UiFvName
= self
.CurrentFvName
2141 self
.Profile
.FvDict
[self
.CurrentFvName
] = FvObj
2143 Status
= self
.__GetCreateFile
(FvObj
)
2145 raise Warning("FV name error", self
.FileName
, self
.CurrentLineNumber
)
2147 self
.__GetDefineStatements
(FvObj
)
2149 self
.__GetAddressStatements
(FvObj
)
2151 FvObj
.FvExtEntryTypeValue
= []
2152 FvObj
.FvExtEntryType
= []
2153 FvObj
.FvExtEntryData
= []
2155 self
.__GetSetStatements
(FvObj
)
2157 if not (self
.__GetBlockStatement
(FvObj
) or self
.__GetFvBaseAddress
(FvObj
) or
2158 self
.__GetFvForceRebase
(FvObj
) or self
.__GetFvAlignment
(FvObj
) or
2159 self
.__GetFvAttributes
(FvObj
) or self
.__GetFvNameGuid
(FvObj
) or
2160 self
.__GetFvExtEntryStatement
(FvObj
) or self
.__GetFvNameString
(FvObj
)):
2163 if FvObj
.FvNameString
== 'TRUE' and not FvObj
.FvNameGuid
:
2164 raise Warning("FvNameString found but FvNameGuid was not found", self
.FileName
, self
.CurrentLineNumber
)
2166 self
.__GetAprioriSection
(FvObj
, FvObj
.DefineVarDict
.copy())
2167 self
.__GetAprioriSection
(FvObj
, FvObj
.DefineVarDict
.copy())
2170 isInf
= self
.__GetInfStatement
(FvObj
, MacroDict
= FvObj
.DefineVarDict
.copy())
2171 isFile
= self
.__GetFileStatement
(FvObj
, MacroDict
= FvObj
.DefineVarDict
.copy())
2172 if not isInf
and not isFile
:
2177 ## __GetFvAlignment() method
2179 # Get alignment for FV
2181 # @param self The object pointer
2182 # @param Obj for whom alignment is got
2183 # @retval True Successfully find a alignment statement
2184 # @retval False Not able to find a alignment statement
2186 def __GetFvAlignment(self
, Obj
):
2188 if not self
.__IsKeyword
( "FvAlignment"):
2191 if not self
.__IsToken
( "="):
2192 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2194 if not self
.__GetNextToken
():
2195 raise Warning("expected alignment value", self
.FileName
, self
.CurrentLineNumber
)
2197 if self
.__Token
.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
2198 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
2199 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
2201 raise Warning("Unknown alignment value '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2202 Obj
.FvAlignment
= self
.__Token
2205 ## __GetFvBaseAddress() method
2207 # Get BaseAddress for FV
2209 # @param self The object pointer
2210 # @param Obj for whom FvBaseAddress is got
2211 # @retval True Successfully find a FvBaseAddress statement
2212 # @retval False Not able to find a FvBaseAddress statement
2214 def __GetFvBaseAddress(self
, Obj
):
2216 if not self
.__IsKeyword
("FvBaseAddress"):
2219 if not self
.__IsToken
( "="):
2220 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2222 if not self
.__GetNextToken
():
2223 raise Warning("expected FV base address value", self
.FileName
, self
.CurrentLineNumber
)
2225 IsValidBaseAddrValue
= re
.compile('^0[x|X][0-9a-fA-F]+')
2227 if not IsValidBaseAddrValue
.match(self
.__Token
.upper()):
2228 raise Warning("Unknown FV base address value '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2229 Obj
.FvBaseAddress
= self
.__Token
2232 ## __GetFvForceRebase() method
2234 # Get FvForceRebase for FV
2236 # @param self The object pointer
2237 # @param Obj for whom FvForceRebase is got
2238 # @retval True Successfully find a FvForceRebase statement
2239 # @retval False Not able to find a FvForceRebase statement
2241 def __GetFvForceRebase(self
, Obj
):
2243 if not self
.__IsKeyword
("FvForceRebase"):
2246 if not self
.__IsToken
( "="):
2247 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2249 if not self
.__GetNextToken
():
2250 raise Warning("expected FvForceRebase value", self
.FileName
, self
.CurrentLineNumber
)
2252 if self
.__Token
.upper() not in ["TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"]:
2253 raise Warning("Unknown FvForceRebase value '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2255 if self
.__Token
.upper() in ["TRUE", "1", "0X1", "0X01"]:
2256 Obj
.FvForceRebase
= True
2257 elif self
.__Token
.upper() in ["FALSE", "0", "0X0", "0X00"]:
2258 Obj
.FvForceRebase
= False
2260 Obj
.FvForceRebase
= None
2265 ## __GetFvAttributes() method
2267 # Get attributes for FV
2269 # @param self The object pointer
2270 # @param Obj for whom attribute is got
2273 def __GetFvAttributes(self
, FvObj
):
2275 while self
.__GetNextWord
():
2278 if name
not in ("ERASE_POLARITY", "MEMORY_MAPPED", \
2279 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
2280 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
2281 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
2282 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
2283 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT"):
2287 if not self
.__IsToken
( "="):
2288 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2290 if not self
.__GetNextToken
() or self
.__Token
.upper() not in ("TRUE", "FALSE", "1", "0"):
2291 raise Warning("expected TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
2293 FvObj
.FvAttributeDict
[name
] = self
.__Token
2297 ## __GetFvNameGuid() method
2299 # Get FV GUID for FV
2301 # @param self The object pointer
2302 # @param Obj for whom GUID is got
2305 def __GetFvNameGuid(self
, FvObj
):
2307 if not self
.__IsKeyword
( "FvNameGuid"):
2310 if not self
.__IsToken
( "="):
2311 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2313 if not self
.__GetNextGuid
():
2314 raise Warning("expected FV GUID value", self
.FileName
, self
.CurrentLineNumber
)
2316 FvObj
.FvNameGuid
= self
.__Token
2320 def __GetFvNameString(self
, FvObj
):
2322 if not self
.__IsKeyword
( "FvNameString"):
2325 if not self
.__IsToken
( "="):
2326 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2328 if not self
.__GetNextToken
() or self
.__Token
not in ('TRUE', 'FALSE'):
2329 raise Warning("expected TRUE or FALSE for FvNameString", self
.FileName
, self
.CurrentLineNumber
)
2331 FvObj
.FvNameString
= self
.__Token
2335 def __GetFvExtEntryStatement(self
, FvObj
):
2337 if not self
.__IsKeyword
( "FV_EXT_ENTRY"):
2340 if not self
.__IsKeyword
("TYPE"):
2341 raise Warning("expected 'TYPE'", self
.FileName
, self
.CurrentLineNumber
)
2343 if not self
.__IsToken
( "="):
2344 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2346 if not self
.__GetNextHexNumber
() and not self
.__GetNextDecimalNumber
():
2347 raise Warning("expected Hex FV extension entry type value At Line ", self
.FileName
, self
.CurrentLineNumber
)
2349 FvObj
.FvExtEntryTypeValue
+= [self
.__Token
]
2351 if not self
.__IsToken
( "{"):
2352 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2354 if not self
.__IsKeyword
("FILE") and not self
.__IsKeyword
("DATA"):
2355 raise Warning("expected 'FILE' or 'DATA'", self
.FileName
, self
.CurrentLineNumber
)
2357 FvObj
.FvExtEntryType
+= [self
.__Token
]
2359 if self
.__Token
== 'DATA':
2361 if not self
.__IsToken
( "="):
2362 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2364 if not self
.__IsToken
( "{"):
2365 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2367 if not self
.__GetNextHexNumber
():
2368 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2370 if len(self
.__Token
) > 4:
2371 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2373 DataString
= self
.__Token
2376 while self
.__IsToken
(","):
2377 if not self
.__GetNextHexNumber
():
2378 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2379 if len(self
.__Token
) > 4:
2380 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2381 DataString
+= self
.__Token
2384 if not self
.__IsToken
( "}"):
2385 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2387 if not self
.__IsToken
( "}"):
2388 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2390 DataString
= DataString
.rstrip(",")
2391 FvObj
.FvExtEntryData
+= [DataString
]
2393 if self
.__Token
== 'FILE':
2395 if not self
.__IsToken
( "="):
2396 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2398 if not self
.__GetNextToken
():
2399 raise Warning("expected FV Extension Entry file path At Line ", self
.FileName
, self
.CurrentLineNumber
)
2401 FvObj
.FvExtEntryData
+= [self
.__Token
]
2403 if not self
.__IsToken
( "}"):
2404 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2408 ## __GetAprioriSection() method
2410 # Get token statements
2412 # @param self The object pointer
2413 # @param FvObj for whom apriori is got
2414 # @param MacroDict dictionary used to replace macro
2415 # @retval True Successfully find apriori statement
2416 # @retval False Not able to find apriori statement
2418 def __GetAprioriSection(self
, FvObj
, MacroDict
= {}):
2420 if not self
.__IsKeyword
( "APRIORI"):
2423 if not self
.__IsKeyword
("PEI") and not self
.__IsKeyword
("DXE"):
2424 raise Warning("expected Apriori file type", self
.FileName
, self
.CurrentLineNumber
)
2425 AprType
= self
.__Token
2427 if not self
.__IsToken
( "{"):
2428 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2430 AprSectionObj
= AprioriSection
.AprioriSection()
2431 AprSectionObj
.AprioriType
= AprType
2433 self
.__GetDefineStatements
(AprSectionObj
)
2434 MacroDict
.update(AprSectionObj
.DefineVarDict
)
2437 IsInf
= self
.__GetInfStatement
( AprSectionObj
, MacroDict
= MacroDict
)
2438 IsFile
= self
.__GetFileStatement
( AprSectionObj
)
2439 if not IsInf
and not IsFile
:
2442 if not self
.__IsToken
( "}"):
2443 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2445 FvObj
.AprioriSectionList
.append(AprSectionObj
)
2448 def __ParseInfStatement(self
):
2449 if not self
.__IsKeyword
("INF"):
2452 ffsInf
= FfsInfStatement
.FfsInfStatement()
2453 self
.__GetInfOptions
(ffsInf
)
2455 if not self
.__GetNextToken
():
2456 raise Warning("expected INF file path", self
.FileName
, self
.CurrentLineNumber
)
2457 ffsInf
.InfFileName
= self
.__Token
2459 ffsInf
.CurrentLineNum
= self
.CurrentLineNumber
2460 ffsInf
.CurrentLineContent
= self
.__CurrentLine
()
2462 #Replace $(SAPCE) with real space
2463 ffsInf
.InfFileName
= ffsInf
.InfFileName
.replace('$(SPACE)', ' ')
2465 if ffsInf
.InfFileName
.replace('$(WORKSPACE)', '').find('$') == -1:
2466 #do case sensitive check for file path
2467 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2469 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2471 if not ffsInf
.InfFileName
in self
.Profile
.InfList
:
2472 self
.Profile
.InfList
.append(ffsInf
.InfFileName
)
2473 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2474 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
2476 if self
.__IsToken
('|'):
2477 if self
.__IsKeyword
('RELOCS_STRIPPED'):
2478 ffsInf
.KeepReloc
= False
2479 elif self
.__IsKeyword
('RELOCS_RETAINED'):
2480 ffsInf
.KeepReloc
= True
2482 raise Warning("Unknown reloc strip flag '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2485 ## __GetInfStatement() method
2487 # Get INF statements
2489 # @param self The object pointer
2490 # @param Obj for whom inf statement is got
2491 # @param MacroDict dictionary used to replace macro
2492 # @retval True Successfully find inf statement
2493 # @retval False Not able to find inf statement
2495 def __GetInfStatement(self
, Obj
, ForCapsule
=False, MacroDict
={}):
2496 ffsInf
= self
.__ParseInfStatement
()
2501 capsuleFfs
= CapsuleData
.CapsuleFfs()
2502 capsuleFfs
.Ffs
= ffsInf
2503 Obj
.CapsuleDataList
.append(capsuleFfs
)
2505 Obj
.FfsList
.append(ffsInf
)
2508 ## __GetInfOptions() method
2510 # Get options for INF
2512 # @param self The object pointer
2513 # @param FfsInfObj for whom option is got
2515 def __GetInfOptions(self
, FfsInfObj
):
2516 if self
.__IsKeyword
("FILE_GUID"):
2517 if not self
.__IsToken
("="):
2518 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2519 if not self
.__GetNextGuid
():
2520 raise Warning("expected GUID value", self
.FileName
, self
.CurrentLineNumber
)
2521 FfsInfObj
.OverrideGuid
= self
.__Token
2523 if self
.__IsKeyword
( "RuleOverride"):
2524 if not self
.__IsToken
( "="):
2525 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2526 if not self
.__GetNextToken
():
2527 raise Warning("expected Rule name", self
.FileName
, self
.CurrentLineNumber
)
2528 FfsInfObj
.Rule
= self
.__Token
2530 if self
.__IsKeyword
( "VERSION"):
2531 if not self
.__IsToken
( "="):
2532 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2533 if not self
.__GetNextToken
():
2534 raise Warning("expected Version", self
.FileName
, self
.CurrentLineNumber
)
2536 if self
.__GetStringData
():
2537 FfsInfObj
.Version
= self
.__Token
2539 if self
.__IsKeyword
( "UI"):
2540 if not self
.__IsToken
( "="):
2541 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2542 if not self
.__GetNextToken
():
2543 raise Warning("expected UI name", self
.FileName
, self
.CurrentLineNumber
)
2545 if self
.__GetStringData
():
2546 FfsInfObj
.Ui
= self
.__Token
2548 if self
.__IsKeyword
( "USE"):
2549 if not self
.__IsToken
( "="):
2550 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2551 if not self
.__GetNextToken
():
2552 raise Warning("expected ARCH name", self
.FileName
, self
.CurrentLineNumber
)
2553 FfsInfObj
.UseArch
= self
.__Token
2556 if self
.__GetNextToken
():
2557 p
= re
.compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
2558 if p
.match(self
.__Token
) and p
.match(self
.__Token
).span()[1] == len(self
.__Token
):
2559 FfsInfObj
.KeyStringList
.append(self
.__Token
)
2560 if not self
.__IsToken
(","):
2566 while self
.__GetNextToken
():
2567 if not p
.match(self
.__Token
):
2568 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2569 FfsInfObj
.KeyStringList
.append(self
.__Token
)
2571 if not self
.__IsToken
(","):
2574 ## __GetFileStatement() method
2576 # Get FILE statements
2578 # @param self The object pointer
2579 # @param Obj for whom FILE statement is got
2580 # @param MacroDict dictionary used to replace macro
2581 # @retval True Successfully find FILE statement
2582 # @retval False Not able to find FILE statement
2584 def __GetFileStatement(self
, Obj
, ForCapsule
= False, MacroDict
= {}):
2586 if not self
.__IsKeyword
( "FILE"):
2589 if not self
.__GetNextWord
():
2590 raise Warning("expected FFS type", self
.FileName
, self
.CurrentLineNumber
)
2592 if ForCapsule
and self
.__Token
== 'DATA':
2597 FfsFileObj
= FfsFileStatement
.FileStatement()
2598 FfsFileObj
.FvFileType
= self
.__Token
2600 if not self
.__IsToken
( "="):
2601 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2603 if not self
.__GetNextGuid
():
2604 if not self
.__GetNextWord
():
2605 raise Warning("expected File GUID", self
.FileName
, self
.CurrentLineNumber
)
2606 if self
.__Token
== 'PCD':
2607 if not self
.__IsToken
( "("):
2608 raise Warning("expected '('", self
.FileName
, self
.CurrentLineNumber
)
2609 PcdPair
= self
.__GetNextPcdName
()
2610 if not self
.__IsToken
( ")"):
2611 raise Warning("expected ')'", self
.FileName
, self
.CurrentLineNumber
)
2612 self
.__Token
= 'PCD('+PcdPair
[1]+'.'+PcdPair
[0]+')'
2614 FfsFileObj
.NameGuid
= self
.__Token
2616 self
.__GetFilePart
( FfsFileObj
, MacroDict
.copy())
2619 capsuleFfs
= CapsuleData
.CapsuleFfs()
2620 capsuleFfs
.Ffs
= FfsFileObj
2621 Obj
.CapsuleDataList
.append(capsuleFfs
)
2623 Obj
.FfsList
.append(FfsFileObj
)
2627 ## __FileCouldHaveRelocFlag() method
2629 # Check whether reloc strip flag can be set for a file type.
2631 # @param self The object pointer
2632 # @param FileType The file type to check with
2633 # @retval True This type could have relocation strip flag
2634 # @retval False No way to have it
2637 def __FileCouldHaveRelocFlag (self
, FileType
):
2638 if FileType
in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'):
2643 ## __SectionCouldHaveRelocFlag() method
2645 # Check whether reloc strip flag can be set for a section type.
2647 # @param self The object pointer
2648 # @param SectionType The section type to check with
2649 # @retval True This type could have relocation strip flag
2650 # @retval False No way to have it
2653 def __SectionCouldHaveRelocFlag (self
, SectionType
):
2654 if SectionType
in ('TE', 'PE32'):
2659 ## __GetFilePart() method
2661 # Get components for FILE statement
2663 # @param self The object pointer
2664 # @param FfsFileObj for whom component is got
2665 # @param MacroDict dictionary used to replace macro
2667 def __GetFilePart(self
, FfsFileObj
, MacroDict
= {}):
2669 self
.__GetFileOpts
( FfsFileObj
)
2671 if not self
.__IsToken
("{"):
2672 if self
.__IsKeyword
('RELOCS_STRIPPED') or self
.__IsKeyword
('RELOCS_RETAINED'):
2673 if self
.__FileCouldHaveRelocFlag
(FfsFileObj
.FvFileType
):
2674 if self
.__Token
== 'RELOCS_STRIPPED':
2675 FfsFileObj
.KeepReloc
= False
2677 FfsFileObj
.KeepReloc
= True
2679 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj
.FvFileType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
2681 if not self
.__IsToken
("{"):
2682 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2684 if not self
.__GetNextToken
():
2685 raise Warning("expected File name or section data", self
.FileName
, self
.CurrentLineNumber
)
2687 if self
.__Token
== "FV":
2688 if not self
.__IsToken
( "="):
2689 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2690 if not self
.__GetNextToken
():
2691 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
2692 FfsFileObj
.FvName
= self
.__Token
2694 elif self
.__Token
== "FD":
2695 if not self
.__IsToken
( "="):
2696 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2697 if not self
.__GetNextToken
():
2698 raise Warning("expected FD name", self
.FileName
, self
.CurrentLineNumber
)
2699 FfsFileObj
.FdName
= self
.__Token
2701 elif self
.__Token
in ("DEFINE", "APRIORI", "SECTION"):
2703 self
.__GetSectionData
( FfsFileObj
, MacroDict
)
2705 elif hasattr(FfsFileObj
, 'FvFileType') and FfsFileObj
.FvFileType
== 'RAW':
2707 self
.__GetRAWData
(FfsFileObj
, MacroDict
)
2710 FfsFileObj
.CurrentLineNum
= self
.CurrentLineNumber
2711 FfsFileObj
.CurrentLineContent
= self
.__CurrentLine
()
2712 FfsFileObj
.FileName
= self
.__Token
.replace('$(SPACE)', ' ')
2713 self
.__VerifyFile
(FfsFileObj
.FileName
)
2715 if not self
.__IsToken
( "}"):
2716 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2718 ## __GetRAWData() method
2720 # Get RAW data for FILE statement
2722 # @param self The object pointer
2723 # @param FfsFileObj for whom section is got
2724 # @param MacroDict dictionary used to replace macro
2726 def __GetRAWData(self
, FfsFileObj
, MacroDict
= {}):
2727 FfsFileObj
.FileName
= []
2728 FfsFileObj
.SubAlignment
= []
2731 if self
.__GetAlignment
():
2732 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2733 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2734 AlignValue
= self
.__Token
2735 if not self
.__GetNextToken
():
2736 raise Warning("expected Filename value", self
.FileName
, self
.CurrentLineNumber
)
2738 FileName
= self
.__Token
.replace('$(SPACE)', ' ')
2741 raise Warning("expected Filename value", self
.FileName
, self
.CurrentLineNumber
)
2743 self
.__VerifyFile
(FileName
)
2744 File
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
)
2745 FfsFileObj
.FileName
.append(File
.Path
)
2746 FfsFileObj
.SubAlignment
.append(AlignValue
)
2748 if self
.__IsToken
( "}"):
2752 if len(FfsFileObj
.SubAlignment
) == 1:
2753 FfsFileObj
.SubAlignment
= FfsFileObj
.SubAlignment
[0]
2754 if len(FfsFileObj
.FileName
) == 1:
2755 FfsFileObj
.FileName
= FfsFileObj
.FileName
[0]
2757 ## __GetFileOpts() method
2759 # Get options for FILE statement
2761 # @param self The object pointer
2762 # @param FfsFileObj for whom options is got
2764 def __GetFileOpts(self
, FfsFileObj
):
2766 if self
.__GetNextToken
():
2767 Pattern
= re
.compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
2768 if Pattern
.match(self
.__Token
):
2769 FfsFileObj
.KeyStringList
.append(self
.__Token
)
2770 if self
.__IsToken
(","):
2771 while self
.__GetNextToken
():
2772 if not Pattern
.match(self
.__Token
):
2773 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2774 FfsFileObj
.KeyStringList
.append(self
.__Token
)
2776 if not self
.__IsToken
(","):
2782 if self
.__IsKeyword
( "FIXED", True):
2783 FfsFileObj
.Fixed
= True
2785 if self
.__IsKeyword
( "CHECKSUM", True):
2786 FfsFileObj
.CheckSum
= True
2788 if self
.__GetAlignment
():
2789 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2790 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2791 #For FFS, Auto is default option same to ""
2792 if not self
.__Token
== "Auto":
2793 FfsFileObj
.Alignment
= self
.__Token
2795 ## __GetAlignment() method
2797 # Return the alignment value
2799 # @param self The object pointer
2800 # @retval True Successfully find alignment
2801 # @retval False Not able to find alignment
2803 def __GetAlignment(self
):
2804 if self
.__IsKeyword
( "Align", True):
2805 if not self
.__IsToken
( "="):
2806 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2808 if not self
.__GetNextToken
():
2809 raise Warning("expected alignment value", self
.FileName
, self
.CurrentLineNumber
)
2814 ## __GetFilePart() method
2816 # Get section data for FILE statement
2818 # @param self The object pointer
2819 # @param FfsFileObj for whom section is got
2820 # @param MacroDict dictionary used to replace macro
2822 def __GetSectionData(self
, FfsFileObj
, MacroDict
= {}):
2824 Dict
.update(MacroDict
)
2826 self
.__GetDefineStatements
(FfsFileObj
)
2828 Dict
.update(FfsFileObj
.DefineVarDict
)
2829 self
.__GetAprioriSection
(FfsFileObj
, Dict
.copy())
2830 self
.__GetAprioriSection
(FfsFileObj
, Dict
.copy())
2833 IsLeafSection
= self
.__GetLeafSection
(FfsFileObj
, Dict
)
2834 IsEncapSection
= self
.__GetEncapsulationSec
(FfsFileObj
)
2835 if not IsLeafSection
and not IsEncapSection
:
2838 ## __GetLeafSection() method
2840 # Get leaf section for Obj
2842 # @param self The object pointer
2843 # @param Obj for whom leaf section is got
2844 # @param MacroDict dictionary used to replace macro
2845 # @retval True Successfully find section statement
2846 # @retval False Not able to find section statement
2848 def __GetLeafSection(self
, Obj
, MacroDict
= {}):
2850 OldPos
= self
.GetFileBufferPos()
2852 if not self
.__IsKeyword
( "SECTION"):
2853 if len(Obj
.SectionList
) == 0:
2854 raise Warning("expected SECTION", self
.FileName
, self
.CurrentLineNumber
)
2859 if self
.__GetAlignment
():
2860 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2861 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2862 AlignValue
= self
.__Token
2865 if self
.__IsKeyword
( "BUILD_NUM"):
2866 if not self
.__IsToken
( "="):
2867 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2869 if not self
.__GetNextToken
():
2870 raise Warning("expected Build number value", self
.FileName
, self
.CurrentLineNumber
)
2872 BuildNum
= self
.__Token
2874 if self
.__IsKeyword
( "VERSION"):
2875 if AlignValue
== 'Auto':
2876 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2877 if not self
.__IsToken
( "="):
2878 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2879 if not self
.__GetNextToken
():
2880 raise Warning("expected version", self
.FileName
, self
.CurrentLineNumber
)
2881 VerSectionObj
= VerSection
.VerSection()
2882 VerSectionObj
.Alignment
= AlignValue
2883 VerSectionObj
.BuildNum
= BuildNum
2884 if self
.__GetStringData
():
2885 VerSectionObj
.StringData
= self
.__Token
2887 VerSectionObj
.FileName
= self
.__Token
2888 Obj
.SectionList
.append(VerSectionObj
)
2890 elif self
.__IsKeyword
( "UI"):
2891 if AlignValue
== 'Auto':
2892 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2893 if not self
.__IsToken
( "="):
2894 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2895 if not self
.__GetNextToken
():
2896 raise Warning("expected UI", self
.FileName
, self
.CurrentLineNumber
)
2897 UiSectionObj
= UiSection
.UiSection()
2898 UiSectionObj
.Alignment
= AlignValue
2899 if self
.__GetStringData
():
2900 UiSectionObj
.StringData
= self
.__Token
2902 UiSectionObj
.FileName
= self
.__Token
2903 Obj
.SectionList
.append(UiSectionObj
)
2905 elif self
.__IsKeyword
( "FV_IMAGE"):
2906 if AlignValue
== 'Auto':
2907 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2908 if not self
.__IsToken
( "="):
2909 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2910 if not self
.__GetNextToken
():
2911 raise Warning("expected FV name or FV file path", self
.FileName
, self
.CurrentLineNumber
)
2913 FvName
= self
.__Token
2916 if self
.__IsToken
( "{"):
2918 FvObj
.UiFvName
= FvName
.upper()
2919 self
.__GetDefineStatements
(FvObj
)
2920 MacroDict
.update(FvObj
.DefineVarDict
)
2921 self
.__GetBlockStatement
(FvObj
)
2922 self
.__GetSetStatements
(FvObj
)
2923 self
.__GetFvAlignment
(FvObj
)
2924 self
.__GetFvAttributes
(FvObj
)
2925 self
.__GetAprioriSection
(FvObj
, MacroDict
.copy())
2926 self
.__GetAprioriSection
(FvObj
, MacroDict
.copy())
2929 IsInf
= self
.__GetInfStatement
(FvObj
, MacroDict
.copy())
2930 IsFile
= self
.__GetFileStatement
(FvObj
, MacroDict
.copy())
2931 if not IsInf
and not IsFile
:
2934 if not self
.__IsToken
( "}"):
2935 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2937 FvImageSectionObj
= FvImageSection
.FvImageSection()
2938 FvImageSectionObj
.Alignment
= AlignValue
2940 FvImageSectionObj
.Fv
= FvObj
2941 FvImageSectionObj
.FvName
= None
2943 FvImageSectionObj
.FvName
= FvName
.upper()
2944 FvImageSectionObj
.FvFileName
= FvName
2946 Obj
.SectionList
.append(FvImageSectionObj
)
2948 elif self
.__IsKeyword
("PEI_DEPEX_EXP") or self
.__IsKeyword
("DXE_DEPEX_EXP") or self
.__IsKeyword
("SMM_DEPEX_EXP"):
2949 if AlignValue
== 'Auto':
2950 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2951 DepexSectionObj
= DepexSection
.DepexSection()
2952 DepexSectionObj
.Alignment
= AlignValue
2953 DepexSectionObj
.DepexType
= self
.__Token
2955 if not self
.__IsToken
( "="):
2956 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2957 if not self
.__IsToken
( "{"):
2958 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2959 if not self
.__SkipToToken
( "}"):
2960 raise Warning("expected Depex expression ending '}'", self
.FileName
, self
.CurrentLineNumber
)
2962 DepexSectionObj
.Expression
= self
.__SkippedChars
.rstrip('}')
2963 Obj
.SectionList
.append(DepexSectionObj
)
2966 if not self
.__GetNextWord
():
2967 raise Warning("expected section type", self
.FileName
, self
.CurrentLineNumber
)
2969 # Encapsulation section appear, UndoToken and return
2970 if self
.__Token
== "COMPRESS" or self
.__Token
== "GUIDED":
2971 self
.SetFileBufferPos(OldPos
)
2974 if self
.__Token
not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
2975 "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"):
2976 raise Warning("Unknown section type '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2977 if AlignValue
== 'Auto'and (not self
.__Token
== 'PE32') and (not self
.__Token
== 'TE'):
2978 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2981 DataSectionObj
= DataSection
.DataSection()
2982 DataSectionObj
.Alignment
= AlignValue
2983 DataSectionObj
.SecType
= self
.__Token
2985 if self
.__IsKeyword
('RELOCS_STRIPPED') or self
.__IsKeyword
('RELOCS_RETAINED'):
2986 if self
.__FileCouldHaveRelocFlag
(Obj
.FvFileType
) and self
.__SectionCouldHaveRelocFlag
(DataSectionObj
.SecType
):
2987 if self
.__Token
== 'RELOCS_STRIPPED':
2988 DataSectionObj
.KeepReloc
= False
2990 DataSectionObj
.KeepReloc
= True
2992 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
)
2994 if self
.__IsToken
("="):
2995 if not self
.__GetNextToken
():
2996 raise Warning("expected section file path", self
.FileName
, self
.CurrentLineNumber
)
2997 DataSectionObj
.SectFileName
= self
.__Token
2998 self
.__VerifyFile
(DataSectionObj
.SectFileName
)
3000 if not self
.__GetCglSection
(DataSectionObj
):
3003 Obj
.SectionList
.append(DataSectionObj
)
3009 # Check if file exists or not:
3010 # If current phase if GenFds, the file must exist;
3011 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist
3012 # @param FileName: File path to be verified.
3014 def __VerifyFile(self
, FileName
):
3015 if FileName
.replace('$(WORKSPACE)', '').find('$') != -1:
3017 if not GlobalData
.gAutoGenPhase
or not self
.__GetMacroValue
("OUTPUT_DIRECTORY") in FileName
:
3018 ErrorCode
, ErrorInfo
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
3020 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
3022 ## __GetCglSection() method
3024 # Get compressed or GUIDed section for Obj
3026 # @param self The object pointer
3027 # @param Obj for whom leaf section is got
3028 # @param AlignValue alignment value for complex section
3029 # @retval True Successfully find section statement
3030 # @retval False Not able to find section statement
3032 def __GetCglSection(self
, Obj
, AlignValue
= None):
3034 if self
.__IsKeyword
( "COMPRESS"):
3036 if self
.__IsKeyword
("PI_STD") or self
.__IsKeyword
("PI_NONE"):
3039 if not self
.__IsToken
("{"):
3040 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
3042 CompressSectionObj
= CompressSection
.CompressSection()
3043 CompressSectionObj
.Alignment
= AlignValue
3044 CompressSectionObj
.CompType
= type
3045 # Recursive sections...
3047 IsLeafSection
= self
.__GetLeafSection
(CompressSectionObj
)
3048 IsEncapSection
= self
.__GetEncapsulationSec
(CompressSectionObj
)
3049 if not IsLeafSection
and not IsEncapSection
:
3053 if not self
.__IsToken
( "}"):
3054 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
3055 Obj
.SectionList
.append(CompressSectionObj
)
3058 # raise Warning("Compress type not known")
3062 elif self
.__IsKeyword
( "GUIDED"):
3064 if self
.__GetNextGuid
():
3065 GuidValue
= self
.__Token
3067 AttribDict
= self
.__GetGuidAttrib
()
3068 if not self
.__IsToken
("{"):
3069 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
3070 GuidSectionObj
= GuidSection
.GuidSection()
3071 GuidSectionObj
.Alignment
= AlignValue
3072 GuidSectionObj
.NameGuid
= GuidValue
3073 GuidSectionObj
.SectionType
= "GUIDED"
3074 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
3075 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
3076 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
3077 # Recursive sections...
3079 IsLeafSection
= self
.__GetLeafSection
(GuidSectionObj
)
3080 IsEncapSection
= self
.__GetEncapsulationSec
(GuidSectionObj
)
3081 if not IsLeafSection
and not IsEncapSection
:
3084 if not self
.__IsToken
( "}"):
3085 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
3086 Obj
.SectionList
.append(GuidSectionObj
)
3092 ## __GetGuidAttri() method
3094 # Get attributes for GUID section
3096 # @param self The object pointer
3097 # @retval AttribDict Dictionary of key-value pair of section attributes
3099 def __GetGuidAttrib(self
):
3102 AttribDict
["PROCESSING_REQUIRED"] = "NONE"
3103 AttribDict
["AUTH_STATUS_VALID"] = "NONE"
3104 AttribDict
["EXTRA_HEADER_SIZE"] = -1
3105 while self
.__IsKeyword
("PROCESSING_REQUIRED") or self
.__IsKeyword
("AUTH_STATUS_VALID") \
3106 or self
.__IsKeyword
("EXTRA_HEADER_SIZE"):
3107 AttribKey
= self
.__Token
3109 if not self
.__IsToken
("="):
3110 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3112 if not self
.__GetNextToken
():
3113 raise Warning("expected TRUE(1)/FALSE(0)/Number", self
.FileName
, self
.CurrentLineNumber
)
3114 elif AttribKey
== "EXTRA_HEADER_SIZE":
3116 if self
.__Token
[0:2].upper() == "0X":
3119 AttribDict
[AttribKey
] = int(self
.__Token
, Base
)
3122 raise Warning("expected Number", self
.FileName
, self
.CurrentLineNumber
)
3123 elif self
.__Token
.upper() not in ("TRUE", "FALSE", "1", "0"):
3124 raise Warning("expected TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
3125 AttribDict
[AttribKey
] = self
.__Token
3129 ## __GetEncapsulationSec() method
3131 # Get encapsulation section for FILE
3133 # @param self The object pointer
3134 # @param FfsFile for whom section is got
3135 # @retval True Successfully find section statement
3136 # @retval False Not able to find section statement
3138 def __GetEncapsulationSec(self
, FfsFileObj
):
3140 OldPos
= self
.GetFileBufferPos()
3141 if not self
.__IsKeyword
( "SECTION"):
3142 if len(FfsFileObj
.SectionList
) == 0:
3143 raise Warning("expected SECTION", self
.FileName
, self
.CurrentLineNumber
)
3148 if self
.__GetAlignment
():
3149 if self
.__Token
not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3150 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3151 AlignValue
= self
.__Token
3153 if not self
.__GetCglSection
(FfsFileObj
, AlignValue
):
3154 self
.SetFileBufferPos(OldPos
)
3160 if not self
.__GetNextToken
():
3162 S
= self
.__Token
.upper()
3163 if S
.startswith("[") and not S
.startswith("[FMPPAYLOAD."):
3164 self
.SectionParser(S
)
3169 self
.__SkipToToken
("[FMPPAYLOAD.", True)
3170 FmpUiName
= self
.__GetUiName
().upper()
3171 if FmpUiName
in self
.Profile
.FmpPayloadDict
:
3172 raise Warning("Duplicated FMP UI name found: %s" % FmpUiName
, self
.FileName
, self
.CurrentLineNumber
)
3174 FmpData
= CapsuleData
.CapsulePayload()
3175 FmpData
.UiName
= FmpUiName
3177 if not self
.__IsToken
( "]"):
3178 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
3180 if not self
.__GetNextToken
():
3181 raise Warning("The FMP payload section is empty!", self
.FileName
, self
.CurrentLineNumber
)
3182 FmpKeyList
= ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE']
3183 while self
.__Token
in FmpKeyList
:
3185 FmpKeyList
.remove(Name
)
3186 if not self
.__IsToken
("="):
3187 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3188 if Name
== 'IMAGE_TYPE_ID':
3189 if not self
.__GetNextGuid
():
3190 raise Warning("expected GUID value for IMAGE_TYPE_ID", self
.FileName
, self
.CurrentLineNumber
)
3191 FmpData
.ImageTypeId
= self
.__Token
3193 if not self
.__GetNextToken
():
3194 raise Warning("expected value of %s" % Name
, self
.FileName
, self
.CurrentLineNumber
)
3195 Value
= self
.__Token
3196 if Name
== 'IMAGE_HEADER_INIT_VERSION':
3197 FmpData
.Version
= Value
3198 elif Name
== 'IMAGE_INDEX':
3199 FmpData
.ImageIndex
= Value
3200 elif Name
== 'HARDWARE_INSTANCE':
3201 FmpData
.HardwareInstance
= Value
3202 if not self
.__GetNextToken
():
3208 raise Warning("Missing keywords %s in FMP payload section" % ', '.join(FmpKeyList
), self
.FileName
, self
.CurrentLineNumber
)
3209 ImageFile
= self
.__ParseRawFileStatement
()
3211 raise Warning("Missing image file in FMP payload section", self
.FileName
, self
.CurrentLineNumber
)
3212 FmpData
.ImageFile
= ImageFile
3213 VendorCodeFile
= self
.__ParseRawFileStatement
()
3215 FmpData
.VendorCodeFile
= VendorCodeFile
3216 self
.Profile
.FmpPayloadDict
[FmpUiName
] = FmpData
3219 ## __GetCapsule() method
3221 # Get capsule section contents and store its data into capsule list of self.Profile
3223 # @param self The object pointer
3224 # @retval True Successfully find a capsule
3225 # @retval False Not able to find a capsule
3227 def __GetCapsule(self
):
3229 if not self
.__GetNextToken
():
3232 S
= self
.__Token
.upper()
3233 if S
.startswith("[") and not S
.startswith("[CAPSULE."):
3234 self
.SectionParser(S
)
3239 if not self
.__IsToken
("[CAPSULE.", True):
3240 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3241 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3242 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3243 raise Warning("expected [Capsule.]", self
.FileName
, self
.CurrentLineNumber
)
3245 CapsuleObj
= Capsule
.Capsule()
3247 CapsuleName
= self
.__GetUiName
()
3249 raise Warning("expected capsule name", self
.FileName
, self
.CurrentLineNumber
)
3251 CapsuleObj
.UiCapsuleName
= CapsuleName
.upper()
3253 if not self
.__IsToken
( "]"):
3254 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
3256 if self
.__IsKeyword
("CREATE_FILE"):
3257 if not self
.__IsToken
( "="):
3258 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3260 if not self
.__GetNextToken
():
3261 raise Warning("expected file name", self
.FileName
, self
.CurrentLineNumber
)
3263 CapsuleObj
.CreateFile
= self
.__Token
3265 self
.__GetCapsuleStatements
(CapsuleObj
)
3266 self
.Profile
.CapsuleDict
[CapsuleObj
.UiCapsuleName
] = CapsuleObj
3269 ## __GetCapsuleStatements() method
3271 # Get statements for capsule
3273 # @param self The object pointer
3274 # @param Obj for whom statements are got
3276 def __GetCapsuleStatements(self
, Obj
):
3277 self
.__GetCapsuleTokens
(Obj
)
3278 self
.__GetDefineStatements
(Obj
)
3279 self
.__GetSetStatements
(Obj
)
3280 self
.__GetCapsuleData
(Obj
)
3282 ## __GetCapsuleTokens() method
3284 # Get token statements for capsule
3286 # @param self The object pointer
3287 # @param Obj for whom token statements are got
3289 def __GetCapsuleTokens(self
, Obj
):
3290 if not self
.__GetNextToken
():
3292 while self
.__Token
in ("CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"):
3293 Name
= self
.__Token
.strip()
3294 if not self
.__IsToken
("="):
3295 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3296 if not self
.__GetNextToken
():
3297 raise Warning("expected value", self
.FileName
, self
.CurrentLineNumber
)
3298 if Name
== 'CAPSULE_FLAGS':
3299 if not self
.__Token
in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
3300 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3301 Value
= self
.__Token
.strip()
3302 while self
.__IsToken
(","):
3304 if not self
.__GetNextToken
():
3305 raise Warning("expected value", self
.FileName
, self
.CurrentLineNumber
)
3306 if not self
.__Token
in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
3307 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3308 Value
+= self
.__Token
.strip()
3309 elif Name
== 'OEM_CAPSULE_FLAGS':
3310 Value
= self
.__Token
.strip()
3311 if not Value
.upper().startswith('0X'):
3312 raise Warning("expected hex value between 0x0000 and 0xFFFF", self
.FileName
, self
.CurrentLineNumber
)
3314 Value
= int(Value
, 0)
3316 raise Warning("expected hex value between 0x0000 and 0xFFFF", self
.FileName
, self
.CurrentLineNumber
)
3317 if not 0x0000 <= Value
<= 0xFFFF:
3318 raise Warning("expected hex value between 0x0000 and 0xFFFF", self
.FileName
, self
.CurrentLineNumber
)
3319 Value
= self
.__Token
.strip()
3321 Value
= self
.__Token
.strip()
3322 Obj
.TokensDict
[Name
] = Value
3323 if not self
.__GetNextToken
():
3327 ## __GetCapsuleData() method
3329 # Get capsule data for capsule
3331 # @param self The object pointer
3332 # @param Obj for whom capsule data are got
3334 def __GetCapsuleData(self
, Obj
):
3337 IsInf
= self
.__GetInfStatement
(Obj
, True)
3338 IsFile
= self
.__GetFileStatement
(Obj
, True)
3339 IsFv
= self
.__GetFvStatement
(Obj
)
3340 IsFd
= self
.__GetFdStatement
(Obj
)
3341 IsAnyFile
= self
.__GetAnyFileStatement
(Obj
)
3342 IsAfile
= self
.__GetAfileStatement
(Obj
)
3343 IsFmp
= self
.__GetFmpStatement
(Obj
)
3344 if not (IsInf
or IsFile
or IsFv
or IsFd
or IsAnyFile
or IsAfile
or IsFmp
):
3347 ## __GetFvStatement() method
3349 # Get FV for capsule
3351 # @param self The object pointer
3352 # @param CapsuleObj for whom FV is got
3353 # @retval True Successfully find a FV statement
3354 # @retval False Not able to find a FV statement
3356 def __GetFvStatement(self
, CapsuleObj
):
3358 if not self
.__IsKeyword
("FV"):
3361 if not self
.__IsToken
("="):
3362 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3364 if not self
.__GetNextToken
():
3365 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
3367 if self
.__Token
.upper() not in self
.Profile
.FvDict
.keys():
3368 raise Warning("FV name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3370 CapsuleFv
= CapsuleData
.CapsuleFv()
3371 CapsuleFv
.FvName
= self
.__Token
3372 CapsuleObj
.CapsuleDataList
.append(CapsuleFv
)
3375 ## __GetFdStatement() method
3377 # Get FD for capsule
3379 # @param self The object pointer
3380 # @param CapsuleObj for whom FD is got
3381 # @retval True Successfully find a FD statement
3382 # @retval False Not able to find a FD statement
3384 def __GetFdStatement(self
, CapsuleObj
):
3386 if not self
.__IsKeyword
("FD"):
3389 if not self
.__IsToken
("="):
3390 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3392 if not self
.__GetNextToken
():
3393 raise Warning("expected FD name", self
.FileName
, self
.CurrentLineNumber
)
3395 if self
.__Token
.upper() not in self
.Profile
.FdDict
.keys():
3396 raise Warning("FD name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3398 CapsuleFd
= CapsuleData
.CapsuleFd()
3399 CapsuleFd
.FdName
= self
.__Token
3400 CapsuleObj
.CapsuleDataList
.append(CapsuleFd
)
3403 def __GetFmpStatement(self
, CapsuleObj
):
3404 if not self
.__IsKeyword
("FMP_PAYLOAD"):
3405 if not self
.__IsKeyword
("FMP"):
3408 if not self
.__IsKeyword
("PAYLOAD"):
3412 if not self
.__IsToken
("="):
3413 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3415 if not self
.__GetNextToken
():
3416 raise Warning("expected payload name after FMP_PAYLOAD =", self
.FileName
, self
.CurrentLineNumber
)
3417 Payload
= self
.__Token
.upper()
3418 if Payload
not in self
.Profile
.FmpPayloadDict
:
3419 raise Warning("This FMP Payload does not exist: %s" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3420 CapsuleObj
.FmpPayloadList
.append(self
.Profile
.FmpPayloadDict
[Payload
])
3423 def __ParseRawFileStatement(self
):
3424 if not self
.__IsKeyword
("FILE"):
3427 if not self
.__IsKeyword
("DATA"):
3431 if not self
.__IsToken
("="):
3432 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3434 if not self
.__GetNextToken
():
3435 raise Warning("expected File name", self
.FileName
, self
.CurrentLineNumber
)
3437 AnyFileName
= self
.__Token
3438 AnyFileName
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(AnyFileName
)
3439 if not os
.path
.exists(AnyFileName
):
3440 raise Warning("File %s not exists"%AnyFileName
, self
.FileName
, self
.CurrentLineNumber
)
3443 ## __GetAnyFileStatement() method
3445 # Get AnyFile for capsule
3447 # @param self The object pointer
3448 # @param CapsuleObj for whom AnyFile is got
3449 # @retval True Successfully find a Anyfile statement
3450 # @retval False Not able to find a AnyFile statement
3452 def __GetAnyFileStatement(self
, CapsuleObj
):
3453 AnyFileName
= self
.__ParseRawFileStatement
()
3457 CapsuleAnyFile
= CapsuleData
.CapsuleAnyFile()
3458 CapsuleAnyFile
.FileName
= AnyFileName
3459 CapsuleObj
.CapsuleDataList
.append(CapsuleAnyFile
)
3462 ## __GetAfileStatement() method
3464 # Get Afile for capsule
3466 # @param self The object pointer
3467 # @param CapsuleObj for whom Afile is got
3468 # @retval True Successfully find a Afile statement
3469 # @retval False Not able to find a Afile statement
3471 def __GetAfileStatement(self
, CapsuleObj
):
3473 if not self
.__IsKeyword
("APPEND"):
3476 if not self
.__IsToken
("="):
3477 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3479 if not self
.__GetNextToken
():
3480 raise Warning("expected Afile name", self
.FileName
, self
.CurrentLineNumber
)
3482 AfileName
= self
.__Token
3483 AfileBaseName
= os
.path
.basename(AfileName
)
3485 if os
.path
.splitext(AfileBaseName
)[1] not in [".bin",".BIN",".Bin",".dat",".DAT",".Dat",".data",".DATA",".Data"]:
3486 raise Warning('invalid binary file type, should be one of "bin","BIN","Bin","dat","DAT","Dat","data","DATA","Data"', \
3487 self
.FileName
, self
.CurrentLineNumber
)
3489 if not os
.path
.isabs(AfileName
):
3490 AfileName
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(AfileName
)
3491 self
.__VerifyFile
(AfileName
)
3493 if not os
.path
.exists(AfileName
):
3494 raise Warning('%s does not exist' % AfileName
, self
.FileName
, self
.CurrentLineNumber
)
3498 CapsuleAfile
= CapsuleData
.CapsuleAfile()
3499 CapsuleAfile
.FileName
= AfileName
3500 CapsuleObj
.CapsuleDataList
.append(CapsuleAfile
)
3503 ## __GetRule() method
3505 # Get Rule section contents and store its data into rule list of self.Profile
3507 # @param self The object pointer
3508 # @retval True Successfully find a Rule
3509 # @retval False Not able to find a Rule
3511 def __GetRule(self
):
3513 if not self
.__GetNextToken
():
3516 S
= self
.__Token
.upper()
3517 if S
.startswith("[") and not S
.startswith("[RULE."):
3518 self
.SectionParser(S
)
3522 if not self
.__IsToken
("[Rule.", True):
3523 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3524 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3525 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3526 raise Warning("expected [Rule.]", self
.FileName
, self
.CurrentLineNumber
)
3528 if not self
.__SkipToToken
("."):
3529 raise Warning("expected '.'", self
.FileName
, self
.CurrentLineNumber
)
3531 Arch
= self
.__SkippedChars
.rstrip(".")
3532 if Arch
.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "AARCH64", "COMMON"):
3533 raise Warning("Unknown Arch '%s'" % Arch
, self
.FileName
, self
.CurrentLineNumber
)
3535 ModuleType
= self
.__GetModuleType
()
3538 if self
.__IsToken
("."):
3539 if not self
.__GetNextWord
():
3540 raise Warning("expected template name", self
.FileName
, self
.CurrentLineNumber
)
3541 TemplateName
= self
.__Token
3543 if not self
.__IsToken
( "]"):
3544 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
3546 RuleObj
= self
.__GetRuleFileStatements
()
3547 RuleObj
.Arch
= Arch
.upper()
3548 RuleObj
.ModuleType
= ModuleType
3549 RuleObj
.TemplateName
= TemplateName
3550 if TemplateName
== '' :
3551 self
.Profile
.RuleDict
['RULE' + \
3555 ModuleType
.upper() ] = RuleObj
3557 self
.Profile
.RuleDict
['RULE' + \
3561 ModuleType
.upper() + \
3563 TemplateName
.upper() ] = RuleObj
3564 # self.Profile.RuleList.append(rule)
3567 ## __GetModuleType() method
3569 # Return the module type
3571 # @param self The object pointer
3572 # @retval string module type
3574 def __GetModuleType(self
):
3576 if not self
.__GetNextWord
():
3577 raise Warning("expected Module type", self
.FileName
, self
.CurrentLineNumber
)
3578 if self
.__Token
.upper() not in ("SEC", "PEI_CORE", "PEIM", "DXE_CORE", \
3579 "DXE_DRIVER", "DXE_SAL_DRIVER", \
3580 "DXE_SMM_DRIVER", "DXE_RUNTIME_DRIVER", \
3581 "UEFI_DRIVER", "UEFI_APPLICATION", "USER_DEFINED", "DEFAULT", "BASE", \
3582 "SECURITY_CORE", "COMBINED_PEIM_DRIVER", "PIC_PEIM", "RELOCATABLE_PEIM", \
3583 "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION", "ACPITABLE", "SMM_CORE"):
3584 raise Warning("Unknown Module type '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3587 ## __GetFileExtension() method
3589 # Return the file extension
3591 # @param self The object pointer
3592 # @retval string file name extension
3594 def __GetFileExtension(self
):
3595 if not self
.__IsToken
("."):
3596 raise Warning("expected '.'", self
.FileName
, self
.CurrentLineNumber
)
3599 if self
.__GetNextToken
():
3600 Pattern
= re
.compile(r
'([a-zA-Z][a-zA-Z0-9]*)')
3601 if Pattern
.match(self
.__Token
):
3605 raise Warning("Unknown file extension '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3608 raise Warning("expected file extension", self
.FileName
, self
.CurrentLineNumber
)
3610 ## __GetRuleFileStatement() method
3614 # @param self The object pointer
3615 # @retval Rule Rule object
3617 def __GetRuleFileStatements(self
):
3619 if not self
.__IsKeyword
("FILE"):
3620 raise Warning("expected FILE", self
.FileName
, self
.CurrentLineNumber
)
3622 if not self
.__GetNextWord
():
3623 raise Warning("expected FFS type", self
.FileName
, self
.CurrentLineNumber
)
3625 Type
= self
.__Token
.strip().upper()
3626 if Type
not in ("RAW", "FREEFORM", "SEC", "PEI_CORE", "PEIM",\
3627 "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE", "SMM", "SMM_CORE"):
3628 raise Warning("Unknown FV type '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3630 if not self
.__IsToken
("="):
3631 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3633 if not self
.__IsKeyword
("$(NAMED_GUID)"):
3634 if not self
.__GetNextWord
():
3635 raise Warning("expected $(NAMED_GUID)", self
.FileName
, self
.CurrentLineNumber
)
3636 if self
.__Token
== 'PCD':
3637 if not self
.__IsToken
( "("):
3638 raise Warning("expected '('", self
.FileName
, self
.CurrentLineNumber
)
3639 PcdPair
= self
.__GetNextPcdName
()
3640 if not self
.__IsToken
( ")"):
3641 raise Warning("expected ')'", self
.FileName
, self
.CurrentLineNumber
)
3642 self
.__Token
= 'PCD('+PcdPair
[1]+'.'+PcdPair
[0]+')'
3644 NameGuid
= self
.__Token
3647 if self
.__IsKeyword
('RELOCS_STRIPPED') or self
.__IsKeyword
('RELOCS_RETAINED'):
3648 if self
.__FileCouldHaveRelocFlag
(Type
):
3649 if self
.__Token
== 'RELOCS_STRIPPED':
3654 raise Warning("File type %s could not have reloc strip flag%d" % (Type
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3657 if self
.__GetNextToken
():
3658 Pattern
= re
.compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
3659 if Pattern
.match(self
.__Token
):
3660 KeyStringList
.append(self
.__Token
)
3661 if self
.__IsToken
(","):
3662 while self
.__GetNextToken
():
3663 if not Pattern
.match(self
.__Token
):
3664 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
3665 KeyStringList
.append(self
.__Token
)
3667 if not self
.__IsToken
(","):
3675 if self
.__IsKeyword
("Fixed", True):
3679 if self
.__IsKeyword
("CheckSum", True):
3683 if self
.__GetAlignment
():
3684 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3685 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3686 #For FFS, Auto is default option same to ""
3687 if not self
.__Token
== "Auto":
3688 AlignValue
= self
.__Token
3690 if self
.__IsToken
("{"):
3691 # Complex file rule expected
3692 Rule
= RuleComplexFile
.RuleComplexFile()
3693 Rule
.FvFileType
= Type
3694 Rule
.NameGuid
= NameGuid
3695 Rule
.Alignment
= AlignValue
3696 Rule
.CheckSum
= CheckSum
3698 Rule
.KeyStringList
= KeyStringList
3699 if KeepReloc
!= None:
3700 Rule
.KeepReloc
= KeepReloc
3703 IsEncapsulate
= self
.__GetRuleEncapsulationSection
(Rule
)
3704 IsLeaf
= self
.__GetEfiSection
(Rule
)
3705 if not IsEncapsulate
and not IsLeaf
:
3708 if not self
.__IsToken
("}"):
3709 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
3714 # Simple file rule expected
3715 if not self
.__GetNextWord
():
3716 raise Warning("expected leaf section type", self
.FileName
, self
.CurrentLineNumber
)
3718 SectionName
= self
.__Token
3720 if SectionName
not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3721 "UI", "PEI_DEPEX", "VERSION", "SUBTYPE_GUID", "SMM_DEPEX"):
3722 raise Warning("Unknown leaf section name '%s'" % SectionName
, self
.FileName
, self
.CurrentLineNumber
)
3725 if self
.__IsKeyword
("Fixed", True):
3728 if self
.__IsKeyword
("CheckSum", True):
3732 if self
.__GetAlignment
():
3733 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3734 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3735 if self
.__Token
== 'Auto' and (not SectionName
== 'PE32') and (not SectionName
== 'TE'):
3736 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3737 SectAlignment
= self
.__Token
3740 if self
.__IsToken
('|'):
3741 Ext
= self
.__GetFileExtension
()
3742 elif not self
.__GetNextToken
():
3743 raise Warning("expected File name", self
.FileName
, self
.CurrentLineNumber
)
3745 Rule
= RuleSimpleFile
.RuleSimpleFile()
3746 Rule
.SectionType
= SectionName
3747 Rule
.FvFileType
= Type
3748 Rule
.NameGuid
= NameGuid
3749 Rule
.Alignment
= AlignValue
3750 Rule
.SectAlignment
= SectAlignment
3751 Rule
.CheckSum
= CheckSum
3753 Rule
.KeyStringList
= KeyStringList
3754 if KeepReloc
!= None:
3755 Rule
.KeepReloc
= KeepReloc
3756 Rule
.FileExtension
= Ext
3757 Rule
.FileName
= self
.__Token
3760 ## __GetEfiSection() method
3762 # Get section list for Rule
3764 # @param self The object pointer
3765 # @param Obj for whom section is got
3766 # @retval True Successfully find section statement
3767 # @retval False Not able to find section statement
3769 def __GetEfiSection(self
, Obj
):
3771 OldPos
= self
.GetFileBufferPos()
3772 if not self
.__GetNextWord
():
3774 SectionName
= self
.__Token
3776 if SectionName
not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3777 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3781 if SectionName
== "FV_IMAGE":
3782 FvImageSectionObj
= FvImageSection
.FvImageSection()
3783 if self
.__IsKeyword
("FV_IMAGE"):
3785 if self
.__IsToken
( "{"):
3787 self
.__GetDefineStatements
(FvObj
)
3788 self
.__GetBlockStatement
(FvObj
)
3789 self
.__GetSetStatements
(FvObj
)
3790 self
.__GetFvAlignment
(FvObj
)
3791 self
.__GetFvAttributes
(FvObj
)
3792 self
.__GetAprioriSection
(FvObj
)
3793 self
.__GetAprioriSection
(FvObj
)
3796 IsInf
= self
.__GetInfStatement
(FvObj
)
3797 IsFile
= self
.__GetFileStatement
(FvObj
)
3798 if not IsInf
and not IsFile
:
3801 if not self
.__IsToken
( "}"):
3802 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
3803 FvImageSectionObj
.Fv
= FvObj
3804 FvImageSectionObj
.FvName
= None
3807 if not self
.__IsKeyword
("FV"):
3808 raise Warning("expected 'FV'", self
.FileName
, self
.CurrentLineNumber
)
3809 FvImageSectionObj
.FvFileType
= self
.__Token
3811 if self
.__GetAlignment
():
3812 if self
.__Token
not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3813 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3814 FvImageSectionObj
.Alignment
= self
.__Token
3816 if self
.__IsToken
('|'):
3817 FvImageSectionObj
.FvFileExtension
= self
.__GetFileExtension
()
3818 elif self
.__GetNextToken
():
3819 if self
.__Token
not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3820 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3821 FvImageSectionObj
.FvFileName
= self
.__Token
3825 raise Warning("expected FV file name", self
.FileName
, self
.CurrentLineNumber
)
3827 Obj
.SectionList
.append(FvImageSectionObj
)
3830 EfiSectionObj
= EfiSection
.EfiSection()
3831 EfiSectionObj
.SectionType
= SectionName
3833 if not self
.__GetNextToken
():
3834 raise Warning("expected file type", self
.FileName
, self
.CurrentLineNumber
)
3836 if self
.__Token
== "STRING":
3837 if not self
.__RuleSectionCouldHaveString
(EfiSectionObj
.SectionType
):
3838 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3840 if not self
.__IsToken
('='):
3841 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3843 if not self
.__GetNextToken
():
3844 raise Warning("expected Quoted String", self
.FileName
, self
.CurrentLineNumber
)
3846 if self
.__GetStringData
():
3847 EfiSectionObj
.StringData
= self
.__Token
3849 if self
.__IsKeyword
("BUILD_NUM"):
3850 if not self
.__RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3851 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3853 if not self
.__IsToken
("="):
3854 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3855 if not self
.__GetNextToken
():
3856 raise Warning("expected Build number", self
.FileName
, self
.CurrentLineNumber
)
3857 EfiSectionObj
.BuildNum
= self
.__Token
3860 EfiSectionObj
.FileType
= self
.__Token
3861 self
.__CheckRuleSectionFileType
(EfiSectionObj
.SectionType
, EfiSectionObj
.FileType
)
3863 if self
.__IsKeyword
("Optional"):
3864 if not self
.__RuleSectionCouldBeOptional
(EfiSectionObj
.SectionType
):
3865 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3866 EfiSectionObj
.Optional
= True
3868 if self
.__IsKeyword
("BUILD_NUM"):
3869 if not self
.__RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3870 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3872 if not self
.__IsToken
("="):
3873 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3874 if not self
.__GetNextToken
():
3875 raise Warning("expected Build number", self
.FileName
, self
.CurrentLineNumber
)
3876 EfiSectionObj
.BuildNum
= self
.__Token
3878 if self
.__GetAlignment
():
3879 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3880 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3881 if self
.__Token
== 'Auto' and (not SectionName
== 'PE32') and (not SectionName
== 'TE'):
3882 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3883 EfiSectionObj
.Alignment
= self
.__Token
3885 if self
.__IsKeyword
('RELOCS_STRIPPED') or self
.__IsKeyword
('RELOCS_RETAINED'):
3886 if self
.__SectionCouldHaveRelocFlag
(EfiSectionObj
.SectionType
):
3887 if self
.__Token
== 'RELOCS_STRIPPED':
3888 EfiSectionObj
.KeepReloc
= False
3890 EfiSectionObj
.KeepReloc
= True
3891 if Obj
.KeepReloc
!= None and Obj
.KeepReloc
!= EfiSectionObj
.KeepReloc
:
3892 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3894 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3897 if self
.__IsToken
('|'):
3898 EfiSectionObj
.FileExtension
= self
.__GetFileExtension
()
3899 elif self
.__GetNextToken
():
3900 if self
.__Token
not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3901 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3903 if self
.__Token
.startswith('PCD'):
3905 self
.__GetNextWord
()
3907 if self
.__Token
== 'PCD':
3908 if not self
.__IsToken
( "("):
3909 raise Warning("expected '('", self
.FileName
, self
.CurrentLineNumber
)
3910 PcdPair
= self
.__GetNextPcdName
()
3911 if not self
.__IsToken
( ")"):
3912 raise Warning("expected ')'", self
.FileName
, self
.CurrentLineNumber
)
3913 self
.__Token
= 'PCD('+PcdPair
[1]+'.'+PcdPair
[0]+')'
3915 EfiSectionObj
.FileName
= self
.__Token
3920 raise Warning("expected section file name", self
.FileName
, self
.CurrentLineNumber
)
3922 Obj
.SectionList
.append(EfiSectionObj
)
3925 ## __RuleSectionCouldBeOptional() method
3927 # Get whether a section could be optional
3929 # @param self The object pointer
3930 # @param SectionType The section type to check
3931 # @retval True section could be optional
3932 # @retval False section never optional
3934 def __RuleSectionCouldBeOptional(self
, SectionType
):
3935 if SectionType
in ("DXE_DEPEX", "UI", "VERSION", "PEI_DEPEX", "RAW", "SMM_DEPEX"):
3940 ## __RuleSectionCouldHaveBuildNum() method
3942 # Get whether a section could have build number information
3944 # @param self The object pointer
3945 # @param SectionType The section type to check
3946 # @retval True section could have build number information
3947 # @retval False section never have build number information
3949 def __RuleSectionCouldHaveBuildNum(self
, SectionType
):
3950 if SectionType
in ("VERSION"):
3955 ## __RuleSectionCouldHaveString() method
3957 # Get whether a section could have string
3959 # @param self The object pointer
3960 # @param SectionType The section type to check
3961 # @retval True section could have string
3962 # @retval False section never have string
3964 def __RuleSectionCouldHaveString(self
, SectionType
):
3965 if SectionType
in ("UI", "VERSION"):
3970 ## __CheckRuleSectionFileType() method
3972 # Get whether a section matches a file type
3974 # @param self The object pointer
3975 # @param SectionType The section type to check
3976 # @param FileType The file type to check
3978 def __CheckRuleSectionFileType(self
, SectionType
, FileType
):
3979 if SectionType
== "COMPAT16":
3980 if FileType
not in ("COMPAT16", "SEC_COMPAT16"):
3981 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3982 elif SectionType
== "PE32":
3983 if FileType
not in ("PE32", "SEC_PE32"):
3984 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3985 elif SectionType
== "PIC":
3986 if FileType
not in ("PIC", "PIC"):
3987 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3988 elif SectionType
== "TE":
3989 if FileType
not in ("TE", "SEC_TE"):
3990 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3991 elif SectionType
== "RAW":
3992 if FileType
not in ("BIN", "SEC_BIN", "RAW", "ASL", "ACPI"):
3993 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3994 elif SectionType
== "DXE_DEPEX" or SectionType
== "SMM_DEPEX":
3995 if FileType
not in ("DXE_DEPEX", "SEC_DXE_DEPEX", "SMM_DEPEX"):
3996 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3997 elif SectionType
== "UI":
3998 if FileType
not in ("UI", "SEC_UI"):
3999 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
4000 elif SectionType
== "VERSION":
4001 if FileType
not in ("VERSION", "SEC_VERSION"):
4002 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
4003 elif SectionType
== "PEI_DEPEX":
4004 if FileType
not in ("PEI_DEPEX", "SEC_PEI_DEPEX"):
4005 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
4006 elif SectionType
== "GUID":
4007 if FileType
not in ("PE32", "SEC_GUID"):
4008 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
4010 ## __GetRuleEncapsulationSection() method
4012 # Get encapsulation section for Rule
4014 # @param self The object pointer
4015 # @param Rule for whom section is got
4016 # @retval True Successfully find section statement
4017 # @retval False Not able to find section statement
4019 def __GetRuleEncapsulationSection(self
, Rule
):
4021 if self
.__IsKeyword
( "COMPRESS"):
4023 if self
.__IsKeyword
("PI_STD") or self
.__IsKeyword
("PI_NONE"):
4026 if not self
.__IsToken
("{"):
4027 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
4029 CompressSectionObj
= CompressSection
.CompressSection()
4031 CompressSectionObj
.CompType
= Type
4032 # Recursive sections...
4034 IsEncapsulate
= self
.__GetRuleEncapsulationSection
(CompressSectionObj
)
4035 IsLeaf
= self
.__GetEfiSection
(CompressSectionObj
)
4036 if not IsEncapsulate
and not IsLeaf
:
4039 if not self
.__IsToken
( "}"):
4040 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
4041 Rule
.SectionList
.append(CompressSectionObj
)
4045 elif self
.__IsKeyword
( "GUIDED"):
4047 if self
.__GetNextGuid
():
4048 GuidValue
= self
.__Token
4050 if self
.__IsKeyword
( "$(NAMED_GUID)"):
4051 GuidValue
= self
.__Token
4053 AttribDict
= self
.__GetGuidAttrib
()
4055 if not self
.__IsToken
("{"):
4056 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
4057 GuidSectionObj
= GuidSection
.GuidSection()
4058 GuidSectionObj
.NameGuid
= GuidValue
4059 GuidSectionObj
.SectionType
= "GUIDED"
4060 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
4061 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
4062 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
4066 IsEncapsulate
= self
.__GetRuleEncapsulationSection
(GuidSectionObj
)
4067 IsLeaf
= self
.__GetEfiSection
(GuidSectionObj
)
4068 if not IsEncapsulate
and not IsLeaf
:
4071 if not self
.__IsToken
( "}"):
4072 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
4073 Rule
.SectionList
.append(GuidSectionObj
)
4079 ## __GetVtf() method
4081 # Get VTF section contents and store its data into VTF list of self.Profile
4083 # @param self The object pointer
4084 # @retval True Successfully find a VTF
4085 # @retval False Not able to find a VTF
4089 if not self
.__GetNextToken
():
4092 S
= self
.__Token
.upper()
4093 if S
.startswith("[") and not S
.startswith("[VTF."):
4094 self
.SectionParser(S
)
4099 if not self
.__IsToken
("[VTF.", True):
4100 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4101 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
4102 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
4103 raise Warning("expected [VTF.]", self
.FileName
, self
.CurrentLineNumber
)
4105 if not self
.__SkipToToken
("."):
4106 raise Warning("expected '.'", self
.FileName
, self
.CurrentLineNumber
)
4108 Arch
= self
.__SkippedChars
.rstrip(".").upper()
4109 if Arch
not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
4110 raise Warning("Unknown Arch '%s'" % Arch
, self
.FileName
, self
.CurrentLineNumber
)
4112 if not self
.__GetNextWord
():
4113 raise Warning("expected VTF name", self
.FileName
, self
.CurrentLineNumber
)
4114 Name
= self
.__Token
.upper()
4117 VtfObj
.UiName
= Name
4118 VtfObj
.KeyArch
= Arch
4120 if self
.__IsToken
(","):
4121 if not self
.__GetNextWord
():
4122 raise Warning("expected Arch list", self
.FileName
, self
.CurrentLineNumber
)
4123 if self
.__Token
.upper() not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
4124 raise Warning("Unknown Arch '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
4125 VtfObj
.ArchList
= self
.__Token
.upper()
4127 if not self
.__IsToken
( "]"):
4128 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
4130 if self
.__IsKeyword
("IA32_RST_BIN"):
4131 if not self
.__IsToken
("="):
4132 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4134 if not self
.__GetNextToken
():
4135 raise Warning("expected Reset file", self
.FileName
, self
.CurrentLineNumber
)
4137 VtfObj
.ResetBin
= self
.__Token
4138 if VtfObj
.ResetBin
.replace('$(WORKSPACE)', '').find('$') == -1:
4139 #check for file path
4140 ErrorCode
, ErrorInfo
= PathClass(NormPath(VtfObj
.ResetBin
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4142 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4144 while self
.__GetComponentStatement
(VtfObj
):
4147 self
.Profile
.VtfList
.append(VtfObj
)
4150 ## __GetComponentStatement() method
4152 # Get components in VTF
4154 # @param self The object pointer
4155 # @param VtfObj for whom component is got
4156 # @retval True Successfully find a component
4157 # @retval False Not able to find a component
4159 def __GetComponentStatement(self
, VtfObj
):
4161 if not self
.__IsKeyword
("COMP_NAME"):
4164 if not self
.__IsToken
("="):
4165 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4167 if not self
.__GetNextWord
():
4168 raise Warning("expected Component Name", self
.FileName
, self
.CurrentLineNumber
)
4170 CompStatementObj
= ComponentStatement
.ComponentStatement()
4171 CompStatementObj
.CompName
= self
.__Token
4173 if not self
.__IsKeyword
("COMP_LOC"):
4174 raise Warning("expected COMP_LOC", self
.FileName
, self
.CurrentLineNumber
)
4176 if not self
.__IsToken
("="):
4177 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4179 CompStatementObj
.CompLoc
= ""
4180 if self
.__GetNextWord
():
4181 CompStatementObj
.CompLoc
= self
.__Token
4182 if self
.__IsToken
('|'):
4183 if not self
.__GetNextWord
():
4184 raise Warning("Expected Region Name", self
.FileName
, self
.CurrentLineNumber
)
4186 if self
.__Token
not in ("F", "N", "S"): #, "H", "L", "PH", "PL"): not support
4187 raise Warning("Unknown location type '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
4189 CompStatementObj
.FilePos
= self
.__Token
4191 self
.CurrentLineNumber
+= 1
4192 self
.CurrentOffsetWithinLine
= 0
4194 if not self
.__IsKeyword
("COMP_TYPE"):
4195 raise Warning("expected COMP_TYPE", self
.FileName
, self
.CurrentLineNumber
)
4197 if not self
.__IsToken
("="):
4198 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4200 if not self
.__GetNextToken
():
4201 raise Warning("expected Component type", self
.FileName
, self
.CurrentLineNumber
)
4202 if self
.__Token
not in ("FIT", "PAL_B", "PAL_A", "OEM"):
4203 if not self
.__Token
.startswith("0x") or len(self
.__Token
) < 3 or len(self
.__Token
) > 4 or \
4204 not self
.__HexDigit
(self
.__Token
[2]) or not self
.__HexDigit
(self
.__Token
[-1]):
4205 raise Warning("Unknown location type '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
4206 CompStatementObj
.CompType
= self
.__Token
4208 if not self
.__IsKeyword
("COMP_VER"):
4209 raise Warning("expected COMP_VER", self
.FileName
, self
.CurrentLineNumber
)
4211 if not self
.__IsToken
("="):
4212 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4214 if not self
.__GetNextToken
():
4215 raise Warning("expected Component version", self
.FileName
, self
.CurrentLineNumber
)
4217 Pattern
= re
.compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', re
.DOTALL
)
4218 if Pattern
.match(self
.__Token
) == None:
4219 raise Warning("Unknown version format '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
4220 CompStatementObj
.CompVer
= self
.__Token
4222 if not self
.__IsKeyword
("COMP_CS"):
4223 raise Warning("expected COMP_CS", self
.FileName
, self
.CurrentLineNumber
)
4225 if not self
.__IsToken
("="):
4226 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4228 if not self
.__GetNextToken
():
4229 raise Warning("expected Component CS", self
.FileName
, self
.CurrentLineNumber
)
4230 if self
.__Token
not in ("1", "0"):
4231 raise Warning("Unknown Component CS '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
4232 CompStatementObj
.CompCs
= self
.__Token
4235 if not self
.__IsKeyword
("COMP_BIN"):
4236 raise Warning("expected COMP_BIN", self
.FileName
, self
.CurrentLineNumber
)
4238 if not self
.__IsToken
("="):
4239 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4241 if not self
.__GetNextToken
():
4242 raise Warning("expected Component file", self
.FileName
, self
.CurrentLineNumber
)
4244 CompStatementObj
.CompBin
= self
.__Token
4245 if CompStatementObj
.CompBin
!= '-' and CompStatementObj
.CompBin
.replace('$(WORKSPACE)', '').find('$') == -1:
4246 #check for file path
4247 ErrorCode
, ErrorInfo
= PathClass(NormPath(CompStatementObj
.CompBin
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4249 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4251 if not self
.__IsKeyword
("COMP_SYM"):
4252 raise Warning("expected COMP_SYM", self
.FileName
, self
.CurrentLineNumber
)
4254 if not self
.__IsToken
("="):
4255 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4257 if not self
.__GetNextToken
():
4258 raise Warning("expected Component symbol file", self
.FileName
, self
.CurrentLineNumber
)
4260 CompStatementObj
.CompSym
= self
.__Token
4261 if CompStatementObj
.CompSym
!= '-' and CompStatementObj
.CompSym
.replace('$(WORKSPACE)', '').find('$') == -1:
4262 #check for file path
4263 ErrorCode
, ErrorInfo
= PathClass(NormPath(CompStatementObj
.CompSym
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4265 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4267 if not self
.__IsKeyword
("COMP_SIZE"):
4268 raise Warning("expected COMP_SIZE", self
.FileName
, self
.CurrentLineNumber
)
4270 if not self
.__IsToken
("="):
4271 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4273 if self
.__IsToken
("-"):
4274 CompStatementObj
.CompSize
= self
.__Token
4275 elif self
.__GetNextDecimalNumber
():
4276 CompStatementObj
.CompSize
= self
.__Token
4277 elif self
.__GetNextHexNumber
():
4278 CompStatementObj
.CompSize
= self
.__Token
4280 raise Warning("Unknown size '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
4282 VtfObj
.ComponentStatementList
.append(CompStatementObj
)
4285 ## __GetOptionRom() method
4287 # Get OptionROM section contents and store its data into OptionROM list of self.Profile
4289 # @param self The object pointer
4290 # @retval True Successfully find a OptionROM
4291 # @retval False Not able to find a OptionROM
4293 def __GetOptionRom(self
):
4295 if not self
.__GetNextToken
():
4298 S
= self
.__Token
.upper()
4299 if S
.startswith("[") and not S
.startswith("[OPTIONROM."):
4300 self
.SectionParser(S
)
4305 if not self
.__IsToken
("[OptionRom.", True):
4306 raise Warning("Unknown Keyword '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
4308 OptRomName
= self
.__GetUiName
()
4310 if not self
.__IsToken
( "]"):
4311 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
4313 OptRomObj
= OptionRom
.OPTIONROM()
4314 OptRomObj
.DriverName
= OptRomName
4315 self
.Profile
.OptRomDict
[OptRomName
] = OptRomObj
4318 isInf
= self
.__GetOptRomInfStatement
(OptRomObj
)
4319 isFile
= self
.__GetOptRomFileStatement
(OptRomObj
)
4320 if not isInf
and not isFile
:
4325 ## __GetOptRomInfStatement() method
4327 # Get INF statements
4329 # @param self The object pointer
4330 # @param Obj for whom inf statement is got
4331 # @retval True Successfully find inf statement
4332 # @retval False Not able to find inf statement
4334 def __GetOptRomInfStatement(self
, Obj
):
4336 if not self
.__IsKeyword
( "INF"):
4339 ffsInf
= OptRomInfStatement
.OptRomInfStatement()
4340 self
.__GetInfOptions
( ffsInf
)
4342 if not self
.__GetNextToken
():
4343 raise Warning("expected INF file path", self
.FileName
, self
.CurrentLineNumber
)
4344 ffsInf
.InfFileName
= self
.__Token
4345 if ffsInf
.InfFileName
.replace('$(WORKSPACE)', '').find('$') == -1:
4346 #check for file path
4347 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4349 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4351 if not ffsInf
.InfFileName
in self
.Profile
.InfList
:
4352 self
.Profile
.InfList
.append(ffsInf
.InfFileName
)
4353 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4354 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
4357 self
.__GetOptRomOverrides
(ffsInf
)
4359 Obj
.FfsList
.append(ffsInf
)
4362 ## __GetOptRomOverrides() method
4364 # Get overrides for OptROM INF & FILE
4366 # @param self The object pointer
4367 # @param FfsInfObj for whom overrides is got
4369 def __GetOptRomOverrides(self
, Obj
):
4370 if self
.__IsToken
('{'):
4371 Overrides
= OptionRom
.OverrideAttribs()
4373 if self
.__IsKeyword
( "PCI_VENDOR_ID"):
4374 if not self
.__IsToken
( "="):
4375 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4376 if not self
.__GetNextHexNumber
():
4377 raise Warning("expected Hex vendor id", self
.FileName
, self
.CurrentLineNumber
)
4378 Overrides
.PciVendorId
= self
.__Token
4381 if self
.__IsKeyword
( "PCI_CLASS_CODE"):
4382 if not self
.__IsToken
( "="):
4383 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4384 if not self
.__GetNextHexNumber
():
4385 raise Warning("expected Hex class code", self
.FileName
, self
.CurrentLineNumber
)
4386 Overrides
.PciClassCode
= self
.__Token
4389 if self
.__IsKeyword
( "PCI_DEVICE_ID"):
4390 if not self
.__IsToken
( "="):
4391 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4392 if not self
.__GetNextHexNumber
():
4393 raise Warning("expected Hex device id", self
.FileName
, self
.CurrentLineNumber
)
4395 Overrides
.PciDeviceId
= self
.__Token
4398 if self
.__IsKeyword
( "PCI_REVISION"):
4399 if not self
.__IsToken
( "="):
4400 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4401 if not self
.__GetNextHexNumber
():
4402 raise Warning("expected Hex revision", self
.FileName
, self
.CurrentLineNumber
)
4403 Overrides
.PciRevision
= self
.__Token
4406 if self
.__IsKeyword
( "PCI_COMPRESS"):
4407 if not self
.__IsToken
( "="):
4408 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4409 if not self
.__GetNextToken
():
4410 raise Warning("expected TRUE/FALSE for compress", self
.FileName
, self
.CurrentLineNumber
)
4411 Overrides
.NeedCompress
= self
.__Token
.upper() == 'TRUE'
4414 if self
.__IsToken
( "}"):
4417 EdkLogger
.error("FdfParser", FORMAT_INVALID
, File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
4419 Obj
.OverrideAttribs
= Overrides
4421 ## __GetOptRomFileStatement() method
4423 # Get FILE statements
4425 # @param self The object pointer
4426 # @param Obj for whom FILE statement is got
4427 # @retval True Successfully find FILE statement
4428 # @retval False Not able to find FILE statement
4430 def __GetOptRomFileStatement(self
, Obj
):
4432 if not self
.__IsKeyword
( "FILE"):
4435 FfsFileObj
= OptRomFileStatement
.OptRomFileStatement()
4437 if not self
.__IsKeyword
("EFI") and not self
.__IsKeyword
("BIN"):
4438 raise Warning("expected Binary type (EFI/BIN)", self
.FileName
, self
.CurrentLineNumber
)
4439 FfsFileObj
.FileType
= self
.__Token
4441 if not self
.__GetNextToken
():
4442 raise Warning("expected File path", self
.FileName
, self
.CurrentLineNumber
)
4443 FfsFileObj
.FileName
= self
.__Token
4444 if FfsFileObj
.FileName
.replace('$(WORKSPACE)', '').find('$') == -1:
4445 #check for file path
4446 ErrorCode
, ErrorInfo
= PathClass(NormPath(FfsFileObj
.FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4448 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4450 if FfsFileObj
.FileType
== 'EFI':
4451 self
.__GetOptRomOverrides
(FfsFileObj
)
4453 Obj
.FfsList
.append(FfsFileObj
)
4457 ## __GetCapInFd() method
4459 # Get Cap list contained in FD
4461 # @param self The object pointer
4462 # @param FdName FD name
4463 # @retval CapList List of Capsule in FD
4465 def __GetCapInFd (self
, FdName
):
4468 if FdName
.upper() in self
.Profile
.FdDict
.keys():
4469 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4470 for elementRegion
in FdObj
.RegionList
:
4471 if elementRegion
.RegionType
== 'CAPSULE':
4472 for elementRegionData
in elementRegion
.RegionDataList
:
4473 if elementRegionData
.endswith(".cap"):
4475 if elementRegionData
!= None and elementRegionData
.upper() not in CapList
:
4476 CapList
.append(elementRegionData
.upper())
4479 ## __GetReferencedFdCapTuple() method
4481 # Get FV and FD list referenced by a capsule image
4483 # @param self The object pointer
4484 # @param CapObj Capsule section to be searched
4485 # @param RefFdList referenced FD by section
4486 # @param RefFvList referenced FV by section
4488 def __GetReferencedFdCapTuple(self
, CapObj
, RefFdList
= [], RefFvList
= []):
4490 for CapsuleDataObj
in CapObj
.CapsuleDataList
:
4491 if hasattr(CapsuleDataObj
, 'FvName') and CapsuleDataObj
.FvName
!= None and CapsuleDataObj
.FvName
.upper() not in RefFvList
:
4492 RefFvList
.append (CapsuleDataObj
.FvName
.upper())
4493 elif hasattr(CapsuleDataObj
, 'FdName') and CapsuleDataObj
.FdName
!= None and CapsuleDataObj
.FdName
.upper() not in RefFdList
:
4494 RefFdList
.append (CapsuleDataObj
.FdName
.upper())
4495 elif CapsuleDataObj
.Ffs
!= None:
4496 if isinstance(CapsuleDataObj
.Ffs
, FfsFileStatement
.FileStatement
):
4497 if CapsuleDataObj
.Ffs
.FvName
!= None and CapsuleDataObj
.Ffs
.FvName
.upper() not in RefFvList
:
4498 RefFvList
.append(CapsuleDataObj
.Ffs
.FvName
.upper())
4499 elif CapsuleDataObj
.Ffs
.FdName
!= None and CapsuleDataObj
.Ffs
.FdName
.upper() not in RefFdList
:
4500 RefFdList
.append(CapsuleDataObj
.Ffs
.FdName
.upper())
4502 self
.__GetReferencedFdFvTupleFromSection
(CapsuleDataObj
.Ffs
, RefFdList
, RefFvList
)
4504 ## __GetFvInFd() method
4506 # Get FV list contained in FD
4508 # @param self The object pointer
4509 # @param FdName FD name
4510 # @retval FvList list of FV in FD
4512 def __GetFvInFd (self
, FdName
):
4515 if FdName
.upper() in self
.Profile
.FdDict
.keys():
4516 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4517 for elementRegion
in FdObj
.RegionList
:
4518 if elementRegion
.RegionType
== 'FV':
4519 for elementRegionData
in elementRegion
.RegionDataList
:
4520 if elementRegionData
.endswith(".fv"):
4522 if elementRegionData
!= None and elementRegionData
.upper() not in FvList
:
4523 FvList
.append(elementRegionData
.upper())
4526 ## __GetReferencedFdFvTuple() method
4528 # Get FD and FV list referenced by a FFS file
4530 # @param self The object pointer
4531 # @param FfsFile contains sections to be searched
4532 # @param RefFdList referenced FD by section
4533 # @param RefFvList referenced FV by section
4535 def __GetReferencedFdFvTuple(self
, FvObj
, RefFdList
= [], RefFvList
= []):
4537 for FfsObj
in FvObj
.FfsList
:
4538 if isinstance(FfsObj
, FfsFileStatement
.FileStatement
):
4539 if FfsObj
.FvName
!= None and FfsObj
.FvName
.upper() not in RefFvList
:
4540 RefFvList
.append(FfsObj
.FvName
.upper())
4541 elif FfsObj
.FdName
!= None and FfsObj
.FdName
.upper() not in RefFdList
:
4542 RefFdList
.append(FfsObj
.FdName
.upper())
4544 self
.__GetReferencedFdFvTupleFromSection
(FfsObj
, RefFdList
, RefFvList
)
4546 ## __GetReferencedFdFvTupleFromSection() method
4548 # Get FD and FV list referenced by a FFS section
4550 # @param self The object pointer
4551 # @param FfsFile contains sections to be searched
4552 # @param FdList referenced FD by section
4553 # @param FvList referenced FV by section
4555 def __GetReferencedFdFvTupleFromSection(self
, FfsFile
, FdList
= [], FvList
= []):
4558 SectionStack
.extend(FfsFile
.SectionList
)
4559 while SectionStack
!= []:
4560 SectionObj
= SectionStack
.pop()
4561 if isinstance(SectionObj
, FvImageSection
.FvImageSection
):
4562 if SectionObj
.FvName
!= None and SectionObj
.FvName
.upper() not in FvList
:
4563 FvList
.append(SectionObj
.FvName
.upper())
4564 if SectionObj
.Fv
!= None and SectionObj
.Fv
.UiFvName
!= None and SectionObj
.Fv
.UiFvName
.upper() not in FvList
:
4565 FvList
.append(SectionObj
.Fv
.UiFvName
.upper())
4566 self
.__GetReferencedFdFvTuple
(SectionObj
.Fv
, FdList
, FvList
)
4568 if isinstance(SectionObj
, CompressSection
.CompressSection
) or isinstance(SectionObj
, GuidSection
.GuidSection
):
4569 SectionStack
.extend(SectionObj
.SectionList
)
4571 ## CycleReferenceCheck() method
4573 # Check whether cycle reference exists in FDF
4575 # @param self The object pointer
4576 # @retval True cycle reference exists
4577 # @retval False Not exists cycle reference
4579 def CycleReferenceCheck(self
):
4581 # Check the cycle between FV and FD image
4583 MaxLength
= len (self
.Profile
.FvDict
)
4584 for FvName
in self
.Profile
.FvDict
.keys():
4585 LogStr
= "\nCycle Reference Checking for FV: %s\n" % FvName
4587 RefFvStack
.append(FvName
)
4591 while RefFvStack
!= [] and Index
< MaxLength
:
4593 FvNameFromStack
= RefFvStack
.pop()
4594 if FvNameFromStack
.upper() in self
.Profile
.FvDict
.keys():
4595 FvObj
= self
.Profile
.FvDict
[FvNameFromStack
.upper()]
4601 self
.__GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4603 for RefFdName
in RefFdList
:
4604 if RefFdName
in FdAnalyzedList
:
4607 LogStr
+= "FV %s contains FD %s\n" % (FvNameFromStack
, RefFdName
)
4608 FvInFdList
= self
.__GetFvInFd
(RefFdName
)
4609 if FvInFdList
!= []:
4610 for FvNameInFd
in FvInFdList
:
4611 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
,FvNameInFd
)
4612 if FvNameInFd
not in RefFvStack
:
4613 RefFvStack
.append(FvNameInFd
)
4615 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4616 EdkLogger
.info(LogStr
)
4618 FdAnalyzedList
.append(RefFdName
)
4620 for RefFvName
in RefFvList
:
4621 LogStr
+= "FV %s contains FV %s\n" % (FvNameFromStack
, RefFvName
)
4622 if RefFvName
not in RefFvStack
:
4623 RefFvStack
.append(RefFvName
)
4625 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4626 EdkLogger
.info(LogStr
)
4630 # Check the cycle between Capsule and FD image
4632 MaxLength
= len (self
.Profile
.CapsuleDict
)
4633 for CapName
in self
.Profile
.CapsuleDict
.keys():
4635 # Capsule image to be checked.
4637 LogStr
= "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
4639 RefCapStack
.append(CapName
)
4644 while RefCapStack
!= [] and Index
< MaxLength
:
4646 CapNameFromStack
= RefCapStack
.pop()
4647 if CapNameFromStack
.upper() in self
.Profile
.CapsuleDict
.keys():
4648 CapObj
= self
.Profile
.CapsuleDict
[CapNameFromStack
.upper()]
4654 self
.__GetReferencedFdCapTuple
(CapObj
, RefFdList
, RefFvList
)
4658 while FvListLength
< len (RefFvList
) or FdListLength
< len (RefFdList
):
4659 for RefFdName
in RefFdList
:
4660 if RefFdName
in FdAnalyzedList
:
4663 LogStr
+= "Capsule %s contains FD %s\n" % (CapNameFromStack
, RefFdName
)
4664 CapInFdList
= self
.__GetCapInFd
(RefFdName
)
4665 if CapInFdList
!= []:
4666 for CapNameInFd
in CapInFdList
:
4667 LogStr
+= "FD %s contains Capsule %s\n" % (RefFdName
,CapNameInFd
)
4668 if CapNameInFd
not in RefCapStack
:
4669 RefCapStack
.append(CapNameInFd
)
4671 if CapName
in RefCapStack
or CapNameFromStack
in RefCapStack
:
4672 EdkLogger
.info(LogStr
)
4675 FvInFdList
= self
.__GetFvInFd
(RefFdName
)
4676 if FvInFdList
!= []:
4677 for FvNameInFd
in FvInFdList
:
4678 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
,FvNameInFd
)
4679 if FvNameInFd
not in RefFvList
:
4680 RefFvList
.append(FvNameInFd
)
4682 FdAnalyzedList
.append(RefFdName
)
4684 # the number of the parsed FV and FD image
4686 FvListLength
= len (RefFvList
)
4687 FdListLength
= len (RefFdList
)
4688 for RefFvName
in RefFvList
:
4689 if RefFvName
in FvAnalyzedList
:
4691 LogStr
+= "Capsule %s contains FV %s\n" % (CapNameFromStack
, RefFvName
)
4692 if RefFvName
.upper() in self
.Profile
.FvDict
.keys():
4693 FvObj
= self
.Profile
.FvDict
[RefFvName
.upper()]
4696 self
.__GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4697 FvAnalyzedList
.append(RefFvName
)
4701 if __name__
== "__main__":
4704 test_file
= sys
.argv
[1]
4705 except IndexError, v
:
4706 print "Usage: %s filename" % sys
.argv
[0]
4709 parser
= FdfParser(test_file
)
4712 parser
.CycleReferenceCheck()