4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 # Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>
7 # This program and the accompanying materials
8 # are licensed and made available under the terms and conditions of the BSD License
9 # which accompanies this distribution. The full text of the license may be found at
10 # http://opensource.org/licenses/bsd-license.php
12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
25 import FfsInfStatement
26 import FfsFileStatement
32 import CompressSection
37 import RuleComplexFile
41 import ComponentStatement
43 import OptRomInfStatement
44 import OptRomFileStatement
46 from GenFdsGlobalVariable
import GenFdsGlobalVariable
47 from Common
.BuildToolError
import *
48 from Common
import EdkLogger
49 from Common
.Misc
import PathClass
50 from Common
.String
import NormPath
51 import Common
.GlobalData
as GlobalData
52 from Common
.Expression
import *
53 from Common
import GlobalData
54 from Common
.String
import ReplaceMacro
56 from Common
.Misc
import tdict
57 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
58 import Common
.LongFilePathOs
as os
59 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
60 from Capsule
import EFI_CERT_TYPE_PKCS7_GUID
61 from Capsule
import EFI_CERT_TYPE_RSA2048_SHA256_GUID
62 from Common
.RangeExpression
import RangeExpression
63 from Common
.FdfParserLite
import FileExtensionPattern
65 ##define T_CHAR_SPACE ' '
66 ##define T_CHAR_NULL '\0'
67 ##define T_CHAR_CR '\r'
68 ##define T_CHAR_TAB '\t'
69 ##define T_CHAR_LF '\n'
70 ##define T_CHAR_SLASH '/'
71 ##define T_CHAR_BACKSLASH '\\'
72 ##define T_CHAR_DOUBLE_QUOTE '\"'
73 ##define T_CHAR_SINGLE_QUOTE '\''
74 ##define T_CHAR_STAR '*'
75 ##define T_CHAR_HASH '#'
77 (T_CHAR_SPACE
, T_CHAR_NULL
, T_CHAR_CR
, T_CHAR_TAB
, T_CHAR_LF
, T_CHAR_SLASH
, \
78 T_CHAR_BACKSLASH
, T_CHAR_DOUBLE_QUOTE
, T_CHAR_SINGLE_QUOTE
, T_CHAR_STAR
, T_CHAR_HASH
) = \
79 (' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#')
81 SEPERATOR_TUPLE
= ('=', '|', ',', '{', '}')
83 RegionSizePattern
= re
.compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
84 RegionSizeGuidPattern
= re
.compile("\s*(?P<base>\w+\.\w+)\s*\|\s*(?P<size>\w+\.\w+)\s*")
85 RegionOffsetPcdPattern
= re
.compile("\s*(?P<base>\w+\.\w+)\s*$")
86 ShortcutPcdPattern
= re
.compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
88 AllIncludeFileList
= []
90 # Get the closest parent
91 def GetParentAtLine (Line
):
92 for Profile
in AllIncludeFileList
:
93 if Profile
.IsLineInFile(Line
):
98 def IsValidInclude (File
, Line
):
99 for Profile
in AllIncludeFileList
:
100 if Profile
.IsLineInFile(Line
) and Profile
.FileName
== File
:
105 def GetRealFileLine (File
, Line
):
108 for Profile
in AllIncludeFileList
:
109 if Profile
.IsLineInFile(Line
):
110 return Profile
.GetLineInFile(Line
)
111 elif Line
>= Profile
.InsertStartLineNumber
and Profile
.Level
== 1:
112 InsertedLines
+= Profile
.GetTotalLines()
114 return (File
, Line
- InsertedLines
)
116 ## The exception class that used to report error messages when parsing FDF
118 # Currently the "ToolName" is set to be "FDF Parser".
120 class Warning (Exception):
123 # @param self The object pointer
124 # @param Str The message to record
125 # @param File The FDF name
126 # @param Line The Line number that error occurs
128 def __init__(self
, Str
, File
= None, Line
= None):
130 FileLineTuple
= GetRealFileLine(File
, Line
)
131 self
.FileName
= FileLineTuple
[0]
132 self
.LineNumber
= FileLineTuple
[1]
133 self
.OriginalLineNumber
= Line
135 self
.ToolName
= 'FdfParser'
140 ## The Include file content class that used to record file data when parsing include file
142 # May raise Exception when opening file.
144 class IncludeFileProfile
:
147 # @param self The object pointer
148 # @param FileName The file that to be parsed
150 def __init__(self
, FileName
):
151 self
.FileName
= FileName
152 self
.FileLinesList
= []
154 fsock
= open(FileName
, "rb", 0)
156 self
.FileLinesList
= fsock
.readlines()
157 for index
, line
in enumerate(self
.FileLinesList
):
158 if not line
.endswith('\n'):
159 self
.FileLinesList
[index
] += '\n'
165 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
167 self
.InsertStartLineNumber
= None
168 self
.InsertAdjust
= 0
169 self
.IncludeFileList
= []
170 self
.Level
= 1 # first level include file
172 def GetTotalLines(self
):
173 TotalLines
= self
.InsertAdjust
+ len(self
.FileLinesList
)
175 for Profile
in self
.IncludeFileList
:
176 TotalLines
+= Profile
.GetTotalLines()
180 def IsLineInFile(self
, Line
):
181 if Line
>= self
.InsertStartLineNumber
and Line
< self
.InsertStartLineNumber
+ self
.GetTotalLines():
186 def GetLineInFile(self
, Line
):
187 if not self
.IsLineInFile (Line
):
188 return (self
.FileName
, -1)
190 InsertedLines
= self
.InsertStartLineNumber
192 for Profile
in self
.IncludeFileList
:
193 if Profile
.IsLineInFile(Line
):
194 return Profile
.GetLineInFile(Line
)
195 elif Line
>= Profile
.InsertStartLineNumber
:
196 InsertedLines
+= Profile
.GetTotalLines()
198 return (self
.FileName
, Line
- InsertedLines
+ 1)
202 ## The FDF content class that used to record file data when parsing FDF
204 # May raise Exception when opening file.
209 # @param self The object pointer
210 # @param FileName The file that to be parsed
212 def __init__(self
, FileName
):
213 self
.FileLinesList
= []
215 fsock
= open(FileName
, "rb", 0)
217 self
.FileLinesList
= fsock
.readlines()
222 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
227 self
.InfDict
= {'ArchTBD':[]}
228 # ECC will use this Dict and List information
229 self
.PcdFileLineDict
= {}
230 self
.InfFileLineList
= []
233 self
.FdNameNotSet
= False
235 self
.CapsuleDict
= {}
239 self
.FmpPayloadDict
= {}
241 ## The syntax parser for FDF
243 # PreprocessFile method should be called prior to ParseFile
244 # CycleReferenceCheck method can detect cycles in FDF contents
246 # GetNext*** procedures mean these procedures will get next token first, then make judgement.
247 # Get*** procedures mean these procedures will make judgement on current token only.
252 # @param self The object pointer
253 # @param FileName The file that to be parsed
255 def __init__(self
, FileName
):
256 self
.Profile
= FileProfile(FileName
)
257 self
.FileName
= FileName
258 self
.CurrentLineNumber
= 1
259 self
.CurrentOffsetWithinLine
= 0
260 self
.CurrentFdName
= None
261 self
.CurrentFvName
= None
263 self
.__SkippedChars
= ""
264 GlobalData
.gFdfParser
= self
266 # Used to section info
267 self
.__CurSection
= []
268 # Key: [section name, UI name, arch]
269 # Value: {MACRO_NAME : MACRO_VALUE}
270 self
.__MacroDict
= tdict(True, 3)
273 self
.__WipeOffArea
= []
274 if GenFdsGlobalVariable
.WorkSpaceDir
== '':
275 GenFdsGlobalVariable
.WorkSpaceDir
= os
.getenv("WORKSPACE")
277 ## __IsWhiteSpace() method
279 # Whether char at current FileBufferPos is whitespace
281 # @param self The object pointer
282 # @param Char The char to test
283 # @retval True The char is a kind of white space
284 # @retval False The char is NOT a kind of white space
286 def __IsWhiteSpace(self
, Char
):
287 if Char
in (T_CHAR_NULL
, T_CHAR_CR
, T_CHAR_SPACE
, T_CHAR_TAB
, T_CHAR_LF
):
292 ## __SkipWhiteSpace() method
294 # Skip white spaces from current char, return number of chars skipped
296 # @param self The object pointer
297 # @retval Count The number of chars skipped
299 def __SkipWhiteSpace(self
):
301 while not self
.__EndOfFile
():
303 if self
.__CurrentChar
() in (T_CHAR_NULL
, T_CHAR_CR
, T_CHAR_LF
, T_CHAR_SPACE
, T_CHAR_TAB
):
304 self
.__SkippedChars
+= str(self
.__CurrentChar
())
311 ## __EndOfFile() method
313 # Judge current buffer pos is at file end
315 # @param self The object pointer
316 # @retval True Current File buffer position is at file end
317 # @retval False Current File buffer position is NOT at file end
319 def __EndOfFile(self
):
320 NumberOfLines
= len(self
.Profile
.FileLinesList
)
321 SizeOfLastLine
= len(self
.Profile
.FileLinesList
[-1])
322 if self
.CurrentLineNumber
== NumberOfLines
and self
.CurrentOffsetWithinLine
>= SizeOfLastLine
- 1:
324 elif self
.CurrentLineNumber
> NumberOfLines
:
329 ## __EndOfLine() method
331 # Judge current buffer pos is at line end
333 # @param self The object pointer
334 # @retval True Current File buffer position is at line end
335 # @retval False Current File buffer position is NOT at line end
337 def __EndOfLine(self
):
338 if self
.CurrentLineNumber
> len(self
.Profile
.FileLinesList
):
340 SizeOfCurrentLine
= len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
341 if self
.CurrentOffsetWithinLine
>= SizeOfCurrentLine
:
348 # Reset file data buffer to the initial state
350 # @param self The object pointer
351 # @param DestLine Optional new destination line number.
352 # @param DestOffset Optional new destination offset.
354 def Rewind(self
, DestLine
= 1, DestOffset
= 0):
355 self
.CurrentLineNumber
= DestLine
356 self
.CurrentOffsetWithinLine
= DestOffset
358 ## __UndoOneChar() method
360 # Go back one char in the file buffer
362 # @param self The object pointer
363 # @retval True Successfully go back one char
364 # @retval False Not able to go back one char as file beginning reached
366 def __UndoOneChar(self
):
368 if self
.CurrentLineNumber
== 1 and self
.CurrentOffsetWithinLine
== 0:
370 elif self
.CurrentOffsetWithinLine
== 0:
371 self
.CurrentLineNumber
-= 1
372 self
.CurrentOffsetWithinLine
= len(self
.__CurrentLine
()) - 1
374 self
.CurrentOffsetWithinLine
-= 1
377 ## __GetOneChar() method
379 # Move forward one char in the file buffer
381 # @param self The object pointer
383 def __GetOneChar(self
):
384 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
385 self
.CurrentLineNumber
+= 1
386 self
.CurrentOffsetWithinLine
= 0
388 self
.CurrentOffsetWithinLine
+= 1
390 ## __CurrentChar() method
392 # Get the char pointed to by the file buffer pointer
394 # @param self The object pointer
395 # @retval Char Current char
397 def __CurrentChar(self
):
398 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
]
400 ## __NextChar() method
402 # Get the one char pass the char pointed to by the file buffer pointer
404 # @param self The object pointer
405 # @retval Char Next char
407 def __NextChar(self
):
408 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
409 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
][0]
411 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
+ 1]
413 ## __SetCurrentCharValue() method
415 # Modify the value of current char
417 # @param self The object pointer
418 # @param Value The new value of current char
420 def __SetCurrentCharValue(self
, Value
):
421 self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
] = Value
423 ## __CurrentLine() method
425 # Get the list that contains current line contents
427 # @param self The object pointer
428 # @retval List current line contents
430 def __CurrentLine(self
):
431 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
433 def __StringToList(self
):
434 self
.Profile
.FileLinesList
= [list(s
) for s
in self
.Profile
.FileLinesList
]
435 self
.Profile
.FileLinesList
[-1].append(' ')
437 def __ReplaceFragment(self
, StartPos
, EndPos
, Value
= ' '):
438 if StartPos
[0] == EndPos
[0]:
440 while Offset
<= EndPos
[1]:
441 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
446 while self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] not in ('\r', '\n'):
447 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
451 while Line
< EndPos
[0]:
453 while self
.Profile
.FileLinesList
[Line
][Offset
] not in ('\r', '\n'):
454 self
.Profile
.FileLinesList
[Line
][Offset
] = Value
459 while Offset
<= EndPos
[1]:
460 self
.Profile
.FileLinesList
[EndPos
[0]][Offset
] = Value
464 def __GetMacroName(self
):
465 if not self
.__GetNextToken
():
466 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
467 MacroName
= self
.__Token
469 if MacroName
.startswith('!'):
471 MacroName
= MacroName
[1:].strip()
473 if not MacroName
.startswith('$(') or not MacroName
.endswith(')'):
474 raise Warning("Macro name expected(Please use '$(%(Token)s)' if '%(Token)s' is a macro.)" % {"Token" : MacroName
},
475 self
.FileName
, self
.CurrentLineNumber
)
476 MacroName
= MacroName
[2:-1]
477 return MacroName
, NotFlag
479 def __SetMacroValue(self
, Macro
, Value
):
480 if not self
.__CurSection
:
484 if not self
.__MacroDict
[self
.__CurSection
[0], self
.__CurSection
[1], self
.__CurSection
[2]]:
485 self
.__MacroDict
[self
.__CurSection
[0], self
.__CurSection
[1], self
.__CurSection
[2]] = MacroDict
487 MacroDict
= self
.__MacroDict
[self
.__CurSection
[0], self
.__CurSection
[1], self
.__CurSection
[2]]
488 MacroDict
[Macro
] = Value
490 def __GetMacroValue(self
, Macro
):
492 if Macro
in GlobalData
.gCommandLineDefines
:
493 return GlobalData
.gCommandLineDefines
[Macro
]
494 if Macro
in GlobalData
.gGlobalDefines
:
495 return GlobalData
.gGlobalDefines
[Macro
]
497 if self
.__CurSection
:
498 MacroDict
= self
.__MacroDict
[
499 self
.__CurSection
[0],
500 self
.__CurSection
[1],
503 if MacroDict
and Macro
in MacroDict
:
504 return MacroDict
[Macro
]
507 if Macro
in GlobalData
.gPlatformDefines
:
508 return GlobalData
.gPlatformDefines
[Macro
]
511 def __SectionHeaderParser(self
, Section
):
513 # [FD.UiName]: use dummy instead if UI name is optional
516 # [Rule]: don't take rule section into account, macro is not allowed in this section
517 # [VTF.arch.UiName, arch]
518 # [OptionRom.DriverName]
519 self
.__CurSection
= []
520 Section
= Section
.strip()[1:-1].upper().replace(' ', '').strip('.')
521 ItemList
= Section
.split('.')
523 if Item
== '' or Item
== 'RULE':
526 if Item
== 'DEFINES':
527 self
.__CurSection
= ['COMMON', 'COMMON', 'COMMON']
528 elif Item
== 'VTF' and len(ItemList
) == 3:
530 Pos
= UiName
.find(',')
532 UiName
= UiName
[:Pos
]
533 self
.__CurSection
= ['VTF', UiName
, ItemList
[1]]
534 elif len(ItemList
) > 1:
535 self
.__CurSection
= [ItemList
[0], ItemList
[1], 'COMMON']
536 elif len(ItemList
) > 0:
537 self
.__CurSection
= [ItemList
[0], 'DUMMY', 'COMMON']
539 ## PreprocessFile() method
541 # Preprocess file contents, replace comments with spaces.
542 # In the end, rewind the file buffer pointer to the beginning
543 # BUGBUG: No !include statement processing contained in this procedure
544 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
546 # @param self The object pointer
548 def PreprocessFile(self
):
552 DoubleSlashComment
= False
554 # HashComment in quoted string " " is ignored.
557 while not self
.__EndOfFile
():
559 if self
.__CurrentChar
() == T_CHAR_DOUBLE_QUOTE
and not InComment
:
560 InString
= not InString
561 # meet new line, then no longer in a comment for // and '#'
562 if self
.__CurrentChar
() == T_CHAR_LF
:
563 self
.CurrentLineNumber
+= 1
564 self
.CurrentOffsetWithinLine
= 0
565 if InComment
and DoubleSlashComment
:
567 DoubleSlashComment
= False
568 if InComment
and HashComment
:
571 # check for */ comment end
572 elif InComment
and not DoubleSlashComment
and not HashComment
and self
.__CurrentChar
() == T_CHAR_STAR
and self
.__NextChar
() == T_CHAR_SLASH
:
573 self
.__SetCurrentCharValue
(T_CHAR_SPACE
)
575 self
.__SetCurrentCharValue
(T_CHAR_SPACE
)
578 # set comments to spaces
580 self
.__SetCurrentCharValue
(T_CHAR_SPACE
)
582 # check for // comment
583 elif self
.__CurrentChar
() == T_CHAR_SLASH
and self
.__NextChar
() == T_CHAR_SLASH
and not self
.__EndOfLine
():
585 DoubleSlashComment
= True
586 # check for '#' comment
587 elif self
.__CurrentChar
() == T_CHAR_HASH
and not self
.__EndOfLine
() and not InString
:
590 # check for /* comment start
591 elif self
.__CurrentChar
() == T_CHAR_SLASH
and self
.__NextChar
() == T_CHAR_STAR
:
592 self
.__SetCurrentCharValue
( T_CHAR_SPACE
)
594 self
.__SetCurrentCharValue
( T_CHAR_SPACE
)
600 # restore from ListOfList to ListOfString
601 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
604 ## PreprocessIncludeFile() method
606 # Preprocess file contents, replace !include statements with file contents.
607 # In the end, rewind the file buffer pointer to the beginning
609 # @param self The object pointer
611 def PreprocessIncludeFile(self
):
612 # nested include support
615 while self
.__GetNextToken
():
617 if self
.__Token
== 'DEFINE':
618 if not self
.__GetNextToken
():
619 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
621 if not self
.__IsToken
( "="):
622 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
623 Value
= self
.__GetExpression
()
624 MacroDict
[Macro
] = Value
626 elif self
.__Token
== '!include':
628 IncludeLine
= self
.CurrentLineNumber
629 IncludeOffset
= self
.CurrentOffsetWithinLine
- len('!include')
630 if not self
.__GetNextToken
():
631 raise Warning("expected include file name", self
.FileName
, self
.CurrentLineNumber
)
632 IncFileName
= self
.__Token
634 StartPos
= IncFileName
.find('$(', PreIndex
)
635 EndPos
= IncFileName
.find(')', StartPos
+2)
636 while StartPos
!= -1 and EndPos
!= -1:
637 Macro
= IncFileName
[StartPos
+2 : EndPos
]
638 MacroVal
= self
.__GetMacroValue
(Macro
)
640 if Macro
in MacroDict
:
641 MacroVal
= MacroDict
[Macro
]
643 IncFileName
= IncFileName
.replace('$(' + Macro
+ ')', MacroVal
, 1)
644 if MacroVal
.find('$(') != -1:
647 PreIndex
= StartPos
+ len(MacroVal
)
649 raise Warning("The Macro %s is not defined" %Macro
, self
.FileName
, self
.CurrentLineNumber
)
650 StartPos
= IncFileName
.find('$(', PreIndex
)
651 EndPos
= IncFileName
.find(')', StartPos
+2)
653 IncludedFile
= NormPath(IncFileName
)
655 # First search the include file under the same directory as FDF file
657 IncludedFile1
= PathClass(IncludedFile
, os
.path
.dirname(self
.FileName
))
658 ErrorCode
= IncludedFile1
.Validate()[0]
661 # Then search the include file under the same directory as DSC file
664 if GenFdsGlobalVariable
.ActivePlatform
:
665 PlatformDir
= GenFdsGlobalVariable
.ActivePlatform
.Dir
666 elif GlobalData
.gActivePlatform
:
667 PlatformDir
= GlobalData
.gActivePlatform
.MetaFile
.Dir
668 IncludedFile1
= PathClass(IncludedFile
, PlatformDir
)
669 ErrorCode
= IncludedFile1
.Validate()[0]
672 # Also search file under the WORKSPACE directory
674 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
675 ErrorCode
= IncludedFile1
.Validate()[0]
677 raise Warning("The include file does not exist under below directories: \n%s\n%s\n%s\n"%(os
.path
.dirname(self
.FileName
), PlatformDir
, GlobalData
.gWorkspace
),
678 self
.FileName
, self
.CurrentLineNumber
)
680 if not IsValidInclude (IncludedFile1
.Path
, self
.CurrentLineNumber
):
681 raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1
.Path
), self
.FileName
, self
.CurrentLineNumber
)
683 IncFileProfile
= IncludeFileProfile(IncludedFile1
.Path
)
685 CurrentLine
= self
.CurrentLineNumber
686 CurrentOffset
= self
.CurrentOffsetWithinLine
687 # list index of the insertion, note that line number is 'CurrentLine + 1'
688 InsertAtLine
= CurrentLine
689 ParentProfile
= GetParentAtLine (CurrentLine
)
690 if ParentProfile
!= None:
691 ParentProfile
.IncludeFileList
.insert(0, IncFileProfile
)
692 IncFileProfile
.Level
= ParentProfile
.Level
+ 1
693 IncFileProfile
.InsertStartLineNumber
= InsertAtLine
+ 1
694 # deal with remaining portions after "!include filename", if exists.
695 if self
.__GetNextToken
():
696 if self
.CurrentLineNumber
== CurrentLine
:
697 RemainingLine
= self
.__CurrentLine
()[CurrentOffset
:]
698 self
.Profile
.FileLinesList
.insert(self
.CurrentLineNumber
, RemainingLine
)
699 IncFileProfile
.InsertAdjust
+= 1
700 self
.CurrentLineNumber
+= 1
701 self
.CurrentOffsetWithinLine
= 0
703 for Line
in IncFileProfile
.FileLinesList
:
704 self
.Profile
.FileLinesList
.insert(InsertAtLine
, Line
)
705 self
.CurrentLineNumber
+= 1
708 # reversely sorted to better determine error in file
709 AllIncludeFileList
.insert(0, IncFileProfile
)
711 # comment out the processed include file statement
712 TempList
= list(self
.Profile
.FileLinesList
[IncludeLine
- 1])
713 TempList
.insert(IncludeOffset
, '#')
714 self
.Profile
.FileLinesList
[IncludeLine
- 1] = ''.join(TempList
)
715 if Processed
: # Nested and back-to-back support
716 self
.Rewind(DestLine
= IncFileProfile
.InsertStartLineNumber
- 1)
721 def __GetIfListCurrentItemStat(self
, IfList
):
731 ## PreprocessConditionalStatement() method
733 # Preprocess conditional statement.
734 # In the end, rewind the file buffer pointer to the beginning
736 # @param self The object pointer
738 def PreprocessConditionalStatement(self
):
739 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
743 while self
.__GetNextToken
():
744 # Determine section name and the location dependent macro
745 if self
.__GetIfListCurrentItemStat
(IfList
):
746 if self
.__Token
.startswith('['):
747 Header
= self
.__Token
748 if not self
.__Token
.endswith(']'):
749 self
.__SkipToToken
(']')
750 Header
+= self
.__SkippedChars
751 if Header
.find('$(') != -1:
752 raise Warning("macro cannot be used in section header", self
.FileName
, self
.CurrentLineNumber
)
753 self
.__SectionHeaderParser
(Header
)
755 # Replace macros except in RULE section or out of section
756 elif self
.__CurSection
and ReplacedLine
!= self
.CurrentLineNumber
:
757 ReplacedLine
= self
.CurrentLineNumber
759 CurLine
= self
.Profile
.FileLinesList
[ReplacedLine
- 1]
761 StartPos
= CurLine
.find('$(', PreIndex
)
762 EndPos
= CurLine
.find(')', StartPos
+2)
763 while StartPos
!= -1 and EndPos
!= -1 and self
.__Token
not in ['!ifdef', '!ifndef', '!if', '!elseif']:
764 MacroName
= CurLine
[StartPos
+2 : EndPos
]
765 MacorValue
= self
.__GetMacroValue
(MacroName
)
766 if MacorValue
!= None:
767 CurLine
= CurLine
.replace('$(' + MacroName
+ ')', MacorValue
, 1)
768 if MacorValue
.find('$(') != -1:
771 PreIndex
= StartPos
+ len(MacorValue
)
773 PreIndex
= EndPos
+ 1
774 StartPos
= CurLine
.find('$(', PreIndex
)
775 EndPos
= CurLine
.find(')', StartPos
+2)
776 self
.Profile
.FileLinesList
[ReplacedLine
- 1] = CurLine
779 if self
.__Token
== 'DEFINE':
780 if self
.__GetIfListCurrentItemStat
(IfList
):
781 if not self
.__CurSection
:
782 raise Warning("macro cannot be defined in Rule section or out of section", self
.FileName
, self
.CurrentLineNumber
)
783 DefineLine
= self
.CurrentLineNumber
- 1
784 DefineOffset
= self
.CurrentOffsetWithinLine
- len('DEFINE')
785 if not self
.__GetNextToken
():
786 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
788 if not self
.__IsToken
( "="):
789 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
791 Value
= self
.__GetExpression
()
792 self
.__SetMacroValue
(Macro
, Value
)
793 self
.__WipeOffArea
.append(((DefineLine
, DefineOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
794 elif self
.__Token
== 'SET':
795 if not self
.__GetIfListCurrentItemStat
(IfList
):
797 SetLine
= self
.CurrentLineNumber
- 1
798 SetOffset
= self
.CurrentOffsetWithinLine
- len('SET')
799 PcdPair
= self
.__GetNextPcdName
()
800 PcdName
= "%s.%s" % (PcdPair
[1], PcdPair
[0])
801 if not self
.__IsToken
( "="):
802 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
804 Value
= self
.__GetExpression
()
805 Value
= self
.__EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
807 self
.__PcdDict
[PcdName
] = Value
809 self
.Profile
.PcdDict
[PcdPair
] = Value
810 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
811 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
813 self
.__WipeOffArea
.append(((SetLine
, SetOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
814 elif self
.__Token
in ('!ifdef', '!ifndef', '!if'):
815 IfStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
.__Token
))
816 IfList
.append([IfStartPos
, None, None])
818 CondLabel
= self
.__Token
819 Expression
= self
.__GetExpression
()
821 if CondLabel
== '!if':
822 ConditionSatisfied
= self
.__EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
824 ConditionSatisfied
= self
.__EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'in')
825 if CondLabel
== '!ifndef':
826 ConditionSatisfied
= not ConditionSatisfied
828 BranchDetermined
= ConditionSatisfied
829 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, BranchDetermined
]
830 if ConditionSatisfied
:
831 self
.__WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
832 elif self
.__Token
in ('!elseif', '!else'):
833 ElseStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
.__Token
))
835 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
838 IfList
[-1] = [ElseStartPos
, False, True]
839 self
.__WipeOffArea
.append((ElseStartPos
, (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
841 self
.__WipeOffArea
.append((IfList
[-1][0], ElseStartPos
))
842 IfList
[-1] = [ElseStartPos
, True, IfList
[-1][2]]
843 if self
.__Token
== '!elseif':
844 Expression
= self
.__GetExpression
()
845 ConditionSatisfied
= self
.__EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
846 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, IfList
[-1][2]]
850 IfList
[-1][1] = False
853 self
.__WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
854 elif self
.__Token
== '!endif':
856 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
858 self
.__WipeOffArea
.append(((self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len('!endif')), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
860 self
.__WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
863 elif not IfList
: # Don't use PCDs inside conditional directive
864 if self
.CurrentLineNumber
<= RegionLayoutLine
:
865 # Don't try the same line twice
867 SetPcd
= ShortcutPcdPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
869 self
.__PcdDict
[SetPcd
.group('name')] = SetPcd
.group('value')
870 RegionLayoutLine
= self
.CurrentLineNumber
872 RegionSize
= RegionSizePattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
874 RegionLayoutLine
= self
.CurrentLineNumber
876 RegionSizeGuid
= RegionSizeGuidPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
])
877 if not RegionSizeGuid
:
878 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
880 self
.__PcdDict
[RegionSizeGuid
.group('base')] = RegionSize
.group('base')
881 self
.__PcdDict
[RegionSizeGuid
.group('size')] = RegionSize
.group('size')
882 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
885 raise Warning("Missing !endif", self
.FileName
, self
.CurrentLineNumber
)
888 def __CollectMacroPcd(self
):
892 MacroDict
.update(GlobalData
.gPlatformPcds
)
893 MacroDict
.update(self
.__PcdDict
)
896 MacroDict
.update(GlobalData
.gPlatformDefines
)
898 if self
.__CurSection
:
900 ScopeMacro
= self
.__MacroDict
['COMMON', 'COMMON', 'COMMON']
902 MacroDict
.update(ScopeMacro
)
905 ScopeMacro
= self
.__MacroDict
[
906 self
.__CurSection
[0],
907 self
.__CurSection
[1],
911 MacroDict
.update(ScopeMacro
)
913 MacroDict
.update(GlobalData
.gGlobalDefines
)
914 MacroDict
.update(GlobalData
.gCommandLineDefines
)
915 if GlobalData
.BuildOptionPcd
:
916 for Item
in GlobalData
.BuildOptionPcd
:
917 if type(Item
) is tuple:
919 PcdName
, TmpValue
= Item
.split("=")
920 TmpValue
= BuildOptionValue(TmpValue
, {})
921 MacroDict
[PcdName
.strip()] = TmpValue
926 def __EvaluateConditional(self
, Expression
, Line
, Op
= None, Value
= None):
927 FileLineTuple
= GetRealFileLine(self
.FileName
, Line
)
928 MacroPcdDict
= self
.__CollectMacroPcd
()
932 return ValueExpression(Expression
, MacroPcdDict
)(True)
934 return ValueExpression(Expression
, MacroPcdDict
)()
935 except WrnExpression
, Excpt
:
937 # Catch expression evaluation warning here. We need to report
938 # the precise number of line and return the evaluation result
940 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
941 File
=self
.FileName
, ExtraData
=self
.__CurrentLine
(),
944 except Exception, Excpt
:
945 if hasattr(Excpt
, 'Pcd'):
946 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
947 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
948 raise Warning("Cannot use this PCD (%s) in an expression as"
949 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
950 " of the DSC file (%s), and it is currently defined in this section:"
951 " %s, line #: %d." % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE'], Info
[0], Info
[1]),
954 raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE']),
957 raise Warning(str(Excpt
), *FileLineTuple
)
959 if Expression
.startswith('$(') and Expression
[-1] == ')':
960 Expression
= Expression
[2:-1]
961 return Expression
in MacroPcdDict
963 ## __IsToken() method
965 # Check whether input string is found from current char position along
966 # If found, the string value is put into self.__Token
968 # @param self The object pointer
969 # @param String The string to search
970 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
971 # @retval True Successfully find string, file buffer pointer moved forward
972 # @retval False Not able to find string, file buffer pointer not changed
974 def __IsToken(self
, String
, IgnoreCase
= False):
975 self
.__SkipWhiteSpace
()
977 # Only consider the same line, no multi-line token allowed
978 StartPos
= self
.CurrentOffsetWithinLine
981 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
983 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
985 self
.CurrentOffsetWithinLine
+= len(String
)
986 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
990 ## __IsKeyword() method
992 # Check whether input keyword is found from current char position along, whole word only!
993 # If found, the string value is put into self.__Token
995 # @param self The object pointer
996 # @param Keyword The string to search
997 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
998 # @retval True Successfully find string, file buffer pointer moved forward
999 # @retval False Not able to find string, file buffer pointer not changed
1001 def __IsKeyword(self
, KeyWord
, IgnoreCase
= False):
1002 self
.__SkipWhiteSpace
()
1004 # Only consider the same line, no multi-line token allowed
1005 StartPos
= self
.CurrentOffsetWithinLine
1008 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(KeyWord
.upper())
1010 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(KeyWord
)
1012 followingChar
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
+ len(KeyWord
)]
1013 if not str(followingChar
).isspace() and followingChar
not in SEPERATOR_TUPLE
:
1015 self
.CurrentOffsetWithinLine
+= len(KeyWord
)
1016 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1020 def __GetExpression(self
):
1021 Line
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
1022 Index
= len(Line
) - 1
1023 while Line
[Index
] in ['\r', '\n']:
1025 ExpressionString
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:Index
+1]
1026 self
.CurrentOffsetWithinLine
+= len(ExpressionString
)
1027 ExpressionString
= ExpressionString
.strip()
1028 return ExpressionString
1030 ## __GetNextWord() method
1032 # Get next C name from file lines
1033 # If found, the string value is put into self.__Token
1035 # @param self The object pointer
1036 # @retval True Successfully find a C name string, file buffer pointer moved forward
1037 # @retval False Not able to find a C name string, file buffer pointer not changed
1039 def __GetNextWord(self
):
1040 self
.__SkipWhiteSpace
()
1041 if self
.__EndOfFile
():
1044 TempChar
= self
.__CurrentChar
()
1045 StartPos
= self
.CurrentOffsetWithinLine
1046 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_':
1048 while not self
.__EndOfLine
():
1049 TempChar
= self
.__CurrentChar
()
1050 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
1051 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-':
1057 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1062 ## __GetNextToken() method
1064 # Get next token unit before a seperator
1065 # If found, the string value is put into self.__Token
1067 # @param self The object pointer
1068 # @retval True Successfully find a token unit, file buffer pointer moved forward
1069 # @retval False Not able to find a token unit, file buffer pointer not changed
1071 def __GetNextToken(self
):
1072 # Skip leading spaces, if exist.
1073 self
.__SkipWhiteSpace
()
1074 if self
.__EndOfFile
():
1076 # Record the token start position, the position of the first non-space char.
1077 StartPos
= self
.CurrentOffsetWithinLine
1078 StartLine
= self
.CurrentLineNumber
1079 while StartLine
== self
.CurrentLineNumber
:
1080 TempChar
= self
.__CurrentChar
()
1081 # Try to find the end char that is not a space and not in seperator tuple.
1082 # That is, when we got a space or any char in the tuple, we got the end of token.
1083 if not str(TempChar
).isspace() and TempChar
not in SEPERATOR_TUPLE
:
1085 # if we happen to meet a seperator as the first char, we must proceed to get it.
1086 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1087 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPERATOR_TUPLE
:
1095 EndPos
= self
.CurrentOffsetWithinLine
1096 if self
.CurrentLineNumber
!= StartLine
:
1097 EndPos
= len(self
.Profile
.FileLinesList
[StartLine
-1])
1098 self
.__Token
= self
.Profile
.FileLinesList
[StartLine
-1][StartPos
: EndPos
]
1099 if StartPos
!= self
.CurrentOffsetWithinLine
:
1104 def __GetNextOp(self
):
1105 # Skip leading spaces, if exist.
1106 self
.__SkipWhiteSpace
()
1107 if self
.__EndOfFile
():
1109 # Record the token start position, the position of the first non-space char.
1110 StartPos
= self
.CurrentOffsetWithinLine
1111 while not self
.__EndOfLine
():
1112 TempChar
= self
.__CurrentChar
()
1113 # Try to find the end char that is not a space
1114 if not str(TempChar
).isspace():
1121 if StartPos
!= self
.CurrentOffsetWithinLine
:
1122 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1126 ## __GetNextGuid() method
1128 # Get next token unit before a seperator
1129 # If found, the GUID string is put into self.__Token
1131 # @param self The object pointer
1132 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward
1133 # @retval False Not able to find a registry format GUID, file buffer pointer not changed
1135 def __GetNextGuid(self
):
1137 if not self
.__GetNextToken
():
1139 if RangeExpression
.RegGuidPattern
.match(self
.__Token
) != None:
1145 def __Verify(self
, Name
, Value
, Scope
):
1146 if Scope
in ['UINT64', 'UINT8']:
1149 if Value
.upper().startswith('0X'):
1150 ValueNumber
= int (Value
, 16)
1152 ValueNumber
= int (Value
)
1154 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value is not valid dec or hex number for %s." % Name
)
1156 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value can't be set to negative value for %s." % Name
)
1157 if Scope
== 'UINT64':
1158 if ValueNumber
>= 0x10000000000000000:
1159 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "Too large value for %s." % Name
)
1160 if Scope
== 'UINT8':
1161 if ValueNumber
>= 0x100:
1162 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "Too large value for %s." % Name
)
1165 ## __UndoToken() method
1167 # Go back one token unit in file buffer
1169 # @param self The object pointer
1171 def __UndoToken(self
):
1172 self
.__UndoOneChar
()
1173 while self
.__CurrentChar
().isspace():
1174 if not self
.__UndoOneChar
():
1179 StartPos
= self
.CurrentOffsetWithinLine
1180 CurrentLine
= self
.CurrentLineNumber
1181 while CurrentLine
== self
.CurrentLineNumber
:
1183 TempChar
= self
.__CurrentChar
()
1184 # Try to find the end char that is not a space and not in seperator tuple.
1185 # That is, when we got a space or any char in the tuple, we got the end of token.
1186 if not str(TempChar
).isspace() and not TempChar
in SEPERATOR_TUPLE
:
1187 if not self
.__UndoOneChar
():
1189 # if we happen to meet a seperator as the first char, we must proceed to get it.
1190 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1191 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPERATOR_TUPLE
:
1198 ## __HexDigit() method
1200 # Whether char input is a Hex data bit
1202 # @param self The object pointer
1203 # @param TempChar The char to test
1204 # @retval True The char is a Hex data bit
1205 # @retval False The char is NOT a Hex data bit
1207 def __HexDigit(self
, TempChar
):
1208 if (TempChar
>= 'a' and TempChar
<= 'f') or (TempChar
>= 'A' and TempChar
<= 'F') \
1209 or (TempChar
>= '0' and TempChar
<= '9'):
1214 def __IsHex(self
, HexStr
):
1215 if not HexStr
.upper().startswith("0X"):
1217 if len(self
.__Token
) <= 2:
1219 charList
= [c
for c
in HexStr
[2 : ] if not self
.__HexDigit
( c
)]
1220 if len(charList
) == 0:
1224 ## __GetNextHexNumber() method
1226 # Get next HEX data before a seperator
1227 # If found, the HEX data is put into self.__Token
1229 # @param self The object pointer
1230 # @retval True Successfully find a HEX data, file buffer pointer moved forward
1231 # @retval False Not able to find a HEX data, file buffer pointer not changed
1233 def __GetNextHexNumber(self
):
1234 if not self
.__GetNextToken
():
1236 if self
.__IsHex
(self
.__Token
):
1242 ## __GetNextDecimalNumber() method
1244 # Get next decimal data before a seperator
1245 # If found, the decimal data is put into self.__Token
1247 # @param self The object pointer
1248 # @retval True Successfully find a decimal data, file buffer pointer moved forward
1249 # @retval False Not able to find a decimal data, file buffer pointer not changed
1251 def __GetNextDecimalNumber(self
):
1252 if not self
.__GetNextToken
():
1254 if self
.__Token
.isdigit():
1260 ## __GetNextPcdName() method
1262 # Get next PCD token space C name and PCD C name pair before a seperator
1263 # If found, the decimal data is put into self.__Token
1265 # @param self The object pointer
1266 # @retval Tuple PCD C name and PCD token space C name pair
1268 def __GetNextPcdName(self
):
1269 if not self
.__GetNextWord
():
1270 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1271 pcdTokenSpaceCName
= self
.__Token
1273 if not self
.__IsToken
( "."):
1274 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1276 if not self
.__GetNextWord
():
1277 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1278 pcdCName
= self
.__Token
1280 return (pcdCName
, pcdTokenSpaceCName
)
1282 ## __GetStringData() method
1284 # Get string contents quoted in ""
1285 # If found, the decimal data is put into self.__Token
1287 # @param self The object pointer
1288 # @retval True Successfully find a string data, file buffer pointer moved forward
1289 # @retval False Not able to find a string data, file buffer pointer not changed
1291 def __GetStringData(self
):
1292 if self
.__Token
.startswith("\"") or self
.__Token
.startswith("L\""):
1294 self
.__SkipToToken
("\"")
1295 currentLineNumber
= self
.CurrentLineNumber
1297 if not self
.__SkipToToken
("\""):
1298 raise Warning("Missing Quote \" for String", self
.FileName
, self
.CurrentLineNumber
)
1299 if currentLineNumber
!= self
.CurrentLineNumber
:
1300 raise Warning("Missing Quote \" for String", self
.FileName
, self
.CurrentLineNumber
)
1301 self
.__Token
= self
.__SkippedChars
.rstrip('\"')
1304 elif self
.__Token
.startswith("\'") or self
.__Token
.startswith("L\'"):
1306 self
.__SkipToToken
("\'")
1307 currentLineNumber
= self
.CurrentLineNumber
1309 if not self
.__SkipToToken
("\'"):
1310 raise Warning("Missing Quote \' for String", self
.FileName
, self
.CurrentLineNumber
)
1311 if currentLineNumber
!= self
.CurrentLineNumber
:
1312 raise Warning("Missing Quote \' for String", self
.FileName
, self
.CurrentLineNumber
)
1313 self
.__Token
= self
.__SkippedChars
.rstrip('\'')
1319 ## __SkipToToken() method
1321 # Search forward in file buffer for the string
1322 # The skipped chars are put into self.__SkippedChars
1324 # @param self The object pointer
1325 # @param String The string to search
1326 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
1327 # @retval True Successfully find the string, file buffer pointer moved forward
1328 # @retval False Not able to find the string, file buffer pointer not changed
1330 def __SkipToToken(self
, String
, IgnoreCase
= False):
1331 StartPos
= self
.GetFileBufferPos()
1333 self
.__SkippedChars
= ""
1334 while not self
.__EndOfFile
():
1337 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
1339 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
1341 self
.CurrentOffsetWithinLine
+= len(String
)
1342 self
.__SkippedChars
+= String
1344 self
.__SkippedChars
+= str(self
.__CurrentChar
())
1347 self
.SetFileBufferPos( StartPos
)
1348 self
.__SkippedChars
= ""
1351 ## GetFileBufferPos() method
1353 # Return the tuple of current line and offset within the line
1355 # @param self The object pointer
1356 # @retval Tuple Line number and offset pair
1358 def GetFileBufferPos(self
):
1359 return (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
)
1361 ## SetFileBufferPos() method
1363 # Restore the file buffer position
1365 # @param self The object pointer
1366 # @param Pos The new file buffer position
1368 def SetFileBufferPos(self
, Pos
):
1369 (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
) = Pos
1371 ## Preprocess() method
1373 # Preprocess comment, conditional directive, include directive, replace macro.
1374 # Exception will be raised if syntax error found
1376 # @param self The object pointer
1378 def Preprocess(self
):
1379 self
.__StringToList
()
1380 self
.PreprocessFile()
1381 self
.PreprocessIncludeFile()
1382 self
.__StringToList
()
1383 self
.PreprocessFile()
1384 self
.PreprocessConditionalStatement()
1385 self
.__StringToList
()
1386 for Pos
in self
.__WipeOffArea
:
1387 self
.__ReplaceFragment
(Pos
[0], Pos
[1])
1388 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
1390 while self
.__GetDefines
():
1393 ## ParseFile() method
1395 # Parse the file profile buffer to extract fd, fv ... information
1396 # Exception will be raised if syntax error found
1398 # @param self The object pointer
1400 def ParseFile(self
):
1405 # Keep processing sections of the FDF until no new sections or a syntax error is found
1407 while self
.__GetFd
() or self
.__GetFv
() or self
.__GetFmp
() or self
.__GetCapsule
() or self
.__GetVtf
() or self
.__GetRule
() or self
.__GetOptionRom
():
1412 #'\n\tGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \
1413 # At this point, the closest parent would be the included file itself
1414 Profile
= GetParentAtLine(X
.OriginalLineNumber
)
1416 X
.Message
+= ' near line %d, column %d: %s' \
1417 % (X
.LineNumber
, 0, Profile
.FileLinesList
[X
.LineNumber
-1])
1419 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1420 X
.Message
+= ' near line %d, column %d: %s' \
1421 % (FileLineTuple
[1], self
.CurrentOffsetWithinLine
+ 1, self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:].rstrip('\n').rstrip('\r'))
1424 ## SectionParser() method
1426 # Parse the file section info
1427 # Exception will be raised if syntax error found
1429 # @param self The object pointer
1430 # @param section The section string
1432 def SectionParser(self
, section
):
1434 if not S
.startswith("[DEFINES") and not S
.startswith("[FD.") and not S
.startswith("[FV.") and not S
.startswith("[CAPSULE.") \
1435 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM.") and not S
.startswith('[FMPPAYLOAD.'):
1436 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
)
1438 ## __GetDefines() method
1440 # Get Defines section contents and store its data into AllMacrosList
1442 # @param self The object pointer
1443 # @retval True Successfully find a Defines
1444 # @retval False Not able to find a Defines
1446 def __GetDefines(self
):
1448 if not self
.__GetNextToken
():
1451 S
= self
.__Token
.upper()
1452 if S
.startswith("[") and not S
.startswith("[DEFINES"):
1453 self
.SectionParser(S
)
1458 if not self
.__IsToken
("[DEFINES", True):
1459 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1460 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1461 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1462 raise Warning("expected [DEFINES", self
.FileName
, self
.CurrentLineNumber
)
1464 if not self
.__IsToken
( "]"):
1465 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
1467 while self
.__GetNextWord
():
1468 # handle the SET statement
1469 if self
.__Token
== 'SET':
1471 self
.__GetSetStatement
(None)
1474 Macro
= self
.__Token
1476 if not self
.__IsToken
("="):
1477 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1478 if not self
.__GetNextToken
() or self
.__Token
.startswith('['):
1479 raise Warning("expected MACRO value", self
.FileName
, self
.CurrentLineNumber
)
1480 Value
= self
.__Token
1486 # Get FD section contents and store its data into FD dictionary of self.Profile
1488 # @param self The object pointer
1489 # @retval True Successfully find a FD
1490 # @retval False Not able to find a FD
1494 if not self
.__GetNextToken
():
1497 S
= self
.__Token
.upper()
1498 if S
.startswith("[") and not S
.startswith("[FD."):
1499 if not S
.startswith("[FV.") and not S
.startswith('[FMPPAYLOAD.') and not S
.startswith("[CAPSULE.") \
1500 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM."):
1501 raise Warning("Unknown section", self
.FileName
, self
.CurrentLineNumber
)
1506 if not self
.__IsToken
("[FD.", True):
1507 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1508 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1509 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1510 raise Warning("expected [FD.]", self
.FileName
, self
.CurrentLineNumber
)
1512 FdName
= self
.__GetUiName
()
1514 if len (self
.Profile
.FdDict
) == 0:
1515 FdName
= GenFdsGlobalVariable
.PlatformName
1516 if FdName
== "" and GlobalData
.gActivePlatform
:
1517 FdName
= GlobalData
.gActivePlatform
.PlatformName
1518 self
.Profile
.FdNameNotSet
= True
1520 raise Warning("expected FdName in [FD.] section", self
.FileName
, self
.CurrentLineNumber
)
1521 self
.CurrentFdName
= FdName
.upper()
1523 if self
.CurrentFdName
in self
.Profile
.FdDict
:
1524 raise Warning("Unexpected the same FD name", self
.FileName
, self
.CurrentLineNumber
)
1526 if not self
.__IsToken
( "]"):
1527 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
1530 FdObj
.FdUiName
= self
.CurrentFdName
1531 self
.Profile
.FdDict
[self
.CurrentFdName
] = FdObj
1533 if len (self
.Profile
.FdDict
) > 1 and self
.Profile
.FdNameNotSet
:
1534 raise Warning("expected all FDs have their name", self
.FileName
, self
.CurrentLineNumber
)
1536 Status
= self
.__GetCreateFile
(FdObj
)
1538 raise Warning("FD name error", self
.FileName
, self
.CurrentLineNumber
)
1540 while self
.__GetTokenStatements
(FdObj
):
1542 for Attr
in ("BaseAddress", "Size", "ErasePolarity"):
1543 if getattr(FdObj
, Attr
) == None:
1544 self
.__GetNextToken
()
1545 raise Warning("Keyword %s missing" % Attr
, self
.FileName
, self
.CurrentLineNumber
)
1547 if not FdObj
.BlockSizeList
:
1548 FdObj
.BlockSizeList
.append((1, FdObj
.Size
, None))
1550 self
.__GetDefineStatements
(FdObj
)
1552 self
.__GetSetStatements
(FdObj
)
1554 if not self
.__GetRegionLayout
(FdObj
):
1555 raise Warning("expected region layout", self
.FileName
, self
.CurrentLineNumber
)
1557 while self
.__GetRegionLayout
(FdObj
):
1561 ## __GetUiName() method
1563 # Return the UI name of a section
1565 # @param self The object pointer
1566 # @retval FdName UI name
1568 def __GetUiName(self
):
1570 if self
.__GetNextWord
():
1575 ## __GetCreateFile() method
1577 # Return the output file name of object
1579 # @param self The object pointer
1580 # @param Obj object whose data will be stored in file
1581 # @retval FdName UI name
1583 def __GetCreateFile(self
, Obj
):
1585 if self
.__IsKeyword
( "CREATE_FILE"):
1586 if not self
.__IsToken
( "="):
1587 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1589 if not self
.__GetNextToken
():
1590 raise Warning("expected file name", self
.FileName
, self
.CurrentLineNumber
)
1592 FileName
= self
.__Token
1593 Obj
.CreateFileName
= FileName
1597 ## __GetTokenStatements() method
1599 # Get token statements
1601 # @param self The object pointer
1602 # @param Obj for whom token statement is got
1604 def __GetTokenStatements(self
, Obj
):
1605 if self
.__IsKeyword
( "BaseAddress"):
1606 if not self
.__IsToken
( "="):
1607 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1609 if not self
.__GetNextHexNumber
():
1610 raise Warning("expected Hex base address", self
.FileName
, self
.CurrentLineNumber
)
1612 Obj
.BaseAddress
= self
.__Token
1614 if self
.__IsToken
( "|"):
1615 pcdPair
= self
.__GetNextPcdName
()
1616 Obj
.BaseAddressPcd
= pcdPair
1617 self
.Profile
.PcdDict
[pcdPair
] = Obj
.BaseAddress
1618 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1619 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1622 if self
.__IsKeyword
( "Size"):
1623 if not self
.__IsToken
( "="):
1624 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1626 if not self
.__GetNextHexNumber
():
1627 raise Warning("expected Hex size", self
.FileName
, self
.CurrentLineNumber
)
1630 if self
.__IsToken
( "|"):
1631 pcdPair
= self
.__GetNextPcdName
()
1632 Obj
.SizePcd
= pcdPair
1633 self
.Profile
.PcdDict
[pcdPair
] = Size
1634 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1635 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1636 Obj
.Size
= long(Size
, 0)
1639 if self
.__IsKeyword
( "ErasePolarity"):
1640 if not self
.__IsToken
( "="):
1641 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1643 if not self
.__GetNextToken
():
1644 raise Warning("expected Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1646 if self
.__Token
!= "1" and self
.__Token
!= "0":
1647 raise Warning("expected 1 or 0 Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1649 Obj
.ErasePolarity
= self
.__Token
1652 return self
.__GetBlockStatements
(Obj
)
1654 ## __GetAddressStatements() method
1656 # Get address statements
1658 # @param self The object pointer
1659 # @param Obj for whom address statement is got
1660 # @retval True Successfully find
1661 # @retval False Not able to find
1663 def __GetAddressStatements(self
, Obj
):
1665 if self
.__IsKeyword
("BsBaseAddress"):
1666 if not self
.__IsToken
( "="):
1667 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1669 if not self
.__GetNextDecimalNumber
() and not self
.__GetNextHexNumber
():
1670 raise Warning("expected address", self
.FileName
, self
.CurrentLineNumber
)
1672 BsAddress
= long(self
.__Token
, 0)
1673 Obj
.BsBaseAddress
= BsAddress
1675 if self
.__IsKeyword
("RtBaseAddress"):
1676 if not self
.__IsToken
( "="):
1677 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1679 if not self
.__GetNextDecimalNumber
() and not self
.__GetNextHexNumber
():
1680 raise Warning("expected address", self
.FileName
, self
.CurrentLineNumber
)
1682 RtAddress
= long(self
.__Token
, 0)
1683 Obj
.RtBaseAddress
= RtAddress
1685 ## __GetBlockStatements() method
1687 # Get block statements
1689 # @param self The object pointer
1690 # @param Obj for whom block statement is got
1692 def __GetBlockStatements(self
, Obj
):
1694 while self
.__GetBlockStatement
(Obj
):
1697 Item
= Obj
.BlockSizeList
[-1]
1698 if Item
[0] == None or Item
[1] == None:
1699 raise Warning("expected block statement", self
.FileName
, self
.CurrentLineNumber
)
1702 ## __GetBlockStatement() method
1704 # Get block statement
1706 # @param self The object pointer
1707 # @param Obj for whom block statement is got
1708 # @retval True Successfully find
1709 # @retval False Not able to find
1711 def __GetBlockStatement(self
, Obj
):
1712 if not self
.__IsKeyword
( "BlockSize"):
1715 if not self
.__IsToken
( "="):
1716 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1718 if not self
.__GetNextHexNumber
() and not self
.__GetNextDecimalNumber
():
1719 raise Warning("expected Hex or Integer block size", self
.FileName
, self
.CurrentLineNumber
)
1721 BlockSize
= self
.__Token
1723 if self
.__IsToken
( "|"):
1724 PcdPair
= self
.__GetNextPcdName
()
1725 BlockSizePcd
= PcdPair
1726 self
.Profile
.PcdDict
[PcdPair
] = BlockSize
1727 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1728 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1729 BlockSize
= long(BlockSize
, 0)
1732 if self
.__IsKeyword
( "NumBlocks"):
1733 if not self
.__IsToken
( "="):
1734 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1736 if not self
.__GetNextDecimalNumber
() and not self
.__GetNextHexNumber
():
1737 raise Warning("expected block numbers", self
.FileName
, self
.CurrentLineNumber
)
1739 BlockNumber
= long(self
.__Token
, 0)
1741 Obj
.BlockSizeList
.append((BlockSize
, BlockNumber
, BlockSizePcd
))
1744 ## __GetDefineStatements() method
1746 # Get define statements
1748 # @param self The object pointer
1749 # @param Obj for whom define statement is got
1750 # @retval True Successfully find
1751 # @retval False Not able to find
1753 def __GetDefineStatements(self
, Obj
):
1754 while self
.__GetDefineStatement
( Obj
):
1757 ## __GetDefineStatement() method
1759 # Get define statement
1761 # @param self The object pointer
1762 # @param Obj for whom define statement is got
1763 # @retval True Successfully find
1764 # @retval False Not able to find
1766 def __GetDefineStatement(self
, Obj
):
1767 if self
.__IsKeyword
("DEFINE"):
1768 self
.__GetNextToken
()
1769 Macro
= self
.__Token
1770 if not self
.__IsToken
( "="):
1771 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1773 if not self
.__GetNextToken
():
1774 raise Warning("expected value", self
.FileName
, self
.CurrentLineNumber
)
1776 Value
= self
.__Token
1777 Macro
= '$(' + Macro
+ ')'
1778 Obj
.DefineVarDict
[Macro
] = Value
1783 ## __GetSetStatements() method
1785 # Get set statements
1787 # @param self The object pointer
1788 # @param Obj for whom set statement is got
1789 # @retval True Successfully find
1790 # @retval False Not able to find
1792 def __GetSetStatements(self
, Obj
):
1793 while self
.__GetSetStatement
(Obj
):
1796 ## __GetSetStatement() method
1800 # @param self The object pointer
1801 # @param Obj for whom set statement is got
1802 # @retval True Successfully find
1803 # @retval False Not able to find
1805 def __GetSetStatement(self
, Obj
):
1806 if self
.__IsKeyword
("SET"):
1807 PcdPair
= self
.__GetNextPcdName
()
1809 if not self
.__IsToken
( "="):
1810 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1812 Value
= self
.__GetExpression
()
1813 Value
= self
.__EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
1816 Obj
.SetVarDict
[PcdPair
] = Value
1817 self
.Profile
.PcdDict
[PcdPair
] = Value
1818 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1819 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1824 ## __CalcRegionExpr(self)
1826 # Calculate expression for offset or size of a region
1828 # @return: None if invalid expression
1829 # Calculated number if successfully
1831 def __CalcRegionExpr(self
):
1832 StartPos
= self
.GetFileBufferPos()
1835 while not self
.__EndOfFile
():
1836 CurCh
= self
.__CurrentChar
()
1842 if CurCh
in '|\r\n' and PairCount
== 0:
1848 ValueExpression(Expr
,
1849 self
.__CollectMacroPcd
()
1852 self
.SetFileBufferPos(StartPos
)
1855 ## __GetRegionLayout() method
1857 # Get region layout for FD
1859 # @param self The object pointer
1860 # @param Fd for whom region is got
1861 # @retval True Successfully find
1862 # @retval False Not able to find
1864 def __GetRegionLayout(self
, Fd
):
1865 Offset
= self
.__CalcRegionExpr
()
1869 RegionObj
= Region
.Region()
1870 RegionObj
.Offset
= Offset
1871 Fd
.RegionList
.append(RegionObj
)
1873 if not self
.__IsToken
( "|"):
1874 raise Warning("expected '|'", self
.FileName
, self
.CurrentLineNumber
)
1876 Size
= self
.__CalcRegionExpr
()
1878 raise Warning("expected Region Size", self
.FileName
, self
.CurrentLineNumber
)
1879 RegionObj
.Size
= Size
1881 if not self
.__GetNextWord
():
1884 if not self
.__Token
in ("SET", "FV", "FILE", "DATA", "CAPSULE", "INF"):
1886 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]
1887 # Or it might be next region's offset described by an expression which starts with a PCD.
1888 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size
1891 IsRegionPcd
= (RegionSizeGuidPattern
.match(self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
:]) or
1892 RegionOffsetPcdPattern
.match(self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
:]))
1894 RegionObj
.PcdOffset
= self
.__GetNextPcdName
()
1895 self
.Profile
.PcdDict
[RegionObj
.PcdOffset
] = "0x%08X" % (RegionObj
.Offset
+ long(Fd
.BaseAddress
, 0))
1896 self
.__PcdDict
['%s.%s' % (RegionObj
.PcdOffset
[1], RegionObj
.PcdOffset
[0])] = "0x%x" % RegionObj
.Offset
1897 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1898 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdOffset
] = FileLineTuple
1899 if self
.__IsToken
( "|"):
1900 RegionObj
.PcdSize
= self
.__GetNextPcdName
()
1901 self
.Profile
.PcdDict
[RegionObj
.PcdSize
] = "0x%08X" % RegionObj
.Size
1902 self
.__PcdDict
['%s.%s' % (RegionObj
.PcdSize
[1], RegionObj
.PcdSize
[0])] = "0x%x" % RegionObj
.Size
1903 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1904 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdSize
] = FileLineTuple
1906 if not self
.__GetNextWord
():
1909 if self
.__Token
== "SET":
1911 self
.__GetSetStatements
( RegionObj
)
1912 if not self
.__GetNextWord
():
1915 elif self
.__Token
== "FV":
1917 self
.__GetRegionFvType
( RegionObj
)
1919 elif self
.__Token
== "CAPSULE":
1921 self
.__GetRegionCapType
( RegionObj
)
1923 elif self
.__Token
== "FILE":
1925 self
.__GetRegionFileType
(RegionObj
)
1927 elif self
.__Token
== "INF":
1929 RegionObj
.RegionType
= "INF"
1930 while self
.__IsKeyword
("INF"):
1932 ffsInf
= self
.__ParseInfStatement
()
1935 RegionObj
.RegionDataList
.append(ffsInf
)
1937 elif self
.__Token
== "DATA":
1939 self
.__GetRegionDataType
(RegionObj
)
1942 if self
.__GetRegionLayout
(Fd
):
1944 raise Warning("A valid region type was not found. "
1945 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
1946 self
.FileName
, self
.CurrentLineNumber
)
1950 ## __GetRegionFvType() method
1952 # Get region fv data for region
1954 # @param self The object pointer
1955 # @param RegionObj for whom region data is got
1957 def __GetRegionFvType(self
, RegionObj
):
1959 if not self
.__IsKeyword
( "FV"):
1960 raise Warning("expected Keyword 'FV'", self
.FileName
, self
.CurrentLineNumber
)
1962 if not self
.__IsToken
( "="):
1963 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1965 if not self
.__GetNextToken
():
1966 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
1968 RegionObj
.RegionType
= "FV"
1969 RegionObj
.RegionDataList
.append((self
.__Token
).upper())
1971 while self
.__IsKeyword
( "FV"):
1973 if not self
.__IsToken
( "="):
1974 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1976 if not self
.__GetNextToken
():
1977 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
1979 RegionObj
.RegionDataList
.append((self
.__Token
).upper())
1981 ## __GetRegionCapType() method
1983 # Get region capsule data for region
1985 # @param self The object pointer
1986 # @param RegionObj for whom region data is got
1988 def __GetRegionCapType(self
, RegionObj
):
1990 if not self
.__IsKeyword
("CAPSULE"):
1991 raise Warning("expected Keyword 'CAPSULE'", self
.FileName
, self
.CurrentLineNumber
)
1993 if not self
.__IsToken
("="):
1994 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1996 if not self
.__GetNextToken
():
1997 raise Warning("expected CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1999 RegionObj
.RegionType
= "CAPSULE"
2000 RegionObj
.RegionDataList
.append(self
.__Token
)
2002 while self
.__IsKeyword
("CAPSULE"):
2004 if not self
.__IsToken
("="):
2005 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2007 if not self
.__GetNextToken
():
2008 raise Warning("expected CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
2010 RegionObj
.RegionDataList
.append(self
.__Token
)
2012 ## __GetRegionFileType() method
2014 # Get region file data for region
2016 # @param self The object pointer
2017 # @param RegionObj for whom region data is got
2019 def __GetRegionFileType(self
, RegionObj
):
2021 if not self
.__IsKeyword
( "FILE"):
2022 raise Warning("expected Keyword 'FILE'", self
.FileName
, self
.CurrentLineNumber
)
2024 if not self
.__IsToken
( "="):
2025 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2027 if not self
.__GetNextToken
():
2028 raise Warning("expected File name", self
.FileName
, self
.CurrentLineNumber
)
2030 RegionObj
.RegionType
= "FILE"
2031 RegionObj
.RegionDataList
.append( self
.__Token
)
2033 while self
.__IsKeyword
( "FILE"):
2035 if not self
.__IsToken
( "="):
2036 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2038 if not self
.__GetNextToken
():
2039 raise Warning("expected FILE name", self
.FileName
, self
.CurrentLineNumber
)
2041 RegionObj
.RegionDataList
.append(self
.__Token
)
2043 ## __GetRegionDataType() method
2045 # Get region array data for region
2047 # @param self The object pointer
2048 # @param RegionObj for whom region data is got
2050 def __GetRegionDataType(self
, RegionObj
):
2052 if not self
.__IsKeyword
( "DATA"):
2053 raise Warning("expected Region Data type", self
.FileName
, self
.CurrentLineNumber
)
2055 if not self
.__IsToken
( "="):
2056 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2058 if not self
.__IsToken
( "{"):
2059 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2061 if not self
.__GetNextHexNumber
():
2062 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2064 if len(self
.__Token
) > 18:
2065 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2067 # convert hex string value to byte hex string array
2068 AllString
= self
.__Token
2069 AllStrLen
= len (AllString
)
2071 while AllStrLen
> 4:
2072 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + ","
2073 AllStrLen
= AllStrLen
- 2
2074 DataString
= DataString
+ AllString
[:AllStrLen
] + ","
2077 if len (self
.__Token
) <= 4:
2078 while self
.__IsToken
(","):
2079 if not self
.__GetNextHexNumber
():
2080 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2081 if len(self
.__Token
) > 4:
2082 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2083 DataString
+= self
.__Token
2086 if not self
.__IsToken
( "}"):
2087 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2089 DataString
= DataString
.rstrip(",")
2090 RegionObj
.RegionType
= "DATA"
2091 RegionObj
.RegionDataList
.append( DataString
)
2093 while self
.__IsKeyword
( "DATA"):
2095 if not self
.__IsToken
( "="):
2096 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2098 if not self
.__IsToken
( "{"):
2099 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2101 if not self
.__GetNextHexNumber
():
2102 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2104 if len(self
.__Token
) > 18:
2105 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2107 # convert hex string value to byte hex string array
2108 AllString
= self
.__Token
2109 AllStrLen
= len (AllString
)
2111 while AllStrLen
> 4:
2112 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + ","
2113 AllStrLen
= AllStrLen
- 2
2114 DataString
= DataString
+ AllString
[:AllStrLen
] + ","
2117 if len (self
.__Token
) <= 4:
2118 while self
.__IsToken
(","):
2119 if not self
.__GetNextHexNumber
():
2120 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2121 if len(self
.__Token
) > 4:
2122 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2123 DataString
+= self
.__Token
2126 if not self
.__IsToken
( "}"):
2127 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2129 DataString
= DataString
.rstrip(",")
2130 RegionObj
.RegionDataList
.append( DataString
)
2134 # Get FV section contents and store its data into FV dictionary of self.Profile
2136 # @param self The object pointer
2137 # @retval True Successfully find a FV
2138 # @retval False Not able to find a FV
2141 if not self
.__GetNextToken
():
2144 S
= self
.__Token
.upper()
2145 if S
.startswith("[") and not S
.startswith("[FV."):
2146 self
.SectionParser(S
)
2151 if not self
.__IsToken
("[FV.", True):
2152 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2153 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2154 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2155 raise Warning("Unknown Keyword '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2157 FvName
= self
.__GetUiName
()
2158 self
.CurrentFvName
= FvName
.upper()
2160 if not self
.__IsToken
( "]"):
2161 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
2164 FvObj
.UiFvName
= self
.CurrentFvName
2165 self
.Profile
.FvDict
[self
.CurrentFvName
] = FvObj
2167 Status
= self
.__GetCreateFile
(FvObj
)
2169 raise Warning("FV name error", self
.FileName
, self
.CurrentLineNumber
)
2171 self
.__GetDefineStatements
(FvObj
)
2173 self
.__GetAddressStatements
(FvObj
)
2175 FvObj
.FvExtEntryTypeValue
= []
2176 FvObj
.FvExtEntryType
= []
2177 FvObj
.FvExtEntryData
= []
2179 self
.__GetSetStatements
(FvObj
)
2181 if not (self
.__GetBlockStatement
(FvObj
) or self
.__GetFvBaseAddress
(FvObj
) or
2182 self
.__GetFvForceRebase
(FvObj
) or self
.__GetFvAlignment
(FvObj
) or
2183 self
.__GetFvAttributes
(FvObj
) or self
.__GetFvNameGuid
(FvObj
) or
2184 self
.__GetFvExtEntryStatement
(FvObj
) or self
.__GetFvNameString
(FvObj
)):
2187 if FvObj
.FvNameString
== 'TRUE' and not FvObj
.FvNameGuid
:
2188 raise Warning("FvNameString found but FvNameGuid was not found", self
.FileName
, self
.CurrentLineNumber
)
2190 self
.__GetAprioriSection
(FvObj
, FvObj
.DefineVarDict
.copy())
2191 self
.__GetAprioriSection
(FvObj
, FvObj
.DefineVarDict
.copy())
2194 isInf
= self
.__GetInfStatement
(FvObj
, MacroDict
= FvObj
.DefineVarDict
.copy())
2195 isFile
= self
.__GetFileStatement
(FvObj
, MacroDict
= FvObj
.DefineVarDict
.copy())
2196 if not isInf
and not isFile
:
2201 ## __GetFvAlignment() method
2203 # Get alignment for FV
2205 # @param self The object pointer
2206 # @param Obj for whom alignment is got
2207 # @retval True Successfully find a alignment statement
2208 # @retval False Not able to find a alignment statement
2210 def __GetFvAlignment(self
, Obj
):
2212 if not self
.__IsKeyword
( "FvAlignment"):
2215 if not self
.__IsToken
( "="):
2216 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2218 if not self
.__GetNextToken
():
2219 raise Warning("expected alignment value", self
.FileName
, self
.CurrentLineNumber
)
2221 if self
.__Token
.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
2222 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
2223 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
2225 raise Warning("Unknown alignment value '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2226 Obj
.FvAlignment
= self
.__Token
2229 ## __GetFvBaseAddress() method
2231 # Get BaseAddress for FV
2233 # @param self The object pointer
2234 # @param Obj for whom FvBaseAddress is got
2235 # @retval True Successfully find a FvBaseAddress statement
2236 # @retval False Not able to find a FvBaseAddress statement
2238 def __GetFvBaseAddress(self
, Obj
):
2240 if not self
.__IsKeyword
("FvBaseAddress"):
2243 if not self
.__IsToken
( "="):
2244 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2246 if not self
.__GetNextToken
():
2247 raise Warning("expected FV base address value", self
.FileName
, self
.CurrentLineNumber
)
2249 IsValidBaseAddrValue
= re
.compile('^0[x|X][0-9a-fA-F]+')
2251 if not IsValidBaseAddrValue
.match(self
.__Token
.upper()):
2252 raise Warning("Unknown FV base address value '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2253 Obj
.FvBaseAddress
= self
.__Token
2256 ## __GetFvForceRebase() method
2258 # Get FvForceRebase for FV
2260 # @param self The object pointer
2261 # @param Obj for whom FvForceRebase is got
2262 # @retval True Successfully find a FvForceRebase statement
2263 # @retval False Not able to find a FvForceRebase statement
2265 def __GetFvForceRebase(self
, Obj
):
2267 if not self
.__IsKeyword
("FvForceRebase"):
2270 if not self
.__IsToken
( "="):
2271 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2273 if not self
.__GetNextToken
():
2274 raise Warning("expected FvForceRebase value", self
.FileName
, self
.CurrentLineNumber
)
2276 if self
.__Token
.upper() not in ["TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"]:
2277 raise Warning("Unknown FvForceRebase value '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2279 if self
.__Token
.upper() in ["TRUE", "1", "0X1", "0X01"]:
2280 Obj
.FvForceRebase
= True
2281 elif self
.__Token
.upper() in ["FALSE", "0", "0X0", "0X00"]:
2282 Obj
.FvForceRebase
= False
2284 Obj
.FvForceRebase
= None
2289 ## __GetFvAttributes() method
2291 # Get attributes for FV
2293 # @param self The object pointer
2294 # @param Obj for whom attribute is got
2297 def __GetFvAttributes(self
, FvObj
):
2299 while self
.__GetNextWord
():
2302 if name
not in ("ERASE_POLARITY", "MEMORY_MAPPED", \
2303 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
2304 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
2305 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
2306 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
2307 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"):
2311 if not self
.__IsToken
( "="):
2312 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2314 if not self
.__GetNextToken
() or self
.__Token
.upper() not in ("TRUE", "FALSE", "1", "0"):
2315 raise Warning("expected TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
2317 FvObj
.FvAttributeDict
[name
] = self
.__Token
2321 ## __GetFvNameGuid() method
2323 # Get FV GUID for FV
2325 # @param self The object pointer
2326 # @param Obj for whom GUID is got
2329 def __GetFvNameGuid(self
, FvObj
):
2331 if not self
.__IsKeyword
( "FvNameGuid"):
2334 if not self
.__IsToken
( "="):
2335 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2337 if not self
.__GetNextGuid
():
2338 raise Warning("expected FV GUID value", self
.FileName
, self
.CurrentLineNumber
)
2340 FvObj
.FvNameGuid
= self
.__Token
2344 def __GetFvNameString(self
, FvObj
):
2346 if not self
.__IsKeyword
( "FvNameString"):
2349 if not self
.__IsToken
( "="):
2350 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2352 if not self
.__GetNextToken
() or self
.__Token
not in ('TRUE', 'FALSE'):
2353 raise Warning("expected TRUE or FALSE for FvNameString", self
.FileName
, self
.CurrentLineNumber
)
2355 FvObj
.FvNameString
= self
.__Token
2359 def __GetFvExtEntryStatement(self
, FvObj
):
2361 if not (self
.__IsKeyword
( "FV_EXT_ENTRY") or self
.__IsKeyword
( "FV_EXT_ENTRY_TYPE")):
2364 if not self
.__IsKeyword
("TYPE"):
2365 raise Warning("expected 'TYPE'", self
.FileName
, self
.CurrentLineNumber
)
2367 if not self
.__IsToken
( "="):
2368 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2370 if not self
.__GetNextHexNumber
() and not self
.__GetNextDecimalNumber
():
2371 raise Warning("expected Hex FV extension entry type value At Line ", self
.FileName
, self
.CurrentLineNumber
)
2373 FvObj
.FvExtEntryTypeValue
+= [self
.__Token
]
2375 if not self
.__IsToken
( "{"):
2376 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2378 if not self
.__IsKeyword
("FILE") and not self
.__IsKeyword
("DATA"):
2379 raise Warning("expected 'FILE' or 'DATA'", self
.FileName
, self
.CurrentLineNumber
)
2381 FvObj
.FvExtEntryType
+= [self
.__Token
]
2383 if self
.__Token
== 'DATA':
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 if not self
.__GetNextHexNumber
():
2392 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2394 if len(self
.__Token
) > 4:
2395 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2397 DataString
= self
.__Token
2400 while self
.__IsToken
(","):
2401 if not self
.__GetNextHexNumber
():
2402 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2403 if len(self
.__Token
) > 4:
2404 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2405 DataString
+= self
.__Token
2408 if not self
.__IsToken
( "}"):
2409 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2411 if not self
.__IsToken
( "}"):
2412 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2414 DataString
= DataString
.rstrip(",")
2415 FvObj
.FvExtEntryData
+= [DataString
]
2417 if self
.__Token
== 'FILE':
2419 if not self
.__IsToken
( "="):
2420 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2422 if not self
.__GetNextToken
():
2423 raise Warning("expected FV Extension Entry file path At Line ", self
.FileName
, self
.CurrentLineNumber
)
2425 FvObj
.FvExtEntryData
+= [self
.__Token
]
2427 if not self
.__IsToken
( "}"):
2428 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2432 ## __GetAprioriSection() method
2434 # Get token statements
2436 # @param self The object pointer
2437 # @param FvObj for whom apriori is got
2438 # @param MacroDict dictionary used to replace macro
2439 # @retval True Successfully find apriori statement
2440 # @retval False Not able to find apriori statement
2442 def __GetAprioriSection(self
, FvObj
, MacroDict
= {}):
2444 if not self
.__IsKeyword
( "APRIORI"):
2447 if not self
.__IsKeyword
("PEI") and not self
.__IsKeyword
("DXE"):
2448 raise Warning("expected Apriori file type", self
.FileName
, self
.CurrentLineNumber
)
2449 AprType
= self
.__Token
2451 if not self
.__IsToken
( "{"):
2452 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2454 AprSectionObj
= AprioriSection
.AprioriSection()
2455 AprSectionObj
.AprioriType
= AprType
2457 self
.__GetDefineStatements
(AprSectionObj
)
2458 MacroDict
.update(AprSectionObj
.DefineVarDict
)
2461 IsInf
= self
.__GetInfStatement
( AprSectionObj
, MacroDict
= MacroDict
)
2462 IsFile
= self
.__GetFileStatement
( AprSectionObj
)
2463 if not IsInf
and not IsFile
:
2466 if not self
.__IsToken
( "}"):
2467 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2469 FvObj
.AprioriSectionList
.append(AprSectionObj
)
2472 def __ParseInfStatement(self
):
2473 if not self
.__IsKeyword
("INF"):
2476 ffsInf
= FfsInfStatement
.FfsInfStatement()
2477 self
.__GetInfOptions
(ffsInf
)
2479 if not self
.__GetNextToken
():
2480 raise Warning("expected INF file path", self
.FileName
, self
.CurrentLineNumber
)
2481 ffsInf
.InfFileName
= self
.__Token
2482 if not ffsInf
.InfFileName
.endswith('.inf'):
2483 raise Warning("expected .inf file path", self
.FileName
, self
.CurrentLineNumber
)
2485 ffsInf
.CurrentLineNum
= self
.CurrentLineNumber
2486 ffsInf
.CurrentLineContent
= self
.__CurrentLine
()
2488 #Replace $(SAPCE) with real space
2489 ffsInf
.InfFileName
= ffsInf
.InfFileName
.replace('$(SPACE)', ' ')
2491 if ffsInf
.InfFileName
.replace('$(WORKSPACE)', '').find('$') == -1:
2492 #do case sensitive check for file path
2493 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2495 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2497 if not ffsInf
.InfFileName
in self
.Profile
.InfList
:
2498 self
.Profile
.InfList
.append(ffsInf
.InfFileName
)
2499 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2500 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
2502 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
2503 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
2505 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
2507 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
2509 if self
.__IsToken
('|'):
2510 if self
.__IsKeyword
('RELOCS_STRIPPED'):
2511 ffsInf
.KeepReloc
= False
2512 elif self
.__IsKeyword
('RELOCS_RETAINED'):
2513 ffsInf
.KeepReloc
= True
2515 raise Warning("Unknown reloc strip flag '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2518 ## __GetInfStatement() method
2520 # Get INF statements
2522 # @param self The object pointer
2523 # @param Obj for whom inf statement is got
2524 # @param MacroDict dictionary used to replace macro
2525 # @retval True Successfully find inf statement
2526 # @retval False Not able to find inf statement
2528 def __GetInfStatement(self
, Obj
, ForCapsule
=False, MacroDict
={}):
2529 ffsInf
= self
.__ParseInfStatement
()
2534 capsuleFfs
= CapsuleData
.CapsuleFfs()
2535 capsuleFfs
.Ffs
= ffsInf
2536 Obj
.CapsuleDataList
.append(capsuleFfs
)
2538 Obj
.FfsList
.append(ffsInf
)
2541 ## __GetInfOptions() method
2543 # Get options for INF
2545 # @param self The object pointer
2546 # @param FfsInfObj for whom option is got
2548 def __GetInfOptions(self
, FfsInfObj
):
2549 if self
.__IsKeyword
("FILE_GUID"):
2550 if not self
.__IsToken
("="):
2551 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2552 if not self
.__GetNextGuid
():
2553 raise Warning("expected GUID value", self
.FileName
, self
.CurrentLineNumber
)
2554 FfsInfObj
.OverrideGuid
= self
.__Token
2556 if self
.__IsKeyword
( "RuleOverride"):
2557 if not self
.__IsToken
( "="):
2558 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2559 if not self
.__GetNextToken
():
2560 raise Warning("expected Rule name", self
.FileName
, self
.CurrentLineNumber
)
2561 FfsInfObj
.Rule
= self
.__Token
2563 if self
.__IsKeyword
( "VERSION"):
2564 if not self
.__IsToken
( "="):
2565 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2566 if not self
.__GetNextToken
():
2567 raise Warning("expected Version", self
.FileName
, self
.CurrentLineNumber
)
2569 if self
.__GetStringData
():
2570 FfsInfObj
.Version
= self
.__Token
2572 if self
.__IsKeyword
( "UI"):
2573 if not self
.__IsToken
( "="):
2574 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2575 if not self
.__GetNextToken
():
2576 raise Warning("expected UI name", self
.FileName
, self
.CurrentLineNumber
)
2578 if self
.__GetStringData
():
2579 FfsInfObj
.Ui
= self
.__Token
2581 if self
.__IsKeyword
( "USE"):
2582 if not self
.__IsToken
( "="):
2583 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2584 if not self
.__GetNextToken
():
2585 raise Warning("expected ARCH name", self
.FileName
, self
.CurrentLineNumber
)
2586 FfsInfObj
.UseArch
= self
.__Token
2589 if self
.__GetNextToken
():
2590 p
= re
.compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
2591 if p
.match(self
.__Token
) and p
.match(self
.__Token
).span()[1] == len(self
.__Token
):
2592 FfsInfObj
.KeyStringList
.append(self
.__Token
)
2593 if not self
.__IsToken
(","):
2599 while self
.__GetNextToken
():
2600 if not p
.match(self
.__Token
):
2601 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2602 FfsInfObj
.KeyStringList
.append(self
.__Token
)
2604 if not self
.__IsToken
(","):
2607 ## __GetFileStatement() method
2609 # Get FILE statements
2611 # @param self The object pointer
2612 # @param Obj for whom FILE statement is got
2613 # @param MacroDict dictionary used to replace macro
2614 # @retval True Successfully find FILE statement
2615 # @retval False Not able to find FILE statement
2617 def __GetFileStatement(self
, Obj
, ForCapsule
= False, MacroDict
= {}):
2619 if not self
.__IsKeyword
( "FILE"):
2622 if not self
.__GetNextWord
():
2623 raise Warning("expected FFS type", self
.FileName
, self
.CurrentLineNumber
)
2625 if ForCapsule
and self
.__Token
== 'DATA':
2630 FfsFileObj
= FfsFileStatement
.FileStatement()
2631 FfsFileObj
.FvFileType
= self
.__Token
2633 if not self
.__IsToken
( "="):
2634 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2636 if not self
.__GetNextGuid
():
2637 if not self
.__GetNextWord
():
2638 raise Warning("expected File GUID", self
.FileName
, self
.CurrentLineNumber
)
2639 if self
.__Token
== 'PCD':
2640 if not self
.__IsToken
( "("):
2641 raise Warning("expected '('", self
.FileName
, self
.CurrentLineNumber
)
2642 PcdPair
= self
.__GetNextPcdName
()
2643 if not self
.__IsToken
( ")"):
2644 raise Warning("expected ')'", self
.FileName
, self
.CurrentLineNumber
)
2645 self
.__Token
= 'PCD('+PcdPair
[1]+'.'+PcdPair
[0]+')'
2647 FfsFileObj
.NameGuid
= self
.__Token
2649 self
.__GetFilePart
( FfsFileObj
, MacroDict
.copy())
2652 capsuleFfs
= CapsuleData
.CapsuleFfs()
2653 capsuleFfs
.Ffs
= FfsFileObj
2654 Obj
.CapsuleDataList
.append(capsuleFfs
)
2656 Obj
.FfsList
.append(FfsFileObj
)
2660 ## __FileCouldHaveRelocFlag() method
2662 # Check whether reloc strip flag can be set for a file type.
2664 # @param self The object pointer
2665 # @param FileType The file type to check with
2666 # @retval True This type could have relocation strip flag
2667 # @retval False No way to have it
2670 def __FileCouldHaveRelocFlag (self
, FileType
):
2671 if FileType
in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'):
2676 ## __SectionCouldHaveRelocFlag() method
2678 # Check whether reloc strip flag can be set for a section type.
2680 # @param self The object pointer
2681 # @param SectionType The section type to check with
2682 # @retval True This type could have relocation strip flag
2683 # @retval False No way to have it
2686 def __SectionCouldHaveRelocFlag (self
, SectionType
):
2687 if SectionType
in ('TE', 'PE32'):
2692 ## __GetFilePart() method
2694 # Get components for FILE statement
2696 # @param self The object pointer
2697 # @param FfsFileObj for whom component is got
2698 # @param MacroDict dictionary used to replace macro
2700 def __GetFilePart(self
, FfsFileObj
, MacroDict
= {}):
2702 self
.__GetFileOpts
( FfsFileObj
)
2704 if not self
.__IsToken
("{"):
2705 if self
.__IsKeyword
('RELOCS_STRIPPED') or self
.__IsKeyword
('RELOCS_RETAINED'):
2706 if self
.__FileCouldHaveRelocFlag
(FfsFileObj
.FvFileType
):
2707 if self
.__Token
== 'RELOCS_STRIPPED':
2708 FfsFileObj
.KeepReloc
= False
2710 FfsFileObj
.KeepReloc
= True
2712 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj
.FvFileType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
2714 if not self
.__IsToken
("{"):
2715 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2717 if not self
.__GetNextToken
():
2718 raise Warning("expected File name or section data", self
.FileName
, self
.CurrentLineNumber
)
2720 if self
.__Token
== "FV":
2721 if not self
.__IsToken
( "="):
2722 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2723 if not self
.__GetNextToken
():
2724 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
2725 FfsFileObj
.FvName
= self
.__Token
2727 elif self
.__Token
== "FD":
2728 if not self
.__IsToken
( "="):
2729 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2730 if not self
.__GetNextToken
():
2731 raise Warning("expected FD name", self
.FileName
, self
.CurrentLineNumber
)
2732 FfsFileObj
.FdName
= self
.__Token
2734 elif self
.__Token
in ("DEFINE", "APRIORI", "SECTION"):
2736 self
.__GetSectionData
( FfsFileObj
, MacroDict
)
2738 elif hasattr(FfsFileObj
, 'FvFileType') and FfsFileObj
.FvFileType
== 'RAW':
2740 self
.__GetRAWData
(FfsFileObj
, MacroDict
)
2743 FfsFileObj
.CurrentLineNum
= self
.CurrentLineNumber
2744 FfsFileObj
.CurrentLineContent
= self
.__CurrentLine
()
2745 FfsFileObj
.FileName
= self
.__Token
.replace('$(SPACE)', ' ')
2746 self
.__VerifyFile
(FfsFileObj
.FileName
)
2748 if not self
.__IsToken
( "}"):
2749 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2751 ## __GetRAWData() method
2753 # Get RAW data for FILE statement
2755 # @param self The object pointer
2756 # @param FfsFileObj for whom section is got
2757 # @param MacroDict dictionary used to replace macro
2759 def __GetRAWData(self
, FfsFileObj
, MacroDict
= {}):
2760 FfsFileObj
.FileName
= []
2761 FfsFileObj
.SubAlignment
= []
2764 if self
.__GetAlignment
():
2765 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
2766 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
2767 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2768 #For FFS, Auto is default option same to ""
2769 if not self
.__Token
== "Auto":
2770 AlignValue
= self
.__Token
2771 if not self
.__GetNextToken
():
2772 raise Warning("expected Filename value", self
.FileName
, self
.CurrentLineNumber
)
2774 FileName
= self
.__Token
.replace('$(SPACE)', ' ')
2777 raise Warning("expected Filename value", self
.FileName
, self
.CurrentLineNumber
)
2779 self
.__VerifyFile
(FileName
)
2780 File
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
)
2781 FfsFileObj
.FileName
.append(File
.Path
)
2782 FfsFileObj
.SubAlignment
.append(AlignValue
)
2784 if self
.__IsToken
( "}"):
2788 if len(FfsFileObj
.SubAlignment
) == 1:
2789 FfsFileObj
.SubAlignment
= FfsFileObj
.SubAlignment
[0]
2790 if len(FfsFileObj
.FileName
) == 1:
2791 FfsFileObj
.FileName
= FfsFileObj
.FileName
[0]
2793 ## __GetFileOpts() method
2795 # Get options for FILE statement
2797 # @param self The object pointer
2798 # @param FfsFileObj for whom options is got
2800 def __GetFileOpts(self
, FfsFileObj
):
2802 if self
.__GetNextToken
():
2803 Pattern
= re
.compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
2804 if Pattern
.match(self
.__Token
):
2805 FfsFileObj
.KeyStringList
.append(self
.__Token
)
2806 if self
.__IsToken
(","):
2807 while self
.__GetNextToken
():
2808 if not Pattern
.match(self
.__Token
):
2809 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2810 FfsFileObj
.KeyStringList
.append(self
.__Token
)
2812 if not self
.__IsToken
(","):
2818 if self
.__IsKeyword
( "FIXED", True):
2819 FfsFileObj
.Fixed
= True
2821 if self
.__IsKeyword
( "CHECKSUM", True):
2822 FfsFileObj
.CheckSum
= True
2824 if self
.__GetAlignment
():
2825 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
2826 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
2827 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2828 #For FFS, Auto is default option same to ""
2829 if not self
.__Token
== "Auto":
2830 FfsFileObj
.Alignment
= self
.__Token
2832 ## __GetAlignment() method
2834 # Return the alignment value
2836 # @param self The object pointer