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 self
.InfDict
= {'ArchTBD':[]}
235 # ECC will use this Dict and List information
236 self
.PcdFileLineDict
= {}
237 self
.InfFileLineList
= []
240 self
.FdNameNotSet
= False
242 self
.CapsuleDict
= {}
246 self
.FmpPayloadDict
= {}
248 ## The syntax parser for FDF
250 # PreprocessFile method should be called prior to ParseFile
251 # CycleReferenceCheck method can detect cycles in FDF contents
253 # GetNext*** procedures mean these procedures will get next token first, then make judgement.
254 # Get*** procedures mean these procedures will make judgement on current token only.
259 # @param self The object pointer
260 # @param FileName The file that to be parsed
262 def __init__(self
, FileName
):
263 self
.Profile
= FileProfile(FileName
)
264 self
.FileName
= FileName
265 self
.CurrentLineNumber
= 1
266 self
.CurrentOffsetWithinLine
= 0
267 self
.CurrentFdName
= None
268 self
.CurrentFvName
= None
270 self
.__SkippedChars
= ""
271 GlobalData
.gFdfParser
= self
273 # Used to section info
274 self
.__CurSection
= []
275 # Key: [section name, UI name, arch]
276 # Value: {MACRO_NAME : MACRO_VALUE}
277 self
.__MacroDict
= tdict(True, 3)
280 self
.__WipeOffArea
= []
281 if GenFdsGlobalVariable
.WorkSpaceDir
== '':
282 GenFdsGlobalVariable
.WorkSpaceDir
= os
.getenv("WORKSPACE")
284 ## __IsWhiteSpace() method
286 # Whether char at current FileBufferPos is whitespace
288 # @param self The object pointer
289 # @param Char The char to test
290 # @retval True The char is a kind of white space
291 # @retval False The char is NOT a kind of white space
293 def __IsWhiteSpace(self
, Char
):
294 if Char
in (T_CHAR_NULL
, T_CHAR_CR
, T_CHAR_SPACE
, T_CHAR_TAB
, T_CHAR_LF
):
299 ## __SkipWhiteSpace() method
301 # Skip white spaces from current char, return number of chars skipped
303 # @param self The object pointer
304 # @retval Count The number of chars skipped
306 def __SkipWhiteSpace(self
):
308 while not self
.__EndOfFile
():
310 if self
.__CurrentChar
() in (T_CHAR_NULL
, T_CHAR_CR
, T_CHAR_LF
, T_CHAR_SPACE
, T_CHAR_TAB
):
311 self
.__SkippedChars
+= str(self
.__CurrentChar
())
318 ## __EndOfFile() method
320 # Judge current buffer pos is at file end
322 # @param self The object pointer
323 # @retval True Current File buffer position is at file end
324 # @retval False Current File buffer position is NOT at file end
326 def __EndOfFile(self
):
327 NumberOfLines
= len(self
.Profile
.FileLinesList
)
328 SizeOfLastLine
= len(self
.Profile
.FileLinesList
[-1])
329 if self
.CurrentLineNumber
== NumberOfLines
and self
.CurrentOffsetWithinLine
>= SizeOfLastLine
- 1:
331 elif self
.CurrentLineNumber
> NumberOfLines
:
336 ## __EndOfLine() method
338 # Judge current buffer pos is at line end
340 # @param self The object pointer
341 # @retval True Current File buffer position is at line end
342 # @retval False Current File buffer position is NOT at line end
344 def __EndOfLine(self
):
345 if self
.CurrentLineNumber
> len(self
.Profile
.FileLinesList
):
347 SizeOfCurrentLine
= len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
348 if self
.CurrentOffsetWithinLine
>= SizeOfCurrentLine
:
355 # Reset file data buffer to the initial state
357 # @param self The object pointer
358 # @param DestLine Optional new destination line number.
359 # @param DestOffset Optional new destination offset.
361 def Rewind(self
, DestLine
= 1, DestOffset
= 0):
362 self
.CurrentLineNumber
= DestLine
363 self
.CurrentOffsetWithinLine
= DestOffset
365 ## __UndoOneChar() method
367 # Go back one char in the file buffer
369 # @param self The object pointer
370 # @retval True Successfully go back one char
371 # @retval False Not able to go back one char as file beginning reached
373 def __UndoOneChar(self
):
375 if self
.CurrentLineNumber
== 1 and self
.CurrentOffsetWithinLine
== 0:
377 elif self
.CurrentOffsetWithinLine
== 0:
378 self
.CurrentLineNumber
-= 1
379 self
.CurrentOffsetWithinLine
= len(self
.__CurrentLine
()) - 1
381 self
.CurrentOffsetWithinLine
-= 1
384 ## __GetOneChar() method
386 # Move forward one char in the file buffer
388 # @param self The object pointer
390 def __GetOneChar(self
):
391 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
392 self
.CurrentLineNumber
+= 1
393 self
.CurrentOffsetWithinLine
= 0
395 self
.CurrentOffsetWithinLine
+= 1
397 ## __CurrentChar() method
399 # Get the char pointed to by the file buffer pointer
401 # @param self The object pointer
402 # @retval Char Current char
404 def __CurrentChar(self
):
405 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
]
407 ## __NextChar() method
409 # Get the one char pass the char pointed to by the file buffer pointer
411 # @param self The object pointer
412 # @retval Char Next char
414 def __NextChar(self
):
415 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
416 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
][0]
418 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
+ 1]
420 ## __SetCurrentCharValue() method
422 # Modify the value of current char
424 # @param self The object pointer
425 # @param Value The new value of current char
427 def __SetCurrentCharValue(self
, Value
):
428 self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
] = Value
430 ## __CurrentLine() method
432 # Get the list that contains current line contents
434 # @param self The object pointer
435 # @retval List current line contents
437 def __CurrentLine(self
):
438 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
440 def __StringToList(self
):
441 self
.Profile
.FileLinesList
= [list(s
) for s
in self
.Profile
.FileLinesList
]
442 self
.Profile
.FileLinesList
[-1].append(' ')
444 def __ReplaceFragment(self
, StartPos
, EndPos
, Value
= ' '):
445 if StartPos
[0] == EndPos
[0]:
447 while Offset
<= EndPos
[1]:
448 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
453 while self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] not in ('\r', '\n'):
454 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
458 while Line
< EndPos
[0]:
460 while self
.Profile
.FileLinesList
[Line
][Offset
] not in ('\r', '\n'):
461 self
.Profile
.FileLinesList
[Line
][Offset
] = Value
466 while Offset
<= EndPos
[1]:
467 self
.Profile
.FileLinesList
[EndPos
[0]][Offset
] = Value
471 def __GetMacroName(self
):
472 if not self
.__GetNextToken
():
473 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
474 MacroName
= self
.__Token
476 if MacroName
.startswith('!'):
478 MacroName
= MacroName
[1:].strip()
480 if not MacroName
.startswith('$(') or not MacroName
.endswith(')'):
481 raise Warning("Macro name expected(Please use '$(%(Token)s)' if '%(Token)s' is a macro.)" % {"Token" : MacroName
},
482 self
.FileName
, self
.CurrentLineNumber
)
483 MacroName
= MacroName
[2:-1]
484 return MacroName
, NotFlag
486 def __SetMacroValue(self
, Macro
, Value
):
487 if not self
.__CurSection
:
491 if not self
.__MacroDict
[self
.__CurSection
[0], self
.__CurSection
[1], self
.__CurSection
[2]]:
492 self
.__MacroDict
[self
.__CurSection
[0], self
.__CurSection
[1], self
.__CurSection
[2]] = MacroDict
494 MacroDict
= self
.__MacroDict
[self
.__CurSection
[0], self
.__CurSection
[1], self
.__CurSection
[2]]
495 MacroDict
[Macro
] = Value
497 def __GetMacroValue(self
, Macro
):
499 if Macro
in GlobalData
.gCommandLineDefines
:
500 return GlobalData
.gCommandLineDefines
[Macro
]
501 if Macro
in GlobalData
.gGlobalDefines
:
502 return GlobalData
.gGlobalDefines
[Macro
]
504 if self
.__CurSection
:
505 MacroDict
= self
.__MacroDict
[
506 self
.__CurSection
[0],
507 self
.__CurSection
[1],
510 if MacroDict
and Macro
in MacroDict
:
511 return MacroDict
[Macro
]
514 if Macro
in GlobalData
.gPlatformDefines
:
515 return GlobalData
.gPlatformDefines
[Macro
]
518 def __SectionHeaderParser(self
, Section
):
520 # [FD.UiName]: use dummy instead if UI name is optional
523 # [Rule]: don't take rule section into account, macro is not allowed in this section
524 # [VTF.arch.UiName, arch]
525 # [OptionRom.DriverName]
526 self
.__CurSection
= []
527 Section
= Section
.strip()[1:-1].upper().replace(' ', '').strip('.')
528 ItemList
= Section
.split('.')
530 if Item
== '' or Item
== 'RULE':
533 if Item
== 'DEFINES':
534 self
.__CurSection
= ['COMMON', 'COMMON', 'COMMON']
535 elif Item
== 'VTF' and len(ItemList
) == 3:
537 Pos
= UiName
.find(',')
539 UiName
= UiName
[:Pos
]
540 self
.__CurSection
= ['VTF', UiName
, ItemList
[1]]
541 elif len(ItemList
) > 1:
542 self
.__CurSection
= [ItemList
[0], ItemList
[1], 'COMMON']
543 elif len(ItemList
) > 0:
544 self
.__CurSection
= [ItemList
[0], 'DUMMY', 'COMMON']
546 ## PreprocessFile() method
548 # Preprocess file contents, replace comments with spaces.
549 # In the end, rewind the file buffer pointer to the beginning
550 # BUGBUG: No !include statement processing contained in this procedure
551 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
553 # @param self The object pointer
555 def PreprocessFile(self
):
559 DoubleSlashComment
= False
561 # HashComment in quoted string " " is ignored.
564 while not self
.__EndOfFile
():
566 if self
.__CurrentChar
() == T_CHAR_DOUBLE_QUOTE
and not InComment
:
567 InString
= not InString
568 # meet new line, then no longer in a comment for // and '#'
569 if self
.__CurrentChar
() == T_CHAR_LF
:
570 self
.CurrentLineNumber
+= 1
571 self
.CurrentOffsetWithinLine
= 0
572 if InComment
and DoubleSlashComment
:
574 DoubleSlashComment
= False
575 if InComment
and HashComment
:
578 # check for */ comment end
579 elif InComment
and not DoubleSlashComment
and not HashComment
and self
.__CurrentChar
() == T_CHAR_STAR
and self
.__NextChar
() == T_CHAR_SLASH
:
580 self
.__SetCurrentCharValue
(T_CHAR_SPACE
)
582 self
.__SetCurrentCharValue
(T_CHAR_SPACE
)
585 # set comments to spaces
587 self
.__SetCurrentCharValue
(T_CHAR_SPACE
)
589 # check for // comment
590 elif self
.__CurrentChar
() == T_CHAR_SLASH
and self
.__NextChar
() == T_CHAR_SLASH
and not self
.__EndOfLine
():
592 DoubleSlashComment
= True
593 # check for '#' comment
594 elif self
.__CurrentChar
() == T_CHAR_HASH
and not self
.__EndOfLine
() and not InString
:
597 # check for /* comment start
598 elif self
.__CurrentChar
() == T_CHAR_SLASH
and self
.__NextChar
() == T_CHAR_STAR
:
599 self
.__SetCurrentCharValue
( T_CHAR_SPACE
)
601 self
.__SetCurrentCharValue
( T_CHAR_SPACE
)
607 # restore from ListOfList to ListOfString
608 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
611 ## PreprocessIncludeFile() method
613 # Preprocess file contents, replace !include statements with file contents.
614 # In the end, rewind the file buffer pointer to the beginning
616 # @param self The object pointer
618 def PreprocessIncludeFile(self
):
619 # nested include support
621 while self
.__GetNextToken
():
623 if self
.__Token
== '!include':
625 IncludeLine
= self
.CurrentLineNumber
626 IncludeOffset
= self
.CurrentOffsetWithinLine
- len('!include')
627 if not self
.__GetNextToken
():
628 raise Warning("expected include file name", self
.FileName
, self
.CurrentLineNumber
)
629 IncFileName
= self
.__Token
631 for Macro
in ['WORKSPACE', 'ECP_SOURCE', 'EFI_SOURCE', 'EDK_SOURCE']:
632 MacroVal
= self
.__GetMacroValue
(Macro
)
634 __IncludeMacros
[Macro
] = MacroVal
637 IncludedFile
= NormPath(ReplaceMacro(IncFileName
, __IncludeMacros
, RaiseError
=True))
639 raise Warning("only these system environment variables are permitted to start the path of the included file: "
640 "$(WORKSPACE), $(ECP_SOURCE), $(EFI_SOURCE), $(EDK_SOURCE)",
641 self
.FileName
, self
.CurrentLineNumber
)
643 # First search the include file under the same directory as FDF file
645 IncludedFile1
= PathClass(IncludedFile
, os
.path
.dirname(self
.FileName
))
646 ErrorCode
= IncludedFile1
.Validate()[0]
649 # Then search the include file under the same directory as DSC file
652 if GenFdsGlobalVariable
.ActivePlatform
:
653 PlatformDir
= GenFdsGlobalVariable
.ActivePlatform
.Dir
654 elif GlobalData
.gActivePlatform
:
655 PlatformDir
= GlobalData
.gActivePlatform
.MetaFile
.Dir
656 IncludedFile1
= PathClass(IncludedFile
, PlatformDir
)
657 ErrorCode
= IncludedFile1
.Validate()[0]
660 # Also search file under the WORKSPACE directory
662 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
663 ErrorCode
= IncludedFile1
.Validate()[0]
665 raise Warning("The include file does not exist under below directories: \n%s\n%s\n%s\n"%(os
.path
.dirname(self
.FileName
), PlatformDir
, GlobalData
.gWorkspace
),
666 self
.FileName
, self
.CurrentLineNumber
)
668 if not IsValidInclude (IncludedFile1
.Path
, self
.CurrentLineNumber
):
669 raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1
.Path
), self
.FileName
, self
.CurrentLineNumber
)
671 IncFileProfile
= IncludeFileProfile(IncludedFile1
.Path
)
673 CurrentLine
= self
.CurrentLineNumber
674 CurrentOffset
= self
.CurrentOffsetWithinLine
675 # list index of the insertion, note that line number is 'CurrentLine + 1'
676 InsertAtLine
= CurrentLine
677 ParentProfile
= GetParentAtLine (CurrentLine
)
678 if ParentProfile
!= None:
679 ParentProfile
.IncludeFileList
.insert(0, IncFileProfile
)
680 IncFileProfile
.Level
= ParentProfile
.Level
+ 1
681 IncFileProfile
.InsertStartLineNumber
= InsertAtLine
+ 1
682 # deal with remaining portions after "!include filename", if exists.
683 if self
.__GetNextToken
():
684 if self
.CurrentLineNumber
== CurrentLine
:
685 RemainingLine
= self
.__CurrentLine
()[CurrentOffset
:]
686 self
.Profile
.FileLinesList
.insert(self
.CurrentLineNumber
, RemainingLine
)
687 IncFileProfile
.InsertAdjust
+= 1
688 self
.CurrentLineNumber
+= 1
689 self
.CurrentOffsetWithinLine
= 0
691 for Line
in IncFileProfile
.FileLinesList
:
692 self
.Profile
.FileLinesList
.insert(InsertAtLine
, Line
)
693 self
.CurrentLineNumber
+= 1
696 # reversely sorted to better determine error in file
697 AllIncludeFileList
.insert(0, IncFileProfile
)
699 # comment out the processed include file statement
700 TempList
= list(self
.Profile
.FileLinesList
[IncludeLine
- 1])
701 TempList
.insert(IncludeOffset
, '#')
702 self
.Profile
.FileLinesList
[IncludeLine
- 1] = ''.join(TempList
)
703 if Processed
: # Nested and back-to-back support
704 self
.Rewind(DestLine
= IncFileProfile
.InsertStartLineNumber
- 1)
709 def __GetIfListCurrentItemStat(self
, IfList
):
719 ## PreprocessConditionalStatement() method
721 # Preprocess conditional statement.
722 # In the end, rewind the file buffer pointer to the beginning
724 # @param self The object pointer
726 def PreprocessConditionalStatement(self
):
727 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
731 while self
.__GetNextToken
():
732 # Determine section name and the location dependent macro
733 if self
.__GetIfListCurrentItemStat
(IfList
):
734 if self
.__Token
.startswith('['):
735 Header
= self
.__Token
736 if not self
.__Token
.endswith(']'):
737 self
.__SkipToToken
(']')
738 Header
+= self
.__SkippedChars
739 if Header
.find('$(') != -1:
740 raise Warning("macro cannot be used in section header", self
.FileName
, self
.CurrentLineNumber
)
741 self
.__SectionHeaderParser
(Header
)
743 # Replace macros except in RULE section or out of section
744 elif self
.__CurSection
and ReplacedLine
!= self
.CurrentLineNumber
:
745 ReplacedLine
= self
.CurrentLineNumber
747 CurLine
= self
.Profile
.FileLinesList
[ReplacedLine
- 1]
749 StartPos
= CurLine
.find('$(', PreIndex
)
750 EndPos
= CurLine
.find(')', StartPos
+2)
751 while StartPos
!= -1 and EndPos
!= -1 and self
.__Token
not in ['!ifdef', '!ifndef', '!if', '!elseif']:
752 MacroName
= CurLine
[StartPos
+2 : EndPos
]
753 MacorValue
= self
.__GetMacroValue
(MacroName
)
754 if MacorValue
!= None:
755 CurLine
= CurLine
.replace('$(' + MacroName
+ ')', MacorValue
, 1)
756 if MacorValue
.find('$(') != -1:
759 PreIndex
= StartPos
+ len(MacorValue
)
761 PreIndex
= EndPos
+ 1
762 StartPos
= CurLine
.find('$(', PreIndex
)
763 EndPos
= CurLine
.find(')', StartPos
+2)
764 self
.Profile
.FileLinesList
[ReplacedLine
- 1] = CurLine
767 if self
.__Token
== 'DEFINE':
768 if self
.__GetIfListCurrentItemStat
(IfList
):
769 if not self
.__CurSection
:
770 raise Warning("macro cannot be defined in Rule section or out of section", self
.FileName
, self
.CurrentLineNumber
)
771 DefineLine
= self
.CurrentLineNumber
- 1
772 DefineOffset
= self
.CurrentOffsetWithinLine
- len('DEFINE')
773 if not self
.__GetNextToken
():
774 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
776 if not self
.__IsToken
( "="):
777 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
779 Value
= self
.__GetExpression
()
780 self
.__SetMacroValue
(Macro
, Value
)
781 self
.__WipeOffArea
.append(((DefineLine
, DefineOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
782 elif self
.__Token
== 'SET':
783 if not self
.__GetIfListCurrentItemStat
(IfList
):
785 SetLine
= self
.CurrentLineNumber
- 1
786 SetOffset
= self
.CurrentOffsetWithinLine
- len('SET')
787 PcdPair
= self
.__GetNextPcdName
()
788 PcdName
= "%s.%s" % (PcdPair
[1], PcdPair
[0])
789 if not self
.__IsToken
( "="):
790 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
792 Value
= self
.__GetExpression
()
793 Value
= self
.__EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
795 self
.__PcdDict
[PcdName
] = Value
797 self
.Profile
.PcdDict
[PcdPair
] = Value
798 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
799 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
801 self
.__WipeOffArea
.append(((SetLine
, SetOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
802 elif self
.__Token
in ('!ifdef', '!ifndef', '!if'):
803 IfStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
.__Token
))
804 IfList
.append([IfStartPos
, None, None])
806 CondLabel
= self
.__Token
807 Expression
= self
.__GetExpression
()
809 if CondLabel
== '!if':
810 ConditionSatisfied
= self
.__EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
812 ConditionSatisfied
= self
.__EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'in')
813 if CondLabel
== '!ifndef':
814 ConditionSatisfied
= not ConditionSatisfied
816 BranchDetermined
= ConditionSatisfied
817 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, BranchDetermined
]
818 if ConditionSatisfied
:
819 self
.__WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
820 elif self
.__Token
in ('!elseif', '!else'):
821 ElseStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
.__Token
))
823 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
826 IfList
[-1] = [ElseStartPos
, False, True]
827 self
.__WipeOffArea
.append((ElseStartPos
, (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
829 self
.__WipeOffArea
.append((IfList
[-1][0], ElseStartPos
))
830 IfList
[-1] = [ElseStartPos
, True, IfList
[-1][2]]
831 if self
.__Token
== '!elseif':
832 Expression
= self
.__GetExpression
()
833 ConditionSatisfied
= self
.__EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
834 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, IfList
[-1][2]]
838 IfList
[-1][1] = False
841 self
.__WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
842 elif self
.__Token
== '!endif':
844 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
846 self
.__WipeOffArea
.append(((self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len('!endif')), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
848 self
.__WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
851 elif not IfList
: # Don't use PCDs inside conditional directive
852 if self
.CurrentLineNumber
<= RegionLayoutLine
:
853 # Don't try the same line twice
855 SetPcd
= ShortcutPcdPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
857 self
.__PcdDict
[SetPcd
.group('name')] = SetPcd
.group('value')
858 RegionLayoutLine
= self
.CurrentLineNumber
860 RegionSize
= RegionSizePattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
862 RegionLayoutLine
= self
.CurrentLineNumber
864 RegionSizeGuid
= RegionSizeGuidPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
])
865 if not RegionSizeGuid
:
866 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
868 self
.__PcdDict
[RegionSizeGuid
.group('base')] = RegionSize
.group('base')
869 self
.__PcdDict
[RegionSizeGuid
.group('size')] = RegionSize
.group('size')
870 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
873 raise Warning("Missing !endif", self
.FileName
, self
.CurrentLineNumber
)
876 def __CollectMacroPcd(self
):
880 MacroDict
.update(GlobalData
.gPlatformPcds
)
881 MacroDict
.update(self
.__PcdDict
)
884 MacroDict
.update(GlobalData
.gPlatformDefines
)
886 if self
.__CurSection
:
888 ScopeMacro
= self
.__MacroDict
['COMMON', 'COMMON', 'COMMON']
890 MacroDict
.update(ScopeMacro
)
893 ScopeMacro
= self
.__MacroDict
[
894 self
.__CurSection
[0],
895 self
.__CurSection
[1],
899 MacroDict
.update(ScopeMacro
)
901 MacroDict
.update(GlobalData
.gGlobalDefines
)
902 MacroDict
.update(GlobalData
.gCommandLineDefines
)
907 def __EvaluateConditional(self
, Expression
, Line
, Op
= None, Value
= None):
908 FileLineTuple
= GetRealFileLine(self
.FileName
, Line
)
909 MacroPcdDict
= self
.__CollectMacroPcd
()
913 return ValueExpression(Expression
, MacroPcdDict
)(True)
915 return ValueExpression(Expression
, MacroPcdDict
)()
916 except WrnExpression
, Excpt
:
918 # Catch expression evaluation warning here. We need to report
919 # the precise number of line and return the evaluation result
921 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
922 File
=self
.FileName
, ExtraData
=self
.__CurrentLine
(),
925 except Exception, Excpt
:
926 if hasattr(Excpt
, 'Pcd'):
927 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
928 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
929 raise Warning("Cannot use this PCD (%s) in an expression as"
930 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
931 " of the DSC file (%s), and it is currently defined in this section:"
932 " %s, line #: %d." % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE'], Info
[0], Info
[1]),
935 raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE']),
938 raise Warning(str(Excpt
), *FileLineTuple
)
940 if Expression
.startswith('$(') and Expression
[-1] == ')':
941 Expression
= Expression
[2:-1]
942 return Expression
in MacroPcdDict
944 ## __IsToken() method
946 # Check whether input string is found from current char position along
947 # If found, the string value is put into self.__Token
949 # @param self The object pointer
950 # @param String The string to search
951 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
952 # @retval True Successfully find string, file buffer pointer moved forward
953 # @retval False Not able to find string, file buffer pointer not changed
955 def __IsToken(self
, String
, IgnoreCase
= False):
956 self
.__SkipWhiteSpace
()
958 # Only consider the same line, no multi-line token allowed
959 StartPos
= self
.CurrentOffsetWithinLine
962 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
964 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
966 self
.CurrentOffsetWithinLine
+= len(String
)
967 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
971 ## __IsKeyword() method
973 # Check whether input keyword is found from current char position along, whole word only!
974 # If found, the string value is put into self.__Token
976 # @param self The object pointer
977 # @param Keyword The string to search
978 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
979 # @retval True Successfully find string, file buffer pointer moved forward
980 # @retval False Not able to find string, file buffer pointer not changed
982 def __IsKeyword(self
, KeyWord
, IgnoreCase
= False):
983 self
.__SkipWhiteSpace
()
985 # Only consider the same line, no multi-line token allowed
986 StartPos
= self
.CurrentOffsetWithinLine
989 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(KeyWord
.upper())
991 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(KeyWord
)
993 followingChar
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
+ len(KeyWord
)]
994 if not str(followingChar
).isspace() and followingChar
not in SEPERATOR_TUPLE
:
996 self
.CurrentOffsetWithinLine
+= len(KeyWord
)
997 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1001 def __GetExpression(self
):
1002 Line
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
1003 Index
= len(Line
) - 1
1004 while Line
[Index
] in ['\r', '\n']:
1006 ExpressionString
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:Index
+1]
1007 self
.CurrentOffsetWithinLine
+= len(ExpressionString
)
1008 ExpressionString
= ExpressionString
.strip()
1009 return ExpressionString
1011 ## __GetNextWord() method
1013 # Get next C name from file lines
1014 # If found, the string value is put into self.__Token
1016 # @param self The object pointer
1017 # @retval True Successfully find a C name string, file buffer pointer moved forward
1018 # @retval False Not able to find a C name string, file buffer pointer not changed
1020 def __GetNextWord(self
):
1021 self
.__SkipWhiteSpace
()
1022 if self
.__EndOfFile
():
1025 TempChar
= self
.__CurrentChar
()
1026 StartPos
= self
.CurrentOffsetWithinLine
1027 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_':
1029 while not self
.__EndOfLine
():
1030 TempChar
= self
.__CurrentChar
()
1031 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
1032 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-':
1038 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1043 ## __GetNextToken() method
1045 # Get next token unit before a seperator
1046 # If found, the string value is put into self.__Token
1048 # @param self The object pointer
1049 # @retval True Successfully find a token unit, file buffer pointer moved forward
1050 # @retval False Not able to find a token unit, file buffer pointer not changed
1052 def __GetNextToken(self
):
1053 # Skip leading spaces, if exist.
1054 self
.__SkipWhiteSpace
()
1055 if self
.__EndOfFile
():
1057 # Record the token start position, the position of the first non-space char.
1058 StartPos
= self
.CurrentOffsetWithinLine
1059 StartLine
= self
.CurrentLineNumber
1060 while StartLine
== self
.CurrentLineNumber
:
1061 TempChar
= self
.__CurrentChar
()
1062 # Try to find the end char that is not a space and not in seperator tuple.
1063 # That is, when we got a space or any char in the tuple, we got the end of token.
1064 if not str(TempChar
).isspace() and TempChar
not in SEPERATOR_TUPLE
:
1066 # if we happen to meet a seperator as the first char, we must proceed to get it.
1067 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1068 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPERATOR_TUPLE
:
1076 EndPos
= self
.CurrentOffsetWithinLine
1077 if self
.CurrentLineNumber
!= StartLine
:
1078 EndPos
= len(self
.Profile
.FileLinesList
[StartLine
-1])
1079 self
.__Token
= self
.Profile
.FileLinesList
[StartLine
-1][StartPos
: EndPos
]
1080 if StartPos
!= self
.CurrentOffsetWithinLine
:
1085 def __GetNextOp(self
):
1086 # Skip leading spaces, if exist.
1087 self
.__SkipWhiteSpace
()
1088 if self
.__EndOfFile
():
1090 # Record the token start position, the position of the first non-space char.
1091 StartPos
= self
.CurrentOffsetWithinLine
1092 while not self
.__EndOfLine
():
1093 TempChar
= self
.__CurrentChar
()
1094 # Try to find the end char that is not a space
1095 if not str(TempChar
).isspace():
1102 if StartPos
!= self
.CurrentOffsetWithinLine
:
1103 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1107 ## __GetNextGuid() method
1109 # Get next token unit before a seperator
1110 # If found, the GUID string is put into self.__Token
1112 # @param self The object pointer
1113 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward
1114 # @retval False Not able to find a registry format GUID, file buffer pointer not changed
1116 def __GetNextGuid(self
):
1118 if not self
.__GetNextToken
():
1120 p
= re
.compile('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}')
1121 if p
.match(self
.__Token
) != None:
1127 ## __UndoToken() method
1129 # Go back one token unit in file buffer
1131 # @param self The object pointer
1133 def __UndoToken(self
):
1134 self
.__UndoOneChar
()
1135 while self
.__CurrentChar
().isspace():
1136 if not self
.__UndoOneChar
():
1141 StartPos
= self
.CurrentOffsetWithinLine
1142 CurrentLine
= self
.CurrentLineNumber
1143 while CurrentLine
== self
.CurrentLineNumber
:
1145 TempChar
= self
.__CurrentChar
()
1146 # Try to find the end char that is not a space and not in seperator tuple.
1147 # That is, when we got a space or any char in the tuple, we got the end of token.
1148 if not str(TempChar
).isspace() and not TempChar
in SEPERATOR_TUPLE
:
1149 if not self
.__UndoOneChar
():
1151 # if we happen to meet a seperator as the first char, we must proceed to get it.
1152 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1153 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPERATOR_TUPLE
:
1160 ## __HexDigit() method
1162 # Whether char input is a Hex data bit
1164 # @param self The object pointer
1165 # @param TempChar The char to test
1166 # @retval True The char is a Hex data bit
1167 # @retval False The char is NOT a Hex data bit
1169 def __HexDigit(self
, TempChar
):
1170 if (TempChar
>= 'a' and TempChar
<= 'f') or (TempChar
>= 'A' and TempChar
<= 'F') \
1171 or (TempChar
>= '0' and TempChar
<= '9'):
1176 def __IsHex(self
, HexStr
):
1177 if not HexStr
.upper().startswith("0X"):
1179 if len(self
.__Token
) <= 2:
1181 charList
= [c
for c
in HexStr
[2 : ] if not self
.__HexDigit
( c
)]
1182 if len(charList
) == 0:
1186 ## __GetNextHexNumber() method
1188 # Get next HEX data before a seperator
1189 # If found, the HEX data is put into self.__Token
1191 # @param self The object pointer
1192 # @retval True Successfully find a HEX data, file buffer pointer moved forward
1193 # @retval False Not able to find a HEX data, file buffer pointer not changed
1195 def __GetNextHexNumber(self
):
1196 if not self
.__GetNextToken
():
1198 if self
.__IsHex
(self
.__Token
):
1204 ## __GetNextDecimalNumber() method
1206 # Get next decimal data before a seperator
1207 # If found, the decimal data is put into self.__Token
1209 # @param self The object pointer
1210 # @retval True Successfully find a decimal data, file buffer pointer moved forward
1211 # @retval False Not able to find a decimal data, file buffer pointer not changed
1213 def __GetNextDecimalNumber(self
):
1214 if not self
.__GetNextToken
():
1216 if self
.__Token
.isdigit():
1222 ## __GetNextPcdName() method
1224 # Get next PCD token space C name and PCD C name pair before a seperator
1225 # If found, the decimal data is put into self.__Token
1227 # @param self The object pointer
1228 # @retval Tuple PCD C name and PCD token space C name pair
1230 def __GetNextPcdName(self
):
1231 if not self
.__GetNextWord
():
1232 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1233 pcdTokenSpaceCName
= self
.__Token
1235 if not self
.__IsToken
( "."):
1236 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1238 if not self
.__GetNextWord
():
1239 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1240 pcdCName
= self
.__Token
1242 return (pcdCName
, pcdTokenSpaceCName
)
1244 ## __GetStringData() method
1246 # Get string contents quoted in ""
1247 # If found, the decimal data is put into self.__Token
1249 # @param self The object pointer
1250 # @retval True Successfully find a string data, file buffer pointer moved forward
1251 # @retval False Not able to find a string data, file buffer pointer not changed
1253 def __GetStringData(self
):
1254 if self
.__Token
.startswith("\"") or self
.__Token
.startswith("L\""):
1256 self
.__SkipToToken
("\"")
1257 currentLineNumber
= self
.CurrentLineNumber
1259 if not self
.__SkipToToken
("\""):
1260 raise Warning("Missing Quote \" for String", self
.FileName
, self
.CurrentLineNumber
)
1261 if currentLineNumber
!= self
.CurrentLineNumber
:
1262 raise Warning("Missing Quote \" for String", self
.FileName
, self
.CurrentLineNumber
)
1263 self
.__Token
= self
.__SkippedChars
.rstrip('\"')
1266 elif self
.__Token
.startswith("\'") or self
.__Token
.startswith("L\'"):
1268 self
.__SkipToToken
("\'")
1269 currentLineNumber
= self
.CurrentLineNumber
1271 if not self
.__SkipToToken
("\'"):
1272 raise Warning("Missing Quote \' for String", self
.FileName
, self
.CurrentLineNumber
)
1273 if currentLineNumber
!= self
.CurrentLineNumber
:
1274 raise Warning("Missing Quote \' for String", self
.FileName
, self
.CurrentLineNumber
)
1275 self
.__Token
= self
.__SkippedChars
.rstrip('\'')
1281 ## __SkipToToken() method
1283 # Search forward in file buffer for the string
1284 # The skipped chars are put into self.__SkippedChars
1286 # @param self The object pointer
1287 # @param String The string to search
1288 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
1289 # @retval True Successfully find the string, file buffer pointer moved forward
1290 # @retval False Not able to find the string, file buffer pointer not changed
1292 def __SkipToToken(self
, String
, IgnoreCase
= False):
1293 StartPos
= self
.GetFileBufferPos()
1295 self
.__SkippedChars
= ""
1296 while not self
.__EndOfFile
():
1299 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
1301 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
1303 self
.CurrentOffsetWithinLine
+= len(String
)
1304 self
.__SkippedChars
+= String
1306 self
.__SkippedChars
+= str(self
.__CurrentChar
())
1309 self
.SetFileBufferPos( StartPos
)
1310 self
.__SkippedChars
= ""
1313 ## GetFileBufferPos() method
1315 # Return the tuple of current line and offset within the line
1317 # @param self The object pointer
1318 # @retval Tuple Line number and offset pair
1320 def GetFileBufferPos(self
):
1321 return (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
)
1323 ## SetFileBufferPos() method
1325 # Restore the file buffer position
1327 # @param self The object pointer
1328 # @param Pos The new file buffer position
1330 def SetFileBufferPos(self
, Pos
):
1331 (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
) = Pos
1333 ## Preprocess() method
1335 # Preprocess comment, conditional directive, include directive, replace macro.
1336 # Exception will be raised if syntax error found
1338 # @param self The object pointer
1340 def Preprocess(self
):
1341 self
.__StringToList
()
1342 self
.PreprocessFile()
1343 self
.PreprocessIncludeFile()
1344 self
.__StringToList
()
1345 self
.PreprocessFile()
1346 self
.PreprocessConditionalStatement()
1347 self
.__StringToList
()
1348 for Pos
in self
.__WipeOffArea
:
1349 self
.__ReplaceFragment
(Pos
[0], Pos
[1])
1350 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
1352 while self
.__GetDefines
():
1355 ## ParseFile() method
1357 # Parse the file profile buffer to extract fd, fv ... information
1358 # Exception will be raised if syntax error found
1360 # @param self The object pointer
1362 def ParseFile(self
):
1366 while self
.__GetFd
():
1369 while self
.__GetFv
():
1372 while self
.__GetFmp
():
1375 while self
.__GetCapsule
():
1378 while self
.__GetVtf
():
1381 while self
.__GetRule
():
1384 while self
.__GetOptionRom
():
1389 #'\n\tGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \
1390 # At this point, the closest parent would be the included file itself
1391 Profile
= GetParentAtLine(X
.OriginalLineNumber
)
1393 X
.Message
+= ' near line %d, column %d: %s' \
1394 % (X
.LineNumber
, 0, Profile
.FileLinesList
[X
.LineNumber
-1])
1396 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1397 X
.Message
+= ' near line %d, column %d: %s' \
1398 % (FileLineTuple
[1], self
.CurrentOffsetWithinLine
+ 1, self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:].rstrip('\n').rstrip('\r'))
1401 ## SectionParser() method
1403 # Parse the file section info
1404 # Exception will be raised if syntax error found
1406 # @param self The object pointer
1407 # @param section The section string
1409 def SectionParser(self
, section
):
1411 if not S
.startswith("[DEFINES") and not S
.startswith("[FD.") and not S
.startswith("[FV.") and not S
.startswith("[CAPSULE.") \
1412 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM.") and not S
.startswith('[FMPPAYLOAD.'):
1413 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
)
1415 ## __GetDefines() method
1417 # Get Defines section contents and store its data into AllMacrosList
1419 # @param self The object pointer
1420 # @retval True Successfully find a Defines
1421 # @retval False Not able to find a Defines
1423 def __GetDefines(self
):
1425 if not self
.__GetNextToken
():
1428 S
= self
.__Token
.upper()
1429 if S
.startswith("[") and not S
.startswith("[DEFINES"):
1430 self
.SectionParser(S
)
1435 if not self
.__IsToken
("[DEFINES", True):
1436 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1437 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1438 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1439 raise Warning("expected [DEFINES", self
.FileName
, self
.CurrentLineNumber
)
1441 if not self
.__IsToken
( "]"):
1442 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
1444 while self
.__GetNextWord
():
1445 # handle the SET statement
1446 if self
.__Token
== 'SET':
1448 self
.__GetSetStatement
(None)
1451 Macro
= self
.__Token
1453 if not self
.__IsToken
("="):
1454 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1455 if not self
.__GetNextToken
() or self
.__Token
.startswith('['):
1456 raise Warning("expected MACRO value", self
.FileName
, self
.CurrentLineNumber
)
1457 Value
= self
.__Token
1463 # Get FD section contents and store its data into FD dictionary of self.Profile
1465 # @param self The object pointer
1466 # @retval True Successfully find a FD
1467 # @retval False Not able to find a FD
1471 if not self
.__GetNextToken
():
1474 S
= self
.__Token
.upper()
1475 if S
.startswith("[") and not S
.startswith("[FD."):
1476 if not S
.startswith("[FV.") and not S
.startswith('[FMPPAYLOAD.') and not S
.startswith("[CAPSULE.") \
1477 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM."):
1478 raise Warning("Unknown section", self
.FileName
, self
.CurrentLineNumber
)
1483 if not self
.__IsToken
("[FD.", True):
1484 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1485 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1486 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1487 raise Warning("expected [FD.]", self
.FileName
, self
.CurrentLineNumber
)
1489 FdName
= self
.__GetUiName
()
1491 if len (self
.Profile
.FdDict
) == 0:
1492 FdName
= GenFdsGlobalVariable
.PlatformName
1493 if FdName
== "" and GlobalData
.gActivePlatform
:
1494 FdName
= GlobalData
.gActivePlatform
.PlatformName
1495 self
.Profile
.FdNameNotSet
= True
1497 raise Warning("expected FdName in [FD.] section", self
.FileName
, self
.CurrentLineNumber
)
1498 self
.CurrentFdName
= FdName
.upper()
1500 if self
.CurrentFdName
in self
.Profile
.FdDict
:
1501 raise Warning("Unexpected the same FD name", self
.FileName
, self
.CurrentLineNumber
)
1503 if not self
.__IsToken
( "]"):
1504 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
1507 FdObj
.FdUiName
= self
.CurrentFdName
1508 self
.Profile
.FdDict
[self
.CurrentFdName
] = FdObj
1510 if len (self
.Profile
.FdDict
) > 1 and self
.Profile
.FdNameNotSet
:
1511 raise Warning("expected all FDs have their name", self
.FileName
, self
.CurrentLineNumber
)
1513 Status
= self
.__GetCreateFile
(FdObj
)
1515 raise Warning("FD name error", self
.FileName
, self
.CurrentLineNumber
)
1517 while self
.__GetTokenStatements
(FdObj
):
1519 for Attr
in ("BaseAddress", "Size", "ErasePolarity"):
1520 if getattr(FdObj
, Attr
) == None:
1521 self
.__GetNextToken
()
1522 raise Warning("Keyword %s missing" % Attr
, self
.FileName
, self
.CurrentLineNumber
)
1524 if not FdObj
.BlockSizeList
:
1525 FdObj
.BlockSizeList
.append((1, FdObj
.Size
, None))
1527 self
.__GetDefineStatements
(FdObj
)
1529 self
.__GetSetStatements
(FdObj
)
1531 if not self
.__GetRegionLayout
(FdObj
):
1532 raise Warning("expected region layout", self
.FileName
, self
.CurrentLineNumber
)
1534 while self
.__GetRegionLayout
(FdObj
):
1538 ## __GetUiName() method
1540 # Return the UI name of a section
1542 # @param self The object pointer
1543 # @retval FdName UI name
1545 def __GetUiName(self
):
1547 if self
.__GetNextWord
():
1552 ## __GetCreateFile() method
1554 # Return the output file name of object
1556 # @param self The object pointer
1557 # @param Obj object whose data will be stored in file
1558 # @retval FdName UI name
1560 def __GetCreateFile(self
, Obj
):
1562 if self
.__IsKeyword
( "CREATE_FILE"):
1563 if not self
.__IsToken
( "="):
1564 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1566 if not self
.__GetNextToken
():
1567 raise Warning("expected file name", self
.FileName
, self
.CurrentLineNumber
)
1569 FileName
= self
.__Token
1570 Obj
.CreateFileName
= FileName
1574 ## __GetTokenStatements() method
1576 # Get token statements
1578 # @param self The object pointer
1579 # @param Obj for whom token statement is got
1581 def __GetTokenStatements(self
, Obj
):
1582 if self
.__IsKeyword
( "BaseAddress"):
1583 if not self
.__IsToken
( "="):
1584 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1586 if not self
.__GetNextHexNumber
():
1587 raise Warning("expected Hex base address", self
.FileName
, self
.CurrentLineNumber
)
1589 Obj
.BaseAddress
= self
.__Token
1591 if self
.__IsToken
( "|"):
1592 pcdPair
= self
.__GetNextPcdName
()
1593 Obj
.BaseAddressPcd
= pcdPair
1594 self
.Profile
.PcdDict
[pcdPair
] = Obj
.BaseAddress
1595 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1596 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1599 if self
.__IsKeyword
( "Size"):
1600 if not self
.__IsToken
( "="):
1601 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1603 if not self
.__GetNextHexNumber
():
1604 raise Warning("expected Hex size", self
.FileName
, self
.CurrentLineNumber
)
1607 if self
.__IsToken
( "|"):
1608 pcdPair
= self
.__GetNextPcdName
()
1609 Obj
.SizePcd
= pcdPair
1610 self
.Profile
.PcdDict
[pcdPair
] = Size
1611 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1612 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1613 Obj
.Size
= long(Size
, 0)
1616 if self
.__IsKeyword
( "ErasePolarity"):
1617 if not self
.__IsToken
( "="):
1618 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1620 if not self
.__GetNextToken
():
1621 raise Warning("expected Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1623 if self
.__Token
!= "1" and self
.__Token
!= "0":
1624 raise Warning("expected 1 or 0 Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1626 Obj
.ErasePolarity
= self
.__Token
1629 return self
.__GetBlockStatements
(Obj
)
1631 ## __GetAddressStatements() method
1633 # Get address statements
1635 # @param self The object pointer
1636 # @param Obj for whom address statement is got
1637 # @retval True Successfully find
1638 # @retval False Not able to find
1640 def __GetAddressStatements(self
, Obj
):
1642 if self
.__IsKeyword
("BsBaseAddress"):
1643 if not self
.__IsToken
( "="):
1644 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1646 if not self
.__GetNextDecimalNumber
() and not self
.__GetNextHexNumber
():
1647 raise Warning("expected address", self
.FileName
, self
.CurrentLineNumber
)
1649 BsAddress
= long(self
.__Token
, 0)
1650 Obj
.BsBaseAddress
= BsAddress
1652 if self
.__IsKeyword
("RtBaseAddress"):
1653 if not self
.__IsToken
( "="):
1654 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1656 if not self
.__GetNextDecimalNumber
() and not self
.__GetNextHexNumber
():
1657 raise Warning("expected address", self
.FileName
, self
.CurrentLineNumber
)
1659 RtAddress
= long(self
.__Token
, 0)
1660 Obj
.RtBaseAddress
= RtAddress
1662 ## __GetBlockStatements() method
1664 # Get block statements
1666 # @param self The object pointer
1667 # @param Obj for whom block statement is got
1669 def __GetBlockStatements(self
, Obj
):
1671 while self
.__GetBlockStatement
(Obj
):
1674 Item
= Obj
.BlockSizeList
[-1]
1675 if Item
[0] == None or Item
[1] == None:
1676 raise Warning("expected block statement", self
.FileName
, self
.CurrentLineNumber
)
1679 ## __GetBlockStatement() method
1681 # Get block statement
1683 # @param self The object pointer
1684 # @param Obj for whom block statement is got
1685 # @retval True Successfully find
1686 # @retval False Not able to find
1688 def __GetBlockStatement(self
, Obj
):
1689 if not self
.__IsKeyword
( "BlockSize"):
1692 if not self
.__IsToken
( "="):
1693 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1695 if not self
.__GetNextHexNumber
() and not self
.__GetNextDecimalNumber
():
1696 raise Warning("expected Hex or Integer block size", self
.FileName
, self
.CurrentLineNumber
)
1698 BlockSize
= self
.__Token
1700 if self
.__IsToken
( "|"):
1701 PcdPair
= self
.__GetNextPcdName
()
1702 BlockSizePcd
= PcdPair
1703 self
.Profile
.PcdDict
[PcdPair
] = BlockSize
1704 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1705 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1706 BlockSize
= long(BlockSize
, 0)
1709 if self
.__IsKeyword
( "NumBlocks"):
1710 if not self
.__IsToken
( "="):
1711 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1713 if not self
.__GetNextDecimalNumber
() and not self
.__GetNextHexNumber
():
1714 raise Warning("expected block numbers", self
.FileName
, self
.CurrentLineNumber
)
1716 BlockNumber
= long(self
.__Token
, 0)
1718 Obj
.BlockSizeList
.append((BlockSize
, BlockNumber
, BlockSizePcd
))
1721 ## __GetDefineStatements() method
1723 # Get define statements
1725 # @param self The object pointer
1726 # @param Obj for whom define statement is got
1727 # @retval True Successfully find
1728 # @retval False Not able to find
1730 def __GetDefineStatements(self
, Obj
):
1731 while self
.__GetDefineStatement
( Obj
):
1734 ## __GetDefineStatement() method
1736 # Get define statement
1738 # @param self The object pointer
1739 # @param Obj for whom define statement is got
1740 # @retval True Successfully find
1741 # @retval False Not able to find
1743 def __GetDefineStatement(self
, Obj
):
1744 if self
.__IsKeyword
("DEFINE"):
1745 self
.__GetNextToken
()
1746 Macro
= self
.__Token
1747 if not self
.__IsToken
( "="):
1748 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1750 if not self
.__GetNextToken
():
1751 raise Warning("expected value", self
.FileName
, self
.CurrentLineNumber
)
1753 Value
= self
.__Token
1754 Macro
= '$(' + Macro
+ ')'
1755 Obj
.DefineVarDict
[Macro
] = Value
1760 ## __GetSetStatements() method
1762 # Get set statements
1764 # @param self The object pointer
1765 # @param Obj for whom set statement is got
1766 # @retval True Successfully find
1767 # @retval False Not able to find
1769 def __GetSetStatements(self
, Obj
):
1770 while self
.__GetSetStatement
(Obj
):
1773 ## __GetSetStatement() method
1777 # @param self The object pointer
1778 # @param Obj for whom set statement is got
1779 # @retval True Successfully find
1780 # @retval False Not able to find
1782 def __GetSetStatement(self
, Obj
):
1783 if self
.__IsKeyword
("SET"):
1784 PcdPair
= self
.__GetNextPcdName
()
1786 if not self
.__IsToken
( "="):
1787 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1789 Value
= self
.__GetExpression
()
1790 Value
= self
.__EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
1793 Obj
.SetVarDict
[PcdPair
] = Value
1794 self
.Profile
.PcdDict
[PcdPair
] = Value
1795 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1796 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1801 ## __CalcRegionExpr(self)
1803 # Calculate expression for offset or size of a region
1805 # @return: None if invalid expression
1806 # Calculated number if successfully
1808 def __CalcRegionExpr(self
):
1809 StartPos
= self
.GetFileBufferPos()
1812 while not self
.__EndOfFile
():
1813 CurCh
= self
.__CurrentChar
()
1819 if CurCh
in '|\r\n' and PairCount
== 0:
1825 ValueExpression(Expr
,
1826 self
.__CollectMacroPcd
()
1829 self
.SetFileBufferPos(StartPos
)
1832 ## __GetRegionLayout() method
1834 # Get region layout for FD
1836 # @param self The object pointer
1837 # @param Fd for whom region is got
1838 # @retval True Successfully find
1839 # @retval False Not able to find
1841 def __GetRegionLayout(self
, Fd
):
1842 Offset
= self
.__CalcRegionExpr
()
1846 RegionObj
= Region
.Region()
1847 RegionObj
.Offset
= Offset
1848 Fd
.RegionList
.append(RegionObj
)
1850 if not self
.__IsToken
( "|"):
1851 raise Warning("expected '|'", self
.FileName
, self
.CurrentLineNumber
)
1853 Size
= self
.__CalcRegionExpr
()
1855 raise Warning("expected Region Size", self
.FileName
, self
.CurrentLineNumber
)
1856 RegionObj
.Size
= Size
1858 if not self
.__GetNextWord
():
1861 if not self
.__Token
in ("SET", "FV", "FILE", "DATA", "CAPSULE", "INF"):
1863 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]
1864 # Or it might be next region's offset described by an expression which starts with a PCD.
1865 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size
1868 IsRegionPcd
= (RegionSizeGuidPattern
.match(self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
:]) or
1869 RegionOffsetPcdPattern
.match(self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
:]))
1871 RegionObj
.PcdOffset
= self
.__GetNextPcdName
()
1872 self
.Profile
.PcdDict
[RegionObj
.PcdOffset
] = "0x%08X" % (RegionObj
.Offset
+ long(Fd
.BaseAddress
, 0))
1873 self
.__PcdDict
['%s.%s' % (RegionObj
.PcdOffset
[1], RegionObj
.PcdOffset
[0])] = "0x%x" % RegionObj
.Offset
1874 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1875 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdOffset
] = FileLineTuple
1876 if self
.__IsToken
( "|"):
1877 RegionObj
.PcdSize
= self
.__GetNextPcdName
()
1878 self
.Profile
.PcdDict
[RegionObj
.PcdSize
] = "0x%08X" % RegionObj
.Size
1879 self
.__PcdDict
['%s.%s' % (RegionObj
.PcdSize
[1], RegionObj
.PcdSize
[0])] = "0x%x" % RegionObj
.Size
1880 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1881 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdSize
] = FileLineTuple
1883 if not self
.__GetNextWord
():
1886 if self
.__Token
== "SET":
1888 self
.__GetSetStatements
( RegionObj
)
1889 if not self
.__GetNextWord
():
1892 elif self
.__Token
== "FV":
1894 self
.__GetRegionFvType
( RegionObj
)
1896 elif self
.__Token
== "CAPSULE":
1898 self
.__GetRegionCapType
( RegionObj
)
1900 elif self
.__Token
== "FILE":
1902 self
.__GetRegionFileType
(RegionObj
)
1904 elif self
.__Token
== "INF":
1906 RegionObj
.RegionType
= "INF"
1907 while self
.__IsKeyword
("INF"):
1909 ffsInf
= self
.__ParseInfStatement
()
1912 RegionObj
.RegionDataList
.append(ffsInf
)
1914 elif self
.__Token
== "DATA":
1916 self
.__GetRegionDataType
(RegionObj
)
1919 if self
.__GetRegionLayout
(Fd
):
1921 raise Warning("A valid region type was not found. "
1922 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
1923 self
.FileName
, self
.CurrentLineNumber
)
1927 ## __GetRegionFvType() method
1929 # Get region fv data for region
1931 # @param self The object pointer
1932 # @param RegionObj for whom region data is got
1934 def __GetRegionFvType(self
, RegionObj
):
1936 if not self
.__IsKeyword
( "FV"):
1937 raise Warning("expected Keyword 'FV'", self
.FileName
, self
.CurrentLineNumber
)
1939 if not self
.__IsToken
( "="):
1940 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1942 if not self
.__GetNextToken
():
1943 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
1945 RegionObj
.RegionType
= "FV"
1946 RegionObj
.RegionDataList
.append((self
.__Token
).upper())
1948 while self
.__IsKeyword
( "FV"):
1950 if not self
.__IsToken
( "="):
1951 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1953 if not self
.__GetNextToken
():
1954 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
1956 RegionObj
.RegionDataList
.append((self
.__Token
).upper())
1958 ## __GetRegionCapType() method
1960 # Get region capsule data for region
1962 # @param self The object pointer
1963 # @param RegionObj for whom region data is got
1965 def __GetRegionCapType(self
, RegionObj
):
1967 if not self
.__IsKeyword
("CAPSULE"):
1968 raise Warning("expected Keyword 'CAPSULE'", self
.FileName
, self
.CurrentLineNumber
)
1970 if not self
.__IsToken
("="):
1971 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1973 if not self
.__GetNextToken
():
1974 raise Warning("expected CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1976 RegionObj
.RegionType
= "CAPSULE"
1977 RegionObj
.RegionDataList
.append(self
.__Token
)
1979 while self
.__IsKeyword
("CAPSULE"):
1981 if not self
.__IsToken
("="):
1982 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1984 if not self
.__GetNextToken
():
1985 raise Warning("expected CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1987 RegionObj
.RegionDataList
.append(self
.__Token
)
1989 ## __GetRegionFileType() method
1991 # Get region file data for region
1993 # @param self The object pointer
1994 # @param RegionObj for whom region data is got
1996 def __GetRegionFileType(self
, RegionObj
):
1998 if not self
.__IsKeyword
( "FILE"):
1999 raise Warning("expected Keyword 'FILE'", self
.FileName
, self
.CurrentLineNumber
)
2001 if not self
.__IsToken
( "="):
2002 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2004 if not self
.__GetNextToken
():
2005 raise Warning("expected File name", self
.FileName
, self
.CurrentLineNumber
)
2007 RegionObj
.RegionType
= "FILE"
2008 RegionObj
.RegionDataList
.append( self
.__Token
)
2010 while self
.__IsKeyword
( "FILE"):
2012 if not self
.__IsToken
( "="):
2013 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2015 if not self
.__GetNextToken
():
2016 raise Warning("expected FILE name", self
.FileName
, self
.CurrentLineNumber
)
2018 RegionObj
.RegionDataList
.append(self
.__Token
)
2020 ## __GetRegionDataType() method
2022 # Get region array data for region
2024 # @param self The object pointer
2025 # @param RegionObj for whom region data is got
2027 def __GetRegionDataType(self
, RegionObj
):
2029 if not self
.__IsKeyword
( "DATA"):
2030 raise Warning("expected Region Data type", self
.FileName
, self
.CurrentLineNumber
)
2032 if not self
.__IsToken
( "="):
2033 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2035 if not self
.__IsToken
( "{"):
2036 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2038 if not self
.__GetNextHexNumber
():
2039 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2041 if len(self
.__Token
) > 18:
2042 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2044 # convert hex string value to byte hex string array
2045 AllString
= self
.__Token
2046 AllStrLen
= len (AllString
)
2048 while AllStrLen
> 4:
2049 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + ","
2050 AllStrLen
= AllStrLen
- 2
2051 DataString
= DataString
+ AllString
[:AllStrLen
] + ","
2054 if len (self
.__Token
) <= 4:
2055 while self
.__IsToken
(","):
2056 if not self
.__GetNextHexNumber
():
2057 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2058 if len(self
.__Token
) > 4:
2059 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2060 DataString
+= self
.__Token
2063 if not self
.__IsToken
( "}"):
2064 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2066 DataString
= DataString
.rstrip(",")
2067 RegionObj
.RegionType
= "DATA"
2068 RegionObj
.RegionDataList
.append( DataString
)
2070 while self
.__IsKeyword
( "DATA"):
2072 if not self
.__IsToken
( "="):
2073 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2075 if not self
.__IsToken
( "{"):
2076 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2078 if not self
.__GetNextHexNumber
():
2079 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2081 if len(self
.__Token
) > 18:
2082 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2084 # convert hex string value to byte hex string array
2085 AllString
= self
.__Token
2086 AllStrLen
= len (AllString
)
2088 while AllStrLen
> 4:
2089 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + ","
2090 AllStrLen
= AllStrLen
- 2
2091 DataString
= DataString
+ AllString
[:AllStrLen
] + ","
2094 if len (self
.__Token
) <= 4:
2095 while self
.__IsToken
(","):
2096 if not self
.__GetNextHexNumber
():
2097 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2098 if len(self
.__Token
) > 4:
2099 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2100 DataString
+= self
.__Token
2103 if not self
.__IsToken
( "}"):
2104 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2106 DataString
= DataString
.rstrip(",")
2107 RegionObj
.RegionDataList
.append( DataString
)
2111 # Get FV section contents and store its data into FV dictionary of self.Profile
2113 # @param self The object pointer
2114 # @retval True Successfully find a FV
2115 # @retval False Not able to find a FV
2118 if not self
.__GetNextToken
():
2121 S
= self
.__Token
.upper()
2122 if S
.startswith("[") and not S
.startswith("[FV."):
2123 self
.SectionParser(S
)
2128 if not self
.__IsToken
("[FV.", True):
2129 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2130 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2131 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2132 raise Warning("Unknown Keyword '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2134 FvName
= self
.__GetUiName
()
2135 self
.CurrentFvName
= FvName
.upper()
2137 if not self
.__IsToken
( "]"):
2138 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
2141 FvObj
.UiFvName
= self
.CurrentFvName
2142 self
.Profile
.FvDict
[self
.CurrentFvName
] = FvObj
2144 Status
= self
.__GetCreateFile
(FvObj
)
2146 raise Warning("FV name error", self
.FileName
, self
.CurrentLineNumber
)
2148 self
.__GetDefineStatements
(FvObj
)
2150 self
.__GetAddressStatements
(FvObj
)
2152 FvObj
.FvExtEntryTypeValue
= []
2153 FvObj
.FvExtEntryType
= []
2154 FvObj
.FvExtEntryData
= []
2156 self
.__GetSetStatements
(FvObj
)
2158 if not (self
.__GetBlockStatement
(FvObj
) or self
.__GetFvBaseAddress
(FvObj
) or
2159 self
.__GetFvForceRebase
(FvObj
) or self
.__GetFvAlignment
(FvObj
) or
2160 self
.__GetFvAttributes
(FvObj
) or self
.__GetFvNameGuid
(FvObj
) or
2161 self
.__GetFvExtEntryStatement
(FvObj
) or self
.__GetFvNameString
(FvObj
)):
2164 if FvObj
.FvNameString
== 'TRUE' and not FvObj
.FvNameGuid
:
2165 raise Warning("FvNameString found but FvNameGuid was not found", self
.FileName
, self
.CurrentLineNumber
)
2167 self
.__GetAprioriSection
(FvObj
, FvObj
.DefineVarDict
.copy())
2168 self
.__GetAprioriSection
(FvObj
, FvObj
.DefineVarDict
.copy())
2171 isInf
= self
.__GetInfStatement
(FvObj
, MacroDict
= FvObj
.DefineVarDict
.copy())
2172 isFile
= self
.__GetFileStatement
(FvObj
, MacroDict
= FvObj
.DefineVarDict
.copy())
2173 if not isInf
and not isFile
:
2178 ## __GetFvAlignment() method
2180 # Get alignment for FV
2182 # @param self The object pointer
2183 # @param Obj for whom alignment is got
2184 # @retval True Successfully find a alignment statement
2185 # @retval False Not able to find a alignment statement
2187 def __GetFvAlignment(self
, Obj
):
2189 if not self
.__IsKeyword
( "FvAlignment"):
2192 if not self
.__IsToken
( "="):
2193 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2195 if not self
.__GetNextToken
():
2196 raise Warning("expected alignment value", self
.FileName
, self
.CurrentLineNumber
)
2198 if self
.__Token
.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
2199 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
2200 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
2202 raise Warning("Unknown alignment value '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2203 Obj
.FvAlignment
= self
.__Token
2206 ## __GetFvBaseAddress() method
2208 # Get BaseAddress for FV
2210 # @param self The object pointer
2211 # @param Obj for whom FvBaseAddress is got
2212 # @retval True Successfully find a FvBaseAddress statement
2213 # @retval False Not able to find a FvBaseAddress statement
2215 def __GetFvBaseAddress(self
, Obj
):
2217 if not self
.__IsKeyword
("FvBaseAddress"):
2220 if not self
.__IsToken
( "="):
2221 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2223 if not self
.__GetNextToken
():
2224 raise Warning("expected FV base address value", self
.FileName
, self
.CurrentLineNumber
)
2226 IsValidBaseAddrValue
= re
.compile('^0[x|X][0-9a-fA-F]+')
2228 if not IsValidBaseAddrValue
.match(self
.__Token
.upper()):
2229 raise Warning("Unknown FV base address value '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2230 Obj
.FvBaseAddress
= self
.__Token
2233 ## __GetFvForceRebase() method
2235 # Get FvForceRebase for FV
2237 # @param self The object pointer
2238 # @param Obj for whom FvForceRebase is got
2239 # @retval True Successfully find a FvForceRebase statement
2240 # @retval False Not able to find a FvForceRebase statement
2242 def __GetFvForceRebase(self
, Obj
):
2244 if not self
.__IsKeyword
("FvForceRebase"):
2247 if not self
.__IsToken
( "="):
2248 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2250 if not self
.__GetNextToken
():
2251 raise Warning("expected FvForceRebase value", self
.FileName
, self
.CurrentLineNumber
)
2253 if self
.__Token
.upper() not in ["TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"]:
2254 raise Warning("Unknown FvForceRebase value '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2256 if self
.__Token
.upper() in ["TRUE", "1", "0X1", "0X01"]:
2257 Obj
.FvForceRebase
= True
2258 elif self
.__Token
.upper() in ["FALSE", "0", "0X0", "0X00"]:
2259 Obj
.FvForceRebase
= False
2261 Obj
.FvForceRebase
= None
2266 ## __GetFvAttributes() method
2268 # Get attributes for FV
2270 # @param self The object pointer
2271 # @param Obj for whom attribute is got
2274 def __GetFvAttributes(self
, FvObj
):
2276 while self
.__GetNextWord
():
2279 if name
not in ("ERASE_POLARITY", "MEMORY_MAPPED", \
2280 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
2281 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
2282 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
2283 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
2284 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT"):
2288 if not self
.__IsToken
( "="):
2289 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2291 if not self
.__GetNextToken
() or self
.__Token
.upper() not in ("TRUE", "FALSE", "1", "0"):
2292 raise Warning("expected TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
2294 FvObj
.FvAttributeDict
[name
] = self
.__Token
2298 ## __GetFvNameGuid() method
2300 # Get FV GUID for FV
2302 # @param self The object pointer
2303 # @param Obj for whom GUID is got
2306 def __GetFvNameGuid(self
, FvObj
):
2308 if not self
.__IsKeyword
( "FvNameGuid"):
2311 if not self
.__IsToken
( "="):
2312 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2314 if not self
.__GetNextGuid
():
2315 raise Warning("expected FV GUID value", self
.FileName
, self
.CurrentLineNumber
)
2317 FvObj
.FvNameGuid
= self
.__Token
2321 def __GetFvNameString(self
, FvObj
):
2323 if not self
.__IsKeyword
( "FvNameString"):
2326 if not self
.__IsToken
( "="):
2327 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2329 if not self
.__GetNextToken
() or self
.__Token
not in ('TRUE', 'FALSE'):
2330 raise Warning("expected TRUE or FALSE for FvNameString", self
.FileName
, self
.CurrentLineNumber
)
2332 FvObj
.FvNameString
= self
.__Token
2336 def __GetFvExtEntryStatement(self
, FvObj
):
2338 if not self
.__IsKeyword
( "FV_EXT_ENTRY"):
2341 if not self
.__IsKeyword
("TYPE"):
2342 raise Warning("expected 'TYPE'", self
.FileName
, self
.CurrentLineNumber
)
2344 if not self
.__IsToken
( "="):
2345 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2347 if not self
.__GetNextHexNumber
() and not self
.__GetNextDecimalNumber
():
2348 raise Warning("expected Hex FV extension entry type value At Line ", self
.FileName
, self
.CurrentLineNumber
)
2350 FvObj
.FvExtEntryTypeValue
+= [self
.__Token
]
2352 if not self
.__IsToken
( "{"):
2353 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2355 if not self
.__IsKeyword
("FILE") and not self
.__IsKeyword
("DATA"):
2356 raise Warning("expected 'FILE' or 'DATA'", self
.FileName
, self
.CurrentLineNumber
)
2358 FvObj
.FvExtEntryType
+= [self
.__Token
]
2360 if self
.__Token
== 'DATA':
2362 if not self
.__IsToken
( "="):
2363 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2365 if not self
.__IsToken
( "{"):
2366 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2368 if not self
.__GetNextHexNumber
():
2369 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2371 if len(self
.__Token
) > 4:
2372 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2374 DataString
= self
.__Token
2377 while self
.__IsToken
(","):
2378 if not self
.__GetNextHexNumber
():
2379 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2380 if len(self
.__Token
) > 4:
2381 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2382 DataString
+= self
.__Token
2385 if not self
.__IsToken
( "}"):
2386 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2388 if not self
.__IsToken
( "}"):
2389 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2391 DataString
= DataString
.rstrip(",")
2392 FvObj
.FvExtEntryData
+= [DataString
]
2394 if self
.__Token
== 'FILE':
2396 if not self
.__IsToken
( "="):
2397 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2399 if not self
.__GetNextToken
():
2400 raise Warning("expected FV Extension Entry file path At Line ", self
.FileName
, self
.CurrentLineNumber
)
2402 FvObj
.FvExtEntryData
+= [self
.__Token
]
2404 if not self
.__IsToken
( "}"):
2405 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2409 ## __GetAprioriSection() method
2411 # Get token statements
2413 # @param self The object pointer
2414 # @param FvObj for whom apriori is got
2415 # @param MacroDict dictionary used to replace macro
2416 # @retval True Successfully find apriori statement
2417 # @retval False Not able to find apriori statement
2419 def __GetAprioriSection(self
, FvObj
, MacroDict
= {}):
2421 if not self
.__IsKeyword
( "APRIORI"):
2424 if not self
.__IsKeyword
("PEI") and not self
.__IsKeyword
("DXE"):
2425 raise Warning("expected Apriori file type", self
.FileName
, self
.CurrentLineNumber
)
2426 AprType
= self
.__Token
2428 if not self
.__IsToken
( "{"):
2429 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2431 AprSectionObj
= AprioriSection
.AprioriSection()
2432 AprSectionObj
.AprioriType
= AprType
2434 self
.__GetDefineStatements
(AprSectionObj
)
2435 MacroDict
.update(AprSectionObj
.DefineVarDict
)
2438 IsInf
= self
.__GetInfStatement
( AprSectionObj
, MacroDict
= MacroDict
)
2439 IsFile
= self
.__GetFileStatement
( AprSectionObj
)
2440 if not IsInf
and not IsFile
:
2443 if not self
.__IsToken
( "}"):
2444 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2446 FvObj
.AprioriSectionList
.append(AprSectionObj
)
2449 def __ParseInfStatement(self
):
2450 if not self
.__IsKeyword
("INF"):
2453 ffsInf
= FfsInfStatement
.FfsInfStatement()
2454 self
.__GetInfOptions
(ffsInf
)
2456 if not self
.__GetNextToken
():
2457 raise Warning("expected INF file path", self
.FileName
, self
.CurrentLineNumber
)
2458 ffsInf
.InfFileName
= self
.__Token
2460 ffsInf
.CurrentLineNum
= self
.CurrentLineNumber
2461 ffsInf
.CurrentLineContent
= self
.__CurrentLine
()
2463 #Replace $(SAPCE) with real space
2464 ffsInf
.InfFileName
= ffsInf
.InfFileName
.replace('$(SPACE)', ' ')
2466 if ffsInf
.InfFileName
.replace('$(WORKSPACE)', '').find('$') == -1:
2467 #do case sensitive check for file path
2468 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2470 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2472 if not ffsInf
.InfFileName
in self
.Profile
.InfList
:
2473 self
.Profile
.InfList
.append(ffsInf
.InfFileName
)
2474 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2475 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
2477 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
2478 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
2480 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
2482 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
2484 if self
.__IsToken
('|'):
2485 if self
.__IsKeyword
('RELOCS_STRIPPED'):
2486 ffsInf
.KeepReloc
= False
2487 elif self
.__IsKeyword
('RELOCS_RETAINED'):
2488 ffsInf
.KeepReloc
= True
2490 raise Warning("Unknown reloc strip flag '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2493 ## __GetInfStatement() method
2495 # Get INF statements
2497 # @param self The object pointer
2498 # @param Obj for whom inf statement is got
2499 # @param MacroDict dictionary used to replace macro
2500 # @retval True Successfully find inf statement
2501 # @retval False Not able to find inf statement
2503 def __GetInfStatement(self
, Obj
, ForCapsule
=False, MacroDict
={}):
2504 ffsInf
= self
.__ParseInfStatement
()
2509 capsuleFfs
= CapsuleData
.CapsuleFfs()
2510 capsuleFfs
.Ffs
= ffsInf
2511 Obj
.CapsuleDataList
.append(capsuleFfs
)
2513 Obj
.FfsList
.append(ffsInf
)
2516 ## __GetInfOptions() method
2518 # Get options for INF
2520 # @param self The object pointer
2521 # @param FfsInfObj for whom option is got
2523 def __GetInfOptions(self
, FfsInfObj
):
2524 if self
.__IsKeyword
("FILE_GUID"):
2525 if not self
.__IsToken
("="):
2526 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2527 if not self
.__GetNextGuid
():
2528 raise Warning("expected GUID value", self
.FileName
, self
.CurrentLineNumber
)
2529 FfsInfObj
.OverrideGuid
= self
.__Token
2531 if self
.__IsKeyword
( "RuleOverride"):
2532 if not self
.__IsToken
( "="):
2533 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2534 if not self
.__GetNextToken
():
2535 raise Warning("expected Rule name", self
.FileName
, self
.CurrentLineNumber
)
2536 FfsInfObj
.Rule
= self
.__Token
2538 if self
.__IsKeyword
( "VERSION"):
2539 if not self
.__IsToken
( "="):
2540 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2541 if not self
.__GetNextToken
():
2542 raise Warning("expected Version", self
.FileName
, self
.CurrentLineNumber
)
2544 if self
.__GetStringData
():
2545 FfsInfObj
.Version
= self
.__Token
2547 if self
.__IsKeyword
( "UI"):
2548 if not self
.__IsToken
( "="):
2549 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2550 if not self
.__GetNextToken
():
2551 raise Warning("expected UI name", self
.FileName
, self
.CurrentLineNumber
)
2553 if self
.__GetStringData
():
2554 FfsInfObj
.Ui
= self
.__Token
2556 if self
.__IsKeyword
( "USE"):
2557 if not self
.__IsToken
( "="):
2558 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2559 if not self
.__GetNextToken
():
2560 raise Warning("expected ARCH name", self
.FileName
, self
.CurrentLineNumber
)
2561 FfsInfObj
.UseArch
= self
.__Token
2564 if self
.__GetNextToken
():
2565 p
= re
.compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
2566 if p
.match(self
.__Token
) and p
.match(self
.__Token
).span()[1] == len(self
.__Token
):
2567 FfsInfObj
.KeyStringList
.append(self
.__Token
)
2568 if not self
.__IsToken
(","):
2574 while self
.__GetNextToken
():
2575 if not p
.match(self
.__Token
):
2576 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2577 FfsInfObj
.KeyStringList
.append(self
.__Token
)
2579 if not self
.__IsToken
(","):
2582 ## __GetFileStatement() method
2584 # Get FILE statements
2586 # @param self The object pointer
2587 # @param Obj for whom FILE statement is got
2588 # @param MacroDict dictionary used to replace macro
2589 # @retval True Successfully find FILE statement
2590 # @retval False Not able to find FILE statement
2592 def __GetFileStatement(self
, Obj
, ForCapsule
= False, MacroDict
= {}):
2594 if not self
.__IsKeyword
( "FILE"):
2597 if not self
.__GetNextWord
():
2598 raise Warning("expected FFS type", self
.FileName
, self
.CurrentLineNumber
)
2600 if ForCapsule
and self
.__Token
== 'DATA':
2605 FfsFileObj
= FfsFileStatement
.FileStatement()
2606 FfsFileObj
.FvFileType
= self
.__Token
2608 if not self
.__IsToken
( "="):
2609 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2611 if not self
.__GetNextGuid
():
2612 if not self
.__GetNextWord
():
2613 raise Warning("expected File GUID", self
.FileName
, self
.CurrentLineNumber
)
2614 if self
.__Token
== 'PCD':
2615 if not self
.__IsToken
( "("):
2616 raise Warning("expected '('", self
.FileName
, self
.CurrentLineNumber
)
2617 PcdPair
= self
.__GetNextPcdName
()
2618 if not self
.__IsToken
( ")"):
2619 raise Warning("expected ')'", self
.FileName
, self
.CurrentLineNumber
)
2620 self
.__Token
= 'PCD('+PcdPair
[1]+'.'+PcdPair
[0]+')'
2622 FfsFileObj
.NameGuid
= self
.__Token
2624 self
.__GetFilePart
( FfsFileObj
, MacroDict
.copy())
2627 capsuleFfs
= CapsuleData
.CapsuleFfs()
2628 capsuleFfs
.Ffs
= FfsFileObj
2629 Obj
.CapsuleDataList
.append(capsuleFfs
)
2631 Obj
.FfsList
.append(FfsFileObj
)
2635 ## __FileCouldHaveRelocFlag() method
2637 # Check whether reloc strip flag can be set for a file type.
2639 # @param self The object pointer
2640 # @param FileType The file type to check with
2641 # @retval True This type could have relocation strip flag
2642 # @retval False No way to have it
2645 def __FileCouldHaveRelocFlag (self
, FileType
):
2646 if FileType
in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'):
2651 ## __SectionCouldHaveRelocFlag() method
2653 # Check whether reloc strip flag can be set for a section type.
2655 # @param self The object pointer
2656 # @param SectionType The section type to check with
2657 # @retval True This type could have relocation strip flag
2658 # @retval False No way to have it
2661 def __SectionCouldHaveRelocFlag (self
, SectionType
):
2662 if SectionType
in ('TE', 'PE32'):
2667 ## __GetFilePart() method
2669 # Get components for FILE statement
2671 # @param self The object pointer
2672 # @param FfsFileObj for whom component is got
2673 # @param MacroDict dictionary used to replace macro
2675 def __GetFilePart(self
, FfsFileObj
, MacroDict
= {}):
2677 self
.__GetFileOpts
( FfsFileObj
)
2679 if not self
.__IsToken
("{"):
2680 if self
.__IsKeyword
('RELOCS_STRIPPED') or self
.__IsKeyword
('RELOCS_RETAINED'):
2681 if self
.__FileCouldHaveRelocFlag
(FfsFileObj
.FvFileType
):
2682 if self
.__Token
== 'RELOCS_STRIPPED':
2683 FfsFileObj
.KeepReloc
= False
2685 FfsFileObj
.KeepReloc
= True
2687 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj
.FvFileType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
2689 if not self
.__IsToken
("{"):
2690 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2692 if not self
.__GetNextToken
():
2693 raise Warning("expected File name or section data", self
.FileName
, self
.CurrentLineNumber
)
2695 if self
.__Token
== "FV":
2696 if not self
.__IsToken
( "="):
2697 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2698 if not self
.__GetNextToken
():
2699 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
2700 FfsFileObj
.FvName
= self
.__Token
2702 elif self
.__Token
== "FD":
2703 if not self
.__IsToken
( "="):
2704 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2705 if not self
.__GetNextToken
():
2706 raise Warning("expected FD name", self
.FileName
, self
.CurrentLineNumber
)
2707 FfsFileObj
.FdName
= self
.__Token
2709 elif self
.__Token
in ("DEFINE", "APRIORI", "SECTION"):
2711 self
.__GetSectionData
( FfsFileObj
, MacroDict
)
2713 elif hasattr(FfsFileObj
, 'FvFileType') and FfsFileObj
.FvFileType
== 'RAW':
2715 self
.__GetRAWData
(FfsFileObj
, MacroDict
)
2718 FfsFileObj
.CurrentLineNum
= self
.CurrentLineNumber
2719 FfsFileObj
.CurrentLineContent
= self
.__CurrentLine
()
2720 FfsFileObj
.FileName
= self
.__Token
.replace('$(SPACE)', ' ')
2721 self
.__VerifyFile
(FfsFileObj
.FileName
)
2723 if not self
.__IsToken
( "}"):
2724 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2726 ## __GetRAWData() method
2728 # Get RAW data for FILE statement
2730 # @param self The object pointer
2731 # @param FfsFileObj for whom section is got
2732 # @param MacroDict dictionary used to replace macro
2734 def __GetRAWData(self
, FfsFileObj
, MacroDict
= {}):
2735 FfsFileObj
.FileName
= []
2736 FfsFileObj
.SubAlignment
= []
2739 if self
.__GetAlignment
():
2740 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2741 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2742 AlignValue
= self
.__Token
2743 if not self
.__GetNextToken
():
2744 raise Warning("expected Filename value", self
.FileName
, self
.CurrentLineNumber
)
2746 FileName
= self
.__Token
.replace('$(SPACE)', ' ')
2749 raise Warning("expected Filename value", self
.FileName
, self
.CurrentLineNumber
)
2751 self
.__VerifyFile
(FileName
)
2752 File
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
)
2753 FfsFileObj
.FileName
.append(File
.Path
)
2754 FfsFileObj
.SubAlignment
.append(AlignValue
)
2756 if self
.__IsToken
( "}"):
2760 if len(FfsFileObj
.SubAlignment
) == 1:
2761 FfsFileObj
.SubAlignment
= FfsFileObj
.SubAlignment
[0]
2762 if len(FfsFileObj
.FileName
) == 1:
2763 FfsFileObj
.FileName
= FfsFileObj
.FileName
[0]
2765 ## __GetFileOpts() method
2767 # Get options for FILE statement
2769 # @param self The object pointer
2770 # @param FfsFileObj for whom options is got
2772 def __GetFileOpts(self
, FfsFileObj
):
2774 if self
.__GetNextToken
():
2775 Pattern
= re
.compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
2776 if Pattern
.match(self
.__Token
):
2777 FfsFileObj
.KeyStringList
.append(self
.__Token
)
2778 if self
.__IsToken
(","):
2779 while self
.__GetNextToken
():
2780 if not Pattern
.match(self
.__Token
):
2781 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2782 FfsFileObj
.KeyStringList
.append(self
.__Token
)
2784 if not self
.__IsToken
(","):
2790 if self
.__IsKeyword
( "FIXED", True):
2791 FfsFileObj
.Fixed
= True
2793 if self
.__IsKeyword
( "CHECKSUM", True):
2794 FfsFileObj
.CheckSum
= True
2796 if self
.__GetAlignment
():
2797 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2798 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2799 #For FFS, Auto is default option same to ""
2800 if not self
.__Token
== "Auto":
2801 FfsFileObj
.Alignment
= self
.__Token
2803 ## __GetAlignment() method
2805 # Return the alignment value
2807 # @param self The object pointer
2808 # @retval True Successfully find alignment
2809 # @retval False Not able to find alignment
2811 def __GetAlignment(self
):
2812 if self
.__IsKeyword
( "Align", True):
2813 if not self
.__IsToken
( "="):
2814 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2816 if not self
.__GetNextToken
():
2817 raise Warning("expected alignment value", self
.FileName
, self
.CurrentLineNumber
)
2822 ## __GetFilePart() method
2824 # Get section data for FILE statement
2826 # @param self The object pointer
2827 # @param FfsFileObj for whom section is got
2828 # @param MacroDict dictionary used to replace macro
2830 def __GetSectionData(self
, FfsFileObj
, MacroDict
= {}):
2832 Dict
.update(MacroDict
)
2834 self
.__GetDefineStatements
(FfsFileObj
)
2836 Dict
.update(FfsFileObj
.DefineVarDict
)
2837 self
.__GetAprioriSection
(FfsFileObj
, Dict
.copy())
2838 self
.__GetAprioriSection
(FfsFileObj
, Dict
.copy())
2841 IsLeafSection
= self
.__GetLeafSection
(FfsFileObj
, Dict
)
2842 IsEncapSection
= self
.__GetEncapsulationSec
(FfsFileObj
)
2843 if not IsLeafSection
and not IsEncapSection
:
2846 ## __GetLeafSection() method
2848 # Get leaf section for Obj
2850 # @param self The object pointer
2851 # @param Obj for whom leaf section is got
2852 # @param MacroDict dictionary used to replace macro
2853 # @retval True Successfully find section statement
2854 # @retval False Not able to find section statement
2856 def __GetLeafSection(self
, Obj
, MacroDict
= {}):
2858 OldPos
= self
.GetFileBufferPos()
2860 if not self
.__IsKeyword
( "SECTION"):
2861 if len(Obj
.SectionList
) == 0:
2862 raise Warning("expected SECTION", self
.FileName
, self
.CurrentLineNumber
)
2867 if self
.__GetAlignment
():
2868 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2869 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2870 AlignValue
= self
.__Token
2873 if self
.__IsKeyword
( "BUILD_NUM"):
2874 if not self
.__IsToken
( "="):
2875 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2877 if not self
.__GetNextToken
():
2878 raise Warning("expected Build number value", self
.FileName
, self
.CurrentLineNumber
)
2880 BuildNum
= self
.__Token
2882 if self
.__IsKeyword
( "VERSION"):
2883 if AlignValue
== 'Auto':
2884 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2885 if not self
.__IsToken
( "="):
2886 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2887 if not self
.__GetNextToken
():
2888 raise Warning("expected version", self
.FileName
, self
.CurrentLineNumber
)
2889 VerSectionObj
= VerSection
.VerSection()
2890 VerSectionObj
.Alignment
= AlignValue
2891 VerSectionObj
.BuildNum
= BuildNum
2892 if self
.__GetStringData
():
2893 VerSectionObj
.StringData
= self
.__Token
2895 VerSectionObj
.FileName
= self
.__Token
2896 Obj
.SectionList
.append(VerSectionObj
)
2898 elif self
.__IsKeyword
( "UI"):
2899 if AlignValue
== 'Auto':
2900 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2901 if not self
.__IsToken
( "="):
2902 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2903 if not self
.__GetNextToken
():
2904 raise Warning("expected UI", self
.FileName
, self
.CurrentLineNumber
)
2905 UiSectionObj
= UiSection
.UiSection()
2906 UiSectionObj
.Alignment
= AlignValue
2907 if self
.__GetStringData
():
2908 UiSectionObj
.StringData
= self
.__Token
2910 UiSectionObj
.FileName
= self
.__Token
2911 Obj
.SectionList
.append(UiSectionObj
)
2913 elif self
.__IsKeyword
( "FV_IMAGE"):
2914 if AlignValue
== 'Auto':
2915 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2916 if not self
.__IsToken
( "="):
2917 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2918 if not self
.__GetNextToken
():
2919 raise Warning("expected FV name or FV file path", self
.FileName
, self
.CurrentLineNumber
)
2921 FvName
= self
.__Token
2924 if self
.__IsToken
( "{"):
2926 FvObj
.UiFvName
= FvName
.upper()
2927 self
.__GetDefineStatements
(FvObj
)
2928 MacroDict
.update(FvObj
.DefineVarDict
)
2929 self
.__GetBlockStatement
(FvObj
)
2930 self
.__GetSetStatements
(FvObj
)
2931 self
.__GetFvAlignment
(FvObj
)
2932 self
.__GetFvAttributes
(FvObj
)
2933 self
.__GetAprioriSection
(FvObj
, MacroDict
.copy())
2934 self
.__GetAprioriSection
(FvObj
, MacroDict
.copy())
2937 IsInf
= self
.__GetInfStatement
(FvObj
, MacroDict
.copy())
2938 IsFile
= self
.__GetFileStatement
(FvObj
, MacroDict
.copy())
2939 if not IsInf
and not IsFile
:
2942 if not self
.__IsToken
( "}"):
2943 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2945 FvImageSectionObj
= FvImageSection
.FvImageSection()
2946 FvImageSectionObj
.Alignment
= AlignValue
2948 FvImageSectionObj
.Fv
= FvObj
2949 FvImageSectionObj
.FvName
= None
2951 FvImageSectionObj
.FvName
= FvName
.upper()
2952 FvImageSectionObj
.FvFileName
= FvName
2954 Obj
.SectionList
.append(FvImageSectionObj
)
2956 elif self
.__IsKeyword
("PEI_DEPEX_EXP") or self
.__IsKeyword
("DXE_DEPEX_EXP") or self
.__IsKeyword
("SMM_DEPEX_EXP"):
2957 if AlignValue
== 'Auto':
2958 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2959 DepexSectionObj
= DepexSection
.DepexSection()
2960 DepexSectionObj
.Alignment
= AlignValue
2961 DepexSectionObj
.DepexType
= self
.__Token
2963 if not self
.__IsToken
( "="):
2964 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2965 if not self
.__IsToken
( "{"):
2966 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2967 if not self
.__SkipToToken
( "}"):
2968 raise Warning("expected Depex expression ending '}'", self
.FileName
, self
.CurrentLineNumber
)
2970 DepexSectionObj
.Expression
= self
.__SkippedChars
.rstrip('}')
2971 Obj
.SectionList
.append(DepexSectionObj
)
2974 if not self
.__GetNextWord
():
2975 raise Warning("expected section type", self
.FileName
, self
.CurrentLineNumber
)
2977 # Encapsulation section appear, UndoToken and return
2978 if self
.__Token
== "COMPRESS" or self
.__Token
== "GUIDED":
2979 self
.SetFileBufferPos(OldPos
)
2982 if self
.__Token
not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
2983 "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"):
2984 raise Warning("Unknown section type '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2985 if AlignValue
== 'Auto'and (not self
.__Token
== 'PE32') and (not self
.__Token
== 'TE'):
2986 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2989 DataSectionObj
= DataSection
.DataSection()
2990 DataSectionObj
.Alignment
= AlignValue
2991 DataSectionObj
.SecType
= self
.__Token
2993 if self
.__IsKeyword
('RELOCS_STRIPPED') or self
.__IsKeyword
('RELOCS_RETAINED'):
2994 if self
.__FileCouldHaveRelocFlag
(Obj
.FvFileType
) and self
.__SectionCouldHaveRelocFlag
(DataSectionObj
.SecType
):
2995 if self
.__Token
== 'RELOCS_STRIPPED':
2996 DataSectionObj
.KeepReloc
= False
2998 DataSectionObj
.KeepReloc
= True
3000 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
)
3002 if self
.__IsToken
("="):
3003 if not self
.__GetNextToken
():
3004 raise Warning("expected section file path", self
.FileName
, self
.CurrentLineNumber
)
3005 DataSectionObj
.SectFileName
= self
.__Token
3006 self
.__VerifyFile
(DataSectionObj
.SectFileName
)
3008 if not self
.__GetCglSection
(DataSectionObj
):
3011 Obj
.SectionList
.append(DataSectionObj
)
3017 # Check if file exists or not:
3018 # If current phase if GenFds, the file must exist;
3019 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist
3020 # @param FileName: File path to be verified.
3022 def __VerifyFile(self
, FileName
):
3023 if FileName
.replace('$(WORKSPACE)', '').find('$') != -1:
3025 if not GlobalData
.gAutoGenPhase
or not self
.__GetMacroValue
("OUTPUT_DIRECTORY") in FileName
:
3026 ErrorCode
, ErrorInfo
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
3028 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
3030 ## __GetCglSection() method
3032 # Get compressed or GUIDed section for Obj
3034 # @param self The object pointer
3035 # @param Obj for whom leaf section is got
3036 # @param AlignValue alignment value for complex section
3037 # @retval True Successfully find section statement
3038 # @retval False Not able to find section statement
3040 def __GetCglSection(self
, Obj
, AlignValue
= None):
3042 if self
.__IsKeyword
( "COMPRESS"):
3044 if self
.__IsKeyword
("PI_STD") or self
.__IsKeyword
("PI_NONE"):
3047 if not self
.__IsToken
("{"):
3048 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
3050 CompressSectionObj
= CompressSection
.CompressSection()
3051 CompressSectionObj
.Alignment
= AlignValue
3052 CompressSectionObj
.CompType
= type
3053 # Recursive sections...
3055 IsLeafSection
= self
.__GetLeafSection
(CompressSectionObj
)
3056 IsEncapSection
= self
.__GetEncapsulationSec
(CompressSectionObj
)
3057 if not IsLeafSection
and not IsEncapSection
:
3061 if not self
.__IsToken
( "}"):
3062 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
3063 Obj
.SectionList
.append(CompressSectionObj
)
3066 # raise Warning("Compress type not known")
3070 elif self
.__IsKeyword
( "GUIDED"):
3072 if self
.__GetNextGuid
():
3073 GuidValue
= self
.__Token
3075 AttribDict
= self
.__GetGuidAttrib
()
3076 if not self
.__IsToken
("{"):
3077 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
3078 GuidSectionObj
= GuidSection
.GuidSection()
3079 GuidSectionObj
.Alignment
= AlignValue
3080 GuidSectionObj
.NameGuid
= GuidValue
3081 GuidSectionObj
.SectionType
= "GUIDED"
3082 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
3083 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
3084 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
3085 # Recursive sections...
3087 IsLeafSection
= self
.__GetLeafSection
(GuidSectionObj
)
3088 IsEncapSection
= self
.__GetEncapsulationSec
(GuidSectionObj
)
3089 if not IsLeafSection
and not IsEncapSection
:
3092 if not self
.__IsToken
( "}"):
3093 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
3094 Obj
.SectionList
.append(GuidSectionObj
)
3100 ## __GetGuidAttri() method
3102 # Get attributes for GUID section
3104 # @param self The object pointer
3105 # @retval AttribDict Dictionary of key-value pair of section attributes
3107 def __GetGuidAttrib(self
):
3110 AttribDict
["PROCESSING_REQUIRED"] = "NONE"
3111 AttribDict
["AUTH_STATUS_VALID"] = "NONE"
3112 AttribDict
["EXTRA_HEADER_SIZE"] = -1
3113 while self
.__IsKeyword
("PROCESSING_REQUIRED") or self
.__IsKeyword
("AUTH_STATUS_VALID") \
3114 or self
.__IsKeyword
("EXTRA_HEADER_SIZE"):
3115 AttribKey
= self
.__Token
3117 if not self
.__IsToken
("="):
3118 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3120 if not self
.__GetNextToken
():
3121 raise Warning("expected TRUE(1)/FALSE(0)/Number", self
.FileName
, self
.CurrentLineNumber
)
3122 elif AttribKey
== "EXTRA_HEADER_SIZE":
3124 if self
.__Token
[0:2].upper() == "0X":
3127 AttribDict
[AttribKey
] = int(self
.__Token
, Base
)
3130 raise Warning("expected Number", self
.FileName
, self
.CurrentLineNumber
)
3131 elif self
.__Token
.upper() not in ("TRUE", "FALSE", "1", "0"):
3132 raise Warning("expected TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
3133 AttribDict
[AttribKey
] = self
.__Token
3137 ## __GetEncapsulationSec() method
3139 # Get encapsulation section for FILE
3141 # @param self The object pointer
3142 # @param FfsFile for whom section is got
3143 # @retval True Successfully find section statement
3144 # @retval False Not able to find section statement
3146 def __GetEncapsulationSec(self
, FfsFileObj
):
3148 OldPos
= self
.GetFileBufferPos()
3149 if not self
.__IsKeyword
( "SECTION"):
3150 if len(FfsFileObj
.SectionList
) == 0:
3151 raise Warning("expected SECTION", self
.FileName
, self
.CurrentLineNumber
)
3156 if self
.__GetAlignment
():
3157 if self
.__Token
not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3158 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3159 AlignValue
= self
.__Token
3161 if not self
.__GetCglSection
(FfsFileObj
, AlignValue
):
3162 self
.SetFileBufferPos(OldPos
)
3168 if not self
.__GetNextToken
():
3170 S
= self
.__Token
.upper()
3171 if S
.startswith("[") and not S
.startswith("[FMPPAYLOAD."):
3172 self
.SectionParser(S
)
3177 self
.__SkipToToken
("[FMPPAYLOAD.", True)
3178 FmpUiName
= self
.__GetUiName
().upper()
3179 if FmpUiName
in self
.Profile
.FmpPayloadDict
:
3180 raise Warning("Duplicated FMP UI name found: %s" % FmpUiName
, self
.FileName
, self
.CurrentLineNumber
)
3182 FmpData
= CapsuleData
.CapsulePayload()
3183 FmpData
.UiName
= FmpUiName
3185 if not self
.__IsToken
( "]"):
3186 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
3188 if not self
.__GetNextToken
():
3189 raise Warning("The FMP payload section is empty!", self
.FileName
, self
.CurrentLineNumber
)
3190 FmpKeyList
= ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE']
3191 while self
.__Token
in FmpKeyList
:
3193 FmpKeyList
.remove(Name
)
3194 if not self
.__IsToken
("="):
3195 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3196 if Name
== 'IMAGE_TYPE_ID':
3197 if not self
.__GetNextGuid
():
3198 raise Warning("expected GUID value for IMAGE_TYPE_ID", self
.FileName
, self
.CurrentLineNumber
)
3199 FmpData
.ImageTypeId
= self
.__Token
3201 if not self
.__GetNextToken
():
3202 raise Warning("expected value of %s" % Name
, self
.FileName
, self
.CurrentLineNumber
)
3203 Value
= self
.__Token
3204 if Name
== 'IMAGE_HEADER_INIT_VERSION':
3205 FmpData
.Version
= Value
3206 elif Name
== 'IMAGE_INDEX':
3207 FmpData
.ImageIndex
= Value
3208 elif Name
== 'HARDWARE_INSTANCE':
3209 FmpData
.HardwareInstance
= Value
3210 if not self
.__GetNextToken
():
3216 raise Warning("Missing keywords %s in FMP payload section" % ', '.join(FmpKeyList
), self
.FileName
, self
.CurrentLineNumber
)
3217 ImageFile
= self
.__ParseRawFileStatement
()
3219 raise Warning("Missing image file in FMP payload section", self
.FileName
, self
.CurrentLineNumber
)
3220 FmpData
.ImageFile
= ImageFile
3221 VendorCodeFile
= self
.__ParseRawFileStatement
()
3223 FmpData
.VendorCodeFile
= VendorCodeFile
3224 self
.Profile
.FmpPayloadDict
[FmpUiName
] = FmpData
3227 ## __GetCapsule() method
3229 # Get capsule section contents and store its data into capsule list of self.Profile
3231 # @param self The object pointer
3232 # @retval True Successfully find a capsule
3233 # @retval False Not able to find a capsule
3235 def __GetCapsule(self
):
3237 if not self
.__GetNextToken
():
3240 S
= self
.__Token
.upper()
3241 if S
.startswith("[") and not S
.startswith("[CAPSULE."):
3242 self
.SectionParser(S
)
3247 if not self
.__IsToken
("[CAPSULE.", True):
3248 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3249 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3250 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3251 raise Warning("expected [Capsule.]", self
.FileName
, self
.CurrentLineNumber
)
3253 CapsuleObj
= Capsule
.Capsule()
3255 CapsuleName
= self
.__GetUiName
()
3257 raise Warning("expected capsule name", self
.FileName
, self
.CurrentLineNumber
)
3259 CapsuleObj
.UiCapsuleName
= CapsuleName
.upper()
3261 if not self
.__IsToken
( "]"):
3262 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
3264 if self
.__IsKeyword
("CREATE_FILE"):
3265 if not self
.__IsToken
( "="):
3266 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3268 if not self
.__GetNextToken
():
3269 raise Warning("expected file name", self
.FileName
, self
.CurrentLineNumber
)
3271 CapsuleObj
.CreateFile
= self
.__Token
3273 self
.__GetCapsuleStatements
(CapsuleObj
)
3274 self
.Profile
.CapsuleDict
[CapsuleObj
.UiCapsuleName
] = CapsuleObj
3277 ## __GetCapsuleStatements() method
3279 # Get statements for capsule
3281 # @param self The object pointer
3282 # @param Obj for whom statements are got
3284 def __GetCapsuleStatements(self
, Obj
):
3285 self
.__GetCapsuleTokens
(Obj
)
3286 self
.__GetDefineStatements
(Obj
)
3287 self
.__GetSetStatements
(Obj
)
3288 self
.__GetCapsuleData
(Obj
)
3290 ## __GetCapsuleTokens() method
3292 # Get token statements for capsule
3294 # @param self The object pointer
3295 # @param Obj for whom token statements are got
3297 def __GetCapsuleTokens(self
, Obj
):
3298 if not self
.__GetNextToken
():
3300 while self
.__Token
in ("CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"):
3301 Name
= self
.__Token
.strip()
3302 if not self
.__IsToken
("="):
3303 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3304 if not self
.__GetNextToken
():
3305 raise Warning("expected value", self
.FileName
, self
.CurrentLineNumber
)
3306 if Name
== 'CAPSULE_FLAGS':
3307 if not self
.__Token
in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
3308 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3309 Value
= self
.__Token
.strip()
3310 while self
.__IsToken
(","):
3312 if not self
.__GetNextToken
():
3313 raise Warning("expected value", self
.FileName
, self
.CurrentLineNumber
)
3314 if not self
.__Token
in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
3315 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3316 Value
+= self
.__Token
.strip()
3317 elif Name
== 'OEM_CAPSULE_FLAGS':
3318 Value
= self
.__Token
.strip()
3319 if not Value
.upper().startswith('0X'):
3320 raise Warning("expected hex value between 0x0000 and 0xFFFF", self
.FileName
, self
.CurrentLineNumber
)
3322 Value
= int(Value
, 0)
3324 raise Warning("expected hex value between 0x0000 and 0xFFFF", self
.FileName
, self
.CurrentLineNumber
)
3325 if not 0x0000 <= Value
<= 0xFFFF:
3326 raise Warning("expected hex value between 0x0000 and 0xFFFF", self
.FileName
, self
.CurrentLineNumber
)
3327 Value
= self
.__Token
.strip()
3329 Value
= self
.__Token
.strip()
3330 Obj
.TokensDict
[Name
] = Value
3331 if not self
.__GetNextToken
():
3335 ## __GetCapsuleData() method
3337 # Get capsule data for capsule
3339 # @param self The object pointer
3340 # @param Obj for whom capsule data are got
3342 def __GetCapsuleData(self
, Obj
):
3345 IsInf
= self
.__GetInfStatement
(Obj
, True)
3346 IsFile
= self
.__GetFileStatement
(Obj
, True)
3347 IsFv
= self
.__GetFvStatement
(Obj
)
3348 IsFd
= self
.__GetFdStatement
(Obj
)
3349 IsAnyFile
= self
.__GetAnyFileStatement
(Obj
)
3350 IsAfile
= self
.__GetAfileStatement
(Obj
)
3351 IsFmp
= self
.__GetFmpStatement
(Obj
)
3352 if not (IsInf
or IsFile
or IsFv
or IsFd
or IsAnyFile
or IsAfile
or IsFmp
):
3355 ## __GetFvStatement() method
3357 # Get FV for capsule
3359 # @param self The object pointer
3360 # @param CapsuleObj for whom FV is got
3361 # @retval True Successfully find a FV statement
3362 # @retval False Not able to find a FV statement
3364 def __GetFvStatement(self
, CapsuleObj
):
3366 if not self
.__IsKeyword
("FV"):
3369 if not self
.__IsToken
("="):
3370 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3372 if not self
.__GetNextToken
():
3373 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
3375 if self
.__Token
.upper() not in self
.Profile
.FvDict
.keys():
3376 raise Warning("FV name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3378 CapsuleFv
= CapsuleData
.CapsuleFv()
3379 CapsuleFv
.FvName
= self
.__Token
3380 CapsuleObj
.CapsuleDataList
.append(CapsuleFv
)
3383 ## __GetFdStatement() method
3385 # Get FD for capsule
3387 # @param self The object pointer
3388 # @param CapsuleObj for whom FD is got
3389 # @retval True Successfully find a FD statement
3390 # @retval False Not able to find a FD statement
3392 def __GetFdStatement(self
, CapsuleObj
):
3394 if not self
.__IsKeyword
("FD"):
3397 if not self
.__IsToken
("="):
3398 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3400 if not self
.__GetNextToken
():
3401 raise Warning("expected FD name", self
.FileName
, self
.CurrentLineNumber
)
3403 if self
.__Token
.upper() not in self
.Profile
.FdDict
.keys():
3404 raise Warning("FD name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3406 CapsuleFd
= CapsuleData
.CapsuleFd()
3407 CapsuleFd
.FdName
= self
.__Token
3408 CapsuleObj
.CapsuleDataList
.append(CapsuleFd
)
3411 def __GetFmpStatement(self
, CapsuleObj
):
3412 if not self
.__IsKeyword
("FMP_PAYLOAD"):
3413 if not self
.__IsKeyword
("FMP"):
3416 if not self
.__IsKeyword
("PAYLOAD"):
3420 if not self
.__IsToken
("="):
3421 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3423 if not self
.__GetNextToken
():
3424 raise Warning("expected payload name after FMP_PAYLOAD =", self
.FileName
, self
.CurrentLineNumber
)
3425 Payload
= self
.__Token
.upper()
3426 if Payload
not in self
.Profile
.FmpPayloadDict
:
3427 raise Warning("This FMP Payload does not exist: %s" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3428 CapsuleObj
.FmpPayloadList
.append(self
.Profile
.FmpPayloadDict
[Payload
])
3431 def __ParseRawFileStatement(self
):
3432 if not self
.__IsKeyword
("FILE"):
3435 if not self
.__IsKeyword
("DATA"):
3439 if not self
.__IsToken
("="):
3440 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3442 if not self
.__GetNextToken
():
3443 raise Warning("expected File name", self
.FileName
, self
.CurrentLineNumber
)
3445 AnyFileName
= self
.__Token
3446 self
.__VerifyFile
(AnyFileName
)
3450 ## __GetAnyFileStatement() method
3452 # Get AnyFile for capsule
3454 # @param self The object pointer
3455 # @param CapsuleObj for whom AnyFile is got
3456 # @retval True Successfully find a Anyfile statement
3457 # @retval False Not able to find a AnyFile statement
3459 def __GetAnyFileStatement(self
, CapsuleObj
):
3460 AnyFileName
= self
.__ParseRawFileStatement
()
3464 CapsuleAnyFile
= CapsuleData
.CapsuleAnyFile()
3465 CapsuleAnyFile
.FileName
= AnyFileName
3466 CapsuleObj
.CapsuleDataList
.append(CapsuleAnyFile
)
3469 ## __GetAfileStatement() method
3471 # Get Afile for capsule
3473 # @param self The object pointer
3474 # @param CapsuleObj for whom Afile is got
3475 # @retval True Successfully find a Afile statement
3476 # @retval False Not able to find a Afile statement
3478 def __GetAfileStatement(self
, CapsuleObj
):
3480 if not self
.__IsKeyword
("APPEND"):
3483 if not self
.__IsToken
("="):
3484 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3486 if not self
.__GetNextToken
():
3487 raise Warning("expected Afile name", self
.FileName
, self
.CurrentLineNumber
)
3489 AfileName
= self
.__Token
3490 AfileBaseName
= os
.path
.basename(AfileName
)
3492 if os
.path
.splitext(AfileBaseName
)[1] not in [".bin",".BIN",".Bin",".dat",".DAT",".Dat",".data",".DATA",".Data"]:
3493 raise Warning('invalid binary file type, should be one of "bin","BIN","Bin","dat","DAT","Dat","data","DATA","Data"', \
3494 self
.FileName
, self
.CurrentLineNumber
)
3496 if not os
.path
.isabs(AfileName
):
3497 AfileName
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(AfileName
)
3498 self
.__VerifyFile
(AfileName
)
3500 if not os
.path
.exists(AfileName
):
3501 raise Warning('%s does not exist' % AfileName
, self
.FileName
, self
.CurrentLineNumber
)
3505 CapsuleAfile
= CapsuleData
.CapsuleAfile()
3506 CapsuleAfile
.FileName
= AfileName
3507 CapsuleObj
.CapsuleDataList
.append(CapsuleAfile
)
3510 ## __GetRule() method
3512 # Get Rule section contents and store its data into rule list of self.Profile
3514 # @param self The object pointer
3515 # @retval True Successfully find a Rule
3516 # @retval False Not able to find a Rule
3518 def __GetRule(self
):
3520 if not self
.__GetNextToken
():
3523 S
= self
.__Token
.upper()
3524 if S
.startswith("[") and not S
.startswith("[RULE."):
3525 self
.SectionParser(S
)
3529 if not self
.__IsToken
("[Rule.", True):
3530 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3531 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3532 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3533 raise Warning("expected [Rule.]", self
.FileName
, self
.CurrentLineNumber
)
3535 if not self
.__SkipToToken
("."):
3536 raise Warning("expected '.'", self
.FileName
, self
.CurrentLineNumber
)
3538 Arch
= self
.__SkippedChars
.rstrip(".")
3539 if Arch
.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "AARCH64", "COMMON"):
3540 raise Warning("Unknown Arch '%s'" % Arch
, self
.FileName
, self
.CurrentLineNumber
)
3542 ModuleType
= self
.__GetModuleType
()
3545 if self
.__IsToken
("."):
3546 if not self
.__GetNextWord
():
3547 raise Warning("expected template name", self
.FileName
, self
.CurrentLineNumber
)
3548 TemplateName
= self
.__Token
3550 if not self
.__IsToken
( "]"):
3551 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
3553 RuleObj
= self
.__GetRuleFileStatements
()
3554 RuleObj
.Arch
= Arch
.upper()
3555 RuleObj
.ModuleType
= ModuleType
3556 RuleObj
.TemplateName
= TemplateName
3557 if TemplateName
== '' :
3558 self
.Profile
.RuleDict
['RULE' + \
3562 ModuleType
.upper() ] = RuleObj
3564 self
.Profile
.RuleDict
['RULE' + \
3568 ModuleType
.upper() + \
3570 TemplateName
.upper() ] = RuleObj
3571 # self.Profile.RuleList.append(rule)
3574 ## __GetModuleType() method
3576 # Return the module type
3578 # @param self The object pointer
3579 # @retval string module type
3581 def __GetModuleType(self
):
3583 if not self
.__GetNextWord
():
3584 raise Warning("expected Module type", self
.FileName
, self
.CurrentLineNumber
)
3585 if self
.__Token
.upper() not in ("SEC", "PEI_CORE", "PEIM", "DXE_CORE", \
3586 "DXE_DRIVER", "DXE_SAL_DRIVER", \
3587 "DXE_SMM_DRIVER", "DXE_RUNTIME_DRIVER", \
3588 "UEFI_DRIVER", "UEFI_APPLICATION", "USER_DEFINED", "DEFAULT", "BASE", \
3589 "SECURITY_CORE", "COMBINED_PEIM_DRIVER", "PIC_PEIM", "RELOCATABLE_PEIM", \
3590 "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION", "ACPITABLE", "SMM_CORE"):
3591 raise Warning("Unknown Module type '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3594 ## __GetFileExtension() method
3596 # Return the file extension
3598 # @param self The object pointer
3599 # @retval string file name extension
3601 def __GetFileExtension(self
):
3602 if not self
.__IsToken
("."):
3603 raise Warning("expected '.'", self
.FileName
, self
.CurrentLineNumber
)
3606 if self
.__GetNextToken
():
3607 Pattern
= re
.compile(r
'([a-zA-Z][a-zA-Z0-9]*)')
3608 if Pattern
.match(self
.__Token
):
3612 raise Warning("Unknown file extension '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3615 raise Warning("expected file extension", self
.FileName
, self
.CurrentLineNumber
)
3617 ## __GetRuleFileStatement() method
3621 # @param self The object pointer
3622 # @retval Rule Rule object
3624 def __GetRuleFileStatements(self
):
3626 if not self
.__IsKeyword
("FILE"):
3627 raise Warning("expected FILE", self
.FileName
, self
.CurrentLineNumber
)
3629 if not self
.__GetNextWord
():
3630 raise Warning("expected FFS type", self
.FileName
, self
.CurrentLineNumber
)
3632 Type
= self
.__Token
.strip().upper()
3633 if Type
not in ("RAW", "FREEFORM", "SEC", "PEI_CORE", "PEIM",\
3634 "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE", "SMM", "SMM_CORE"):
3635 raise Warning("Unknown FV type '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3637 if not self
.__IsToken
("="):
3638 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3640 if not self
.__IsKeyword
("$(NAMED_GUID)"):
3641 if not self
.__GetNextWord
():
3642 raise Warning("expected $(NAMED_GUID)", self
.FileName
, self
.CurrentLineNumber
)
3643 if self
.__Token
== 'PCD':
3644 if not self
.__IsToken
( "("):
3645 raise Warning("expected '('", self
.FileName
, self
.CurrentLineNumber
)
3646 PcdPair
= self
.__GetNextPcdName
()
3647 if not self
.__IsToken
( ")"):
3648 raise Warning("expected ')'", self
.FileName
, self
.CurrentLineNumber
)
3649 self
.__Token
= 'PCD('+PcdPair
[1]+'.'+PcdPair
[0]+')'
3651 NameGuid
= self
.__Token
3654 if self
.__IsKeyword
('RELOCS_STRIPPED') or self
.__IsKeyword
('RELOCS_RETAINED'):
3655 if self
.__FileCouldHaveRelocFlag
(Type
):
3656 if self
.__Token
== 'RELOCS_STRIPPED':
3661 raise Warning("File type %s could not have reloc strip flag%d" % (Type
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3664 if self
.__GetNextToken
():
3665 Pattern
= re
.compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
3666 if Pattern
.match(self
.__Token
):
3667 KeyStringList
.append(self
.__Token
)
3668 if self
.__IsToken
(","):
3669 while self
.__GetNextToken
():
3670 if not Pattern
.match(self
.__Token
):
3671 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
3672 KeyStringList
.append(self
.__Token
)
3674 if not self
.__IsToken
(","):
3682 if self
.__IsKeyword
("Fixed", True):
3686 if self
.__IsKeyword
("CheckSum", True):
3690 if self
.__GetAlignment
():
3691 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3692 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3693 #For FFS, Auto is default option same to ""
3694 if not self
.__Token
== "Auto":
3695 AlignValue
= self
.__Token
3697 if self
.__IsToken
("{"):
3698 # Complex file rule expected
3699 Rule
= RuleComplexFile
.RuleComplexFile()
3700 Rule
.FvFileType
= Type
3701 Rule
.NameGuid
= NameGuid
3702 Rule
.Alignment
= AlignValue
3703 Rule
.CheckSum
= CheckSum
3705 Rule
.KeyStringList
= KeyStringList
3706 if KeepReloc
!= None:
3707 Rule
.KeepReloc
= KeepReloc
3710 IsEncapsulate
= self
.__GetRuleEncapsulationSection
(Rule
)
3711 IsLeaf
= self
.__GetEfiSection
(Rule
)
3712 if not IsEncapsulate
and not IsLeaf
:
3715 if not self
.__IsToken
("}"):
3716 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
3721 # Simple file rule expected
3722 if not self
.__GetNextWord
():
3723 raise Warning("expected leaf section type", self
.FileName
, self
.CurrentLineNumber
)
3725 SectionName
= self
.__Token
3727 if SectionName
not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3728 "UI", "PEI_DEPEX", "VERSION", "SUBTYPE_GUID", "SMM_DEPEX"):
3729 raise Warning("Unknown leaf section name '%s'" % SectionName
, self
.FileName
, self
.CurrentLineNumber
)
3732 if self
.__IsKeyword
("Fixed", True):
3735 if self
.__IsKeyword
("CheckSum", True):
3739 if self
.__GetAlignment
():
3740 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3741 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3742 if self
.__Token
== 'Auto' and (not SectionName
== 'PE32') and (not SectionName
== 'TE'):
3743 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3744 SectAlignment
= self
.__Token
3747 if self
.__IsToken
('|'):
3748 Ext
= self
.__GetFileExtension
()
3749 elif not self
.__GetNextToken
():
3750 raise Warning("expected File name", self
.FileName
, self
.CurrentLineNumber
)
3752 Rule
= RuleSimpleFile
.RuleSimpleFile()
3753 Rule
.SectionType
= SectionName
3754 Rule
.FvFileType
= Type
3755 Rule
.NameGuid
= NameGuid
3756 Rule
.Alignment
= AlignValue
3757 Rule
.SectAlignment
= SectAlignment
3758 Rule
.CheckSum
= CheckSum
3760 Rule
.KeyStringList
= KeyStringList
3761 if KeepReloc
!= None:
3762 Rule
.KeepReloc
= KeepReloc
3763 Rule
.FileExtension
= Ext
3764 Rule
.FileName
= self
.__Token
3767 ## __GetEfiSection() method
3769 # Get section list for Rule
3771 # @param self The object pointer
3772 # @param Obj for whom section is got
3773 # @retval True Successfully find section statement
3774 # @retval False Not able to find section statement
3776 def __GetEfiSection(self
, Obj
):
3778 OldPos
= self
.GetFileBufferPos()
3779 if not self
.__GetNextWord
():
3781 SectionName
= self
.__Token
3783 if SectionName
not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3784 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3788 if SectionName
== "FV_IMAGE":
3789 FvImageSectionObj
= FvImageSection
.FvImageSection()
3790 if self
.__IsKeyword
("FV_IMAGE"):
3792 if self
.__IsToken
( "{"):
3794 self
.__GetDefineStatements
(FvObj
)
3795 self
.__GetBlockStatement
(FvObj
)
3796 self
.__GetSetStatements
(FvObj
)
3797 self
.__GetFvAlignment
(FvObj
)
3798 self
.__GetFvAttributes
(FvObj
)
3799 self
.__GetAprioriSection
(FvObj
)
3800 self
.__GetAprioriSection
(FvObj
)
3803 IsInf
= self
.__GetInfStatement
(FvObj
)
3804 IsFile
= self
.__GetFileStatement
(FvObj
)
3805 if not IsInf
and not IsFile
:
3808 if not self
.__IsToken
( "}"):
3809 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
3810 FvImageSectionObj
.Fv
= FvObj
3811 FvImageSectionObj
.FvName
= None
3814 if not self
.__IsKeyword
("FV"):
3815 raise Warning("expected 'FV'", self
.FileName
, self
.CurrentLineNumber
)
3816 FvImageSectionObj
.FvFileType
= self
.__Token
3818 if self
.__GetAlignment
():
3819 if self
.__Token
not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3820 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3821 FvImageSectionObj
.Alignment
= self
.__Token
3823 if self
.__IsToken
('|'):
3824 FvImageSectionObj
.FvFileExtension
= self
.__GetFileExtension
()
3825 elif self
.__GetNextToken
():
3826 if self
.__Token
not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3827 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3828 FvImageSectionObj
.FvFileName
= self
.__Token
3832 raise Warning("expected FV file name", self
.FileName
, self
.CurrentLineNumber
)
3834 Obj
.SectionList
.append(FvImageSectionObj
)
3837 EfiSectionObj
= EfiSection
.EfiSection()
3838 EfiSectionObj
.SectionType
= SectionName
3840 if not self
.__GetNextToken
():
3841 raise Warning("expected file type", self
.FileName
, self
.CurrentLineNumber
)
3843 if self
.__Token
== "STRING":
3844 if not self
.__RuleSectionCouldHaveString
(EfiSectionObj
.SectionType
):
3845 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3847 if not self
.__IsToken
('='):
3848 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3850 if not self
.__GetNextToken
():
3851 raise Warning("expected Quoted String", self
.FileName
, self
.CurrentLineNumber
)
3853 if self
.__GetStringData
():
3854 EfiSectionObj
.StringData
= self
.__Token
3856 if self
.__IsKeyword
("BUILD_NUM"):
3857 if not self
.__RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3858 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3860 if not self
.__IsToken
("="):
3861 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3862 if not self
.__GetNextToken
():
3863 raise Warning("expected Build number", self
.FileName
, self
.CurrentLineNumber
)
3864 EfiSectionObj
.BuildNum
= self
.__Token
3867 EfiSectionObj
.FileType
= self
.__Token
3868 self
.__CheckRuleSectionFileType
(EfiSectionObj
.SectionType
, EfiSectionObj
.FileType
)
3870 if self
.__IsKeyword
("Optional"):
3871 if not self
.__RuleSectionCouldBeOptional
(EfiSectionObj
.SectionType
):
3872 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3873 EfiSectionObj
.Optional
= True
3875 if self
.__IsKeyword
("BUILD_NUM"):
3876 if not self
.__RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3877 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3879 if not self
.__IsToken
("="):
3880 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3881 if not self
.__GetNextToken
():
3882 raise Warning("expected Build number", self
.FileName
, self
.CurrentLineNumber
)
3883 EfiSectionObj
.BuildNum
= self
.__Token
3885 if self
.__GetAlignment
():
3886 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3887 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
3888 if self
.__Token
== 'Auto' and (not SectionName
== 'PE32') and (not SectionName
== 'TE'):
3889 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3890 EfiSectionObj
.Alignment
= self
.__Token
3892 if self
.__IsKeyword
('RELOCS_STRIPPED') or self
.__IsKeyword
('RELOCS_RETAINED'):
3893 if self
.__SectionCouldHaveRelocFlag
(EfiSectionObj
.SectionType
):
3894 if self
.__Token
== 'RELOCS_STRIPPED':
3895 EfiSectionObj
.KeepReloc
= False
3897 EfiSectionObj
.KeepReloc
= True
3898 if Obj
.KeepReloc
!= None and Obj
.KeepReloc
!= EfiSectionObj
.KeepReloc
:
3899 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3901 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3904 if self
.__IsToken
('|'):
3905 EfiSectionObj
.FileExtension
= self
.__GetFileExtension
()
3906 elif self
.__GetNextToken
():
3907 if self
.__Token
not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3908 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3910 if self
.__Token
.startswith('PCD'):
3912 self
.__GetNextWord
()
3914 if self
.__Token
== 'PCD':
3915 if not self
.__IsToken
( "("):
3916 raise Warning("expected '('", self
.FileName
, self
.CurrentLineNumber
)
3917 PcdPair
= self
.__GetNextPcdName
()
3918 if not self
.__IsToken
( ")"):
3919 raise Warning("expected ')'", self
.FileName
, self
.CurrentLineNumber
)
3920 self
.__Token
= 'PCD('+PcdPair
[1]+'.'+PcdPair
[0]+')'
3922 EfiSectionObj
.FileName
= self
.__Token
3927 raise Warning("expected section file name", self
.FileName
, self
.CurrentLineNumber
)
3929 Obj
.SectionList
.append(EfiSectionObj
)
3932 ## __RuleSectionCouldBeOptional() method
3934 # Get whether a section could be optional
3936 # @param self The object pointer
3937 # @param SectionType The section type to check
3938 # @retval True section could be optional
3939 # @retval False section never optional
3941 def __RuleSectionCouldBeOptional(self
, SectionType
):
3942 if SectionType
in ("DXE_DEPEX", "UI", "VERSION", "PEI_DEPEX", "RAW", "SMM_DEPEX"):
3947 ## __RuleSectionCouldHaveBuildNum() method
3949 # Get whether a section could have build number information
3951 # @param self The object pointer
3952 # @param SectionType The section type to check
3953 # @retval True section could have build number information
3954 # @retval False section never have build number information
3956 def __RuleSectionCouldHaveBuildNum(self
, SectionType
):
3957 if SectionType
in ("VERSION"):
3962 ## __RuleSectionCouldHaveString() method
3964 # Get whether a section could have string
3966 # @param self The object pointer
3967 # @param SectionType The section type to check
3968 # @retval True section could have string
3969 # @retval False section never have string
3971 def __RuleSectionCouldHaveString(self
, SectionType
):
3972 if SectionType
in ("UI", "VERSION"):
3977 ## __CheckRuleSectionFileType() method
3979 # Get whether a section matches a file type
3981 # @param self The object pointer
3982 # @param SectionType The section type to check
3983 # @param FileType The file type to check
3985 def __CheckRuleSectionFileType(self
, SectionType
, FileType
):
3986 if SectionType
== "COMPAT16":
3987 if FileType
not in ("COMPAT16", "SEC_COMPAT16"):
3988 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3989 elif SectionType
== "PE32":
3990 if FileType
not in ("PE32", "SEC_PE32"):
3991 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3992 elif SectionType
== "PIC":
3993 if FileType
not in ("PIC", "PIC"):
3994 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3995 elif SectionType
== "TE":
3996 if FileType
not in ("TE", "SEC_TE"):
3997 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3998 elif SectionType
== "RAW":
3999 if FileType
not in ("BIN", "SEC_BIN", "RAW", "ASL", "ACPI"):
4000 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
4001 elif SectionType
== "DXE_DEPEX" or SectionType
== "SMM_DEPEX":
4002 if FileType
not in ("DXE_DEPEX", "SEC_DXE_DEPEX", "SMM_DEPEX"):
4003 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
4004 elif SectionType
== "UI":
4005 if FileType
not in ("UI", "SEC_UI"):
4006 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
4007 elif SectionType
== "VERSION":
4008 if FileType
not in ("VERSION", "SEC_VERSION"):
4009 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
4010 elif SectionType
== "PEI_DEPEX":
4011 if FileType
not in ("PEI_DEPEX", "SEC_PEI_DEPEX"):
4012 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
4013 elif SectionType
== "GUID":
4014 if FileType
not in ("PE32", "SEC_GUID"):
4015 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
4017 ## __GetRuleEncapsulationSection() method
4019 # Get encapsulation section for Rule
4021 # @param self The object pointer
4022 # @param Rule for whom section is got
4023 # @retval True Successfully find section statement
4024 # @retval False Not able to find section statement
4026 def __GetRuleEncapsulationSection(self
, Rule
):
4028 if self
.__IsKeyword
( "COMPRESS"):
4030 if self
.__IsKeyword
("PI_STD") or self
.__IsKeyword
("PI_NONE"):
4033 if not self
.__IsToken
("{"):
4034 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
4036 CompressSectionObj
= CompressSection
.CompressSection()
4038 CompressSectionObj
.CompType
= Type
4039 # Recursive sections...
4041 IsEncapsulate
= self
.__GetRuleEncapsulationSection
(CompressSectionObj
)
4042 IsLeaf
= self
.__GetEfiSection
(CompressSectionObj
)
4043 if not IsEncapsulate
and not IsLeaf
:
4046 if not self
.__IsToken
( "}"):
4047 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
4048 Rule
.SectionList
.append(CompressSectionObj
)
4052 elif self
.__IsKeyword
( "GUIDED"):
4054 if self
.__GetNextGuid
():
4055 GuidValue
= self
.__Token
4057 if self
.__IsKeyword
( "$(NAMED_GUID)"):
4058 GuidValue
= self
.__Token
4060 AttribDict
= self
.__GetGuidAttrib
()
4062 if not self
.__IsToken
("{"):
4063 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
4064 GuidSectionObj
= GuidSection
.GuidSection()
4065 GuidSectionObj
.NameGuid
= GuidValue
4066 GuidSectionObj
.SectionType
= "GUIDED"
4067 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
4068 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
4069 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
4073 IsEncapsulate
= self
.__GetRuleEncapsulationSection
(GuidSectionObj
)
4074 IsLeaf
= self
.__GetEfiSection
(GuidSectionObj
)
4075 if not IsEncapsulate
and not IsLeaf
:
4078 if not self
.__IsToken
( "}"):
4079 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
4080 Rule
.SectionList
.append(GuidSectionObj
)
4086 ## __GetVtf() method
4088 # Get VTF section contents and store its data into VTF list of self.Profile
4090 # @param self The object pointer
4091 # @retval True Successfully find a VTF
4092 # @retval False Not able to find a VTF
4096 if not self
.__GetNextToken
():
4099 S
= self
.__Token
.upper()
4100 if S
.startswith("[") and not S
.startswith("[VTF."):
4101 self
.SectionParser(S
)
4106 if not self
.__IsToken
("[VTF.", True):
4107 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4108 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
4109 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
4110 raise Warning("expected [VTF.]", self
.FileName
, self
.CurrentLineNumber
)
4112 if not self
.__SkipToToken
("."):
4113 raise Warning("expected '.'", self
.FileName
, self
.CurrentLineNumber
)
4115 Arch
= self
.__SkippedChars
.rstrip(".").upper()
4116 if Arch
not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
4117 raise Warning("Unknown Arch '%s'" % Arch
, self
.FileName
, self
.CurrentLineNumber
)
4119 if not self
.__GetNextWord
():
4120 raise Warning("expected VTF name", self
.FileName
, self
.CurrentLineNumber
)
4121 Name
= self
.__Token
.upper()
4124 VtfObj
.UiName
= Name
4125 VtfObj
.KeyArch
= Arch
4127 if self
.__IsToken
(","):
4128 if not self
.__GetNextWord
():
4129 raise Warning("expected Arch list", self
.FileName
, self
.CurrentLineNumber
)
4130 if self
.__Token
.upper() not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
4131 raise Warning("Unknown Arch '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
4132 VtfObj
.ArchList
= self
.__Token
.upper()
4134 if not self
.__IsToken
( "]"):
4135 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
4137 if self
.__IsKeyword
("IA32_RST_BIN"):
4138 if not self
.__IsToken
("="):
4139 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4141 if not self
.__GetNextToken
():
4142 raise Warning("expected Reset file", self
.FileName
, self
.CurrentLineNumber
)
4144 VtfObj
.ResetBin
= self
.__Token
4145 if VtfObj
.ResetBin
.replace('$(WORKSPACE)', '').find('$') == -1:
4146 #check for file path
4147 ErrorCode
, ErrorInfo
= PathClass(NormPath(VtfObj
.ResetBin
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4149 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4151 while self
.__GetComponentStatement
(VtfObj
):
4154 self
.Profile
.VtfList
.append(VtfObj
)
4157 ## __GetComponentStatement() method
4159 # Get components in VTF
4161 # @param self The object pointer
4162 # @param VtfObj for whom component is got
4163 # @retval True Successfully find a component
4164 # @retval False Not able to find a component
4166 def __GetComponentStatement(self
, VtfObj
):
4168 if not self
.__IsKeyword
("COMP_NAME"):
4171 if not self
.__IsToken
("="):
4172 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4174 if not self
.__GetNextWord
():
4175 raise Warning("expected Component Name", self
.FileName
, self
.CurrentLineNumber
)
4177 CompStatementObj
= ComponentStatement
.ComponentStatement()
4178 CompStatementObj
.CompName
= self
.__Token
4180 if not self
.__IsKeyword
("COMP_LOC"):
4181 raise Warning("expected COMP_LOC", self
.FileName
, self
.CurrentLineNumber
)
4183 if not self
.__IsToken
("="):
4184 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4186 CompStatementObj
.CompLoc
= ""
4187 if self
.__GetNextWord
():
4188 CompStatementObj
.CompLoc
= self
.__Token
4189 if self
.__IsToken
('|'):
4190 if not self
.__GetNextWord
():
4191 raise Warning("Expected Region Name", self
.FileName
, self
.CurrentLineNumber
)
4193 if self
.__Token
not in ("F", "N", "S"): #, "H", "L", "PH", "PL"): not support
4194 raise Warning("Unknown location type '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
4196 CompStatementObj
.FilePos
= self
.__Token
4198 self
.CurrentLineNumber
+= 1
4199 self
.CurrentOffsetWithinLine
= 0
4201 if not self
.__IsKeyword
("COMP_TYPE"):
4202 raise Warning("expected COMP_TYPE", self
.FileName
, self
.CurrentLineNumber
)
4204 if not self
.__IsToken
("="):
4205 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4207 if not self
.__GetNextToken
():
4208 raise Warning("expected Component type", self
.FileName
, self
.CurrentLineNumber
)
4209 if self
.__Token
not in ("FIT", "PAL_B", "PAL_A", "OEM"):
4210 if not self
.__Token
.startswith("0x") or len(self
.__Token
) < 3 or len(self
.__Token
) > 4 or \
4211 not self
.__HexDigit
(self
.__Token
[2]) or not self
.__HexDigit
(self
.__Token
[-1]):
4212 raise Warning("Unknown location type '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
4213 CompStatementObj
.CompType
= self
.__Token
4215 if not self
.__IsKeyword
("COMP_VER"):
4216 raise Warning("expected COMP_VER", self
.FileName
, self
.CurrentLineNumber
)
4218 if not self
.__IsToken
("="):
4219 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4221 if not self
.__GetNextToken
():
4222 raise Warning("expected Component version", self
.FileName
, self
.CurrentLineNumber
)
4224 Pattern
= re
.compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', re
.DOTALL
)
4225 if Pattern
.match(self
.__Token
) == None:
4226 raise Warning("Unknown version format '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
4227 CompStatementObj
.CompVer
= self
.__Token
4229 if not self
.__IsKeyword
("COMP_CS"):
4230 raise Warning("expected COMP_CS", self
.FileName
, self
.CurrentLineNumber
)
4232 if not self
.__IsToken
("="):
4233 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4235 if not self
.__GetNextToken
():
4236 raise Warning("expected Component CS", self
.FileName
, self
.CurrentLineNumber
)
4237 if self
.__Token
not in ("1", "0"):
4238 raise Warning("Unknown Component CS '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
4239 CompStatementObj
.CompCs
= self
.__Token
4242 if not self
.__IsKeyword
("COMP_BIN"):
4243 raise Warning("expected COMP_BIN", self
.FileName
, self
.CurrentLineNumber
)
4245 if not self
.__IsToken
("="):
4246 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4248 if not self
.__GetNextToken
():
4249 raise Warning("expected Component file", self
.FileName
, self
.CurrentLineNumber
)
4251 CompStatementObj
.CompBin
= self
.__Token
4252 if CompStatementObj
.CompBin
!= '-' and CompStatementObj
.CompBin
.replace('$(WORKSPACE)', '').find('$') == -1:
4253 #check for file path
4254 ErrorCode
, ErrorInfo
= PathClass(NormPath(CompStatementObj
.CompBin
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4256 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4258 if not self
.__IsKeyword
("COMP_SYM"):
4259 raise Warning("expected COMP_SYM", self
.FileName
, self
.CurrentLineNumber
)
4261 if not self
.__IsToken
("="):
4262 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4264 if not self
.__GetNextToken
():
4265 raise Warning("expected Component symbol file", self
.FileName
, self
.CurrentLineNumber
)
4267 CompStatementObj
.CompSym
= self
.__Token
4268 if CompStatementObj
.CompSym
!= '-' and CompStatementObj
.CompSym
.replace('$(WORKSPACE)', '').find('$') == -1:
4269 #check for file path
4270 ErrorCode
, ErrorInfo
= PathClass(NormPath(CompStatementObj
.CompSym
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4272 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4274 if not self
.__IsKeyword
("COMP_SIZE"):
4275 raise Warning("expected COMP_SIZE", self
.FileName
, self
.CurrentLineNumber
)
4277 if not self
.__IsToken
("="):
4278 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4280 if self
.__IsToken
("-"):
4281 CompStatementObj
.CompSize
= self
.__Token
4282 elif self
.__GetNextDecimalNumber
():
4283 CompStatementObj
.CompSize
= self
.__Token
4284 elif self
.__GetNextHexNumber
():
4285 CompStatementObj
.CompSize
= self
.__Token
4287 raise Warning("Unknown size '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
4289 VtfObj
.ComponentStatementList
.append(CompStatementObj
)
4292 ## __GetOptionRom() method
4294 # Get OptionROM section contents and store its data into OptionROM list of self.Profile
4296 # @param self The object pointer
4297 # @retval True Successfully find a OptionROM
4298 # @retval False Not able to find a OptionROM
4300 def __GetOptionRom(self
):
4302 if not self
.__GetNextToken
():
4305 S
= self
.__Token
.upper()
4306 if S
.startswith("[") and not S
.startswith("[OPTIONROM."):
4307 self
.SectionParser(S
)
4312 if not self
.__IsToken
("[OptionRom.", True):
4313 raise Warning("Unknown Keyword '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
4315 OptRomName
= self
.__GetUiName
()
4317 if not self
.__IsToken
( "]"):
4318 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
4320 OptRomObj
= OptionRom
.OPTIONROM()
4321 OptRomObj
.DriverName
= OptRomName
4322 self
.Profile
.OptRomDict
[OptRomName
] = OptRomObj
4325 isInf
= self
.__GetOptRomInfStatement
(OptRomObj
)
4326 isFile
= self
.__GetOptRomFileStatement
(OptRomObj
)
4327 if not isInf
and not isFile
:
4332 ## __GetOptRomInfStatement() method
4334 # Get INF statements
4336 # @param self The object pointer
4337 # @param Obj for whom inf statement is got
4338 # @retval True Successfully find inf statement
4339 # @retval False Not able to find inf statement
4341 def __GetOptRomInfStatement(self
, Obj
):
4343 if not self
.__IsKeyword
( "INF"):
4346 ffsInf
= OptRomInfStatement
.OptRomInfStatement()
4347 self
.__GetInfOptions
( ffsInf
)
4349 if not self
.__GetNextToken
():
4350 raise Warning("expected INF file path", self
.FileName
, self
.CurrentLineNumber
)
4351 ffsInf
.InfFileName
= self
.__Token
4352 if ffsInf
.InfFileName
.replace('$(WORKSPACE)', '').find('$') == -1:
4353 #check for file path
4354 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4356 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4358 if not ffsInf
.InfFileName
in self
.Profile
.InfList
:
4359 self
.Profile
.InfList
.append(ffsInf
.InfFileName
)
4360 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4361 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
4363 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
4364 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
4366 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
4368 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
4371 self
.__GetOptRomOverrides
(ffsInf
)
4373 Obj
.FfsList
.append(ffsInf
)
4376 ## __GetOptRomOverrides() method
4378 # Get overrides for OptROM INF & FILE
4380 # @param self The object pointer
4381 # @param FfsInfObj for whom overrides is got
4383 def __GetOptRomOverrides(self
, Obj
):
4384 if self
.__IsToken
('{'):
4385 Overrides
= OptionRom
.OverrideAttribs()
4387 if self
.__IsKeyword
( "PCI_VENDOR_ID"):
4388 if not self
.__IsToken
( "="):
4389 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4390 if not self
.__GetNextHexNumber
():
4391 raise Warning("expected Hex vendor id", self
.FileName
, self
.CurrentLineNumber
)
4392 Overrides
.PciVendorId
= self
.__Token
4395 if self
.__IsKeyword
( "PCI_CLASS_CODE"):
4396 if not self
.__IsToken
( "="):
4397 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4398 if not self
.__GetNextHexNumber
():
4399 raise Warning("expected Hex class code", self
.FileName
, self
.CurrentLineNumber
)
4400 Overrides
.PciClassCode
= self
.__Token
4403 if self
.__IsKeyword
( "PCI_DEVICE_ID"):
4404 if not self
.__IsToken
( "="):
4405 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4406 if not self
.__GetNextHexNumber
():
4407 raise Warning("expected Hex device id", self
.FileName
, self
.CurrentLineNumber
)
4409 Overrides
.PciDeviceId
= self
.__Token
4412 if self
.__IsKeyword
( "PCI_REVISION"):
4413 if not self
.__IsToken
( "="):
4414 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4415 if not self
.__GetNextHexNumber
():
4416 raise Warning("expected Hex revision", self
.FileName
, self
.CurrentLineNumber
)
4417 Overrides
.PciRevision
= self
.__Token
4420 if self
.__IsKeyword
( "PCI_COMPRESS"):
4421 if not self
.__IsToken
( "="):
4422 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4423 if not self
.__GetNextToken
():
4424 raise Warning("expected TRUE/FALSE for compress", self
.FileName
, self
.CurrentLineNumber
)
4425 Overrides
.NeedCompress
= self
.__Token
.upper() == 'TRUE'
4428 if self
.__IsToken
( "}"):
4431 EdkLogger
.error("FdfParser", FORMAT_INVALID
, File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
4433 Obj
.OverrideAttribs
= Overrides
4435 ## __GetOptRomFileStatement() method
4437 # Get FILE statements
4439 # @param self The object pointer
4440 # @param Obj for whom FILE statement is got
4441 # @retval True Successfully find FILE statement
4442 # @retval False Not able to find FILE statement
4444 def __GetOptRomFileStatement(self
, Obj
):
4446 if not self
.__IsKeyword
( "FILE"):
4449 FfsFileObj
= OptRomFileStatement
.OptRomFileStatement()
4451 if not self
.__IsKeyword
("EFI") and not self
.__IsKeyword
("BIN"):
4452 raise Warning("expected Binary type (EFI/BIN)", self
.FileName
, self
.CurrentLineNumber
)
4453 FfsFileObj
.FileType
= self
.__Token
4455 if not self
.__GetNextToken
():
4456 raise Warning("expected File path", self
.FileName
, self
.CurrentLineNumber
)
4457 FfsFileObj
.FileName
= self
.__Token
4458 if FfsFileObj
.FileName
.replace('$(WORKSPACE)', '').find('$') == -1:
4459 #check for file path
4460 ErrorCode
, ErrorInfo
= PathClass(NormPath(FfsFileObj
.FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4462 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4464 if FfsFileObj
.FileType
== 'EFI':
4465 self
.__GetOptRomOverrides
(FfsFileObj
)
4467 Obj
.FfsList
.append(FfsFileObj
)
4471 ## __GetCapInFd() method
4473 # Get Cap list contained in FD
4475 # @param self The object pointer
4476 # @param FdName FD name
4477 # @retval CapList List of Capsule in FD
4479 def __GetCapInFd (self
, FdName
):
4482 if FdName
.upper() in self
.Profile
.FdDict
.keys():
4483 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4484 for elementRegion
in FdObj
.RegionList
:
4485 if elementRegion
.RegionType
== 'CAPSULE':
4486 for elementRegionData
in elementRegion
.RegionDataList
:
4487 if elementRegionData
.endswith(".cap"):
4489 if elementRegionData
!= None and elementRegionData
.upper() not in CapList
:
4490 CapList
.append(elementRegionData
.upper())
4493 ## __GetReferencedFdCapTuple() method
4495 # Get FV and FD list referenced by a capsule image
4497 # @param self The object pointer
4498 # @param CapObj Capsule section to be searched
4499 # @param RefFdList referenced FD by section
4500 # @param RefFvList referenced FV by section
4502 def __GetReferencedFdCapTuple(self
, CapObj
, RefFdList
= [], RefFvList
= []):
4504 for CapsuleDataObj
in CapObj
.CapsuleDataList
:
4505 if hasattr(CapsuleDataObj
, 'FvName') and CapsuleDataObj
.FvName
!= None and CapsuleDataObj
.FvName
.upper() not in RefFvList
:
4506 RefFvList
.append (CapsuleDataObj
.FvName
.upper())
4507 elif hasattr(CapsuleDataObj
, 'FdName') and CapsuleDataObj
.FdName
!= None and CapsuleDataObj
.FdName
.upper() not in RefFdList
:
4508 RefFdList
.append (CapsuleDataObj
.FdName
.upper())
4509 elif CapsuleDataObj
.Ffs
!= None:
4510 if isinstance(CapsuleDataObj
.Ffs
, FfsFileStatement
.FileStatement
):
4511 if CapsuleDataObj
.Ffs
.FvName
!= None and CapsuleDataObj
.Ffs
.FvName
.upper() not in RefFvList
:
4512 RefFvList
.append(CapsuleDataObj
.Ffs
.FvName
.upper())
4513 elif CapsuleDataObj
.Ffs
.FdName
!= None and CapsuleDataObj
.Ffs
.FdName
.upper() not in RefFdList
:
4514 RefFdList
.append(CapsuleDataObj
.Ffs
.FdName
.upper())
4516 self
.__GetReferencedFdFvTupleFromSection
(CapsuleDataObj
.Ffs
, RefFdList
, RefFvList
)
4518 ## __GetFvInFd() method
4520 # Get FV list contained in FD
4522 # @param self The object pointer
4523 # @param FdName FD name
4524 # @retval FvList list of FV in FD
4526 def __GetFvInFd (self
, FdName
):
4529 if FdName
.upper() in self
.Profile
.FdDict
.keys():
4530 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4531 for elementRegion
in FdObj
.RegionList
:
4532 if elementRegion
.RegionType
== 'FV':
4533 for elementRegionData
in elementRegion
.RegionDataList
:
4534 if elementRegionData
.endswith(".fv"):
4536 if elementRegionData
!= None and elementRegionData
.upper() not in FvList
:
4537 FvList
.append(elementRegionData
.upper())
4540 ## __GetReferencedFdFvTuple() method
4542 # Get FD and FV list referenced by a FFS file
4544 # @param self The object pointer
4545 # @param FfsFile contains sections to be searched
4546 # @param RefFdList referenced FD by section
4547 # @param RefFvList referenced FV by section
4549 def __GetReferencedFdFvTuple(self
, FvObj
, RefFdList
= [], RefFvList
= []):
4551 for FfsObj
in FvObj
.FfsList
:
4552 if isinstance(FfsObj
, FfsFileStatement
.FileStatement
):
4553 if FfsObj
.FvName
!= None and FfsObj
.FvName
.upper() not in RefFvList
:
4554 RefFvList
.append(FfsObj
.FvName
.upper())
4555 elif FfsObj
.FdName
!= None and FfsObj
.FdName
.upper() not in RefFdList
:
4556 RefFdList
.append(FfsObj
.FdName
.upper())
4558 self
.__GetReferencedFdFvTupleFromSection
(FfsObj
, RefFdList
, RefFvList
)
4560 ## __GetReferencedFdFvTupleFromSection() method
4562 # Get FD and FV list referenced by a FFS section
4564 # @param self The object pointer
4565 # @param FfsFile contains sections to be searched
4566 # @param FdList referenced FD by section
4567 # @param FvList referenced FV by section
4569 def __GetReferencedFdFvTupleFromSection(self
, FfsFile
, FdList
= [], FvList
= []):
4572 SectionStack
.extend(FfsFile
.SectionList
)
4573 while SectionStack
!= []:
4574 SectionObj
= SectionStack
.pop()
4575 if isinstance(SectionObj
, FvImageSection
.FvImageSection
):
4576 if SectionObj
.FvName
!= None and SectionObj
.FvName
.upper() not in FvList
:
4577 FvList
.append(SectionObj
.FvName
.upper())
4578 if SectionObj
.Fv
!= None and SectionObj
.Fv
.UiFvName
!= None and SectionObj
.Fv
.UiFvName
.upper() not in FvList
:
4579 FvList
.append(SectionObj
.Fv
.UiFvName
.upper())
4580 self
.__GetReferencedFdFvTuple
(SectionObj
.Fv
, FdList
, FvList
)
4582 if isinstance(SectionObj
, CompressSection
.CompressSection
) or isinstance(SectionObj
, GuidSection
.GuidSection
):
4583 SectionStack
.extend(SectionObj
.SectionList
)
4585 ## CycleReferenceCheck() method
4587 # Check whether cycle reference exists in FDF
4589 # @param self The object pointer
4590 # @retval True cycle reference exists
4591 # @retval False Not exists cycle reference
4593 def CycleReferenceCheck(self
):
4595 # Check the cycle between FV and FD image
4597 MaxLength
= len (self
.Profile
.FvDict
)
4598 for FvName
in self
.Profile
.FvDict
.keys():
4599 LogStr
= "\nCycle Reference Checking for FV: %s\n" % FvName
4601 RefFvStack
.append(FvName
)
4605 while RefFvStack
!= [] and Index
< MaxLength
:
4607 FvNameFromStack
= RefFvStack
.pop()
4608 if FvNameFromStack
.upper() in self
.Profile
.FvDict
.keys():
4609 FvObj
= self
.Profile
.FvDict
[FvNameFromStack
.upper()]
4615 self
.__GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4617 for RefFdName
in RefFdList
:
4618 if RefFdName
in FdAnalyzedList
:
4621 LogStr
+= "FV %s contains FD %s\n" % (FvNameFromStack
, RefFdName
)
4622 FvInFdList
= self
.__GetFvInFd
(RefFdName
)
4623 if FvInFdList
!= []:
4624 for FvNameInFd
in FvInFdList
:
4625 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
,FvNameInFd
)
4626 if FvNameInFd
not in RefFvStack
:
4627 RefFvStack
.append(FvNameInFd
)
4629 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4630 EdkLogger
.info(LogStr
)
4632 FdAnalyzedList
.append(RefFdName
)
4634 for RefFvName
in RefFvList
:
4635 LogStr
+= "FV %s contains FV %s\n" % (FvNameFromStack
, RefFvName
)
4636 if RefFvName
not in RefFvStack
:
4637 RefFvStack
.append(RefFvName
)
4639 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4640 EdkLogger
.info(LogStr
)
4644 # Check the cycle between Capsule and FD image
4646 MaxLength
= len (self
.Profile
.CapsuleDict
)
4647 for CapName
in self
.Profile
.CapsuleDict
.keys():
4649 # Capsule image to be checked.
4651 LogStr
= "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
4653 RefCapStack
.append(CapName
)
4658 while RefCapStack
!= [] and Index
< MaxLength
:
4660 CapNameFromStack
= RefCapStack
.pop()
4661 if CapNameFromStack
.upper() in self
.Profile
.CapsuleDict
.keys():
4662 CapObj
= self
.Profile
.CapsuleDict
[CapNameFromStack
.upper()]
4668 self
.__GetReferencedFdCapTuple
(CapObj
, RefFdList
, RefFvList
)
4672 while FvListLength
< len (RefFvList
) or FdListLength
< len (RefFdList
):
4673 for RefFdName
in RefFdList
:
4674 if RefFdName
in FdAnalyzedList
:
4677 LogStr
+= "Capsule %s contains FD %s\n" % (CapNameFromStack
, RefFdName
)
4678 CapInFdList
= self
.__GetCapInFd
(RefFdName
)
4679 if CapInFdList
!= []:
4680 for CapNameInFd
in CapInFdList
:
4681 LogStr
+= "FD %s contains Capsule %s\n" % (RefFdName
,CapNameInFd
)
4682 if CapNameInFd
not in RefCapStack
:
4683 RefCapStack
.append(CapNameInFd
)
4685 if CapName
in RefCapStack
or CapNameFromStack
in RefCapStack
:
4686 EdkLogger
.info(LogStr
)
4689 FvInFdList
= self
.__GetFvInFd
(RefFdName
)
4690 if FvInFdList
!= []:
4691 for FvNameInFd
in FvInFdList
:
4692 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
,FvNameInFd
)
4693 if FvNameInFd
not in RefFvList
:
4694 RefFvList
.append(FvNameInFd
)
4696 FdAnalyzedList
.append(RefFdName
)
4698 # the number of the parsed FV and FD image
4700 FvListLength
= len (RefFvList
)
4701 FdListLength
= len (RefFdList
)
4702 for RefFvName
in RefFvList
:
4703 if RefFvName
in FvAnalyzedList
:
4705 LogStr
+= "Capsule %s contains FV %s\n" % (CapNameFromStack
, RefFvName
)
4706 if RefFvName
.upper() in self
.Profile
.FvDict
.keys():
4707 FvObj
= self
.Profile
.FvDict
[RefFvName
.upper()]
4710 self
.__GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4711 FvAnalyzedList
.append(RefFvName
)
4715 if __name__
== "__main__":
4718 test_file
= sys
.argv
[1]
4719 except IndexError, v
:
4720 print "Usage: %s filename" % sys
.argv
[0]
4723 parser
= FdfParser(test_file
)
4726 parser
.CycleReferenceCheck()