4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 # Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>
7 # This program and the accompanying materials
8 # are licensed and made available under the terms and conditions of the BSD License
9 # which accompanies this distribution. The full text of the license may be found at
10 # http://opensource.org/licenses/bsd-license.php
12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
25 import FfsInfStatement
26 import FfsFileStatement
32 import CompressSection
37 import RuleComplexFile
41 import ComponentStatement
43 import OptRomInfStatement
44 import OptRomFileStatement
47 from GenFdsGlobalVariable
import GenFdsGlobalVariable
48 from Common
.BuildToolError
import *
49 from Common
import EdkLogger
50 from Common
.Misc
import PathClass
51 from Common
.String
import NormPath
52 import Common
.GlobalData
as GlobalData
53 from Common
.Expression
import *
54 from Common
import GlobalData
55 from Common
.String
import ReplaceMacro
57 from Common
.Misc
import tdict
58 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
59 import Common
.LongFilePathOs
as os
60 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
61 from Capsule
import EFI_CERT_TYPE_PKCS7_GUID
62 from Capsule
import EFI_CERT_TYPE_RSA2048_SHA256_GUID
63 from Common
.RangeExpression
import RangeExpression
64 from Common
.FdfParserLite
import FileExtensionPattern
,TokenFindPattern
66 ##define T_CHAR_SPACE ' '
67 ##define T_CHAR_NULL '\0'
68 ##define T_CHAR_CR '\r'
69 ##define T_CHAR_TAB '\t'
70 ##define T_CHAR_LF '\n'
71 ##define T_CHAR_SLASH '/'
72 ##define T_CHAR_BACKSLASH '\\'
73 ##define T_CHAR_DOUBLE_QUOTE '\"'
74 ##define T_CHAR_SINGLE_QUOTE '\''
75 ##define T_CHAR_STAR '*'
76 ##define T_CHAR_HASH '#'
78 (T_CHAR_SPACE
, T_CHAR_NULL
, T_CHAR_CR
, T_CHAR_TAB
, T_CHAR_LF
, T_CHAR_SLASH
, \
79 T_CHAR_BACKSLASH
, T_CHAR_DOUBLE_QUOTE
, T_CHAR_SINGLE_QUOTE
, T_CHAR_STAR
, T_CHAR_HASH
) = \
80 (' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#')
82 SEPERATOR_TUPLE
= ('=', '|', ',', '{', '}')
84 RegionSizePattern
= re
.compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
85 RegionSizeGuidPattern
= re
.compile("\s*(?P<base>\w+\.\w+)\s*\|\s*(?P<size>\w+\.\w+)\s*")
86 RegionOffsetPcdPattern
= re
.compile("\s*(?P<base>\w+\.\w+)\s*$")
87 ShortcutPcdPattern
= re
.compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
89 AllIncludeFileList
= []
91 # Get the closest parent
92 def GetParentAtLine (Line
):
93 for Profile
in AllIncludeFileList
:
94 if Profile
.IsLineInFile(Line
):
99 def IsValidInclude (File
, Line
):
100 for Profile
in AllIncludeFileList
:
101 if Profile
.IsLineInFile(Line
) and Profile
.FileName
== File
:
106 def GetRealFileLine (File
, Line
):
109 for Profile
in AllIncludeFileList
:
110 if Profile
.IsLineInFile(Line
):
111 return Profile
.GetLineInFile(Line
)
112 elif Line
>= Profile
.InsertStartLineNumber
and Profile
.Level
== 1:
113 InsertedLines
+= Profile
.GetTotalLines()
115 return (File
, Line
- InsertedLines
)
117 ## The exception class that used to report error messages when parsing FDF
119 # Currently the "ToolName" is set to be "FDF Parser".
121 class Warning (Exception):
124 # @param self The object pointer
125 # @param Str The message to record
126 # @param File The FDF name
127 # @param Line The Line number that error occurs
129 def __init__(self
, Str
, File
= None, Line
= None):
131 FileLineTuple
= GetRealFileLine(File
, Line
)
132 self
.FileName
= FileLineTuple
[0]
133 self
.LineNumber
= FileLineTuple
[1]
134 self
.OriginalLineNumber
= Line
136 self
.ToolName
= 'FdfParser'
141 ## The Include file content class that used to record file data when parsing include file
143 # May raise Exception when opening file.
145 class IncludeFileProfile
:
148 # @param self The object pointer
149 # @param FileName The file that to be parsed
151 def __init__(self
, FileName
):
152 self
.FileName
= FileName
153 self
.FileLinesList
= []
155 fsock
= open(FileName
, "rb", 0)
157 self
.FileLinesList
= fsock
.readlines()
158 for index
, line
in enumerate(self
.FileLinesList
):
159 if not line
.endswith('\n'):
160 self
.FileLinesList
[index
] += '\n'
166 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
168 self
.InsertStartLineNumber
= None
169 self
.InsertAdjust
= 0
170 self
.IncludeFileList
= []
171 self
.Level
= 1 # first level include file
173 def GetTotalLines(self
):
174 TotalLines
= self
.InsertAdjust
+ len(self
.FileLinesList
)
176 for Profile
in self
.IncludeFileList
:
177 TotalLines
+= Profile
.GetTotalLines()
181 def IsLineInFile(self
, Line
):
182 if Line
>= self
.InsertStartLineNumber
and Line
< self
.InsertStartLineNumber
+ self
.GetTotalLines():
187 def GetLineInFile(self
, Line
):
188 if not self
.IsLineInFile (Line
):
189 return (self
.FileName
, -1)
191 InsertedLines
= self
.InsertStartLineNumber
193 for Profile
in self
.IncludeFileList
:
194 if Profile
.IsLineInFile(Line
):
195 return Profile
.GetLineInFile(Line
)
196 elif Line
>= Profile
.InsertStartLineNumber
:
197 InsertedLines
+= Profile
.GetTotalLines()
199 return (self
.FileName
, Line
- InsertedLines
+ 1)
203 ## The FDF content class that used to record file data when parsing FDF
205 # May raise Exception when opening file.
210 # @param self The object pointer
211 # @param FileName The file that to be parsed
213 def __init__(self
, FileName
):
214 self
.FileLinesList
= []
216 fsock
= open(FileName
, "rb", 0)
218 self
.FileLinesList
= fsock
.readlines()
223 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
228 self
.InfDict
= {'ArchTBD':[]}
229 # ECC will use this Dict and List information
230 self
.PcdFileLineDict
= {}
231 self
.InfFileLineList
= []
234 self
.FdNameNotSet
= False
236 self
.CapsuleDict
= {}
240 self
.FmpPayloadDict
= {}
242 ## The syntax parser for FDF
244 # PreprocessFile method should be called prior to ParseFile
245 # CycleReferenceCheck method can detect cycles in FDF contents
247 # GetNext*** procedures mean these procedures will get next token first, then make judgement.
248 # Get*** procedures mean these procedures will make judgement on current token only.
253 # @param self The object pointer
254 # @param FileName The file that to be parsed
256 def __init__(self
, FileName
):
257 self
.Profile
= FileProfile(FileName
)
258 self
.FileName
= FileName
259 self
.CurrentLineNumber
= 1
260 self
.CurrentOffsetWithinLine
= 0
261 self
.CurrentFdName
= None
262 self
.CurrentFvName
= None
264 self
.__SkippedChars
= ""
265 GlobalData
.gFdfParser
= self
267 # Used to section info
268 self
.__CurSection
= []
269 # Key: [section name, UI name, arch]
270 # Value: {MACRO_NAME : MACRO_VALUE}
271 self
.__MacroDict
= tdict(True, 3)
274 self
.__WipeOffArea
= []
275 if GenFdsGlobalVariable
.WorkSpaceDir
== '':
276 GenFdsGlobalVariable
.WorkSpaceDir
= os
.getenv("WORKSPACE")
278 ## __IsWhiteSpace() method
280 # Whether char at current FileBufferPos is whitespace
282 # @param self The object pointer
283 # @param Char The char to test
284 # @retval True The char is a kind of white space
285 # @retval False The char is NOT a kind of white space
287 def __IsWhiteSpace(self
, Char
):
288 if Char
in (T_CHAR_NULL
, T_CHAR_CR
, T_CHAR_SPACE
, T_CHAR_TAB
, T_CHAR_LF
):
293 ## __SkipWhiteSpace() method
295 # Skip white spaces from current char, return number of chars skipped
297 # @param self The object pointer
298 # @retval Count The number of chars skipped
300 def __SkipWhiteSpace(self
):
302 while not self
.__EndOfFile
():
304 if self
.__CurrentChar
() in (T_CHAR_NULL
, T_CHAR_CR
, T_CHAR_LF
, T_CHAR_SPACE
, T_CHAR_TAB
):
305 self
.__SkippedChars
+= str(self
.__CurrentChar
())
312 ## __EndOfFile() method
314 # Judge current buffer pos is at file end
316 # @param self The object pointer
317 # @retval True Current File buffer position is at file end
318 # @retval False Current File buffer position is NOT at file end
320 def __EndOfFile(self
):
321 NumberOfLines
= len(self
.Profile
.FileLinesList
)
322 SizeOfLastLine
= len(self
.Profile
.FileLinesList
[-1])
323 if self
.CurrentLineNumber
== NumberOfLines
and self
.CurrentOffsetWithinLine
>= SizeOfLastLine
- 1:
325 elif self
.CurrentLineNumber
> NumberOfLines
:
330 ## __EndOfLine() method
332 # Judge current buffer pos is at line end
334 # @param self The object pointer
335 # @retval True Current File buffer position is at line end
336 # @retval False Current File buffer position is NOT at line end
338 def __EndOfLine(self
):
339 if self
.CurrentLineNumber
> len(self
.Profile
.FileLinesList
):
341 SizeOfCurrentLine
= len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
342 if self
.CurrentOffsetWithinLine
>= SizeOfCurrentLine
:
349 # Reset file data buffer to the initial state
351 # @param self The object pointer
352 # @param DestLine Optional new destination line number.
353 # @param DestOffset Optional new destination offset.
355 def Rewind(self
, DestLine
= 1, DestOffset
= 0):
356 self
.CurrentLineNumber
= DestLine
357 self
.CurrentOffsetWithinLine
= DestOffset
359 ## __UndoOneChar() method
361 # Go back one char in the file buffer
363 # @param self The object pointer
364 # @retval True Successfully go back one char
365 # @retval False Not able to go back one char as file beginning reached
367 def __UndoOneChar(self
):
369 if self
.CurrentLineNumber
== 1 and self
.CurrentOffsetWithinLine
== 0:
371 elif self
.CurrentOffsetWithinLine
== 0:
372 self
.CurrentLineNumber
-= 1
373 self
.CurrentOffsetWithinLine
= len(self
.__CurrentLine
()) - 1
375 self
.CurrentOffsetWithinLine
-= 1
378 ## __GetOneChar() method
380 # Move forward one char in the file buffer
382 # @param self The object pointer
384 def __GetOneChar(self
):
385 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
386 self
.CurrentLineNumber
+= 1
387 self
.CurrentOffsetWithinLine
= 0
389 self
.CurrentOffsetWithinLine
+= 1
391 ## __CurrentChar() method
393 # Get the char pointed to by the file buffer pointer
395 # @param self The object pointer
396 # @retval Char Current char
398 def __CurrentChar(self
):
399 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
]
401 ## __NextChar() method
403 # Get the one char pass the char pointed to by the file buffer pointer
405 # @param self The object pointer
406 # @retval Char Next char
408 def __NextChar(self
):
409 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
410 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
][0]
412 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
+ 1]
414 ## __SetCurrentCharValue() method
416 # Modify the value of current char
418 # @param self The object pointer
419 # @param Value The new value of current char
421 def __SetCurrentCharValue(self
, Value
):
422 self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
] = Value
424 ## __CurrentLine() method
426 # Get the list that contains current line contents
428 # @param self The object pointer
429 # @retval List current line contents
431 def __CurrentLine(self
):
432 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
434 def __StringToList(self
):
435 self
.Profile
.FileLinesList
= [list(s
) for s
in self
.Profile
.FileLinesList
]
436 self
.Profile
.FileLinesList
[-1].append(' ')
438 def __ReplaceFragment(self
, StartPos
, EndPos
, Value
= ' '):
439 if StartPos
[0] == EndPos
[0]:
441 while Offset
<= EndPos
[1]:
442 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
447 while self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] not in ('\r', '\n'):
448 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
452 while Line
< EndPos
[0]:
454 while self
.Profile
.FileLinesList
[Line
][Offset
] not in ('\r', '\n'):
455 self
.Profile
.FileLinesList
[Line
][Offset
] = Value
460 while Offset
<= EndPos
[1]:
461 self
.Profile
.FileLinesList
[EndPos
[0]][Offset
] = Value
465 def __GetMacroName(self
):
466 if not self
.__GetNextToken
():
467 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
468 MacroName
= self
.__Token
470 if MacroName
.startswith('!'):
472 MacroName
= MacroName
[1:].strip()
474 if not MacroName
.startswith('$(') or not MacroName
.endswith(')'):
475 raise Warning("Macro name expected(Please use '$(%(Token)s)' if '%(Token)s' is a macro.)" % {"Token" : MacroName
},
476 self
.FileName
, self
.CurrentLineNumber
)
477 MacroName
= MacroName
[2:-1]
478 return MacroName
, NotFlag
480 def __SetMacroValue(self
, Macro
, Value
):
481 if not self
.__CurSection
:
485 if not self
.__MacroDict
[self
.__CurSection
[0], self
.__CurSection
[1], self
.__CurSection
[2]]:
486 self
.__MacroDict
[self
.__CurSection
[0], self
.__CurSection
[1], self
.__CurSection
[2]] = MacroDict
488 MacroDict
= self
.__MacroDict
[self
.__CurSection
[0], self
.__CurSection
[1], self
.__CurSection
[2]]
489 MacroDict
[Macro
] = Value
491 def __GetMacroValue(self
, Macro
):
493 if Macro
in GlobalData
.gCommandLineDefines
:
494 return GlobalData
.gCommandLineDefines
[Macro
]
495 if Macro
in GlobalData
.gGlobalDefines
:
496 return GlobalData
.gGlobalDefines
[Macro
]
498 if self
.__CurSection
:
499 MacroDict
= self
.__MacroDict
[
500 self
.__CurSection
[0],
501 self
.__CurSection
[1],
504 if MacroDict
and Macro
in MacroDict
:
505 return MacroDict
[Macro
]
508 if Macro
in GlobalData
.gPlatformDefines
:
509 return GlobalData
.gPlatformDefines
[Macro
]
512 def __SectionHeaderParser(self
, Section
):
514 # [FD.UiName]: use dummy instead if UI name is optional
517 # [Rule]: don't take rule section into account, macro is not allowed in this section
518 # [VTF.arch.UiName, arch]
519 # [OptionRom.DriverName]
520 self
.__CurSection
= []
521 Section
= Section
.strip()[1:-1].upper().replace(' ', '').strip('.')
522 ItemList
= Section
.split('.')
524 if Item
== '' or Item
== 'RULE':
527 if Item
== 'DEFINES':
528 self
.__CurSection
= ['COMMON', 'COMMON', 'COMMON']
529 elif Item
== 'VTF' and len(ItemList
) == 3:
531 Pos
= UiName
.find(',')
533 UiName
= UiName
[:Pos
]
534 self
.__CurSection
= ['VTF', UiName
, ItemList
[1]]
535 elif len(ItemList
) > 1:
536 self
.__CurSection
= [ItemList
[0], ItemList
[1], 'COMMON']
537 elif len(ItemList
) > 0:
538 self
.__CurSection
= [ItemList
[0], 'DUMMY', 'COMMON']
540 ## PreprocessFile() method
542 # Preprocess file contents, replace comments with spaces.
543 # In the end, rewind the file buffer pointer to the beginning
544 # BUGBUG: No !include statement processing contained in this procedure
545 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
547 # @param self The object pointer
549 def PreprocessFile(self
):
553 DoubleSlashComment
= False
555 # HashComment in quoted string " " is ignored.
558 while not self
.__EndOfFile
():
560 if self
.__CurrentChar
() == T_CHAR_DOUBLE_QUOTE
and not InComment
:
561 InString
= not InString
562 # meet new line, then no longer in a comment for // and '#'
563 if self
.__CurrentChar
() == T_CHAR_LF
:
564 self
.CurrentLineNumber
+= 1
565 self
.CurrentOffsetWithinLine
= 0
566 if InComment
and DoubleSlashComment
:
568 DoubleSlashComment
= False
569 if InComment
and HashComment
:
572 # check for */ comment end
573 elif InComment
and not DoubleSlashComment
and not HashComment
and self
.__CurrentChar
() == T_CHAR_STAR
and self
.__NextChar
() == T_CHAR_SLASH
:
574 self
.__SetCurrentCharValue
(T_CHAR_SPACE
)
576 self
.__SetCurrentCharValue
(T_CHAR_SPACE
)
579 # set comments to spaces
581 self
.__SetCurrentCharValue
(T_CHAR_SPACE
)
583 # check for // comment
584 elif self
.__CurrentChar
() == T_CHAR_SLASH
and self
.__NextChar
() == T_CHAR_SLASH
and not self
.__EndOfLine
():
586 DoubleSlashComment
= True
587 # check for '#' comment
588 elif self
.__CurrentChar
() == T_CHAR_HASH
and not self
.__EndOfLine
() and not InString
:
591 # check for /* comment start
592 elif self
.__CurrentChar
() == T_CHAR_SLASH
and self
.__NextChar
() == T_CHAR_STAR
:
593 self
.__SetCurrentCharValue
( T_CHAR_SPACE
)
595 self
.__SetCurrentCharValue
( T_CHAR_SPACE
)
601 # restore from ListOfList to ListOfString
602 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
605 ## PreprocessIncludeFile() method
607 # Preprocess file contents, replace !include statements with file contents.
608 # In the end, rewind the file buffer pointer to the beginning
610 # @param self The object pointer
612 def PreprocessIncludeFile(self
):
613 # nested include support
616 while self
.__GetNextToken
():
618 if self
.__Token
== 'DEFINE':
619 if not self
.__GetNextToken
():
620 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
622 if not self
.__IsToken
( "="):
623 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
624 Value
= self
.__GetExpression
()
625 MacroDict
[Macro
] = Value
627 elif self
.__Token
== '!include':
629 IncludeLine
= self
.CurrentLineNumber
630 IncludeOffset
= self
.CurrentOffsetWithinLine
- len('!include')
631 if not self
.__GetNextToken
():
632 raise Warning("expected include file name", self
.FileName
, self
.CurrentLineNumber
)
633 IncFileName
= self
.__Token
635 StartPos
= IncFileName
.find('$(', PreIndex
)
636 EndPos
= IncFileName
.find(')', StartPos
+2)
637 while StartPos
!= -1 and EndPos
!= -1:
638 Macro
= IncFileName
[StartPos
+2 : EndPos
]
639 MacroVal
= self
.__GetMacroValue
(Macro
)
641 if Macro
in MacroDict
:
642 MacroVal
= MacroDict
[Macro
]
643 if MacroVal
is not None:
644 IncFileName
= IncFileName
.replace('$(' + Macro
+ ')', MacroVal
, 1)
645 if MacroVal
.find('$(') != -1:
648 PreIndex
= StartPos
+ len(MacroVal
)
650 raise Warning("The Macro %s is not defined" %Macro
, self
.FileName
, self
.CurrentLineNumber
)
651 StartPos
= IncFileName
.find('$(', PreIndex
)
652 EndPos
= IncFileName
.find(')', StartPos
+2)
654 IncludedFile
= NormPath(IncFileName
)
656 # First search the include file under the same directory as FDF file
658 IncludedFile1
= PathClass(IncludedFile
, os
.path
.dirname(self
.FileName
))
659 ErrorCode
= IncludedFile1
.Validate()[0]
662 # Then search the include file under the same directory as DSC file
665 if GenFdsGlobalVariable
.ActivePlatform
:
666 PlatformDir
= GenFdsGlobalVariable
.ActivePlatform
.Dir
667 elif GlobalData
.gActivePlatform
:
668 PlatformDir
= GlobalData
.gActivePlatform
.MetaFile
.Dir
669 IncludedFile1
= PathClass(IncludedFile
, PlatformDir
)
670 ErrorCode
= IncludedFile1
.Validate()[0]
673 # Also search file under the WORKSPACE directory
675 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
676 ErrorCode
= IncludedFile1
.Validate()[0]
678 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
),
679 self
.FileName
, self
.CurrentLineNumber
)
681 if not IsValidInclude (IncludedFile1
.Path
, self
.CurrentLineNumber
):
682 raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1
.Path
), self
.FileName
, self
.CurrentLineNumber
)
684 IncFileProfile
= IncludeFileProfile(IncludedFile1
.Path
)
686 CurrentLine
= self
.CurrentLineNumber
687 CurrentOffset
= self
.CurrentOffsetWithinLine
688 # list index of the insertion, note that line number is 'CurrentLine + 1'
689 InsertAtLine
= CurrentLine
690 ParentProfile
= GetParentAtLine (CurrentLine
)
691 if ParentProfile
is not None:
692 ParentProfile
.IncludeFileList
.insert(0, IncFileProfile
)
693 IncFileProfile
.Level
= ParentProfile
.Level
+ 1
694 IncFileProfile
.InsertStartLineNumber
= InsertAtLine
+ 1
695 # deal with remaining portions after "!include filename", if exists.
696 if self
.__GetNextToken
():
697 if self
.CurrentLineNumber
== CurrentLine
:
698 RemainingLine
= self
.__CurrentLine
()[CurrentOffset
:]
699 self
.Profile
.FileLinesList
.insert(self
.CurrentLineNumber
, RemainingLine
)
700 IncFileProfile
.InsertAdjust
+= 1
701 self
.CurrentLineNumber
+= 1
702 self
.CurrentOffsetWithinLine
= 0
704 for Line
in IncFileProfile
.FileLinesList
:
705 self
.Profile
.FileLinesList
.insert(InsertAtLine
, Line
)
706 self
.CurrentLineNumber
+= 1
709 # reversely sorted to better determine error in file
710 AllIncludeFileList
.insert(0, IncFileProfile
)
712 # comment out the processed include file statement
713 TempList
= list(self
.Profile
.FileLinesList
[IncludeLine
- 1])
714 TempList
.insert(IncludeOffset
, '#')
715 self
.Profile
.FileLinesList
[IncludeLine
- 1] = ''.join(TempList
)
716 if Processed
: # Nested and back-to-back support
717 self
.Rewind(DestLine
= IncFileProfile
.InsertStartLineNumber
- 1)
722 def __GetIfListCurrentItemStat(self
, IfList
):
732 ## PreprocessConditionalStatement() method
734 # Preprocess conditional statement.
735 # In the end, rewind the file buffer pointer to the beginning
737 # @param self The object pointer
739 def PreprocessConditionalStatement(self
):
740 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
744 while self
.__GetNextToken
():
745 # Determine section name and the location dependent macro
746 if self
.__GetIfListCurrentItemStat
(IfList
):
747 if self
.__Token
.startswith('['):
748 Header
= self
.__Token
749 if not self
.__Token
.endswith(']'):
750 self
.__SkipToToken
(']')
751 Header
+= self
.__SkippedChars
752 if Header
.find('$(') != -1:
753 raise Warning("macro cannot be used in section header", self
.FileName
, self
.CurrentLineNumber
)
754 self
.__SectionHeaderParser
(Header
)
756 # Replace macros except in RULE section or out of section
757 elif self
.__CurSection
and ReplacedLine
!= self
.CurrentLineNumber
:
758 ReplacedLine
= self
.CurrentLineNumber
760 CurLine
= self
.Profile
.FileLinesList
[ReplacedLine
- 1]
762 StartPos
= CurLine
.find('$(', PreIndex
)
763 EndPos
= CurLine
.find(')', StartPos
+2)
764 while StartPos
!= -1 and EndPos
!= -1 and self
.__Token
not in ['!ifdef', '!ifndef', '!if', '!elseif']:
765 MacroName
= CurLine
[StartPos
+2 : EndPos
]
766 MacorValue
= self
.__GetMacroValue
(MacroName
)
767 if MacorValue
is not None:
768 CurLine
= CurLine
.replace('$(' + MacroName
+ ')', MacorValue
, 1)
769 if MacorValue
.find('$(') != -1:
772 PreIndex
= StartPos
+ len(MacorValue
)
774 PreIndex
= EndPos
+ 1
775 StartPos
= CurLine
.find('$(', PreIndex
)
776 EndPos
= CurLine
.find(')', StartPos
+2)
777 self
.Profile
.FileLinesList
[ReplacedLine
- 1] = CurLine
780 if self
.__Token
== 'DEFINE':
781 if self
.__GetIfListCurrentItemStat
(IfList
):
782 if not self
.__CurSection
:
783 raise Warning("macro cannot be defined in Rule section or out of section", self
.FileName
, self
.CurrentLineNumber
)
784 DefineLine
= self
.CurrentLineNumber
- 1
785 DefineOffset
= self
.CurrentOffsetWithinLine
- len('DEFINE')
786 if not self
.__GetNextToken
():
787 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
789 if not self
.__IsToken
( "="):
790 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
792 Value
= self
.__GetExpression
()
793 self
.__SetMacroValue
(Macro
, Value
)
794 self
.__WipeOffArea
.append(((DefineLine
, DefineOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
795 elif self
.__Token
== 'SET':
796 if not self
.__GetIfListCurrentItemStat
(IfList
):
798 SetLine
= self
.CurrentLineNumber
- 1
799 SetOffset
= self
.CurrentOffsetWithinLine
- len('SET')
800 PcdPair
= self
.__GetNextPcdName
()
801 PcdName
= "%s.%s" % (PcdPair
[1], PcdPair
[0])
802 if not self
.__IsToken
( "="):
803 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
805 Value
= self
.__GetExpression
()
806 Value
= self
.__EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
808 self
.__PcdDict
[PcdName
] = Value
810 self
.Profile
.PcdDict
[PcdPair
] = Value
811 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
812 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
814 self
.__WipeOffArea
.append(((SetLine
, SetOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
815 elif self
.__Token
in ('!ifdef', '!ifndef', '!if'):
816 IfStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
.__Token
))
817 IfList
.append([IfStartPos
, None, None])
819 CondLabel
= self
.__Token
820 Expression
= self
.__GetExpression
()
822 if CondLabel
== '!if':
823 ConditionSatisfied
= self
.__EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
825 ConditionSatisfied
= self
.__EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'in')
826 if CondLabel
== '!ifndef':
827 ConditionSatisfied
= not ConditionSatisfied
829 BranchDetermined
= ConditionSatisfied
830 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, BranchDetermined
]
831 if ConditionSatisfied
:
832 self
.__WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
833 elif self
.__Token
in ('!elseif', '!else'):
834 ElseStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
.__Token
))
836 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
839 IfList
[-1] = [ElseStartPos
, False, True]
840 self
.__WipeOffArea
.append((ElseStartPos
, (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
842 self
.__WipeOffArea
.append((IfList
[-1][0], ElseStartPos
))
843 IfList
[-1] = [ElseStartPos
, True, IfList
[-1][2]]
844 if self
.__Token
== '!elseif':
845 Expression
= self
.__GetExpression
()
846 ConditionSatisfied
= self
.__EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
847 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, IfList
[-1][2]]
851 IfList
[-1][1] = False
854 self
.__WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
855 elif self
.__Token
== '!endif':
857 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
859 self
.__WipeOffArea
.append(((self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len('!endif')), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
861 self
.__WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
864 elif not IfList
: # Don't use PCDs inside conditional directive
865 if self
.CurrentLineNumber
<= RegionLayoutLine
:
866 # Don't try the same line twice
868 SetPcd
= ShortcutPcdPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
870 self
.__PcdDict
[SetPcd
.group('name')] = SetPcd
.group('value')
871 RegionLayoutLine
= self
.CurrentLineNumber
873 RegionSize
= RegionSizePattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
875 RegionLayoutLine
= self
.CurrentLineNumber
877 RegionSizeGuid
= RegionSizeGuidPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
])
878 if not RegionSizeGuid
:
879 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
881 self
.__PcdDict
[RegionSizeGuid
.group('base')] = RegionSize
.group('base')
882 self
.__PcdDict
[RegionSizeGuid
.group('size')] = RegionSize
.group('size')
883 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
886 raise Warning("Missing !endif", self
.FileName
, self
.CurrentLineNumber
)
889 def __CollectMacroPcd(self
):
893 MacroDict
.update(GlobalData
.gPlatformPcds
)
894 MacroDict
.update(self
.__PcdDict
)
897 MacroDict
.update(GlobalData
.gPlatformDefines
)
899 if self
.__CurSection
:
901 ScopeMacro
= self
.__MacroDict
['COMMON', 'COMMON', 'COMMON']
903 MacroDict
.update(ScopeMacro
)
906 ScopeMacro
= self
.__MacroDict
[
907 self
.__CurSection
[0],
908 self
.__CurSection
[1],
912 MacroDict
.update(ScopeMacro
)
914 MacroDict
.update(GlobalData
.gGlobalDefines
)
915 MacroDict
.update(GlobalData
.gCommandLineDefines
)
916 if GlobalData
.BuildOptionPcd
:
917 for Item
in GlobalData
.BuildOptionPcd
:
918 if type(Item
) is tuple:
920 PcdName
, TmpValue
= Item
.split("=")
921 TmpValue
= BuildOptionValue(TmpValue
, {})
922 MacroDict
[PcdName
.strip()] = TmpValue
927 def __EvaluateConditional(self
, Expression
, Line
, Op
= None, Value
= None):
928 FileLineTuple
= GetRealFileLine(self
.FileName
, Line
)
929 MacroPcdDict
= self
.__CollectMacroPcd
()
933 return ValueExpression(Expression
, MacroPcdDict
)(True)
935 return ValueExpression(Expression
, MacroPcdDict
)()
936 except WrnExpression
, Excpt
:
938 # Catch expression evaluation warning here. We need to report
939 # the precise number of line and return the evaluation result
941 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
942 File
=self
.FileName
, ExtraData
=self
.__CurrentLine
(),
945 except Exception, Excpt
:
946 if hasattr(Excpt
, 'Pcd'):
947 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
948 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
949 raise Warning("Cannot use this PCD (%s) in an expression as"
950 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
951 " of the DSC file (%s), and it is currently defined in this section:"
952 " %s, line #: %d." % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE'], Info
[0], Info
[1]),
955 raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE']),
958 raise Warning(str(Excpt
), *FileLineTuple
)
960 if Expression
.startswith('$(') and Expression
[-1] == ')':
961 Expression
= Expression
[2:-1]
962 return Expression
in MacroPcdDict
964 ## __IsToken() method
966 # Check whether input string is found from current char position along
967 # If found, the string value is put into self.__Token
969 # @param self The object pointer
970 # @param String The string to search
971 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
972 # @retval True Successfully find string, file buffer pointer moved forward
973 # @retval False Not able to find string, file buffer pointer not changed
975 def __IsToken(self
, String
, IgnoreCase
= False):
976 self
.__SkipWhiteSpace
()
978 # Only consider the same line, no multi-line token allowed
979 StartPos
= self
.CurrentOffsetWithinLine
982 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
984 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
986 self
.CurrentOffsetWithinLine
+= len(String
)
987 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
991 ## __IsKeyword() method
993 # Check whether input keyword is found from current char position along, whole word only!
994 # If found, the string value is put into self.__Token
996 # @param self The object pointer
997 # @param Keyword The string to search
998 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
999 # @retval True Successfully find string, file buffer pointer moved forward
1000 # @retval False Not able to find string, file buffer pointer not changed
1002 def __IsKeyword(self
, KeyWord
, IgnoreCase
= False):
1003 self
.__SkipWhiteSpace
()
1005 # Only consider the same line, no multi-line token allowed
1006 StartPos
= self
.CurrentOffsetWithinLine
1009 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(KeyWord
.upper())
1011 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(KeyWord
)
1013 followingChar
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
+ len(KeyWord
)]
1014 if not str(followingChar
).isspace() and followingChar
not in SEPERATOR_TUPLE
:
1016 self
.CurrentOffsetWithinLine
+= len(KeyWord
)
1017 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1021 def __GetExpression(self
):
1022 Line
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
1023 Index
= len(Line
) - 1
1024 while Line
[Index
] in ['\r', '\n']:
1026 ExpressionString
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:Index
+1]
1027 self
.CurrentOffsetWithinLine
+= len(ExpressionString
)
1028 ExpressionString
= ExpressionString
.strip()
1029 return ExpressionString
1031 ## __GetNextWord() method
1033 # Get next C name from file lines
1034 # If found, the string value is put into self.__Token
1036 # @param self The object pointer
1037 # @retval True Successfully find a C name string, file buffer pointer moved forward
1038 # @retval False Not able to find a C name string, file buffer pointer not changed
1040 def __GetNextWord(self
):
1041 self
.__SkipWhiteSpace
()
1042 if self
.__EndOfFile
():
1045 TempChar
= self
.__CurrentChar
()
1046 StartPos
= self
.CurrentOffsetWithinLine
1047 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_':
1049 while not self
.__EndOfLine
():
1050 TempChar
= self
.__CurrentChar
()
1051 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
1052 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-':
1058 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1063 ## __GetNextToken() method
1065 # Get next token unit before a seperator
1066 # If found, the string value is put into self.__Token
1068 # @param self The object pointer
1069 # @retval True Successfully find a token unit, file buffer pointer moved forward
1070 # @retval False Not able to find a token unit, file buffer pointer not changed
1072 def __GetNextToken(self
):
1073 # Skip leading spaces, if exist.
1074 self
.__SkipWhiteSpace
()
1075 if self
.__EndOfFile
():
1077 # Record the token start position, the position of the first non-space char.
1078 StartPos
= self
.CurrentOffsetWithinLine
1079 StartLine
= self
.CurrentLineNumber
1080 while StartLine
== self
.CurrentLineNumber
:
1081 TempChar
= self
.__CurrentChar
()
1082 # Try to find the end char that is not a space and not in seperator tuple.
1083 # That is, when we got a space or any char in the tuple, we got the end of token.
1084 if not str(TempChar
).isspace() and TempChar
not in SEPERATOR_TUPLE
:
1086 # if we happen to meet a seperator as the first char, we must proceed to get it.
1087 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1088 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPERATOR_TUPLE
:
1096 EndPos
= self
.CurrentOffsetWithinLine
1097 if self
.CurrentLineNumber
!= StartLine
:
1098 EndPos
= len(self
.Profile
.FileLinesList
[StartLine
-1])
1099 self
.__Token
= self
.Profile
.FileLinesList
[StartLine
-1][StartPos
: EndPos
]
1100 if StartPos
!= self
.CurrentOffsetWithinLine
:
1105 def __GetNextOp(self
):
1106 # Skip leading spaces, if exist.
1107 self
.__SkipWhiteSpace
()
1108 if self
.__EndOfFile
():
1110 # Record the token start position, the position of the first non-space char.
1111 StartPos
= self
.CurrentOffsetWithinLine
1112 while not self
.__EndOfLine
():
1113 TempChar
= self
.__CurrentChar
()
1114 # Try to find the end char that is not a space
1115 if not str(TempChar
).isspace():
1122 if StartPos
!= self
.CurrentOffsetWithinLine
:
1123 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1127 ## __GetNextGuid() method
1129 # Get next token unit before a seperator
1130 # If found, the GUID string is put into self.__Token
1132 # @param self The object pointer
1133 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward
1134 # @retval False Not able to find a registry format GUID, file buffer pointer not changed
1136 def __GetNextGuid(self
):
1138 if not self
.__GetNextToken
():
1140 if gGuidPattern
.match(self
.__Token
) is not None:
1146 def __Verify(self
, Name
, Value
, Scope
):
1147 if Scope
in ['UINT64', 'UINT8']:
1150 ValueNumber
= int (Value
, 0)
1152 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value is not valid dec or hex number for %s." % Name
)
1154 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value can't be set to negative value for %s." % Name
)
1155 if Scope
== 'UINT64':
1156 if ValueNumber
>= 0x10000000000000000:
1157 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "Too large value for %s." % Name
)
1158 if Scope
== 'UINT8':
1159 if ValueNumber
>= 0x100:
1160 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "Too large value for %s." % Name
)
1163 ## __UndoToken() method
1165 # Go back one token unit in file buffer
1167 # @param self The object pointer
1169 def __UndoToken(self
):
1170 self
.__UndoOneChar
()
1171 while self
.__CurrentChar
().isspace():
1172 if not self
.__UndoOneChar
():
1177 StartPos
= self
.CurrentOffsetWithinLine
1178 CurrentLine
= self
.CurrentLineNumber
1179 while CurrentLine
== self
.CurrentLineNumber
:
1181 TempChar
= self
.__CurrentChar
()
1182 # Try to find the end char that is not a space and not in seperator tuple.
1183 # That is, when we got a space or any char in the tuple, we got the end of token.
1184 if not str(TempChar
).isspace() and not TempChar
in SEPERATOR_TUPLE
:
1185 if not self
.__UndoOneChar
():
1187 # if we happen to meet a seperator as the first char, we must proceed to get it.
1188 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1189 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPERATOR_TUPLE
:
1196 def __IsHex(self
, HexStr
):
1197 if not HexStr
.upper().startswith("0X"):
1199 if len(self
.__Token
) <= 2:
1201 return True if all(x
in string
.hexdigits
for x
in HexStr
[2:]) else False
1203 ## __GetNextHexNumber() method
1205 # Get next HEX data before a seperator
1206 # If found, the HEX data is put into self.__Token
1208 # @param self The object pointer
1209 # @retval True Successfully find a HEX data, file buffer pointer moved forward
1210 # @retval False Not able to find a HEX data, file buffer pointer not changed
1212 def __GetNextHexNumber(self
):
1213 if not self
.__GetNextToken
():
1215 if self
.__IsHex
(self
.__Token
):
1221 ## __GetNextDecimalNumber() method
1223 # Get next decimal data before a seperator
1224 # If found, the decimal data is put into self.__Token
1226 # @param self The object pointer
1227 # @retval True Successfully find a decimal data, file buffer pointer moved forward
1228 # @retval False Not able to find a decimal data, file buffer pointer not changed
1230 def __GetNextDecimalNumber(self
):
1231 if not self
.__GetNextToken
():
1233 if self
.__Token
.isdigit():
1239 ## __GetNextPcdName() method
1241 # Get next PCD token space C name and PCD C name pair before a seperator
1242 # If found, the decimal data is put into self.__Token
1244 # @param self The object pointer
1245 # @retval Tuple PCD C name and PCD token space C name pair
1247 def __GetNextPcdName(self
):
1248 if not self
.__GetNextWord
():
1249 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1250 pcdTokenSpaceCName
= self
.__Token
1252 if not self
.__IsToken
( "."):
1253 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1255 if not self
.__GetNextWord
():
1256 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1257 pcdCName
= self
.__Token
1259 return (pcdCName
, pcdTokenSpaceCName
)
1261 ## __GetStringData() method
1263 # Get string contents quoted in ""
1264 # If found, the decimal data is put into self.__Token
1266 # @param self The object pointer
1267 # @retval True Successfully find a string data, file buffer pointer moved forward
1268 # @retval False Not able to find a string data, file buffer pointer not changed
1270 def __GetStringData(self
):
1271 if self
.__Token
.startswith("\"") or self
.__Token
.startswith("L\""):
1273 self
.__SkipToToken
("\"")
1274 currentLineNumber
= self
.CurrentLineNumber
1276 if not self
.__SkipToToken
("\""):
1277 raise Warning("Missing Quote \" for String", self
.FileName
, self
.CurrentLineNumber
)
1278 if currentLineNumber
!= self
.CurrentLineNumber
:
1279 raise Warning("Missing Quote \" for String", self
.FileName
, self
.CurrentLineNumber
)
1280 self
.__Token
= self
.__SkippedChars
.rstrip('\"')
1283 elif self
.__Token
.startswith("\'") or self
.__Token
.startswith("L\'"):
1285 self
.__SkipToToken
("\'")
1286 currentLineNumber
= self
.CurrentLineNumber
1288 if not self
.__SkipToToken
("\'"):
1289 raise Warning("Missing Quote \' for String", self
.FileName
, self
.CurrentLineNumber
)
1290 if currentLineNumber
!= self
.CurrentLineNumber
:
1291 raise Warning("Missing Quote \' for String", self
.FileName
, self
.CurrentLineNumber
)
1292 self
.__Token
= self
.__SkippedChars
.rstrip('\'')
1298 ## __SkipToToken() method
1300 # Search forward in file buffer for the string
1301 # The skipped chars are put into self.__SkippedChars
1303 # @param self The object pointer
1304 # @param String The string to search
1305 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
1306 # @retval True Successfully find the string, file buffer pointer moved forward
1307 # @retval False Not able to find the string, file buffer pointer not changed
1309 def __SkipToToken(self
, String
, IgnoreCase
= False):
1310 StartPos
= self
.GetFileBufferPos()
1312 self
.__SkippedChars
= ""
1313 while not self
.__EndOfFile
():
1316 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
1318 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
1320 self
.CurrentOffsetWithinLine
+= len(String
)
1321 self
.__SkippedChars
+= String
1323 self
.__SkippedChars
+= str(self
.__CurrentChar
())
1326 self
.SetFileBufferPos( StartPos
)
1327 self
.__SkippedChars
= ""
1330 ## GetFileBufferPos() method
1332 # Return the tuple of current line and offset within the line
1334 # @param self The object pointer
1335 # @retval Tuple Line number and offset pair
1337 def GetFileBufferPos(self
):
1338 return (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
)
1340 ## SetFileBufferPos() method
1342 # Restore the file buffer position
1344 # @param self The object pointer
1345 # @param Pos The new file buffer position
1347 def SetFileBufferPos(self
, Pos
):
1348 (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
) = Pos
1350 ## Preprocess() method
1352 # Preprocess comment, conditional directive, include directive, replace macro.
1353 # Exception will be raised if syntax error found
1355 # @param self The object pointer
1357 def Preprocess(self
):
1358 self
.__StringToList
()
1359 self
.PreprocessFile()
1360 self
.PreprocessIncludeFile()
1361 self
.__StringToList
()
1362 self
.PreprocessFile()
1363 self
.PreprocessConditionalStatement()
1364 self
.__StringToList
()
1365 for Pos
in self
.__WipeOffArea
:
1366 self
.__ReplaceFragment
(Pos
[0], Pos
[1])
1367 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
1369 while self
.__GetDefines
():
1372 ## ParseFile() method
1374 # Parse the file profile buffer to extract fd, fv ... information
1375 # Exception will be raised if syntax error found
1377 # @param self The object pointer
1379 def ParseFile(self
):
1384 # Keep processing sections of the FDF until no new sections or a syntax error is found
1386 while self
.__GetFd
() or self
.__GetFv
() or self
.__GetFmp
() or self
.__GetCapsule
() or self
.__GetVtf
() or self
.__GetRule
() or self
.__GetOptionRom
():
1391 #'\n\tGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \
1392 # At this point, the closest parent would be the included file itself
1393 Profile
= GetParentAtLine(X
.OriginalLineNumber
)
1394 if Profile
is not None:
1395 X
.Message
+= ' near line %d, column %d: %s' \
1396 % (X
.LineNumber
, 0, Profile
.FileLinesList
[X
.LineNumber
-1])
1398 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1399 X
.Message
+= ' near line %d, column %d: %s' \
1400 % (FileLineTuple
[1], self
.CurrentOffsetWithinLine
+ 1, self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:].rstrip('\n').rstrip('\r'))
1403 ## SectionParser() method
1405 # Parse the file section info
1406 # Exception will be raised if syntax error found
1408 # @param self The object pointer
1409 # @param section The section string
1411 def SectionParser(self
, section
):
1413 if not S
.startswith("[DEFINES") and not S
.startswith("[FD.") and not S
.startswith("[FV.") and not S
.startswith("[CAPSULE.") \
1414 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM.") and not S
.startswith('[FMPPAYLOAD.'):
1415 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
)
1417 ## __GetDefines() method
1419 # Get Defines section contents and store its data into AllMacrosList
1421 # @param self The object pointer
1422 # @retval True Successfully find a Defines
1423 # @retval False Not able to find a Defines
1425 def __GetDefines(self
):
1427 if not self
.__GetNextToken
():
1430 S
= self
.__Token
.upper()
1431 if S
.startswith("[") and not S
.startswith("[DEFINES"):
1432 self
.SectionParser(S
)
1437 if not self
.__IsToken
("[DEFINES", True):
1438 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1439 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1440 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1441 raise Warning("expected [DEFINES", self
.FileName
, self
.CurrentLineNumber
)
1443 if not self
.__IsToken
( "]"):
1444 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
1446 while self
.__GetNextWord
():
1447 # handle the SET statement
1448 if self
.__Token
== 'SET':
1450 self
.__GetSetStatement
(None)
1453 Macro
= self
.__Token
1455 if not self
.__IsToken
("="):
1456 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1457 if not self
.__GetNextToken
() or self
.__Token
.startswith('['):
1458 raise Warning("expected MACRO value", self
.FileName
, self
.CurrentLineNumber
)
1459 Value
= self
.__Token
1465 # Get FD section contents and store its data into FD dictionary of self.Profile
1467 # @param self The object pointer
1468 # @retval True Successfully find a FD
1469 # @retval False Not able to find a FD
1473 if not self
.__GetNextToken
():
1476 S
= self
.__Token
.upper()
1477 if S
.startswith("[") and not S
.startswith("[FD."):
1478 if not S
.startswith("[FV.") and not S
.startswith('[FMPPAYLOAD.') and not S
.startswith("[CAPSULE.") \
1479 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM."):
1480 raise Warning("Unknown section", self
.FileName
, self
.CurrentLineNumber
)
1485 if not self
.__IsToken
("[FD.", True):
1486 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1487 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1488 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1489 raise Warning("expected [FD.]", self
.FileName
, self
.CurrentLineNumber
)
1491 FdName
= self
.__GetUiName
()
1493 if len (self
.Profile
.FdDict
) == 0:
1494 FdName
= GenFdsGlobalVariable
.PlatformName
1495 if FdName
== "" and GlobalData
.gActivePlatform
:
1496 FdName
= GlobalData
.gActivePlatform
.PlatformName
1497 self
.Profile
.FdNameNotSet
= True
1499 raise Warning("expected FdName in [FD.] section", self
.FileName
, self
.CurrentLineNumber
)
1500 self
.CurrentFdName
= FdName
.upper()
1502 if self
.CurrentFdName
in self
.Profile
.FdDict
:
1503 raise Warning("Unexpected the same FD name", self
.FileName
, self
.CurrentLineNumber
)
1505 if not self
.__IsToken
( "]"):
1506 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
1509 FdObj
.FdUiName
= self
.CurrentFdName
1510 self
.Profile
.FdDict
[self
.CurrentFdName
] = FdObj
1512 if len (self
.Profile
.FdDict
) > 1 and self
.Profile
.FdNameNotSet
:
1513 raise Warning("expected all FDs have their name", self
.FileName
, self
.CurrentLineNumber
)
1515 Status
= self
.__GetCreateFile
(FdObj
)
1517 raise Warning("FD name error", self
.FileName
, self
.CurrentLineNumber
)
1519 while self
.__GetTokenStatements
(FdObj
):
1521 for Attr
in ("BaseAddress", "Size", "ErasePolarity"):
1522 if getattr(FdObj
, Attr
) is None:
1523 self
.__GetNextToken
()
1524 raise Warning("Keyword %s missing" % Attr
, self
.FileName
, self
.CurrentLineNumber
)
1526 if not FdObj
.BlockSizeList
:
1527 FdObj
.BlockSizeList
.append((1, FdObj
.Size
, None))
1529 self
.__GetDefineStatements
(FdObj
)
1531 self
.__GetSetStatements
(FdObj
)
1533 if not self
.__GetRegionLayout
(FdObj
):
1534 raise Warning("expected region layout", self
.FileName
, self
.CurrentLineNumber
)
1536 while self
.__GetRegionLayout
(FdObj
):
1540 ## __GetUiName() method
1542 # Return the UI name of a section
1544 # @param self The object pointer
1545 # @retval FdName UI name
1547 def __GetUiName(self
):
1549 if self
.__GetNextWord
():
1554 ## __GetCreateFile() method
1556 # Return the output file name of object
1558 # @param self The object pointer
1559 # @param Obj object whose data will be stored in file
1560 # @retval FdName UI name
1562 def __GetCreateFile(self
, Obj
):
1564 if self
.__IsKeyword
( "CREATE_FILE"):
1565 if not self
.__IsToken
( "="):
1566 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1568 if not self
.__GetNextToken
():
1569 raise Warning("expected file name", self
.FileName
, self
.CurrentLineNumber
)
1571 FileName
= self
.__Token
1572 Obj
.CreateFileName
= FileName
1576 ## __GetTokenStatements() method
1578 # Get token statements
1580 # @param self The object pointer
1581 # @param Obj for whom token statement is got
1583 def __GetTokenStatements(self
, Obj
):
1584 if self
.__IsKeyword
( "BaseAddress"):
1585 if not self
.__IsToken
( "="):
1586 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1588 if not self
.__GetNextHexNumber
():
1589 raise Warning("expected Hex base address", self
.FileName
, self
.CurrentLineNumber
)
1591 Obj
.BaseAddress
= self
.__Token
1593 if self
.__IsToken
( "|"):
1594 pcdPair
= self
.__GetNextPcdName
()
1595 Obj
.BaseAddressPcd
= pcdPair
1596 self
.Profile
.PcdDict
[pcdPair
] = Obj
.BaseAddress
1597 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1598 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1601 if self
.__IsKeyword
( "Size"):
1602 if not self
.__IsToken
( "="):
1603 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1605 if not self
.__GetNextHexNumber
():
1606 raise Warning("expected Hex size", self
.FileName
, self
.CurrentLineNumber
)
1609 if self
.__IsToken
( "|"):
1610 pcdPair
= self
.__GetNextPcdName
()
1611 Obj
.SizePcd
= pcdPair
1612 self
.Profile
.PcdDict
[pcdPair
] = Size
1613 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1614 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1615 Obj
.Size
= long(Size
, 0)
1618 if self
.__IsKeyword
( "ErasePolarity"):
1619 if not self
.__IsToken
( "="):
1620 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1622 if not self
.__GetNextToken
():
1623 raise Warning("expected Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1625 if self
.__Token
!= "1" and self
.__Token
!= "0":
1626 raise Warning("expected 1 or 0 Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1628 Obj
.ErasePolarity
= self
.__Token
1631 return self
.__GetBlockStatements
(Obj
)
1633 ## __GetAddressStatements() method
1635 # Get address statements
1637 # @param self The object pointer
1638 # @param Obj for whom address statement is got
1639 # @retval True Successfully find
1640 # @retval False Not able to find
1642 def __GetAddressStatements(self
, Obj
):
1644 if self
.__IsKeyword
("BsBaseAddress"):
1645 if not self
.__IsToken
( "="):
1646 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1648 if not self
.__GetNextDecimalNumber
() and not self
.__GetNextHexNumber
():
1649 raise Warning("expected address", self
.FileName
, self
.CurrentLineNumber
)
1651 BsAddress
= long(self
.__Token
, 0)
1652 Obj
.BsBaseAddress
= BsAddress
1654 if self
.__IsKeyword
("RtBaseAddress"):
1655 if not self
.__IsToken
( "="):
1656 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1658 if not self
.__GetNextDecimalNumber
() and not self
.__GetNextHexNumber
():
1659 raise Warning("expected address", self
.FileName
, self
.CurrentLineNumber
)
1661 RtAddress
= long(self
.__Token
, 0)
1662 Obj
.RtBaseAddress
= RtAddress
1664 ## __GetBlockStatements() method
1666 # Get block statements
1668 # @param self The object pointer
1669 # @param Obj for whom block statement is got
1671 def __GetBlockStatements(self
, Obj
):
1673 while self
.__GetBlockStatement
(Obj
):
1676 Item
= Obj
.BlockSizeList
[-1]
1677 if Item
[0] is None or Item
[1] is None:
1678 raise Warning("expected block statement", self
.FileName
, self
.CurrentLineNumber
)
1681 ## __GetBlockStatement() method
1683 # Get block statement
1685 # @param self The object pointer
1686 # @param Obj for whom block statement is got
1687 # @retval True Successfully find
1688 # @retval False Not able to find
1690 def __GetBlockStatement(self
, Obj
):
1691 if not self
.__IsKeyword
( "BlockSize"):
1694 if not self
.__IsToken
( "="):
1695 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1697 if not self
.__GetNextHexNumber
() and not self
.__GetNextDecimalNumber
():
1698 raise Warning("expected Hex or Integer block size", self
.FileName
, self
.CurrentLineNumber
)
1700 BlockSize
= self
.__Token
1702 if self
.__IsToken
( "|"):
1703 PcdPair
= self
.__GetNextPcdName
()
1704 BlockSizePcd
= PcdPair
1705 self
.Profile
.PcdDict
[PcdPair
] = BlockSize
1706 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1707 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1708 BlockSize
= long(BlockSize
, 0)
1711 if self
.__IsKeyword
( "NumBlocks"):
1712 if not self
.__IsToken
( "="):
1713 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1715 if not self
.__GetNextDecimalNumber
() and not self
.__GetNextHexNumber
():
1716 raise Warning("expected block numbers", self
.FileName
, self
.CurrentLineNumber
)
1718 BlockNumber
= long(self
.__Token
, 0)
1720 Obj
.BlockSizeList
.append((BlockSize
, BlockNumber
, BlockSizePcd
))
1723 ## __GetDefineStatements() method
1725 # Get define statements
1727 # @param self The object pointer
1728 # @param Obj for whom define statement is got
1729 # @retval True Successfully find
1730 # @retval False Not able to find
1732 def __GetDefineStatements(self
, Obj
):
1733 while self
.__GetDefineStatement
( Obj
):
1736 ## __GetDefineStatement() method
1738 # Get define statement
1740 # @param self The object pointer
1741 # @param Obj for whom define statement is got
1742 # @retval True Successfully find
1743 # @retval False Not able to find
1745 def __GetDefineStatement(self
, Obj
):
1746 if self
.__IsKeyword
("DEFINE"):
1747 self
.__GetNextToken
()
1748 Macro
= self
.__Token
1749 if not self
.__IsToken
( "="):
1750 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1752 if not self
.__GetNextToken
():
1753 raise Warning("expected value", self
.FileName
, self
.CurrentLineNumber
)
1755 Value
= self
.__Token
1756 Macro
= '$(' + Macro
+ ')'
1757 Obj
.DefineVarDict
[Macro
] = Value
1762 ## __GetSetStatements() method
1764 # Get set statements
1766 # @param self The object pointer
1767 # @param Obj for whom set statement is got
1768 # @retval True Successfully find
1769 # @retval False Not able to find
1771 def __GetSetStatements(self
, Obj
):
1772 while self
.__GetSetStatement
(Obj
):
1775 ## __GetSetStatement() method
1779 # @param self The object pointer
1780 # @param Obj for whom set statement is got
1781 # @retval True Successfully find
1782 # @retval False Not able to find
1784 def __GetSetStatement(self
, Obj
):
1785 if self
.__IsKeyword
("SET"):
1786 PcdPair
= self
.__GetNextPcdName
()
1788 if not self
.__IsToken
( "="):
1789 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1791 Value
= self
.__GetExpression
()
1792 Value
= self
.__EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
1795 Obj
.SetVarDict
[PcdPair
] = Value
1796 self
.Profile
.PcdDict
[PcdPair
] = Value
1797 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1798 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1803 ## __CalcRegionExpr(self)
1805 # Calculate expression for offset or size of a region
1807 # @return: None if invalid expression
1808 # Calculated number if successfully
1810 def __CalcRegionExpr(self
):
1811 StartPos
= self
.GetFileBufferPos()
1814 while not self
.__EndOfFile
():
1815 CurCh
= self
.__CurrentChar
()
1821 if CurCh
in '|\r\n' and PairCount
== 0:
1827 ValueExpression(Expr
,
1828 self
.__CollectMacroPcd
()
1831 self
.SetFileBufferPos(StartPos
)
1834 ## __GetRegionLayout() method
1836 # Get region layout for FD
1838 # @param self The object pointer
1839 # @param Fd for whom region is got
1840 # @retval True Successfully find
1841 # @retval False Not able to find
1843 def __GetRegionLayout(self
, Fd
):
1844 Offset
= self
.__CalcRegionExpr
()
1848 RegionObj
= Region
.Region()
1849 RegionObj
.Offset
= Offset
1850 Fd
.RegionList
.append(RegionObj
)
1852 if not self
.__IsToken
( "|"):
1853 raise Warning("expected '|'", self
.FileName
, self
.CurrentLineNumber
)
1855 Size
= self
.__CalcRegionExpr
()
1857 raise Warning("expected Region Size", self
.FileName
, self
.CurrentLineNumber
)
1858 RegionObj
.Size
= Size
1860 if not self
.__GetNextWord
():
1863 if not self
.__Token
in ("SET", "FV", "FILE", "DATA", "CAPSULE", "INF"):
1865 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]
1866 # Or it might be next region's offset described by an expression which starts with a PCD.
1867 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size
1870 IsRegionPcd
= (RegionSizeGuidPattern
.match(self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
:]) or
1871 RegionOffsetPcdPattern
.match(self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
:]))
1873 RegionObj
.PcdOffset
= self
.__GetNextPcdName
()
1874 self
.Profile
.PcdDict
[RegionObj
.PcdOffset
] = "0x%08X" % (RegionObj
.Offset
+ long(Fd
.BaseAddress
, 0))
1875 self
.__PcdDict
['%s.%s' % (RegionObj
.PcdOffset
[1], RegionObj
.PcdOffset
[0])] = "0x%x" % RegionObj
.Offset
1876 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1877 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdOffset
] = FileLineTuple
1878 if self
.__IsToken
( "|"):
1879 RegionObj
.PcdSize
= self
.__GetNextPcdName
()
1880 self
.Profile
.PcdDict
[RegionObj
.PcdSize
] = "0x%08X" % RegionObj
.Size
1881 self
.__PcdDict
['%s.%s' % (RegionObj
.PcdSize
[1], RegionObj
.PcdSize
[0])] = "0x%x" % RegionObj
.Size
1882 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1883 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdSize
] = FileLineTuple
1885 if not self
.__GetNextWord
():
1888 if self
.__Token
== "SET":
1890 self
.__GetSetStatements
( RegionObj
)
1891 if not self
.__GetNextWord
():
1894 elif self
.__Token
== "FV":
1896 self
.__GetRegionFvType
( RegionObj
)
1898 elif self
.__Token
== "CAPSULE":
1900 self
.__GetRegionCapType
( RegionObj
)
1902 elif self
.__Token
== "FILE":
1904 self
.__GetRegionFileType
(RegionObj
)
1906 elif self
.__Token
== "INF":
1908 RegionObj
.RegionType
= "INF"
1909 while self
.__IsKeyword
("INF"):
1911 ffsInf
= self
.__ParseInfStatement
()
1914 RegionObj
.RegionDataList
.append(ffsInf
)
1916 elif self
.__Token
== "DATA":
1918 self
.__GetRegionDataType
(RegionObj
)
1921 if self
.__GetRegionLayout
(Fd
):
1923 raise Warning("A valid region type was not found. "
1924 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
1925 self
.FileName
, self
.CurrentLineNumber
)
1929 ## __GetRegionFvType() method
1931 # Get region fv data for region
1933 # @param self The object pointer
1934 # @param RegionObj for whom region data is got
1936 def __GetRegionFvType(self
, RegionObj
):
1938 if not self
.__IsKeyword
( "FV"):
1939 raise Warning("expected Keyword 'FV'", self
.FileName
, self
.CurrentLineNumber
)
1941 if not self
.__IsToken
( "="):
1942 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1944 if not self
.__GetNextToken
():
1945 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
1947 RegionObj
.RegionType
= "FV"
1948 RegionObj
.RegionDataList
.append((self
.__Token
).upper())
1950 while self
.__IsKeyword
( "FV"):
1952 if not self
.__IsToken
( "="):
1953 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1955 if not self
.__GetNextToken
():
1956 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
1958 RegionObj
.RegionDataList
.append((self
.__Token
).upper())
1960 ## __GetRegionCapType() method
1962 # Get region capsule data for region
1964 # @param self The object pointer
1965 # @param RegionObj for whom region data is got
1967 def __GetRegionCapType(self
, RegionObj
):
1969 if not self
.__IsKeyword
("CAPSULE"):
1970 raise Warning("expected Keyword 'CAPSULE'", self
.FileName
, self
.CurrentLineNumber
)
1972 if not self
.__IsToken
("="):
1973 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1975 if not self
.__GetNextToken
():
1976 raise Warning("expected CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1978 RegionObj
.RegionType
= "CAPSULE"
1979 RegionObj
.RegionDataList
.append(self
.__Token
)
1981 while self
.__IsKeyword
("CAPSULE"):
1983 if not self
.__IsToken
("="):
1984 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1986 if not self
.__GetNextToken
():
1987 raise Warning("expected CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1989 RegionObj
.RegionDataList
.append(self
.__Token
)
1991 ## __GetRegionFileType() method
1993 # Get region file data for region
1995 # @param self The object pointer
1996 # @param RegionObj for whom region data is got
1998 def __GetRegionFileType(self
, RegionObj
):
2000 if not self
.__IsKeyword
( "FILE"):
2001 raise Warning("expected Keyword 'FILE'", self
.FileName
, self
.CurrentLineNumber
)
2003 if not self
.__IsToken
( "="):
2004 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2006 if not self
.__GetNextToken
():
2007 raise Warning("expected File name", self
.FileName
, self
.CurrentLineNumber
)
2009 RegionObj
.RegionType
= "FILE"
2010 RegionObj
.RegionDataList
.append( self
.__Token
)
2012 while self
.__IsKeyword
( "FILE"):
2014 if not self
.__IsToken
( "="):
2015 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2017 if not self
.__GetNextToken
():
2018 raise Warning("expected FILE name", self
.FileName
, self
.CurrentLineNumber
)
2020 RegionObj
.RegionDataList
.append(self
.__Token
)
2022 ## __GetRegionDataType() method
2024 # Get region array data for region
2026 # @param self The object pointer
2027 # @param RegionObj for whom region data is got
2029 def __GetRegionDataType(self
, RegionObj
):
2031 if not self
.__IsKeyword
( "DATA"):
2032 raise Warning("expected Region Data type", self
.FileName
, self
.CurrentLineNumber
)
2034 if not self
.__IsToken
( "="):
2035 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2037 if not self
.__IsToken
( "{"):
2038 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2040 if not self
.__GetNextHexNumber
():
2041 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2043 if len(self
.__Token
) > 18:
2044 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2046 # convert hex string value to byte hex string array
2047 AllString
= self
.__Token
2048 AllStrLen
= len (AllString
)
2050 while AllStrLen
> 4:
2051 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + ","
2052 AllStrLen
= AllStrLen
- 2
2053 DataString
= DataString
+ AllString
[:AllStrLen
] + ","
2056 if len (self
.__Token
) <= 4:
2057 while self
.__IsToken
(","):
2058 if not self
.__GetNextHexNumber
():
2059 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2060 if len(self
.__Token
) > 4:
2061 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2062 DataString
+= self
.__Token
2065 if not self
.__IsToken
( "}"):
2066 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2068 DataString
= DataString
.rstrip(",")
2069 RegionObj
.RegionType
= "DATA"
2070 RegionObj
.RegionDataList
.append( DataString
)
2072 while self
.__IsKeyword
( "DATA"):
2074 if not self
.__IsToken
( "="):
2075 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2077 if not self
.__IsToken
( "{"):
2078 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2080 if not self
.__GetNextHexNumber
():
2081 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2083 if len(self
.__Token
) > 18:
2084 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2086 # convert hex string value to byte hex string array
2087 AllString
= self
.__Token
2088 AllStrLen
= len (AllString
)
2090 while AllStrLen
> 4:
2091 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + ","
2092 AllStrLen
= AllStrLen
- 2
2093 DataString
= DataString
+ AllString
[:AllStrLen
] + ","
2096 if len (self
.__Token
) <= 4:
2097 while self
.__IsToken
(","):
2098 if not self
.__GetNextHexNumber
():
2099 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2100 if len(self
.__Token
) > 4:
2101 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2102 DataString
+= self
.__Token
2105 if not self
.__IsToken
( "}"):
2106 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2108 DataString
= DataString
.rstrip(",")
2109 RegionObj
.RegionDataList
.append( DataString
)
2113 # Get FV section contents and store its data into FV dictionary of self.Profile
2115 # @param self The object pointer
2116 # @retval True Successfully find a FV
2117 # @retval False Not able to find a FV
2120 if not self
.__GetNextToken
():
2123 S
= self
.__Token
.upper()
2124 if S
.startswith("[") and not S
.startswith("[FV."):
2125 self
.SectionParser(S
)
2130 if not self
.__IsToken
("[FV.", True):
2131 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2132 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2133 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2134 raise Warning("Unknown Keyword '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2136 FvName
= self
.__GetUiName
()
2137 self
.CurrentFvName
= FvName
.upper()
2139 if not self
.__IsToken
( "]"):
2140 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
2143 FvObj
.UiFvName
= self
.CurrentFvName
2144 self
.Profile
.FvDict
[self
.CurrentFvName
] = FvObj
2146 Status
= self
.__GetCreateFile
(FvObj
)
2148 raise Warning("FV name error", self
.FileName
, self
.CurrentLineNumber
)
2150 self
.__GetDefineStatements
(FvObj
)
2152 self
.__GetAddressStatements
(FvObj
)
2154 FvObj
.FvExtEntryTypeValue
= []
2155 FvObj
.FvExtEntryType
= []
2156 FvObj
.FvExtEntryData
= []
2158 self
.__GetSetStatements
(FvObj
)
2160 if not (self
.__GetBlockStatement
(FvObj
) or self
.__GetFvBaseAddress
(FvObj
) or
2161 self
.__GetFvForceRebase
(FvObj
) or self
.__GetFvAlignment
(FvObj
) or
2162 self
.__GetFvAttributes
(FvObj
) or self
.__GetFvNameGuid
(FvObj
) or
2163 self
.__GetFvExtEntryStatement
(FvObj
) or self
.__GetFvNameString
(FvObj
)):
2166 if FvObj
.FvNameString
== 'TRUE' and not FvObj
.FvNameGuid
:
2167 raise Warning("FvNameString found but FvNameGuid was not found", self
.FileName
, self
.CurrentLineNumber
)
2169 self
.__GetAprioriSection
(FvObj
, FvObj
.DefineVarDict
.copy())
2170 self
.__GetAprioriSection
(FvObj
, FvObj
.DefineVarDict
.copy())
2173 isInf
= self
.__GetInfStatement
(FvObj
, MacroDict
= FvObj
.DefineVarDict
.copy())
2174 isFile
= self
.__GetFileStatement
(FvObj
, MacroDict
= FvObj
.DefineVarDict
.copy())
2175 if not isInf
and not isFile
:
2180 ## __GetFvAlignment() method
2182 # Get alignment for FV
2184 # @param self The object pointer
2185 # @param Obj for whom alignment is got
2186 # @retval True Successfully find a alignment statement
2187 # @retval False Not able to find a alignment statement
2189 def __GetFvAlignment(self
, Obj
):
2191 if not self
.__IsKeyword
( "FvAlignment"):
2194 if not self
.__IsToken
( "="):
2195 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2197 if not self
.__GetNextToken
():
2198 raise Warning("expected alignment value", self
.FileName
, self
.CurrentLineNumber
)
2200 if self
.__Token
.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
2201 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
2202 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
2204 raise Warning("Unknown alignment value '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2205 Obj
.FvAlignment
= self
.__Token
2208 ## __GetFvBaseAddress() method
2210 # Get BaseAddress for FV
2212 # @param self The object pointer
2213 # @param Obj for whom FvBaseAddress is got
2214 # @retval True Successfully find a FvBaseAddress statement
2215 # @retval False Not able to find a FvBaseAddress statement
2217 def __GetFvBaseAddress(self
, Obj
):
2219 if not self
.__IsKeyword
("FvBaseAddress"):
2222 if not self
.__IsToken
( "="):
2223 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2225 if not self
.__GetNextToken
():
2226 raise Warning("expected FV base address value", self
.FileName
, self
.CurrentLineNumber
)
2228 IsValidBaseAddrValue
= re
.compile('^0[x|X][0-9a-fA-F]+')
2230 if not IsValidBaseAddrValue
.match(self
.__Token
.upper()):
2231 raise Warning("Unknown FV base address value '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2232 Obj
.FvBaseAddress
= self
.__Token
2235 ## __GetFvForceRebase() method
2237 # Get FvForceRebase for FV
2239 # @param self The object pointer
2240 # @param Obj for whom FvForceRebase is got
2241 # @retval True Successfully find a FvForceRebase statement
2242 # @retval False Not able to find a FvForceRebase statement
2244 def __GetFvForceRebase(self
, Obj
):
2246 if not self
.__IsKeyword
("FvForceRebase"):
2249 if not self
.__IsToken
( "="):
2250 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2252 if not self
.__GetNextToken
():
2253 raise Warning("expected FvForceRebase value", self
.FileName
, self
.CurrentLineNumber
)
2255 if self
.__Token
.upper() not in ["TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"]:
2256 raise Warning("Unknown FvForceRebase value '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2258 if self
.__Token
.upper() in ["TRUE", "1", "0X1", "0X01"]:
2259 Obj
.FvForceRebase
= True
2260 elif self
.__Token
.upper() in ["FALSE", "0", "0X0", "0X00"]:
2261 Obj
.FvForceRebase
= False
2263 Obj
.FvForceRebase
= None
2268 ## __GetFvAttributes() method
2270 # Get attributes for FV
2272 # @param self The object pointer
2273 # @param Obj for whom attribute is got
2276 def __GetFvAttributes(self
, FvObj
):
2278 while self
.__GetNextWord
():
2281 if name
not in ("ERASE_POLARITY", "MEMORY_MAPPED", \
2282 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
2283 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
2284 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
2285 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
2286 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"):
2290 if not self
.__IsToken
( "="):
2291 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2293 if not self
.__GetNextToken
() or self
.__Token
.upper() not in ("TRUE", "FALSE", "1", "0"):
2294 raise Warning("expected TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
2296 FvObj
.FvAttributeDict
[name
] = self
.__Token
2300 ## __GetFvNameGuid() method
2302 # Get FV GUID for FV
2304 # @param self The object pointer
2305 # @param Obj for whom GUID is got
2308 def __GetFvNameGuid(self
, FvObj
):
2310 if not self
.__IsKeyword
( "FvNameGuid"):
2313 if not self
.__IsToken
( "="):
2314 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2316 if not self
.__GetNextGuid
():
2317 raise Warning("expected FV GUID value", self
.FileName
, self
.CurrentLineNumber
)
2319 FvObj
.FvNameGuid
= self
.__Token
2323 def __GetFvNameString(self
, FvObj
):
2325 if not self
.__IsKeyword
( "FvNameString"):
2328 if not self
.__IsToken
( "="):
2329 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2331 if not self
.__GetNextToken
() or self
.__Token
not in ('TRUE', 'FALSE'):
2332 raise Warning("expected TRUE or FALSE for FvNameString", self
.FileName
, self
.CurrentLineNumber
)
2334 FvObj
.FvNameString
= self
.__Token
2338 def __GetFvExtEntryStatement(self
, FvObj
):
2340 if not (self
.__IsKeyword
( "FV_EXT_ENTRY") or self
.__IsKeyword
( "FV_EXT_ENTRY_TYPE")):
2343 if not self
.__IsKeyword
("TYPE"):
2344 raise Warning("expected 'TYPE'", self
.FileName
, self
.CurrentLineNumber
)
2346 if not self
.__IsToken
( "="):
2347 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2349 if not self
.__GetNextHexNumber
() and not self
.__GetNextDecimalNumber
():
2350 raise Warning("expected Hex FV extension entry type value At Line ", self
.FileName
, self
.CurrentLineNumber
)
2352 FvObj
.FvExtEntryTypeValue
+= [self
.__Token
]
2354 if not self
.__IsToken
( "{"):
2355 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2357 if not self
.__IsKeyword
("FILE") and not self
.__IsKeyword
("DATA"):
2358 raise Warning("expected 'FILE' or 'DATA'", self
.FileName
, self
.CurrentLineNumber
)
2360 FvObj
.FvExtEntryType
+= [self
.__Token
]
2362 if self
.__Token
== 'DATA':
2364 if not self
.__IsToken
( "="):
2365 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2367 if not self
.__IsToken
( "{"):
2368 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2370 if not self
.__GetNextHexNumber
():
2371 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2373 if len(self
.__Token
) > 4:
2374 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2376 DataString
= self
.__Token
2379 while self
.__IsToken
(","):
2380 if not self
.__GetNextHexNumber
():
2381 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2382 if len(self
.__Token
) > 4:
2383 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2384 DataString
+= self
.__Token
2387 if not self
.__IsToken
( "}"):
2388 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2390 if not self
.__IsToken
( "}"):
2391 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2393 DataString
= DataString
.rstrip(",")
2394 FvObj
.FvExtEntryData
+= [DataString
]
2396 if self
.__Token
== 'FILE':
2398 if not self
.__IsToken
( "="):
2399 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2401 if not self
.__GetNextToken
():
2402 raise Warning("expected FV Extension Entry file path At Line ", self
.FileName
, self
.CurrentLineNumber
)
2404 FvObj
.FvExtEntryData
+= [self
.__Token
]
2406 if not self
.__IsToken
( "}"):
2407 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2411 ## __GetAprioriSection() method
2413 # Get token statements
2415 # @param self The object pointer
2416 # @param FvObj for whom apriori is got
2417 # @param MacroDict dictionary used to replace macro
2418 # @retval True Successfully find apriori statement
2419 # @retval False Not able to find apriori statement
2421 def __GetAprioriSection(self
, FvObj
, MacroDict
= {}):
2423 if not self
.__IsKeyword
( "APRIORI"):
2426 if not self
.__IsKeyword
("PEI") and not self
.__IsKeyword
("DXE"):
2427 raise Warning("expected Apriori file type", self
.FileName
, self
.CurrentLineNumber
)
2428 AprType
= self
.__Token
2430 if not self
.__IsToken
( "{"):
2431 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2433 AprSectionObj
= AprioriSection
.AprioriSection()
2434 AprSectionObj
.AprioriType
= AprType
2436 self
.__GetDefineStatements
(AprSectionObj
)
2437 MacroDict
.update(AprSectionObj
.DefineVarDict
)
2440 IsInf
= self
.__GetInfStatement
( AprSectionObj
, MacroDict
= MacroDict
)
2441 IsFile
= self
.__GetFileStatement
( AprSectionObj
)
2442 if not IsInf
and not IsFile
:
2445 if not self
.__IsToken
( "}"):
2446 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2448 FvObj
.AprioriSectionList
.append(AprSectionObj
)
2451 def __ParseInfStatement(self
):
2452 if not self
.__IsKeyword
("INF"):
2455 ffsInf
= FfsInfStatement
.FfsInfStatement()
2456 self
.__GetInfOptions
(ffsInf
)
2458 if not self
.__GetNextToken
():
2459 raise Warning("expected INF file path", self
.FileName
, self
.CurrentLineNumber
)
2460 ffsInf
.InfFileName
= self
.__Token
2461 if not ffsInf
.InfFileName
.endswith('.inf'):
2462 raise Warning("expected .inf file path", self
.FileName
, self
.CurrentLineNumber
)
2464 ffsInf
.CurrentLineNum
= self
.CurrentLineNumber
2465 ffsInf
.CurrentLineContent
= self
.__CurrentLine
()
2467 #Replace $(SAPCE) with real space
2468 ffsInf
.InfFileName
= ffsInf
.InfFileName
.replace('$(SPACE)', ' ')
2470 if ffsInf
.InfFileName
.replace('$(WORKSPACE)', '').find('$') == -1:
2471 #do case sensitive check for file path
2472 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2474 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2476 if not ffsInf
.InfFileName
in self
.Profile
.InfList
:
2477 self
.Profile
.InfList
.append(ffsInf
.InfFileName
)
2478 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2479 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
2481 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
2482 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
2484 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
2486 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
2488 if self
.__IsToken
('|'):
2489 if self
.__IsKeyword
('RELOCS_STRIPPED'):
2490 ffsInf
.KeepReloc
= False
2491 elif self
.__IsKeyword
('RELOCS_RETAINED'):
2492 ffsInf
.KeepReloc
= True
2494 raise Warning("Unknown reloc strip flag '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2497 ## __GetInfStatement() method
2499 # Get INF statements
2501 # @param self The object pointer
2502 # @param Obj for whom inf statement is got
2503 # @param MacroDict dictionary used to replace macro
2504 # @retval True Successfully find inf statement
2505 # @retval False Not able to find inf statement
2507 def __GetInfStatement(self
, Obj
, ForCapsule
=False, MacroDict
={}):
2508 ffsInf
= self
.__ParseInfStatement
()
2513 capsuleFfs
= CapsuleData
.CapsuleFfs()
2514 capsuleFfs
.Ffs
= ffsInf
2515 Obj
.CapsuleDataList
.append(capsuleFfs
)
2517 Obj
.FfsList
.append(ffsInf
)
2520 ## __GetInfOptions() method
2522 # Get options for INF
2524 # @param self The object pointer
2525 # @param FfsInfObj for whom option is got
2527 def __GetInfOptions(self
, FfsInfObj
):
2528 if self
.__IsKeyword
("FILE_GUID"):
2529 if not self
.__IsToken
("="):
2530 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2531 if not self
.__GetNextGuid
():
2532 raise Warning("expected GUID value", self
.FileName
, self
.CurrentLineNumber
)
2533 FfsInfObj
.OverrideGuid
= self
.__Token
2535 if self
.__IsKeyword
( "RuleOverride"):
2536 if not self
.__IsToken
( "="):
2537 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2538 if not self
.__GetNextToken
():
2539 raise Warning("expected Rule name", self
.FileName
, self
.CurrentLineNumber
)
2540 FfsInfObj
.Rule
= self
.__Token
2542 if self
.__IsKeyword
( "VERSION"):
2543 if not self
.__IsToken
( "="):
2544 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2545 if not self
.__GetNextToken
():
2546 raise Warning("expected Version", self
.FileName
, self
.CurrentLineNumber
)
2548 if self
.__GetStringData
():
2549 FfsInfObj
.Version
= self
.__Token
2551 if self
.__IsKeyword
( "UI"):
2552 if not self
.__IsToken
( "="):
2553 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2554 if not self
.__GetNextToken
():
2555 raise Warning("expected UI name", self
.FileName
, self
.CurrentLineNumber
)
2557 if self
.__GetStringData
():
2558 FfsInfObj
.Ui
= self
.__Token
2560 if self
.__IsKeyword
( "USE"):
2561 if not self
.__IsToken
( "="):
2562 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2563 if not self
.__GetNextToken
():
2564 raise Warning("expected ARCH name", self
.FileName
, self
.CurrentLineNumber
)
2565 FfsInfObj
.UseArch
= self
.__Token
2568 if self
.__GetNextToken
():
2569 p
= re
.compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
2570 if p
.match(self
.__Token
) and p
.match(self
.__Token
).span()[1] == len(self
.__Token
):
2571 FfsInfObj
.KeyStringList
.append(self
.__Token
)
2572 if not self
.__IsToken
(","):
2578 while self
.__GetNextToken
():
2579 if not p
.match(self
.__Token
):
2580 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2581 FfsInfObj
.KeyStringList
.append(self
.__Token
)
2583 if not self
.__IsToken
(","):
2586 ## __GetFileStatement() method
2588 # Get FILE statements
2590 # @param self The object pointer
2591 # @param Obj for whom FILE statement is got
2592 # @param MacroDict dictionary used to replace macro
2593 # @retval True Successfully find FILE statement
2594 # @retval False Not able to find FILE statement
2596 def __GetFileStatement(self
, Obj
, ForCapsule
= False, MacroDict
= {}):
2598 if not self
.__IsKeyword
( "FILE"):
2601 if not self
.__GetNextWord
():
2602 raise Warning("expected FFS type", self
.FileName
, self
.CurrentLineNumber
)
2604 if ForCapsule
and self
.__Token
== 'DATA':
2609 FfsFileObj
= FfsFileStatement
.FileStatement()
2610 FfsFileObj
.FvFileType
= self
.__Token
2612 if not self
.__IsToken
( "="):
2613 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2615 if not self
.__GetNextGuid
():
2616 if not self
.__GetNextWord
():
2617 raise Warning("expected File GUID", self
.FileName
, self
.CurrentLineNumber
)
2618 if self
.__Token
== 'PCD':
2619 if not self
.__IsToken
( "("):
2620 raise Warning("expected '('", self
.FileName
, self
.CurrentLineNumber
)
2621 PcdPair
= self
.__GetNextPcdName
()
2622 if not self
.__IsToken
( ")"):
2623 raise Warning("expected ')'", self
.FileName
, self
.CurrentLineNumber
)
2624 self
.__Token
= 'PCD('+PcdPair
[1]+'.'+PcdPair
[0]+')'
2626 FfsFileObj
.NameGuid
= self
.__Token
2628 self
.__GetFilePart
( FfsFileObj
, MacroDict
.copy())
2631 capsuleFfs
= CapsuleData
.CapsuleFfs()
2632 capsuleFfs
.Ffs
= FfsFileObj
2633 Obj
.CapsuleDataList
.append(capsuleFfs
)
2635 Obj
.FfsList
.append(FfsFileObj
)
2639 ## __FileCouldHaveRelocFlag() method
2641 # Check whether reloc strip flag can be set for a file type.
2643 # @param self The object pointer
2644 # @param FileType The file type to check with
2645 # @retval True This type could have relocation strip flag
2646 # @retval False No way to have it
2649 def __FileCouldHaveRelocFlag (self
, FileType
):
2650 if FileType
in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'):
2655 ## __SectionCouldHaveRelocFlag() method
2657 # Check whether reloc strip flag can be set for a section type.
2659 # @param self The object pointer
2660 # @param SectionType The section type to check with
2661 # @retval True This type could have relocation strip flag
2662 # @retval False No way to have it
2665 def __SectionCouldHaveRelocFlag (self
, SectionType
):
2666 if SectionType
in ('TE', 'PE32'):
2671 ## __GetFilePart() method
2673 # Get components for FILE statement
2675 # @param self The object pointer
2676 # @param FfsFileObj for whom component is got
2677 # @param MacroDict dictionary used to replace macro
2679 def __GetFilePart(self
, FfsFileObj
, MacroDict
= {}):
2681 self
.__GetFileOpts
( FfsFileObj
)
2683 if not self
.__IsToken
("{"):
2684 if self
.__IsKeyword
('RELOCS_STRIPPED') or self
.__IsKeyword
('RELOCS_RETAINED'):
2685 if self
.__FileCouldHaveRelocFlag
(FfsFileObj
.FvFileType
):
2686 if self
.__Token
== 'RELOCS_STRIPPED':
2687 FfsFileObj
.KeepReloc
= False
2689 FfsFileObj
.KeepReloc
= True
2691 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj
.FvFileType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
2693 if not self
.__IsToken
("{"):
2694 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2696 if not self
.__GetNextToken
():
2697 raise Warning("expected File name or section data", self
.FileName
, self
.CurrentLineNumber
)
2699 if self
.__Token
== "FV":
2700 if not self
.__IsToken
( "="):
2701 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2702 if not self
.__GetNextToken
():
2703 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
2704 FfsFileObj
.FvName
= self
.__Token
2706 elif self
.__Token
== "FD":
2707 if not self
.__IsToken
( "="):
2708 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2709 if not self
.__GetNextToken
():
2710 raise Warning("expected FD name", self
.FileName
, self
.CurrentLineNumber
)
2711 FfsFileObj
.FdName
= self
.__Token
2713 elif self
.__Token
in ("DEFINE", "APRIORI", "SECTION"):
2715 self
.__GetSectionData
( FfsFileObj
, MacroDict
)
2717 elif hasattr(FfsFileObj
, 'FvFileType') and FfsFileObj
.FvFileType
== 'RAW':
2719 self
.__GetRAWData
(FfsFileObj
, MacroDict
)
2722 FfsFileObj
.CurrentLineNum
= self
.CurrentLineNumber
2723 FfsFileObj
.CurrentLineContent
= self
.__CurrentLine
()
2724 FfsFileObj
.FileName
= self
.__Token
.replace('$(SPACE)', ' ')
2725 self
.__VerifyFile
(FfsFileObj
.FileName
)
2727 if not self
.__IsToken
( "}"):
2728 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2730 ## __GetRAWData() method
2732 # Get RAW data for FILE statement
2734 # @param self The object pointer
2735 # @param FfsFileObj for whom section is got
2736 # @param MacroDict dictionary used to replace macro
2738 def __GetRAWData(self
, FfsFileObj
, MacroDict
= {}):
2739 FfsFileObj
.FileName
= []
2740 FfsFileObj
.SubAlignment
= []
2743 if self
.__GetAlignment
():
2744 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
2745 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
2746 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2747 #For FFS, Auto is default option same to ""
2748 if not self
.__Token
== "Auto":
2749 AlignValue
= self
.__Token
2750 if not self
.__GetNextToken
():
2751 raise Warning("expected Filename value", self
.FileName
, self
.CurrentLineNumber
)
2753 FileName
= self
.__Token
.replace('$(SPACE)', ' ')
2756 raise Warning("expected Filename value", self
.FileName
, self
.CurrentLineNumber
)
2758 self
.__VerifyFile
(FileName
)
2759 File
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
)
2760 FfsFileObj
.FileName
.append(File
.Path
)
2761 FfsFileObj
.SubAlignment
.append(AlignValue
)
2763 if self
.__IsToken
( "}"):
2767 if len(FfsFileObj
.SubAlignment
) == 1:
2768 FfsFileObj
.SubAlignment
= FfsFileObj
.SubAlignment
[0]
2769 if len(FfsFileObj
.FileName
) == 1:
2770 FfsFileObj
.FileName
= FfsFileObj
.FileName
[0]
2772 ## __GetFileOpts() method
2774 # Get options for FILE statement
2776 # @param self The object pointer
2777 # @param FfsFileObj for whom options is got
2779 def __GetFileOpts(self
, FfsFileObj
):
2781 if self
.__GetNextToken
():
2782 if TokenFindPattern
.match(self
.__Token
):
2783 FfsFileObj
.KeyStringList
.append(self
.__Token
)
2784 if self
.__IsToken
(","):
2785 while self
.__GetNextToken
():
2786 if not TokenFindPattern
.match(self
.__Token
):
2787 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2788 FfsFileObj
.KeyStringList
.append(self
.__Token
)
2790 if not self
.__IsToken
(","):
2796 if self
.__IsKeyword
( "FIXED", True):
2797 FfsFileObj
.Fixed
= True
2799 if self
.__IsKeyword
( "CHECKSUM", True):
2800 FfsFileObj
.CheckSum
= True
2802 if self
.__GetAlignment
():
2803 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
2804 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
2805 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2806 #For FFS, Auto is default option same to ""
2807 if not self
.__Token
== "Auto":
2808 FfsFileObj
.Alignment
= self
.__Token
2810 ## __GetAlignment() method
2812 # Return the alignment value
2814 # @param self The object pointer
2815 # @retval True Successfully find alignment
2816 # @retval False Not able to find alignment
2818 def __GetAlignment(self
):
2819 if self
.__IsKeyword
( "Align", True):
2820 if not self
.__IsToken
( "="):
2821 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2823 if not self
.__GetNextToken
():
2824 raise Warning("expected alignment value", self
.FileName
, self
.CurrentLineNumber
)
2829 ## __GetFilePart() method
2831 # Get section data for FILE statement
2833 # @param self The object pointer
2834 # @param FfsFileObj for whom section is got
2835 # @param MacroDict dictionary used to replace macro
2837 def __GetSectionData(self
, FfsFileObj
, MacroDict
= {}):