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
.DataType
import *
56 from Common
.String
import ReplaceMacro
58 from Common
.Misc
import tdict
59 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
60 import Common
.LongFilePathOs
as os
61 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
62 from Capsule
import EFI_CERT_TYPE_PKCS7_GUID
63 from Capsule
import EFI_CERT_TYPE_RSA2048_SHA256_GUID
64 from Common
.RangeExpression
import RangeExpression
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*")
88 BaseAddrValuePattern
= re
.compile('^0[xX][0-9a-fA-F]+')
89 FileExtensionPattern
= re
.compile(r
'([a-zA-Z][a-zA-Z0-9]*)')
90 TokenFindPattern
= re
.compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
92 AllIncludeFileList
= []
94 # Get the closest parent
95 def GetParentAtLine (Line
):
96 for Profile
in AllIncludeFileList
:
97 if Profile
.IsLineInFile(Line
):
102 def IsValidInclude (File
, Line
):
103 for Profile
in AllIncludeFileList
:
104 if Profile
.IsLineInFile(Line
) and Profile
.FileName
== File
:
109 def GetRealFileLine (File
, Line
):
112 for Profile
in AllIncludeFileList
:
113 if Profile
.IsLineInFile(Line
):
114 return Profile
.GetLineInFile(Line
)
115 elif Line
>= Profile
.InsertStartLineNumber
and Profile
.Level
== 1:
116 InsertedLines
+= Profile
.GetTotalLines()
118 return (File
, Line
- InsertedLines
)
120 ## The exception class that used to report error messages when parsing FDF
122 # Currently the "ToolName" is set to be "FDF Parser".
124 class Warning (Exception):
127 # @param self The object pointer
128 # @param Str The message to record
129 # @param File The FDF name
130 # @param Line The Line number that error occurs
132 def __init__(self
, Str
, File
= None, Line
= None):
134 FileLineTuple
= GetRealFileLine(File
, Line
)
135 self
.FileName
= FileLineTuple
[0]
136 self
.LineNumber
= FileLineTuple
[1]
137 self
.OriginalLineNumber
= Line
139 self
.ToolName
= 'FdfParser'
144 ## The Include file content class that used to record file data when parsing include file
146 # May raise Exception when opening file.
148 class IncludeFileProfile
:
151 # @param self The object pointer
152 # @param FileName The file that to be parsed
154 def __init__(self
, FileName
):
155 self
.FileName
= FileName
156 self
.FileLinesList
= []
158 fsock
= open(FileName
, "rb", 0)
160 self
.FileLinesList
= fsock
.readlines()
161 for index
, line
in enumerate(self
.FileLinesList
):
162 if not line
.endswith('\n'):
163 self
.FileLinesList
[index
] += '\n'
169 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
171 self
.InsertStartLineNumber
= None
172 self
.InsertAdjust
= 0
173 self
.IncludeFileList
= []
174 self
.Level
= 1 # first level include file
176 def GetTotalLines(self
):
177 TotalLines
= self
.InsertAdjust
+ len(self
.FileLinesList
)
179 for Profile
in self
.IncludeFileList
:
180 TotalLines
+= Profile
.GetTotalLines()
184 def IsLineInFile(self
, Line
):
185 if Line
>= self
.InsertStartLineNumber
and Line
< self
.InsertStartLineNumber
+ self
.GetTotalLines():
190 def GetLineInFile(self
, Line
):
191 if not self
.IsLineInFile (Line
):
192 return (self
.FileName
, -1)
194 InsertedLines
= self
.InsertStartLineNumber
196 for Profile
in self
.IncludeFileList
:
197 if Profile
.IsLineInFile(Line
):
198 return Profile
.GetLineInFile(Line
)
199 elif Line
>= Profile
.InsertStartLineNumber
:
200 InsertedLines
+= Profile
.GetTotalLines()
202 return (self
.FileName
, Line
- InsertedLines
+ 1)
206 ## The FDF content class that used to record file data when parsing FDF
208 # May raise Exception when opening file.
213 # @param self The object pointer
214 # @param FileName The file that to be parsed
216 def __init__(self
, FileName
):
217 self
.FileLinesList
= []
219 fsock
= open(FileName
, "rb", 0)
221 self
.FileLinesList
= fsock
.readlines()
226 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
231 self
.InfDict
= {'ArchTBD':[]}
232 # ECC will use this Dict and List information
233 self
.PcdFileLineDict
= {}
234 self
.InfFileLineList
= []
237 self
.FdNameNotSet
= False
239 self
.CapsuleDict
= {}
243 self
.FmpPayloadDict
= {}
245 ## The syntax parser for FDF
247 # PreprocessFile method should be called prior to ParseFile
248 # CycleReferenceCheck method can detect cycles in FDF contents
250 # GetNext*** procedures mean these procedures will get next token first, then make judgement.
251 # Get*** procedures mean these procedures will make judgement on current token only.
256 # @param self The object pointer
257 # @param FileName The file that to be parsed
259 def __init__(self
, FileName
):
260 self
.Profile
= FileProfile(FileName
)
261 self
.FileName
= FileName
262 self
.CurrentLineNumber
= 1
263 self
.CurrentOffsetWithinLine
= 0
264 self
.CurrentFdName
= None
265 self
.CurrentFvName
= None
267 self
.__SkippedChars
= ""
268 GlobalData
.gFdfParser
= self
270 # Used to section info
271 self
.__CurSection
= []
272 # Key: [section name, UI name, arch]
273 # Value: {MACRO_NAME : MACRO_VALUE}
274 self
.__MacroDict
= tdict(True, 3)
277 self
.__WipeOffArea
= []
278 if GenFdsGlobalVariable
.WorkSpaceDir
== '':
279 GenFdsGlobalVariable
.WorkSpaceDir
= os
.getenv("WORKSPACE")
281 ## __SkipWhiteSpace() method
283 # Skip white spaces from current char, return number of chars skipped
285 # @param self The object pointer
286 # @retval Count The number of chars skipped
288 def __SkipWhiteSpace(self
):
290 while not self
.__EndOfFile
():
292 if self
.__CurrentChar
() in (T_CHAR_NULL
, T_CHAR_CR
, T_CHAR_LF
, T_CHAR_SPACE
, T_CHAR_TAB
):
293 self
.__SkippedChars
+= str(self
.__CurrentChar
())
300 ## __EndOfFile() method
302 # Judge current buffer pos is at file end
304 # @param self The object pointer
305 # @retval True Current File buffer position is at file end
306 # @retval False Current File buffer position is NOT at file end
308 def __EndOfFile(self
):
309 NumberOfLines
= len(self
.Profile
.FileLinesList
)
310 SizeOfLastLine
= len(self
.Profile
.FileLinesList
[-1])
311 if self
.CurrentLineNumber
== NumberOfLines
and self
.CurrentOffsetWithinLine
>= SizeOfLastLine
- 1:
313 elif self
.CurrentLineNumber
> NumberOfLines
:
318 ## __EndOfLine() method
320 # Judge current buffer pos is at line end
322 # @param self The object pointer
323 # @retval True Current File buffer position is at line end
324 # @retval False Current File buffer position is NOT at line end
326 def __EndOfLine(self
):
327 if self
.CurrentLineNumber
> len(self
.Profile
.FileLinesList
):
329 SizeOfCurrentLine
= len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
330 if self
.CurrentOffsetWithinLine
>= SizeOfCurrentLine
:
337 # Reset file data buffer to the initial state
339 # @param self The object pointer
340 # @param DestLine Optional new destination line number.
341 # @param DestOffset Optional new destination offset.
343 def Rewind(self
, DestLine
= 1, DestOffset
= 0):
344 self
.CurrentLineNumber
= DestLine
345 self
.CurrentOffsetWithinLine
= DestOffset
347 ## __UndoOneChar() method
349 # Go back one char in the file buffer
351 # @param self The object pointer
352 # @retval True Successfully go back one char
353 # @retval False Not able to go back one char as file beginning reached
355 def __UndoOneChar(self
):
357 if self
.CurrentLineNumber
== 1 and self
.CurrentOffsetWithinLine
== 0:
359 elif self
.CurrentOffsetWithinLine
== 0:
360 self
.CurrentLineNumber
-= 1
361 self
.CurrentOffsetWithinLine
= len(self
.__CurrentLine
()) - 1
363 self
.CurrentOffsetWithinLine
-= 1
366 ## __GetOneChar() method
368 # Move forward one char in the file buffer
370 # @param self The object pointer
372 def __GetOneChar(self
):
373 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
374 self
.CurrentLineNumber
+= 1
375 self
.CurrentOffsetWithinLine
= 0
377 self
.CurrentOffsetWithinLine
+= 1
379 ## __CurrentChar() method
381 # Get the char pointed to by the file buffer pointer
383 # @param self The object pointer
384 # @retval Char Current char
386 def __CurrentChar(self
):
387 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
]
389 ## __NextChar() method
391 # Get the one char pass the char pointed to by the file buffer pointer
393 # @param self The object pointer
394 # @retval Char Next char
396 def __NextChar(self
):
397 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
398 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
][0]
400 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
+ 1]
402 ## __SetCurrentCharValue() method
404 # Modify the value of current char
406 # @param self The object pointer
407 # @param Value The new value of current char
409 def __SetCurrentCharValue(self
, Value
):
410 self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
] = Value
412 ## __CurrentLine() method
414 # Get the list that contains current line contents
416 # @param self The object pointer
417 # @retval List current line contents
419 def __CurrentLine(self
):
420 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
422 def __StringToList(self
):
423 self
.Profile
.FileLinesList
= [list(s
) for s
in self
.Profile
.FileLinesList
]
424 self
.Profile
.FileLinesList
[-1].append(' ')
426 def __ReplaceFragment(self
, StartPos
, EndPos
, Value
= ' '):
427 if StartPos
[0] == EndPos
[0]:
429 while Offset
<= EndPos
[1]:
430 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
435 while self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] not in ('\r', '\n'):
436 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
440 while Line
< EndPos
[0]:
442 while self
.Profile
.FileLinesList
[Line
][Offset
] not in ('\r', '\n'):
443 self
.Profile
.FileLinesList
[Line
][Offset
] = Value
448 while Offset
<= EndPos
[1]:
449 self
.Profile
.FileLinesList
[EndPos
[0]][Offset
] = Value
453 def __GetMacroName(self
):
454 if not self
.__GetNextToken
():
455 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
456 MacroName
= self
.__Token
458 if MacroName
.startswith('!'):
460 MacroName
= MacroName
[1:].strip()
462 if not MacroName
.startswith('$(') or not MacroName
.endswith(')'):
463 raise Warning("Macro name expected(Please use '$(%(Token)s)' if '%(Token)s' is a macro.)" % {"Token" : MacroName
},
464 self
.FileName
, self
.CurrentLineNumber
)
465 MacroName
= MacroName
[2:-1]
466 return MacroName
, NotFlag
468 def __SetMacroValue(self
, Macro
, Value
):
469 if not self
.__CurSection
:
473 if not self
.__MacroDict
[self
.__CurSection
[0], self
.__CurSection
[1], self
.__CurSection
[2]]:
474 self
.__MacroDict
[self
.__CurSection
[0], self
.__CurSection
[1], self
.__CurSection
[2]] = MacroDict
476 MacroDict
= self
.__MacroDict
[self
.__CurSection
[0], self
.__CurSection
[1], self
.__CurSection
[2]]
477 MacroDict
[Macro
] = Value
479 def __GetMacroValue(self
, Macro
):
481 if Macro
in GlobalData
.gCommandLineDefines
:
482 return GlobalData
.gCommandLineDefines
[Macro
]
483 if Macro
in GlobalData
.gGlobalDefines
:
484 return GlobalData
.gGlobalDefines
[Macro
]
486 if self
.__CurSection
:
487 MacroDict
= self
.__MacroDict
[
488 self
.__CurSection
[0],
489 self
.__CurSection
[1],
492 if MacroDict
and Macro
in MacroDict
:
493 return MacroDict
[Macro
]
496 if Macro
in GlobalData
.gPlatformDefines
:
497 return GlobalData
.gPlatformDefines
[Macro
]
500 def __SectionHeaderParser(self
, Section
):
502 # [FD.UiName]: use dummy instead if UI name is optional
505 # [Rule]: don't take rule section into account, macro is not allowed in this section
506 # [VTF.arch.UiName, arch]
507 # [OptionRom.DriverName]
508 self
.__CurSection
= []
509 Section
= Section
.strip()[1:-1].upper().replace(' ', '').strip('.')
510 ItemList
= Section
.split('.')
512 if Item
== '' or Item
== 'RULE':
515 if Item
== TAB_COMMON_DEFINES
.upper():
516 self
.__CurSection
= [TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]
517 elif Item
== 'VTF' and len(ItemList
) == 3:
519 Pos
= UiName
.find(',')
521 UiName
= UiName
[:Pos
]
522 self
.__CurSection
= ['VTF', UiName
, ItemList
[1]]
523 elif len(ItemList
) > 1:
524 self
.__CurSection
= [ItemList
[0], ItemList
[1], TAB_COMMON
]
525 elif len(ItemList
) > 0:
526 self
.__CurSection
= [ItemList
[0], 'DUMMY', TAB_COMMON
]
528 ## PreprocessFile() method
530 # Preprocess file contents, replace comments with spaces.
531 # In the end, rewind the file buffer pointer to the beginning
532 # BUGBUG: No !include statement processing contained in this procedure
533 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
535 # @param self The object pointer
537 def PreprocessFile(self
):
541 DoubleSlashComment
= False
543 # HashComment in quoted string " " is ignored.
546 while not self
.__EndOfFile
():
548 if self
.__CurrentChar
() == T_CHAR_DOUBLE_QUOTE
and not InComment
:
549 InString
= not InString
550 # meet new line, then no longer in a comment for // and '#'
551 if self
.__CurrentChar
() == T_CHAR_LF
:
552 self
.CurrentLineNumber
+= 1
553 self
.CurrentOffsetWithinLine
= 0
554 if InComment
and DoubleSlashComment
:
556 DoubleSlashComment
= False
557 if InComment
and HashComment
:
560 # check for */ comment end
561 elif InComment
and not DoubleSlashComment
and not HashComment
and self
.__CurrentChar
() == T_CHAR_STAR
and self
.__NextChar
() == T_CHAR_SLASH
:
562 self
.__SetCurrentCharValue
(T_CHAR_SPACE
)
564 self
.__SetCurrentCharValue
(T_CHAR_SPACE
)
567 # set comments to spaces
569 self
.__SetCurrentCharValue
(T_CHAR_SPACE
)
571 # check for // comment
572 elif self
.__CurrentChar
() == T_CHAR_SLASH
and self
.__NextChar
() == T_CHAR_SLASH
and not self
.__EndOfLine
():
574 DoubleSlashComment
= True
575 # check for '#' comment
576 elif self
.__CurrentChar
() == T_CHAR_HASH
and not self
.__EndOfLine
() and not InString
:
579 # check for /* comment start
580 elif self
.__CurrentChar
() == T_CHAR_SLASH
and self
.__NextChar
() == T_CHAR_STAR
:
581 self
.__SetCurrentCharValue
( T_CHAR_SPACE
)
583 self
.__SetCurrentCharValue
( T_CHAR_SPACE
)
589 # restore from ListOfList to ListOfString
590 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
593 ## PreprocessIncludeFile() method
595 # Preprocess file contents, replace !include statements with file contents.
596 # In the end, rewind the file buffer pointer to the beginning
598 # @param self The object pointer
600 def PreprocessIncludeFile(self
):
601 # nested include support
604 while self
.__GetNextToken
():
606 if self
.__Token
== 'DEFINE':
607 if not self
.__GetNextToken
():
608 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
610 if not self
.__IsToken
( "="):
611 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
612 Value
= self
.__GetExpression
()
613 MacroDict
[Macro
] = Value
615 elif self
.__Token
== '!include':
617 IncludeLine
= self
.CurrentLineNumber
618 IncludeOffset
= self
.CurrentOffsetWithinLine
- len('!include')
619 if not self
.__GetNextToken
():
620 raise Warning("expected include file name", self
.FileName
, self
.CurrentLineNumber
)
621 IncFileName
= self
.__Token
623 StartPos
= IncFileName
.find('$(', PreIndex
)
624 EndPos
= IncFileName
.find(')', StartPos
+2)
625 while StartPos
!= -1 and EndPos
!= -1:
626 Macro
= IncFileName
[StartPos
+2 : EndPos
]
627 MacroVal
= self
.__GetMacroValue
(Macro
)
629 if Macro
in MacroDict
:
630 MacroVal
= MacroDict
[Macro
]
631 if MacroVal
is not None:
632 IncFileName
= IncFileName
.replace('$(' + Macro
+ ')', MacroVal
, 1)
633 if MacroVal
.find('$(') != -1:
636 PreIndex
= StartPos
+ len(MacroVal
)
638 raise Warning("The Macro %s is not defined" %Macro
, self
.FileName
, self
.CurrentLineNumber
)
639 StartPos
= IncFileName
.find('$(', PreIndex
)
640 EndPos
= IncFileName
.find(')', StartPos
+2)
642 IncludedFile
= NormPath(IncFileName
)
644 # First search the include file under the same directory as FDF file
646 IncludedFile1
= PathClass(IncludedFile
, os
.path
.dirname(self
.FileName
))
647 ErrorCode
= IncludedFile1
.Validate()[0]
650 # Then search the include file under the same directory as DSC file
653 if GenFdsGlobalVariable
.ActivePlatform
:
654 PlatformDir
= GenFdsGlobalVariable
.ActivePlatform
.Dir
655 elif GlobalData
.gActivePlatform
:
656 PlatformDir
= GlobalData
.gActivePlatform
.MetaFile
.Dir
657 IncludedFile1
= PathClass(IncludedFile
, PlatformDir
)
658 ErrorCode
= IncludedFile1
.Validate()[0]
661 # Also search file under the WORKSPACE directory
663 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
664 ErrorCode
= IncludedFile1
.Validate()[0]
666 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
),
667 self
.FileName
, self
.CurrentLineNumber
)
669 if not IsValidInclude (IncludedFile1
.Path
, self
.CurrentLineNumber
):
670 raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1
.Path
), self
.FileName
, self
.CurrentLineNumber
)
672 IncFileProfile
= IncludeFileProfile(IncludedFile1
.Path
)
674 CurrentLine
= self
.CurrentLineNumber
675 CurrentOffset
= self
.CurrentOffsetWithinLine
676 # list index of the insertion, note that line number is 'CurrentLine + 1'
677 InsertAtLine
= CurrentLine
678 ParentProfile
= GetParentAtLine (CurrentLine
)
679 if ParentProfile
is not None:
680 ParentProfile
.IncludeFileList
.insert(0, IncFileProfile
)
681 IncFileProfile
.Level
= ParentProfile
.Level
+ 1
682 IncFileProfile
.InsertStartLineNumber
= InsertAtLine
+ 1
683 # deal with remaining portions after "!include filename", if exists.
684 if self
.__GetNextToken
():
685 if self
.CurrentLineNumber
== CurrentLine
:
686 RemainingLine
= self
.__CurrentLine
()[CurrentOffset
:]
687 self
.Profile
.FileLinesList
.insert(self
.CurrentLineNumber
, RemainingLine
)
688 IncFileProfile
.InsertAdjust
+= 1
689 self
.CurrentLineNumber
+= 1
690 self
.CurrentOffsetWithinLine
= 0
692 for Line
in IncFileProfile
.FileLinesList
:
693 self
.Profile
.FileLinesList
.insert(InsertAtLine
, Line
)
694 self
.CurrentLineNumber
+= 1
697 # reversely sorted to better determine error in file
698 AllIncludeFileList
.insert(0, IncFileProfile
)
700 # comment out the processed include file statement
701 TempList
= list(self
.Profile
.FileLinesList
[IncludeLine
- 1])
702 TempList
.insert(IncludeOffset
, '#')
703 self
.Profile
.FileLinesList
[IncludeLine
- 1] = ''.join(TempList
)
704 if Processed
: # Nested and back-to-back support
705 self
.Rewind(DestLine
= IncFileProfile
.InsertStartLineNumber
- 1)
711 def __GetIfListCurrentItemStat(IfList
):
721 ## PreprocessConditionalStatement() method
723 # Preprocess conditional statement.
724 # In the end, rewind the file buffer pointer to the beginning
726 # @param self The object pointer
728 def PreprocessConditionalStatement(self
):
729 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
733 while self
.__GetNextToken
():
734 # Determine section name and the location dependent macro
735 if self
.__GetIfListCurrentItemStat
(IfList
):
736 if self
.__Token
.startswith('['):
737 Header
= self
.__Token
738 if not self
.__Token
.endswith(']'):
739 self
.__SkipToToken
(']')
740 Header
+= self
.__SkippedChars
741 if Header
.find('$(') != -1:
742 raise Warning("macro cannot be used in section header", self
.FileName
, self
.CurrentLineNumber
)
743 self
.__SectionHeaderParser
(Header
)
745 # Replace macros except in RULE section or out of section
746 elif self
.__CurSection
and ReplacedLine
!= self
.CurrentLineNumber
:
747 ReplacedLine
= self
.CurrentLineNumber
749 CurLine
= self
.Profile
.FileLinesList
[ReplacedLine
- 1]
751 StartPos
= CurLine
.find('$(', PreIndex
)
752 EndPos
= CurLine
.find(')', StartPos
+2)
753 while StartPos
!= -1 and EndPos
!= -1 and self
.__Token
not in ['!ifdef', '!ifndef', '!if', '!elseif']:
754 MacroName
= CurLine
[StartPos
+2 : EndPos
]
755 MacorValue
= self
.__GetMacroValue
(MacroName
)
756 if MacorValue
is not None:
757 CurLine
= CurLine
.replace('$(' + MacroName
+ ')', MacorValue
, 1)
758 if MacorValue
.find('$(') != -1:
761 PreIndex
= StartPos
+ len(MacorValue
)
763 PreIndex
= EndPos
+ 1
764 StartPos
= CurLine
.find('$(', PreIndex
)
765 EndPos
= CurLine
.find(')', StartPos
+2)
766 self
.Profile
.FileLinesList
[ReplacedLine
- 1] = CurLine
769 if self
.__Token
== 'DEFINE':
770 if self
.__GetIfListCurrentItemStat
(IfList
):
771 if not self
.__CurSection
:
772 raise Warning("macro cannot be defined in Rule section or out of section", self
.FileName
, self
.CurrentLineNumber
)
773 DefineLine
= self
.CurrentLineNumber
- 1
774 DefineOffset
= self
.CurrentOffsetWithinLine
- len('DEFINE')
775 if not self
.__GetNextToken
():
776 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
778 if not self
.__IsToken
( "="):
779 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
781 Value
= self
.__GetExpression
()
782 self
.__SetMacroValue
(Macro
, Value
)
783 self
.__WipeOffArea
.append(((DefineLine
, DefineOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
784 elif self
.__Token
== 'SET':
785 if not self
.__GetIfListCurrentItemStat
(IfList
):
787 SetLine
= self
.CurrentLineNumber
- 1
788 SetOffset
= self
.CurrentOffsetWithinLine
- len('SET')
789 PcdPair
= self
.__GetNextPcdName
()
790 PcdName
= "%s.%s" % (PcdPair
[1], PcdPair
[0])
791 if not self
.__IsToken
( "="):
792 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
794 Value
= self
.__GetExpression
()
795 Value
= self
.__EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
797 self
.__PcdDict
[PcdName
] = Value
799 self
.Profile
.PcdDict
[PcdPair
] = Value
800 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
801 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
803 self
.__WipeOffArea
.append(((SetLine
, SetOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
804 elif self
.__Token
in ('!ifdef', '!ifndef', '!if'):
805 IfStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
.__Token
))
806 IfList
.append([IfStartPos
, None, None])
808 CondLabel
= self
.__Token
809 Expression
= self
.__GetExpression
()
811 if CondLabel
== '!if':
812 ConditionSatisfied
= self
.__EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
814 ConditionSatisfied
= self
.__EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'in')
815 if CondLabel
== '!ifndef':
816 ConditionSatisfied
= not ConditionSatisfied
818 BranchDetermined
= ConditionSatisfied
819 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, BranchDetermined
]
820 if ConditionSatisfied
:
821 self
.__WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
822 elif self
.__Token
in ('!elseif', '!else'):
823 ElseStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
.__Token
))
825 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
828 IfList
[-1] = [ElseStartPos
, False, True]
829 self
.__WipeOffArea
.append((ElseStartPos
, (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
831 self
.__WipeOffArea
.append((IfList
[-1][0], ElseStartPos
))
832 IfList
[-1] = [ElseStartPos
, True, IfList
[-1][2]]
833 if self
.__Token
== '!elseif':
834 Expression
= self
.__GetExpression
()
835 ConditionSatisfied
= self
.__EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
836 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, IfList
[-1][2]]
840 IfList
[-1][1] = False
843 self
.__WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
844 elif self
.__Token
== '!endif':
846 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
848 self
.__WipeOffArea
.append(((self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len('!endif')), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
850 self
.__WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
853 elif not IfList
: # Don't use PCDs inside conditional directive
854 if self
.CurrentLineNumber
<= RegionLayoutLine
:
855 # Don't try the same line twice
857 SetPcd
= ShortcutPcdPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
859 self
.__PcdDict
[SetPcd
.group('name')] = SetPcd
.group('value')
860 RegionLayoutLine
= self
.CurrentLineNumber
862 RegionSize
= RegionSizePattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
864 RegionLayoutLine
= self
.CurrentLineNumber
866 RegionSizeGuid
= RegionSizeGuidPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
])
867 if not RegionSizeGuid
:
868 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
870 self
.__PcdDict
[RegionSizeGuid
.group('base')] = RegionSize
.group('base')
871 self
.__PcdDict
[RegionSizeGuid
.group('size')] = RegionSize
.group('size')
872 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
875 raise Warning("Missing !endif", self
.FileName
, self
.CurrentLineNumber
)
878 def __CollectMacroPcd(self
):
882 MacroDict
.update(GlobalData
.gPlatformPcds
)
883 MacroDict
.update(self
.__PcdDict
)
886 MacroDict
.update(GlobalData
.gPlatformDefines
)
888 if self
.__CurSection
:
890 ScopeMacro
= self
.__MacroDict
[TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]
892 MacroDict
.update(ScopeMacro
)
895 ScopeMacro
= self
.__MacroDict
[
896 self
.__CurSection
[0],
897 self
.__CurSection
[1],
901 MacroDict
.update(ScopeMacro
)
903 MacroDict
.update(GlobalData
.gGlobalDefines
)
904 MacroDict
.update(GlobalData
.gCommandLineDefines
)
905 if GlobalData
.BuildOptionPcd
:
906 for Item
in GlobalData
.BuildOptionPcd
:
907 if type(Item
) is tuple:
909 PcdName
, TmpValue
= Item
.split("=")
910 TmpValue
= BuildOptionValue(TmpValue
, {})
911 MacroDict
[PcdName
.strip()] = TmpValue
916 def __EvaluateConditional(self
, Expression
, Line
, Op
= None, Value
= None):
917 FileLineTuple
= GetRealFileLine(self
.FileName
, Line
)
918 MacroPcdDict
= self
.__CollectMacroPcd
()
922 return ValueExpression(Expression
, MacroPcdDict
)(True)
924 return ValueExpression(Expression
, MacroPcdDict
)()
925 except WrnExpression
, Excpt
:
927 # Catch expression evaluation warning here. We need to report
928 # the precise number of line and return the evaluation result
930 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
931 File
=self
.FileName
, ExtraData
=self
.__CurrentLine
(),
934 except Exception, Excpt
:
935 if hasattr(Excpt
, 'Pcd'):
936 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
937 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
938 raise Warning("Cannot use this PCD (%s) in an expression as"
939 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
940 " of the DSC file (%s), and it is currently defined in this section:"
941 " %s, line #: %d." % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE'], Info
[0], Info
[1]),
944 raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE']),
947 raise Warning(str(Excpt
), *FileLineTuple
)
949 if Expression
.startswith('$(') and Expression
[-1] == ')':
950 Expression
= Expression
[2:-1]
951 return Expression
in MacroPcdDict
953 ## __IsToken() method
955 # Check whether input string is found from current char position along
956 # If found, the string value is put into self.__Token
958 # @param self The object pointer
959 # @param String The string to search
960 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
961 # @retval True Successfully find string, file buffer pointer moved forward
962 # @retval False Not able to find string, file buffer pointer not changed
964 def __IsToken(self
, String
, IgnoreCase
= False):
965 self
.__SkipWhiteSpace
()
967 # Only consider the same line, no multi-line token allowed
968 StartPos
= self
.CurrentOffsetWithinLine
971 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
973 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
975 self
.CurrentOffsetWithinLine
+= len(String
)
976 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
980 ## __IsKeyword() method
982 # Check whether input keyword is found from current char position along, whole word only!
983 # If found, the string value is put into self.__Token
985 # @param self The object pointer
986 # @param Keyword The string to search
987 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
988 # @retval True Successfully find string, file buffer pointer moved forward
989 # @retval False Not able to find string, file buffer pointer not changed
991 def __IsKeyword(self
, KeyWord
, IgnoreCase
= False):
992 self
.__SkipWhiteSpace
()
994 # Only consider the same line, no multi-line token allowed
995 StartPos
= self
.CurrentOffsetWithinLine
998 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(KeyWord
.upper())
1000 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(KeyWord
)
1002 followingChar
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
+ len(KeyWord
)]
1003 if not str(followingChar
).isspace() and followingChar
not in SEPERATOR_TUPLE
:
1005 self
.CurrentOffsetWithinLine
+= len(KeyWord
)
1006 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1010 def __GetExpression(self
):
1011 Line
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
1012 Index
= len(Line
) - 1
1013 while Line
[Index
] in ['\r', '\n']:
1015 ExpressionString
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:Index
+1]
1016 self
.CurrentOffsetWithinLine
+= len(ExpressionString
)
1017 ExpressionString
= ExpressionString
.strip()
1018 return ExpressionString
1020 ## __GetNextWord() method
1022 # Get next C name from file lines
1023 # If found, the string value is put into self.__Token
1025 # @param self The object pointer
1026 # @retval True Successfully find a C name string, file buffer pointer moved forward
1027 # @retval False Not able to find a C name string, file buffer pointer not changed
1029 def __GetNextWord(self
):
1030 self
.__SkipWhiteSpace
()
1031 if self
.__EndOfFile
():
1034 TempChar
= self
.__CurrentChar
()
1035 StartPos
= self
.CurrentOffsetWithinLine
1036 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_':
1038 while not self
.__EndOfLine
():
1039 TempChar
= self
.__CurrentChar
()
1040 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
1041 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-':
1047 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1052 ## __GetNextToken() method
1054 # Get next token unit before a seperator
1055 # If found, the string value is put into self.__Token
1057 # @param self The object pointer
1058 # @retval True Successfully find a token unit, file buffer pointer moved forward
1059 # @retval False Not able to find a token unit, file buffer pointer not changed
1061 def __GetNextToken(self
):
1062 # Skip leading spaces, if exist.
1063 self
.__SkipWhiteSpace
()
1064 if self
.__EndOfFile
():
1066 # Record the token start position, the position of the first non-space char.
1067 StartPos
= self
.CurrentOffsetWithinLine
1068 StartLine
= self
.CurrentLineNumber
1069 while StartLine
== self
.CurrentLineNumber
:
1070 TempChar
= self
.__CurrentChar
()
1071 # Try to find the end char that is not a space and not in seperator tuple.
1072 # That is, when we got a space or any char in the tuple, we got the end of token.
1073 if not str(TempChar
).isspace() and TempChar
not in SEPERATOR_TUPLE
:
1075 # if we happen to meet a seperator as the first char, we must proceed to get it.
1076 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1077 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPERATOR_TUPLE
:
1085 EndPos
= self
.CurrentOffsetWithinLine
1086 if self
.CurrentLineNumber
!= StartLine
:
1087 EndPos
= len(self
.Profile
.FileLinesList
[StartLine
-1])
1088 self
.__Token
= self
.Profile
.FileLinesList
[StartLine
-1][StartPos
: EndPos
]
1089 if StartPos
!= self
.CurrentOffsetWithinLine
:
1094 def __GetNextOp(self
):
1095 # Skip leading spaces, if exist.
1096 self
.__SkipWhiteSpace
()
1097 if self
.__EndOfFile
():
1099 # Record the token start position, the position of the first non-space char.
1100 StartPos
= self
.CurrentOffsetWithinLine
1101 while not self
.__EndOfLine
():
1102 TempChar
= self
.__CurrentChar
()
1103 # Try to find the end char that is not a space
1104 if not str(TempChar
).isspace():
1111 if StartPos
!= self
.CurrentOffsetWithinLine
:
1112 self
.__Token
= self
.__CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1116 ## __GetNextGuid() method
1118 # Get next token unit before a seperator
1119 # If found, the GUID string is put into self.__Token
1121 # @param self The object pointer
1122 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward
1123 # @retval False Not able to find a registry format GUID, file buffer pointer not changed
1125 def __GetNextGuid(self
):
1127 if not self
.__GetNextToken
():
1129 if gGuidPattern
.match(self
.__Token
) is not None:
1136 def __Verify(Name
, Value
, Scope
):
1137 if Scope
in ['UINT64', 'UINT8']:
1140 ValueNumber
= int (Value
, 0)
1142 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value is not valid dec or hex number for %s." % Name
)
1144 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value can't be set to negative value for %s." % Name
)
1145 if Scope
== 'UINT64':
1146 if ValueNumber
>= 0x10000000000000000:
1147 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "Too large value for %s." % Name
)
1148 if Scope
== 'UINT8':
1149 if ValueNumber
>= 0x100:
1150 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "Too large value for %s." % Name
)
1153 ## __UndoToken() method
1155 # Go back one token unit in file buffer
1157 # @param self The object pointer
1159 def __UndoToken(self
):
1160 self
.__UndoOneChar
()
1161 while self
.__CurrentChar
().isspace():
1162 if not self
.__UndoOneChar
():
1167 StartPos
= self
.CurrentOffsetWithinLine
1168 CurrentLine
= self
.CurrentLineNumber
1169 while CurrentLine
== self
.CurrentLineNumber
:
1171 TempChar
= self
.__CurrentChar
()
1172 # Try to find the end char that is not a space and not in seperator tuple.
1173 # That is, when we got a space or any char in the tuple, we got the end of token.
1174 if not str(TempChar
).isspace() and not TempChar
in SEPERATOR_TUPLE
:
1175 if not self
.__UndoOneChar
():
1177 # if we happen to meet a seperator as the first char, we must proceed to get it.
1178 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1179 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPERATOR_TUPLE
:
1186 def __IsHex(self
, HexStr
):
1187 if not HexStr
.upper().startswith("0X"):
1189 if len(self
.__Token
) <= 2:
1191 return True if all(x
in string
.hexdigits
for x
in HexStr
[2:]) else False
1193 ## __GetNextHexNumber() method
1195 # Get next HEX data before a seperator
1196 # If found, the HEX data is put into self.__Token
1198 # @param self The object pointer
1199 # @retval True Successfully find a HEX data, file buffer pointer moved forward
1200 # @retval False Not able to find a HEX data, file buffer pointer not changed
1202 def __GetNextHexNumber(self
):
1203 if not self
.__GetNextToken
():
1205 if self
.__IsHex
(self
.__Token
):
1211 ## __GetNextDecimalNumber() method
1213 # Get next decimal data before a seperator
1214 # If found, the decimal data is put into self.__Token
1216 # @param self The object pointer
1217 # @retval True Successfully find a decimal data, file buffer pointer moved forward
1218 # @retval False Not able to find a decimal data, file buffer pointer not changed
1220 def __GetNextDecimalNumber(self
):
1221 if not self
.__GetNextToken
():
1223 if self
.__Token
.isdigit():
1229 ## __GetNextPcdName() method
1231 # Get next PCD token space C name and PCD C name pair before a seperator
1232 # If found, the decimal data is put into self.__Token
1234 # @param self The object pointer
1235 # @retval Tuple PCD C name and PCD token space C name pair
1237 def __GetNextPcdName(self
):
1238 if not self
.__GetNextWord
():
1239 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1240 pcdTokenSpaceCName
= self
.__Token
1242 if not self
.__IsToken
( "."):
1243 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1245 if not self
.__GetNextWord
():
1246 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1247 pcdCName
= self
.__Token
1249 return (pcdCName
, pcdTokenSpaceCName
)
1251 ## __GetStringData() method
1253 # Get string contents quoted in ""
1254 # If found, the decimal data is put into self.__Token
1256 # @param self The object pointer
1257 # @retval True Successfully find a string data, file buffer pointer moved forward
1258 # @retval False Not able to find a string data, file buffer pointer not changed
1260 def __GetStringData(self
):
1261 if self
.__Token
.startswith("\"") or self
.__Token
.startswith("L\""):
1263 self
.__SkipToToken
("\"")
1264 currentLineNumber
= self
.CurrentLineNumber
1266 if not self
.__SkipToToken
("\""):
1267 raise Warning("Missing Quote \" for String", self
.FileName
, self
.CurrentLineNumber
)
1268 if currentLineNumber
!= self
.CurrentLineNumber
:
1269 raise Warning("Missing Quote \" for String", self
.FileName
, self
.CurrentLineNumber
)
1270 self
.__Token
= self
.__SkippedChars
.rstrip('\"')
1273 elif self
.__Token
.startswith("\'") or self
.__Token
.startswith("L\'"):
1275 self
.__SkipToToken
("\'")
1276 currentLineNumber
= self
.CurrentLineNumber
1278 if not self
.__SkipToToken
("\'"):
1279 raise Warning("Missing Quote \' for String", self
.FileName
, self
.CurrentLineNumber
)
1280 if currentLineNumber
!= self
.CurrentLineNumber
:
1281 raise Warning("Missing Quote \' for String", self
.FileName
, self
.CurrentLineNumber
)
1282 self
.__Token
= self
.__SkippedChars
.rstrip('\'')
1288 ## __SkipToToken() method
1290 # Search forward in file buffer for the string
1291 # The skipped chars are put into self.__SkippedChars
1293 # @param self The object pointer
1294 # @param String The string to search
1295 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
1296 # @retval True Successfully find the string, file buffer pointer moved forward
1297 # @retval False Not able to find the string, file buffer pointer not changed
1299 def __SkipToToken(self
, String
, IgnoreCase
= False):
1300 StartPos
= self
.GetFileBufferPos()
1302 self
.__SkippedChars
= ""
1303 while not self
.__EndOfFile
():
1306 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
1308 index
= self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
1310 self
.CurrentOffsetWithinLine
+= len(String
)
1311 self
.__SkippedChars
+= String
1313 self
.__SkippedChars
+= str(self
.__CurrentChar
())
1316 self
.SetFileBufferPos( StartPos
)
1317 self
.__SkippedChars
= ""
1320 ## GetFileBufferPos() method
1322 # Return the tuple of current line and offset within the line
1324 # @param self The object pointer
1325 # @retval Tuple Line number and offset pair
1327 def GetFileBufferPos(self
):
1328 return (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
)
1330 ## SetFileBufferPos() method
1332 # Restore the file buffer position
1334 # @param self The object pointer
1335 # @param Pos The new file buffer position
1337 def SetFileBufferPos(self
, Pos
):
1338 (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
) = Pos
1340 ## Preprocess() method
1342 # Preprocess comment, conditional directive, include directive, replace macro.
1343 # Exception will be raised if syntax error found
1345 # @param self The object pointer
1347 def Preprocess(self
):
1348 self
.__StringToList
()
1349 self
.PreprocessFile()
1350 self
.PreprocessIncludeFile()
1351 self
.__StringToList
()
1352 self
.PreprocessFile()
1353 self
.PreprocessConditionalStatement()
1354 self
.__StringToList
()
1355 for Pos
in self
.__WipeOffArea
:
1356 self
.__ReplaceFragment
(Pos
[0], Pos
[1])
1357 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
1359 while self
.__GetDefines
():
1362 ## ParseFile() method
1364 # Parse the file profile buffer to extract fd, fv ... information
1365 # Exception will be raised if syntax error found
1367 # @param self The object pointer
1369 def ParseFile(self
):
1374 # Keep processing sections of the FDF until no new sections or a syntax error is found
1376 while self
.__GetFd
() or self
.__GetFv
() or self
.__GetFmp
() or self
.__GetCapsule
() or self
.__GetVtf
() or self
.__GetRule
() or self
.__GetOptionRom
():
1381 #'\n\tGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \
1382 # At this point, the closest parent would be the included file itself
1383 Profile
= GetParentAtLine(X
.OriginalLineNumber
)
1384 if Profile
is not None:
1385 X
.Message
+= ' near line %d, column %d: %s' \
1386 % (X
.LineNumber
, 0, Profile
.FileLinesList
[X
.LineNumber
-1])
1388 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1389 X
.Message
+= ' near line %d, column %d: %s' \
1390 % (FileLineTuple
[1], self
.CurrentOffsetWithinLine
+ 1, self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:].rstrip('\n').rstrip('\r'))
1393 ## SectionParser() method
1395 # Parse the file section info
1396 # Exception will be raised if syntax error found
1398 # @param self The object pointer
1399 # @param section The section string
1401 def SectionParser(self
, section
):
1403 if not S
.startswith("[DEFINES") and not S
.startswith("[FD.") and not S
.startswith("[FV.") and not S
.startswith("[CAPSULE.") \
1404 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM.") and not S
.startswith('[FMPPAYLOAD.'):
1405 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
)
1407 ## __GetDefines() method
1409 # Get Defines section contents and store its data into AllMacrosList
1411 # @param self The object pointer
1412 # @retval True Successfully find a Defines
1413 # @retval False Not able to find a Defines
1415 def __GetDefines(self
):
1417 if not self
.__GetNextToken
():
1420 S
= self
.__Token
.upper()
1421 if S
.startswith("[") and not S
.startswith("[DEFINES"):
1422 self
.SectionParser(S
)
1427 if not self
.__IsToken
("[DEFINES", True):
1428 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1429 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1430 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1431 raise Warning("expected [DEFINES", self
.FileName
, self
.CurrentLineNumber
)
1433 if not self
.__IsToken
( "]"):
1434 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
1436 while self
.__GetNextWord
():
1437 # handle the SET statement
1438 if self
.__Token
== 'SET':
1440 self
.__GetSetStatement
(None)
1443 Macro
= self
.__Token
1445 if not self
.__IsToken
("="):
1446 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1447 if not self
.__GetNextToken
() or self
.__Token
.startswith('['):
1448 raise Warning("expected MACRO value", self
.FileName
, self
.CurrentLineNumber
)
1449 Value
= self
.__Token
1455 # Get FD section contents and store its data into FD dictionary of self.Profile
1457 # @param self The object pointer
1458 # @retval True Successfully find a FD
1459 # @retval False Not able to find a FD
1463 if not self
.__GetNextToken
():
1466 S
= self
.__Token
.upper()
1467 if S
.startswith("[") and not S
.startswith("[FD."):
1468 if not S
.startswith("[FV.") and not S
.startswith('[FMPPAYLOAD.') and not S
.startswith("[CAPSULE.") \
1469 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM."):
1470 raise Warning("Unknown section", self
.FileName
, self
.CurrentLineNumber
)
1475 if not self
.__IsToken
("[FD.", True):
1476 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1477 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1478 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1479 raise Warning("expected [FD.]", self
.FileName
, self
.CurrentLineNumber
)
1481 FdName
= self
.__GetUiName
()
1483 if len (self
.Profile
.FdDict
) == 0:
1484 FdName
= GenFdsGlobalVariable
.PlatformName
1485 if FdName
== "" and GlobalData
.gActivePlatform
:
1486 FdName
= GlobalData
.gActivePlatform
.PlatformName
1487 self
.Profile
.FdNameNotSet
= True
1489 raise Warning("expected FdName in [FD.] section", self
.FileName
, self
.CurrentLineNumber
)
1490 self
.CurrentFdName
= FdName
.upper()
1492 if self
.CurrentFdName
in self
.Profile
.FdDict
:
1493 raise Warning("Unexpected the same FD name", self
.FileName
, self
.CurrentLineNumber
)
1495 if not self
.__IsToken
( "]"):
1496 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
1499 FdObj
.FdUiName
= self
.CurrentFdName
1500 self
.Profile
.FdDict
[self
.CurrentFdName
] = FdObj
1502 if len (self
.Profile
.FdDict
) > 1 and self
.Profile
.FdNameNotSet
:
1503 raise Warning("expected all FDs have their name", self
.FileName
, self
.CurrentLineNumber
)
1505 Status
= self
.__GetCreateFile
(FdObj
)
1507 raise Warning("FD name error", self
.FileName
, self
.CurrentLineNumber
)
1509 while self
.__GetTokenStatements
(FdObj
):
1511 for Attr
in ("BaseAddress", "Size", "ErasePolarity"):
1512 if getattr(FdObj
, Attr
) is None:
1513 self
.__GetNextToken
()
1514 raise Warning("Keyword %s missing" % Attr
, self
.FileName
, self
.CurrentLineNumber
)
1516 if not FdObj
.BlockSizeList
:
1517 FdObj
.BlockSizeList
.append((1, FdObj
.Size
, None))
1519 self
.__GetDefineStatements
(FdObj
)
1521 self
.__GetSetStatements
(FdObj
)
1523 if not self
.__GetRegionLayout
(FdObj
):
1524 raise Warning("expected region layout", self
.FileName
, self
.CurrentLineNumber
)
1526 while self
.__GetRegionLayout
(FdObj
):
1530 ## __GetUiName() method
1532 # Return the UI name of a section
1534 # @param self The object pointer
1535 # @retval FdName UI name
1537 def __GetUiName(self
):
1539 if self
.__GetNextWord
():
1544 ## __GetCreateFile() method
1546 # Return the output file name of object
1548 # @param self The object pointer
1549 # @param Obj object whose data will be stored in file
1550 # @retval FdName UI name
1552 def __GetCreateFile(self
, Obj
):
1554 if self
.__IsKeyword
( "CREATE_FILE"):
1555 if not self
.__IsToken
( "="):
1556 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1558 if not self
.__GetNextToken
():
1559 raise Warning("expected file name", self
.FileName
, self
.CurrentLineNumber
)
1561 FileName
= self
.__Token
1562 Obj
.CreateFileName
= FileName
1566 ## __GetTokenStatements() method
1568 # Get token statements
1570 # @param self The object pointer
1571 # @param Obj for whom token statement is got
1573 def __GetTokenStatements(self
, Obj
):
1574 if self
.__IsKeyword
( "BaseAddress"):
1575 if not self
.__IsToken
( "="):
1576 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1578 if not self
.__GetNextHexNumber
():
1579 raise Warning("expected Hex base address", self
.FileName
, self
.CurrentLineNumber
)
1581 Obj
.BaseAddress
= self
.__Token
1583 if self
.__IsToken
( "|"):
1584 pcdPair
= self
.__GetNextPcdName
()
1585 Obj
.BaseAddressPcd
= pcdPair
1586 self
.Profile
.PcdDict
[pcdPair
] = Obj
.BaseAddress
1587 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1588 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1591 if self
.__IsKeyword
( "Size"):
1592 if not self
.__IsToken
( "="):
1593 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1595 if not self
.__GetNextHexNumber
():
1596 raise Warning("expected Hex size", self
.FileName
, self
.CurrentLineNumber
)
1599 if self
.__IsToken
( "|"):
1600 pcdPair
= self
.__GetNextPcdName
()
1601 Obj
.SizePcd
= pcdPair
1602 self
.Profile
.PcdDict
[pcdPair
] = Size
1603 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1604 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1605 Obj
.Size
= long(Size
, 0)
1608 if self
.__IsKeyword
( "ErasePolarity"):
1609 if not self
.__IsToken
( "="):
1610 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1612 if not self
.__GetNextToken
():
1613 raise Warning("expected Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1615 if self
.__Token
!= "1" and self
.__Token
!= "0":
1616 raise Warning("expected 1 or 0 Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1618 Obj
.ErasePolarity
= self
.__Token
1621 return self
.__GetBlockStatements
(Obj
)
1623 ## __GetAddressStatements() method
1625 # Get address statements
1627 # @param self The object pointer
1628 # @param Obj for whom address statement is got
1629 # @retval True Successfully find
1630 # @retval False Not able to find
1632 def __GetAddressStatements(self
, Obj
):
1634 if self
.__IsKeyword
("BsBaseAddress"):
1635 if not self
.__IsToken
( "="):
1636 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1638 if not self
.__GetNextDecimalNumber
() and not self
.__GetNextHexNumber
():
1639 raise Warning("expected address", self
.FileName
, self
.CurrentLineNumber
)
1641 BsAddress
= long(self
.__Token
, 0)
1642 Obj
.BsBaseAddress
= BsAddress
1644 if self
.__IsKeyword
("RtBaseAddress"):
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 RtAddress
= long(self
.__Token
, 0)
1652 Obj
.RtBaseAddress
= RtAddress
1654 ## __GetBlockStatements() method
1656 # Get block statements
1658 # @param self The object pointer
1659 # @param Obj for whom block statement is got
1661 def __GetBlockStatements(self
, Obj
):
1663 while self
.__GetBlockStatement
(Obj
):
1666 Item
= Obj
.BlockSizeList
[-1]
1667 if Item
[0] is None or Item
[1] is None:
1668 raise Warning("expected block statement", self
.FileName
, self
.CurrentLineNumber
)
1671 ## __GetBlockStatement() method
1673 # Get block statement
1675 # @param self The object pointer
1676 # @param Obj for whom block statement is got
1677 # @retval True Successfully find
1678 # @retval False Not able to find
1680 def __GetBlockStatement(self
, Obj
):
1681 if not self
.__IsKeyword
( "BlockSize"):
1684 if not self
.__IsToken
( "="):
1685 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1687 if not self
.__GetNextHexNumber
() and not self
.__GetNextDecimalNumber
():
1688 raise Warning("expected Hex or Integer block size", self
.FileName
, self
.CurrentLineNumber
)
1690 BlockSize
= self
.__Token
1692 if self
.__IsToken
( "|"):
1693 PcdPair
= self
.__GetNextPcdName
()
1694 BlockSizePcd
= PcdPair
1695 self
.Profile
.PcdDict
[PcdPair
] = BlockSize
1696 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1697 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1698 BlockSize
= long(BlockSize
, 0)
1701 if self
.__IsKeyword
( "NumBlocks"):
1702 if not self
.__IsToken
( "="):
1703 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1705 if not self
.__GetNextDecimalNumber
() and not self
.__GetNextHexNumber
():
1706 raise Warning("expected block numbers", self
.FileName
, self
.CurrentLineNumber
)
1708 BlockNumber
= long(self
.__Token
, 0)
1710 Obj
.BlockSizeList
.append((BlockSize
, BlockNumber
, BlockSizePcd
))
1713 ## __GetDefineStatements() method
1715 # Get define statements
1717 # @param self The object pointer
1718 # @param Obj for whom define statement is got
1719 # @retval True Successfully find
1720 # @retval False Not able to find
1722 def __GetDefineStatements(self
, Obj
):
1723 while self
.__GetDefineStatement
( Obj
):
1726 ## __GetDefineStatement() method
1728 # Get define statement
1730 # @param self The object pointer
1731 # @param Obj for whom define statement is got
1732 # @retval True Successfully find
1733 # @retval False Not able to find
1735 def __GetDefineStatement(self
, Obj
):
1736 if self
.__IsKeyword
("DEFINE"):
1737 self
.__GetNextToken
()
1738 Macro
= self
.__Token
1739 if not self
.__IsToken
( "="):
1740 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1742 if not self
.__GetNextToken
():
1743 raise Warning("expected value", self
.FileName
, self
.CurrentLineNumber
)
1745 Value
= self
.__Token
1746 Macro
= '$(' + Macro
+ ')'
1747 Obj
.DefineVarDict
[Macro
] = Value
1752 ## __GetSetStatements() method
1754 # Get set statements
1756 # @param self The object pointer
1757 # @param Obj for whom set statement is got
1758 # @retval True Successfully find
1759 # @retval False Not able to find
1761 def __GetSetStatements(self
, Obj
):
1762 while self
.__GetSetStatement
(Obj
):
1765 ## __GetSetStatement() method
1769 # @param self The object pointer
1770 # @param Obj for whom set statement is got
1771 # @retval True Successfully find
1772 # @retval False Not able to find
1774 def __GetSetStatement(self
, Obj
):
1775 if self
.__IsKeyword
("SET"):
1776 PcdPair
= self
.__GetNextPcdName
()
1778 if not self
.__IsToken
( "="):
1779 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1781 Value
= self
.__GetExpression
()
1782 Value
= self
.__EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
1785 Obj
.SetVarDict
[PcdPair
] = Value
1786 self
.Profile
.PcdDict
[PcdPair
] = Value
1787 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1788 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1793 ## __CalcRegionExpr(self)
1795 # Calculate expression for offset or size of a region
1797 # @return: None if invalid expression
1798 # Calculated number if successfully
1800 def __CalcRegionExpr(self
):
1801 StartPos
= self
.GetFileBufferPos()
1804 while not self
.__EndOfFile
():
1805 CurCh
= self
.__CurrentChar
()
1811 if CurCh
in '|\r\n' and PairCount
== 0:
1817 ValueExpression(Expr
,
1818 self
.__CollectMacroPcd
()
1821 self
.SetFileBufferPos(StartPos
)
1824 ## __GetRegionLayout() method
1826 # Get region layout for FD
1828 # @param self The object pointer
1829 # @param Fd for whom region is got
1830 # @retval True Successfully find
1831 # @retval False Not able to find
1833 def __GetRegionLayout(self
, Fd
):
1834 Offset
= self
.__CalcRegionExpr
()
1838 RegionObj
= Region
.Region()
1839 RegionObj
.Offset
= Offset
1840 Fd
.RegionList
.append(RegionObj
)
1842 if not self
.__IsToken
( "|"):
1843 raise Warning("expected '|'", self
.FileName
, self
.CurrentLineNumber
)
1845 Size
= self
.__CalcRegionExpr
()
1847 raise Warning("expected Region Size", self
.FileName
, self
.CurrentLineNumber
)
1848 RegionObj
.Size
= Size
1850 if not self
.__GetNextWord
():
1853 if not self
.__Token
in ("SET", "FV", "FILE", "DATA", "CAPSULE", "INF"):
1855 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]
1856 # Or it might be next region's offset described by an expression which starts with a PCD.
1857 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size
1860 IsRegionPcd
= (RegionSizeGuidPattern
.match(self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
:]) or
1861 RegionOffsetPcdPattern
.match(self
.__CurrentLine
()[self
.CurrentOffsetWithinLine
:]))
1863 RegionObj
.PcdOffset
= self
.__GetNextPcdName
()
1864 self
.Profile
.PcdDict
[RegionObj
.PcdOffset
] = "0x%08X" % (RegionObj
.Offset
+ long(Fd
.BaseAddress
, 0))
1865 self
.__PcdDict
['%s.%s' % (RegionObj
.PcdOffset
[1], RegionObj
.PcdOffset
[0])] = "0x%x" % RegionObj
.Offset
1866 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1867 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdOffset
] = FileLineTuple
1868 if self
.__IsToken
( "|"):
1869 RegionObj
.PcdSize
= self
.__GetNextPcdName
()
1870 self
.Profile
.PcdDict
[RegionObj
.PcdSize
] = "0x%08X" % RegionObj
.Size
1871 self
.__PcdDict
['%s.%s' % (RegionObj
.PcdSize
[1], RegionObj
.PcdSize
[0])] = "0x%x" % RegionObj
.Size
1872 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1873 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdSize
] = FileLineTuple
1875 if not self
.__GetNextWord
():
1878 if self
.__Token
== "SET":
1880 self
.__GetSetStatements
( RegionObj
)
1881 if not self
.__GetNextWord
():
1884 elif self
.__Token
== "FV":
1886 self
.__GetRegionFvType
( RegionObj
)
1888 elif self
.__Token
== "CAPSULE":
1890 self
.__GetRegionCapType
( RegionObj
)
1892 elif self
.__Token
== "FILE":
1894 self
.__GetRegionFileType
(RegionObj
)
1896 elif self
.__Token
== "INF":
1898 RegionObj
.RegionType
= "INF"
1899 while self
.__IsKeyword
("INF"):
1901 ffsInf
= self
.__ParseInfStatement
()
1904 RegionObj
.RegionDataList
.append(ffsInf
)
1906 elif self
.__Token
== "DATA":
1908 self
.__GetRegionDataType
(RegionObj
)
1911 if self
.__GetRegionLayout
(Fd
):
1913 raise Warning("A valid region type was not found. "
1914 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
1915 self
.FileName
, self
.CurrentLineNumber
)
1919 ## __GetRegionFvType() method
1921 # Get region fv data for region
1923 # @param self The object pointer
1924 # @param RegionObj for whom region data is got
1926 def __GetRegionFvType(self
, RegionObj
):
1928 if not self
.__IsKeyword
( "FV"):
1929 raise Warning("expected Keyword 'FV'", self
.FileName
, self
.CurrentLineNumber
)
1931 if not self
.__IsToken
( "="):
1932 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1934 if not self
.__GetNextToken
():
1935 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
1937 RegionObj
.RegionType
= "FV"
1938 RegionObj
.RegionDataList
.append((self
.__Token
).upper())
1940 while self
.__IsKeyword
( "FV"):
1942 if not self
.__IsToken
( "="):
1943 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1945 if not self
.__GetNextToken
():
1946 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
1948 RegionObj
.RegionDataList
.append((self
.__Token
).upper())
1950 ## __GetRegionCapType() method
1952 # Get region capsule data for region
1954 # @param self The object pointer
1955 # @param RegionObj for whom region data is got
1957 def __GetRegionCapType(self
, RegionObj
):
1959 if not self
.__IsKeyword
("CAPSULE"):
1960 raise Warning("expected Keyword 'CAPSULE'", 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 CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1968 RegionObj
.RegionType
= "CAPSULE"
1969 RegionObj
.RegionDataList
.append(self
.__Token
)
1971 while self
.__IsKeyword
("CAPSULE"):
1973 if not self
.__IsToken
("="):
1974 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1976 if not self
.__GetNextToken
():
1977 raise Warning("expected CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1979 RegionObj
.RegionDataList
.append(self
.__Token
)
1981 ## __GetRegionFileType() method
1983 # Get region file data for region
1985 # @param self The object pointer
1986 # @param RegionObj for whom region data is got
1988 def __GetRegionFileType(self
, RegionObj
):
1990 if not self
.__IsKeyword
( "FILE"):
1991 raise Warning("expected Keyword 'FILE'", 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 File name", self
.FileName
, self
.CurrentLineNumber
)
1999 RegionObj
.RegionType
= "FILE"
2000 RegionObj
.RegionDataList
.append( self
.__Token
)
2002 while self
.__IsKeyword
( "FILE"):
2004 if not self
.__IsToken
( "="):
2005 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2007 if not self
.__GetNextToken
():
2008 raise Warning("expected FILE name", self
.FileName
, self
.CurrentLineNumber
)
2010 RegionObj
.RegionDataList
.append(self
.__Token
)
2012 ## __GetRegionDataType() method
2014 # Get region array data for region
2016 # @param self The object pointer
2017 # @param RegionObj for whom region data is got
2019 def __GetRegionDataType(self
, RegionObj
):
2021 if not self
.__IsKeyword
( "DATA"):
2022 raise Warning("expected Region Data type", self
.FileName
, self
.CurrentLineNumber
)
2024 if not self
.__IsToken
( "="):
2025 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2027 if not self
.__IsToken
( "{"):
2028 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2030 if not self
.__GetNextHexNumber
():
2031 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2033 if len(self
.__Token
) > 18:
2034 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2036 # convert hex string value to byte hex string array
2037 AllString
= self
.__Token
2038 AllStrLen
= len (AllString
)
2040 while AllStrLen
> 4:
2041 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + ","
2042 AllStrLen
= AllStrLen
- 2
2043 DataString
= DataString
+ AllString
[:AllStrLen
] + ","
2046 if len (self
.__Token
) <= 4:
2047 while self
.__IsToken
(","):
2048 if not self
.__GetNextHexNumber
():
2049 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2050 if len(self
.__Token
) > 4:
2051 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2052 DataString
+= self
.__Token
2055 if not self
.__IsToken
( "}"):
2056 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2058 DataString
= DataString
.rstrip(",")
2059 RegionObj
.RegionType
= "DATA"
2060 RegionObj
.RegionDataList
.append( DataString
)
2062 while self
.__IsKeyword
( "DATA"):
2064 if not self
.__IsToken
( "="):
2065 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2067 if not self
.__IsToken
( "{"):
2068 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2070 if not self
.__GetNextHexNumber
():
2071 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2073 if len(self
.__Token
) > 18:
2074 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2076 # convert hex string value to byte hex string array
2077 AllString
= self
.__Token
2078 AllStrLen
= len (AllString
)
2080 while AllStrLen
> 4:
2081 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + ","
2082 AllStrLen
= AllStrLen
- 2
2083 DataString
= DataString
+ AllString
[:AllStrLen
] + ","
2086 if len (self
.__Token
) <= 4:
2087 while self
.__IsToken
(","):
2088 if not self
.__GetNextHexNumber
():
2089 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2090 if len(self
.__Token
) > 4:
2091 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2092 DataString
+= self
.__Token
2095 if not self
.__IsToken
( "}"):
2096 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2098 DataString
= DataString
.rstrip(",")
2099 RegionObj
.RegionDataList
.append( DataString
)
2103 # Get FV section contents and store its data into FV dictionary of self.Profile
2105 # @param self The object pointer
2106 # @retval True Successfully find a FV
2107 # @retval False Not able to find a FV
2110 if not self
.__GetNextToken
():
2113 S
= self
.__Token
.upper()
2114 if S
.startswith("[") and not S
.startswith("[FV."):
2115 self
.SectionParser(S
)
2120 if not self
.__IsToken
("[FV.", True):
2121 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2122 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2123 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2124 raise Warning("Unknown Keyword '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2126 FvName
= self
.__GetUiName
()
2127 self
.CurrentFvName
= FvName
.upper()
2129 if not self
.__IsToken
( "]"):
2130 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
2133 FvObj
.UiFvName
= self
.CurrentFvName
2134 self
.Profile
.FvDict
[self
.CurrentFvName
] = FvObj
2136 Status
= self
.__GetCreateFile
(FvObj
)
2138 raise Warning("FV name error", self
.FileName
, self
.CurrentLineNumber
)
2140 self
.__GetDefineStatements
(FvObj
)
2142 self
.__GetAddressStatements
(FvObj
)
2144 FvObj
.FvExtEntryTypeValue
= []
2145 FvObj
.FvExtEntryType
= []
2146 FvObj
.FvExtEntryData
= []
2148 self
.__GetSetStatements
(FvObj
)
2150 if not (self
.__GetBlockStatement
(FvObj
) or self
.__GetFvBaseAddress
(FvObj
) or
2151 self
.__GetFvForceRebase
(FvObj
) or self
.__GetFvAlignment
(FvObj
) or
2152 self
.__GetFvAttributes
(FvObj
) or self
.__GetFvNameGuid
(FvObj
) or
2153 self
.__GetFvExtEntryStatement
(FvObj
) or self
.__GetFvNameString
(FvObj
)):
2156 if FvObj
.FvNameString
== 'TRUE' and not FvObj
.FvNameGuid
:
2157 raise Warning("FvNameString found but FvNameGuid was not found", self
.FileName
, self
.CurrentLineNumber
)
2159 self
.__GetAprioriSection
(FvObj
, FvObj
.DefineVarDict
.copy())
2160 self
.__GetAprioriSection
(FvObj
, FvObj
.DefineVarDict
.copy())
2163 isInf
= self
.__GetInfStatement
(FvObj
)
2164 isFile
= self
.__GetFileStatement
(FvObj
, MacroDict
= FvObj
.DefineVarDict
.copy())
2165 if not isInf
and not isFile
:
2170 ## __GetFvAlignment() method
2172 # Get alignment for FV
2174 # @param self The object pointer
2175 # @param Obj for whom alignment is got
2176 # @retval True Successfully find a alignment statement
2177 # @retval False Not able to find a alignment statement
2179 def __GetFvAlignment(self
, Obj
):
2181 if not self
.__IsKeyword
( "FvAlignment"):
2184 if not self
.__IsToken
( "="):
2185 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2187 if not self
.__GetNextToken
():
2188 raise Warning("expected alignment value", self
.FileName
, self
.CurrentLineNumber
)
2190 if self
.__Token
.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
2191 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
2192 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
2194 raise Warning("Unknown alignment value '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2195 Obj
.FvAlignment
= self
.__Token
2198 ## __GetFvBaseAddress() method
2200 # Get BaseAddress for FV
2202 # @param self The object pointer
2203 # @param Obj for whom FvBaseAddress is got
2204 # @retval True Successfully find a FvBaseAddress statement
2205 # @retval False Not able to find a FvBaseAddress statement
2207 def __GetFvBaseAddress(self
, Obj
):
2209 if not self
.__IsKeyword
("FvBaseAddress"):
2212 if not self
.__IsToken
( "="):
2213 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2215 if not self
.__GetNextToken
():
2216 raise Warning("expected FV base address value", self
.FileName
, self
.CurrentLineNumber
)
2218 if not BaseAddrValuePattern
.match(self
.__Token
.upper()):
2219 raise Warning("Unknown FV base address value '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2220 Obj
.FvBaseAddress
= self
.__Token
2223 ## __GetFvForceRebase() method
2225 # Get FvForceRebase for FV
2227 # @param self The object pointer
2228 # @param Obj for whom FvForceRebase is got
2229 # @retval True Successfully find a FvForceRebase statement
2230 # @retval False Not able to find a FvForceRebase statement
2232 def __GetFvForceRebase(self
, Obj
):
2234 if not self
.__IsKeyword
("FvForceRebase"):
2237 if not self
.__IsToken
( "="):
2238 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2240 if not self
.__GetNextToken
():
2241 raise Warning("expected FvForceRebase value", self
.FileName
, self
.CurrentLineNumber
)
2243 if self
.__Token
.upper() not in ["TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"]:
2244 raise Warning("Unknown FvForceRebase value '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2246 if self
.__Token
.upper() in ["TRUE", "1", "0X1", "0X01"]:
2247 Obj
.FvForceRebase
= True
2248 elif self
.__Token
.upper() in ["FALSE", "0", "0X0", "0X00"]:
2249 Obj
.FvForceRebase
= False
2251 Obj
.FvForceRebase
= None
2256 ## __GetFvAttributes() method
2258 # Get attributes for FV
2260 # @param self The object pointer
2261 # @param Obj for whom attribute is got
2264 def __GetFvAttributes(self
, FvObj
):
2266 while self
.__GetNextWord
():
2269 if name
not in ("ERASE_POLARITY", "MEMORY_MAPPED", \
2270 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
2271 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
2272 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
2273 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
2274 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"):
2278 if not self
.__IsToken
( "="):
2279 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2281 if not self
.__GetNextToken
() or self
.__Token
.upper() not in ("TRUE", "FALSE", "1", "0"):
2282 raise Warning("expected TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
2284 FvObj
.FvAttributeDict
[name
] = self
.__Token
2288 ## __GetFvNameGuid() method
2290 # Get FV GUID for FV
2292 # @param self The object pointer
2293 # @param Obj for whom GUID is got
2296 def __GetFvNameGuid(self
, FvObj
):
2298 if not self
.__IsKeyword
( "FvNameGuid"):
2301 if not self
.__IsToken
( "="):
2302 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2304 if not self
.__GetNextGuid
():
2305 raise Warning("expected FV GUID value", self
.FileName
, self
.CurrentLineNumber
)
2307 FvObj
.FvNameGuid
= self
.__Token
2311 def __GetFvNameString(self
, FvObj
):
2313 if not self
.__IsKeyword
( "FvNameString"):
2316 if not self
.__IsToken
( "="):
2317 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2319 if not self
.__GetNextToken
() or self
.__Token
not in ('TRUE', 'FALSE'):
2320 raise Warning("expected TRUE or FALSE for FvNameString", self
.FileName
, self
.CurrentLineNumber
)
2322 FvObj
.FvNameString
= self
.__Token
2326 def __GetFvExtEntryStatement(self
, FvObj
):
2328 if not (self
.__IsKeyword
( "FV_EXT_ENTRY") or self
.__IsKeyword
( "FV_EXT_ENTRY_TYPE")):
2331 if not self
.__IsKeyword
("TYPE"):
2332 raise Warning("expected 'TYPE'", self
.FileName
, self
.CurrentLineNumber
)
2334 if not self
.__IsToken
( "="):
2335 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2337 if not self
.__GetNextHexNumber
() and not self
.__GetNextDecimalNumber
():
2338 raise Warning("expected Hex FV extension entry type value At Line ", self
.FileName
, self
.CurrentLineNumber
)
2340 FvObj
.FvExtEntryTypeValue
+= [self
.__Token
]
2342 if not self
.__IsToken
( "{"):
2343 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2345 if not self
.__IsKeyword
("FILE") and not self
.__IsKeyword
("DATA"):
2346 raise Warning("expected 'FILE' or 'DATA'", self
.FileName
, self
.CurrentLineNumber
)
2348 FvObj
.FvExtEntryType
+= [self
.__Token
]
2350 if self
.__Token
== 'DATA':
2352 if not self
.__IsToken
( "="):
2353 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2355 if not self
.__IsToken
( "{"):
2356 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2358 if not self
.__GetNextHexNumber
():
2359 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2361 if len(self
.__Token
) > 4:
2362 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2364 DataString
= self
.__Token
2367 while self
.__IsToken
(","):
2368 if not self
.__GetNextHexNumber
():
2369 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2370 if len(self
.__Token
) > 4:
2371 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2372 DataString
+= self
.__Token
2375 if not self
.__IsToken
( "}"):
2376 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2378 if not self
.__IsToken
( "}"):
2379 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2381 DataString
= DataString
.rstrip(",")
2382 FvObj
.FvExtEntryData
+= [DataString
]
2384 if self
.__Token
== 'FILE':
2386 if not self
.__IsToken
( "="):
2387 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2389 if not self
.__GetNextToken
():
2390 raise Warning("expected FV Extension Entry file path At Line ", self
.FileName
, self
.CurrentLineNumber
)
2392 FvObj
.FvExtEntryData
+= [self
.__Token
]
2394 if not self
.__IsToken
( "}"):
2395 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2399 ## __GetAprioriSection() method
2401 # Get token statements
2403 # @param self The object pointer
2404 # @param FvObj for whom apriori is got
2405 # @param MacroDict dictionary used to replace macro
2406 # @retval True Successfully find apriori statement
2407 # @retval False Not able to find apriori statement
2409 def __GetAprioriSection(self
, FvObj
, MacroDict
= {}):
2411 if not self
.__IsKeyword
( "APRIORI"):
2414 if not self
.__IsKeyword
("PEI") and not self
.__IsKeyword
("DXE"):
2415 raise Warning("expected Apriori file type", self
.FileName
, self
.CurrentLineNumber
)
2416 AprType
= self
.__Token
2418 if not self
.__IsToken
( "{"):
2419 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2421 AprSectionObj
= AprioriSection
.AprioriSection()
2422 AprSectionObj
.AprioriType
= AprType
2424 self
.__GetDefineStatements
(AprSectionObj
)
2425 MacroDict
.update(AprSectionObj
.DefineVarDict
)
2428 IsInf
= self
.__GetInfStatement
(AprSectionObj
)
2429 IsFile
= self
.__GetFileStatement
( AprSectionObj
)
2430 if not IsInf
and not IsFile
:
2433 if not self
.__IsToken
( "}"):
2434 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2436 FvObj
.AprioriSectionList
.append(AprSectionObj
)
2439 def __ParseInfStatement(self
):
2440 if not self
.__IsKeyword
("INF"):
2443 ffsInf
= FfsInfStatement
.FfsInfStatement()
2444 self
.__GetInfOptions
(ffsInf
)
2446 if not self
.__GetNextToken
():
2447 raise Warning("expected INF file path", self
.FileName
, self
.CurrentLineNumber
)
2448 ffsInf
.InfFileName
= self
.__Token
2449 if not ffsInf
.InfFileName
.endswith('.inf'):
2450 raise Warning("expected .inf file path", self
.FileName
, self
.CurrentLineNumber
)
2452 ffsInf
.CurrentLineNum
= self
.CurrentLineNumber
2453 ffsInf
.CurrentLineContent
= self
.__CurrentLine
()
2455 #Replace $(SAPCE) with real space
2456 ffsInf
.InfFileName
= ffsInf
.InfFileName
.replace('$(SPACE)', ' ')
2458 if ffsInf
.InfFileName
.replace('$(WORKSPACE)', '').find('$') == -1:
2459 #do case sensitive check for file path
2460 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2462 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2464 if not ffsInf
.InfFileName
in self
.Profile
.InfList
:
2465 self
.Profile
.InfList
.append(ffsInf
.InfFileName
)
2466 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2467 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
2469 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
2470 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
2472 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
2474 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
2476 if self
.__IsToken
('|'):
2477 if self
.__IsKeyword
('RELOCS_STRIPPED'):
2478 ffsInf
.KeepReloc
= False
2479 elif self
.__IsKeyword
('RELOCS_RETAINED'):
2480 ffsInf
.KeepReloc
= True
2482 raise Warning("Unknown reloc strip flag '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2485 ## __GetInfStatement() method
2487 # Get INF statements
2489 # @param self The object pointer
2490 # @param Obj for whom inf statement is got
2491 # @retval True Successfully find inf statement
2492 # @retval False Not able to find inf statement
2494 def __GetInfStatement(self
, Obj
, ForCapsule
=False):
2495 ffsInf
= self
.__ParseInfStatement
()
2500 capsuleFfs
= CapsuleData
.CapsuleFfs()
2501 capsuleFfs
.Ffs
= ffsInf
2502 Obj
.CapsuleDataList
.append(capsuleFfs
)
2504 Obj
.FfsList
.append(ffsInf
)
2507 ## __GetInfOptions() method
2509 # Get options for INF
2511 # @param self The object pointer
2512 # @param FfsInfObj for whom option is got
2514 def __GetInfOptions(self
, FfsInfObj
):
2515 if self
.__IsKeyword
("FILE_GUID"):
2516 if not self
.__IsToken
("="):
2517 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2518 if not self
.__GetNextGuid
():
2519 raise Warning("expected GUID value", self
.FileName
, self
.CurrentLineNumber
)
2520 FfsInfObj
.OverrideGuid
= self
.__Token
2522 if self
.__IsKeyword
( "RuleOverride"):
2523 if not self
.__IsToken
( "="):
2524 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2525 if not self
.__GetNextToken
():
2526 raise Warning("expected Rule name", self
.FileName
, self
.CurrentLineNumber
)
2527 FfsInfObj
.Rule
= self
.__Token
2529 if self
.__IsKeyword
( "VERSION"):
2530 if not self
.__IsToken
( "="):
2531 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2532 if not self
.__GetNextToken
():
2533 raise Warning("expected Version", self
.FileName
, self
.CurrentLineNumber
)
2535 if self
.__GetStringData
():
2536 FfsInfObj
.Version
= self
.__Token
2538 if self
.__IsKeyword
( "UI"):
2539 if not self
.__IsToken
( "="):
2540 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2541 if not self
.__GetNextToken
():
2542 raise Warning("expected UI name", self
.FileName
, self
.CurrentLineNumber
)
2544 if self
.__GetStringData
():
2545 FfsInfObj
.Ui
= self
.__Token
2547 if self
.__IsKeyword
( "USE"):
2548 if not self
.__IsToken
( "="):
2549 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2550 if not self
.__GetNextToken
():
2551 raise Warning("expected ARCH name", self
.FileName
, self
.CurrentLineNumber
)
2552 FfsInfObj
.UseArch
= self
.__Token
2555 if self
.__GetNextToken
():
2556 p
= re
.compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
2557 if p
.match(self
.__Token
) and p
.match(self
.__Token
).span()[1] == len(self
.__Token
):
2558 FfsInfObj
.KeyStringList
.append(self
.__Token
)
2559 if not self
.__IsToken
(","):
2565 while self
.__GetNextToken
():
2566 if not p
.match(self
.__Token
):
2567 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2568 FfsInfObj
.KeyStringList
.append(self
.__Token
)
2570 if not self
.__IsToken
(","):
2573 ## __GetFileStatement() method
2575 # Get FILE statements
2577 # @param self The object pointer
2578 # @param Obj for whom FILE statement is got
2579 # @param MacroDict dictionary used to replace macro
2580 # @retval True Successfully find FILE statement
2581 # @retval False Not able to find FILE statement
2583 def __GetFileStatement(self
, Obj
, ForCapsule
= False, MacroDict
= {}):
2585 if not self
.__IsKeyword
( "FILE"):
2588 if not self
.__GetNextWord
():
2589 raise Warning("expected FFS type", self
.FileName
, self
.CurrentLineNumber
)
2591 if ForCapsule
and self
.__Token
== 'DATA':
2596 FfsFileObj
= FfsFileStatement
.FileStatement()
2597 FfsFileObj
.FvFileType
= self
.__Token
2599 if not self
.__IsToken
( "="):
2600 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2602 if not self
.__GetNextGuid
():
2603 if not self
.__GetNextWord
():
2604 raise Warning("expected File GUID", self
.FileName
, self
.CurrentLineNumber
)
2605 if self
.__Token
== 'PCD':
2606 if not self
.__IsToken
( "("):
2607 raise Warning("expected '('", self
.FileName
, self
.CurrentLineNumber
)
2608 PcdPair
= self
.__GetNextPcdName
()
2609 if not self
.__IsToken
( ")"):
2610 raise Warning("expected ')'", self
.FileName
, self
.CurrentLineNumber
)
2611 self
.__Token
= 'PCD('+PcdPair
[1]+'.'+PcdPair
[0]+')'
2613 FfsFileObj
.NameGuid
= self
.__Token
2615 self
.__GetFilePart
( FfsFileObj
, MacroDict
.copy())
2618 capsuleFfs
= CapsuleData
.CapsuleFfs()
2619 capsuleFfs
.Ffs
= FfsFileObj
2620 Obj
.CapsuleDataList
.append(capsuleFfs
)
2622 Obj
.FfsList
.append(FfsFileObj
)
2626 ## __FileCouldHaveRelocFlag() method
2628 # Check whether reloc strip flag can be set for a file type.
2630 # @param FileType The file type to check with
2631 # @retval True This type could have relocation strip flag
2632 # @retval False No way to have it
2635 def __FileCouldHaveRelocFlag (FileType
):
2636 if FileType
in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'):
2641 ## __SectionCouldHaveRelocFlag() method
2643 # Check whether reloc strip flag can be set for a section type.
2645 # @param SectionType The section type to check with
2646 # @retval True This type could have relocation strip flag
2647 # @retval False No way to have it
2650 def __SectionCouldHaveRelocFlag (SectionType
):
2651 if SectionType
in ('TE', 'PE32'):
2656 ## __GetFilePart() method
2658 # Get components for FILE statement
2660 # @param self The object pointer
2661 # @param FfsFileObj for whom component is got
2662 # @param MacroDict dictionary used to replace macro
2664 def __GetFilePart(self
, FfsFileObj
, MacroDict
= {}):
2666 self
.__GetFileOpts
( FfsFileObj
)
2668 if not self
.__IsToken
("{"):
2669 if self
.__IsKeyword
('RELOCS_STRIPPED') or self
.__IsKeyword
('RELOCS_RETAINED'):
2670 if self
.__FileCouldHaveRelocFlag
(FfsFileObj
.FvFileType
):
2671 if self
.__Token
== 'RELOCS_STRIPPED':
2672 FfsFileObj
.KeepReloc
= False
2674 FfsFileObj
.KeepReloc
= True
2676 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj
.FvFileType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
2678 if not self
.__IsToken
("{"):
2679 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2681 if not self
.__GetNextToken
():
2682 raise Warning("expected File name or section data", self
.FileName
, self
.CurrentLineNumber
)
2684 if self
.__Token
== "FV":
2685 if not self
.__IsToken
( "="):
2686 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2687 if not self
.__GetNextToken
():
2688 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
2689 FfsFileObj
.FvName
= self
.__Token
2691 elif self
.__Token
== "FD":
2692 if not self
.__IsToken
( "="):
2693 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2694 if not self
.__GetNextToken
():
2695 raise Warning("expected FD name", self
.FileName
, self
.CurrentLineNumber
)
2696 FfsFileObj
.FdName
= self
.__Token
2698 elif self
.__Token
in ("DEFINE", "APRIORI", "SECTION"):
2700 self
.__GetSectionData
( FfsFileObj
, MacroDict
)
2702 elif hasattr(FfsFileObj
, 'FvFileType') and FfsFileObj
.FvFileType
== 'RAW':
2704 self
.__GetRAWData
(FfsFileObj
, MacroDict
)
2707 FfsFileObj
.CurrentLineNum
= self
.CurrentLineNumber
2708 FfsFileObj
.CurrentLineContent
= self
.__CurrentLine
()
2709 FfsFileObj
.FileName
= self
.__Token
.replace('$(SPACE)', ' ')
2710 self
.__VerifyFile
(FfsFileObj
.FileName
)
2712 if not self
.__IsToken
( "}"):
2713 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2715 ## __GetRAWData() method
2717 # Get RAW data for FILE statement
2719 # @param self The object pointer
2720 # @param FfsFileObj for whom section is got
2721 # @param MacroDict dictionary used to replace macro
2723 def __GetRAWData(self
, FfsFileObj
, MacroDict
= {}):
2724 FfsFileObj
.FileName
= []
2725 FfsFileObj
.SubAlignment
= []
2728 if self
.__GetAlignment
():
2729 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
2730 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
2731 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2732 #For FFS, Auto is default option same to ""
2733 if not self
.__Token
== "Auto":
2734 AlignValue
= self
.__Token
2735 if not self
.__GetNextToken
():
2736 raise Warning("expected Filename value", self
.FileName
, self
.CurrentLineNumber
)
2738 FileName
= self
.__Token
.replace('$(SPACE)', ' ')
2741 raise Warning("expected Filename value", self
.FileName
, self
.CurrentLineNumber
)
2743 self
.__VerifyFile
(FileName
)
2744 File
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
)
2745 FfsFileObj
.FileName
.append(File
.Path
)
2746 FfsFileObj
.SubAlignment
.append(AlignValue
)
2748 if self
.__IsToken
( "}"):
2752 if len(FfsFileObj
.SubAlignment
) == 1:
2753 FfsFileObj
.SubAlignment
= FfsFileObj
.SubAlignment
[0]
2754 if len(FfsFileObj
.FileName
) == 1:
2755 FfsFileObj
.FileName
= FfsFileObj
.FileName
[0]
2757 ## __GetFileOpts() method
2759 # Get options for FILE statement
2761 # @param self The object pointer
2762 # @param FfsFileObj for whom options is got
2764 def __GetFileOpts(self
, FfsFileObj
):
2766 if self
.__GetNextToken
():
2767 if TokenFindPattern
.match(self
.__Token
):
2768 FfsFileObj
.KeyStringList
.append(self
.__Token
)
2769 if self
.__IsToken
(","):
2770 while self
.__GetNextToken
():
2771 if not TokenFindPattern
.match(self
.__Token
):
2772 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2773 FfsFileObj
.KeyStringList
.append(self
.__Token
)
2775 if not self
.__IsToken
(","):
2781 if self
.__IsKeyword
( "FIXED", True):
2782 FfsFileObj
.Fixed
= True
2784 if self
.__IsKeyword
( "CHECKSUM", True):
2785 FfsFileObj
.CheckSum
= True
2787 if self
.__GetAlignment
():
2788 if self
.__Token
not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
2789 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
2790 raise Warning("Incorrect alignment '%s'" % self
.__Token
, self
.FileName
, self
.CurrentLineNumber
)
2791 #For FFS, Auto is default option same to ""
2792 if not self
.__Token
== "Auto":
2793 FfsFileObj
.Alignment
= self
.__Token
2795 ## __GetAlignment() method
2797 # Return the alignment value
2799 # @param self The object pointer
2800 # @retval True Successfully find alignment
2801 # @retval False Not able to find alignment
2803 def __GetAlignment(self
):
2804 if self
.__IsKeyword
( "Align", True):
2805 if not self
.__IsToken
( "="):
2806 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2808 if not self
.__GetNextToken
():
2809 raise Warning("expected alignment value", self
.FileName
, self
.CurrentLineNumber
)
2814 ## __GetFilePart() method
2816 # Get section data for FILE statement
2818 # @param self The object pointer
2819 # @param FfsFileObj for whom section is got
2820 # @param MacroDict dictionary used to replace macro
2822 def __GetSectionData(self
, FfsFileObj
, MacroDict
= {}):
2824 Dict
.update(MacroDict
)
2826 self
.__GetDefineStatements
(FfsFileObj
)
2828 Dict
.update(FfsFileObj
.DefineVarDict
)
2829 self
.__GetAprioriSection
(FfsFileObj
, Dict
.copy())
2830 self
.__GetAprioriSection
(FfsFileObj
, Dict
.copy())
2833 IsLeafSection
= self
.__GetLeafSection
(FfsFileObj
, Dict
)
2834 IsEncapSection
= self
.__GetEncapsulationSec
(FfsFileObj
)
2835 if not IsLeafSection
and not IsEncapSection
:
2838 ## __GetLeafSection() method