8091a51f35122b2da98275a1ef74d25a541df8a9
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FdfParser.py
1 ## @file
2 # parse FDF file
3 #
4 # Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
5 #
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
10 #
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 #
14
15 ##
16 # Import Modules
17 #
18 import re
19
20 import Fd
21 import Region
22 import Fv
23 import AprioriSection
24 import FfsInfStatement
25 import FfsFileStatement
26 import VerSection
27 import UiSection
28 import FvImageSection
29 import DataSection
30 import DepexSection
31 import CompressSection
32 import GuidSection
33 import Capsule
34 import CapsuleData
35 import Rule
36 import RuleComplexFile
37 import RuleSimpleFile
38 import EfiSection
39 import Vtf
40 import ComponentStatement
41 import OptionRom
42 import OptRomInfStatement
43 import OptRomFileStatement
44
45 from GenFdsGlobalVariable import GenFdsGlobalVariable
46 from Common.BuildToolError import *
47 from Common import EdkLogger
48 from Common.Misc import PathClass
49 from Common.String import NormPath
50 import Common.GlobalData as GlobalData
51 from Common.Expression import *
52 from Common import GlobalData
53 from Common.String import ReplaceMacro
54
55 from Common.Misc import tdict
56
57 import re
58 import Common.LongFilePathOs as os
59 from Common.LongFilePathSupport import OpenLongFilePath as open
60
61 ##define T_CHAR_SPACE ' '
62 ##define T_CHAR_NULL '\0'
63 ##define T_CHAR_CR '\r'
64 ##define T_CHAR_TAB '\t'
65 ##define T_CHAR_LF '\n'
66 ##define T_CHAR_SLASH '/'
67 ##define T_CHAR_BACKSLASH '\\'
68 ##define T_CHAR_DOUBLE_QUOTE '\"'
69 ##define T_CHAR_SINGLE_QUOTE '\''
70 ##define T_CHAR_STAR '*'
71 ##define T_CHAR_HASH '#'
72
73 (T_CHAR_SPACE, T_CHAR_NULL, T_CHAR_CR, T_CHAR_TAB, T_CHAR_LF, T_CHAR_SLASH, \
74 T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_HASH) = \
75 (' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#')
76
77 SEPERATOR_TUPLE = ('=', '|', ',', '{', '}')
78
79 RegionSizePattern = re.compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
80 RegionSizeGuidPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*\|\s*(?P<size>\w+\.\w+)\s*")
81 RegionOffsetPcdPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*$")
82 ShortcutPcdPattern = re.compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
83
84 IncludeFileList = []
85
86 def GetRealFileLine (File, Line):
87
88 InsertedLines = 0
89 for Profile in IncludeFileList:
90 if Line >= Profile.InsertStartLineNumber and Line < Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList):
91 return (Profile.FileName, Line - Profile.InsertStartLineNumber + 1)
92 if Line >= Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList):
93 InsertedLines += Profile.InsertAdjust + len(Profile.FileLinesList)
94
95 return (File, Line - InsertedLines)
96
97 ## The exception class that used to report error messages when parsing FDF
98 #
99 # Currently the "ToolName" is set to be "FDF Parser".
100 #
101 class Warning (Exception):
102 ## The constructor
103 #
104 # @param self The object pointer
105 # @param Str The message to record
106 # @param File The FDF name
107 # @param Line The Line number that error occurs
108 #
109 def __init__(self, Str, File = None, Line = None):
110
111 FileLineTuple = GetRealFileLine(File, Line)
112 self.FileName = FileLineTuple[0]
113 self.LineNumber = FileLineTuple[1]
114 self.Message = Str
115 self.ToolName = 'FdfParser'
116
117 def __str__(self):
118 return self.Message
119
120 ## The MACRO class that used to record macro value data when parsing include file
121 #
122 #
123 class MacroProfile :
124 ## The constructor
125 #
126 # @param self The object pointer
127 # @param FileName The file that to be parsed
128 #
129 def __init__(self, FileName, Line):
130 self.FileName = FileName
131 self.DefinedAtLine = Line
132 self.MacroName = None
133 self.MacroValue = None
134
135 ## The Include file content class that used to record file data when parsing include file
136 #
137 # May raise Exception when opening file.
138 #
139 class IncludeFileProfile :
140 ## The constructor
141 #
142 # @param self The object pointer
143 # @param FileName The file that to be parsed
144 #
145 def __init__(self, FileName):
146 self.FileName = FileName
147 self.FileLinesList = []
148 try:
149 fsock = open(FileName, "rb", 0)
150 try:
151 self.FileLinesList = fsock.readlines()
152 finally:
153 fsock.close()
154
155 except:
156 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)
157
158 self.InsertStartLineNumber = None
159 self.InsertAdjust = 0
160
161 ## The FDF content class that used to record file data when parsing FDF
162 #
163 # May raise Exception when opening file.
164 #
165 class FileProfile :
166 ## The constructor
167 #
168 # @param self The object pointer
169 # @param FileName The file that to be parsed
170 #
171 def __init__(self, FileName):
172 self.FileLinesList = []
173 try:
174 fsock = open(FileName, "rb", 0)
175 try:
176 self.FileLinesList = fsock.readlines()
177 finally:
178 fsock.close()
179
180 except:
181 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)
182
183
184 self.PcdDict = {}
185 self.InfList = []
186 # ECC will use this Dict and List information
187 self.PcdFileLineDict = {}
188 self.InfFileLineList = []
189
190 self.FdDict = {}
191 self.FdNameNotSet = False
192 self.FvDict = {}
193 self.CapsuleDict = {}
194 self.VtfList = []
195 self.RuleDict = {}
196 self.OptRomDict = {}
197
198 ## The syntax parser for FDF
199 #
200 # PreprocessFile method should be called prior to ParseFile
201 # CycleReferenceCheck method can detect cycles in FDF contents
202 #
203 # GetNext*** procedures mean these procedures will get next token first, then make judgement.
204 # Get*** procedures mean these procedures will make judgement on current token only.
205 #
206 class FdfParser:
207 ## The constructor
208 #
209 # @param self The object pointer
210 # @param FileName The file that to be parsed
211 #
212 def __init__(self, FileName):
213 self.Profile = FileProfile(FileName)
214 self.FileName = FileName
215 self.CurrentLineNumber = 1
216 self.CurrentOffsetWithinLine = 0
217 self.CurrentFdName = None
218 self.CurrentFvName = None
219 self.__Token = ""
220 self.__SkippedChars = ""
221 GlobalData.gFdfParser = self
222
223 # Used to section info
224 self.__CurSection = []
225 # Key: [section name, UI name, arch]
226 # Value: {MACRO_NAME : MACRO_VALUE}
227 self.__MacroDict = tdict(True, 3)
228 self.__PcdDict = {}
229
230 self.__WipeOffArea = []
231 if GenFdsGlobalVariable.WorkSpaceDir == '':
232 GenFdsGlobalVariable.WorkSpaceDir = os.getenv("WORKSPACE")
233
234 ## __IsWhiteSpace() method
235 #
236 # Whether char at current FileBufferPos is whitespace
237 #
238 # @param self The object pointer
239 # @param Char The char to test
240 # @retval True The char is a kind of white space
241 # @retval False The char is NOT a kind of white space
242 #
243 def __IsWhiteSpace(self, Char):
244 if Char in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_SPACE, T_CHAR_TAB, T_CHAR_LF):
245 return True
246 else:
247 return False
248
249 ## __SkipWhiteSpace() method
250 #
251 # Skip white spaces from current char, return number of chars skipped
252 #
253 # @param self The object pointer
254 # @retval Count The number of chars skipped
255 #
256 def __SkipWhiteSpace(self):
257 Count = 0
258 while not self.__EndOfFile():
259 Count += 1
260 if self.__CurrentChar() in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_LF, T_CHAR_SPACE, T_CHAR_TAB):
261 self.__SkippedChars += str(self.__CurrentChar())
262 self.__GetOneChar()
263
264 else:
265 Count = Count - 1
266 return Count
267
268 ## __EndOfFile() method
269 #
270 # Judge current buffer pos is at file end
271 #
272 # @param self The object pointer
273 # @retval True Current File buffer position is at file end
274 # @retval False Current File buffer position is NOT at file end
275 #
276 def __EndOfFile(self):
277 NumberOfLines = len(self.Profile.FileLinesList)
278 SizeOfLastLine = len(self.Profile.FileLinesList[-1])
279 if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1:
280 return True
281 elif self.CurrentLineNumber > NumberOfLines:
282 return True
283 else:
284 return False
285
286 ## __EndOfLine() method
287 #
288 # Judge current buffer pos is at line end
289 #
290 # @param self The object pointer
291 # @retval True Current File buffer position is at line end
292 # @retval False Current File buffer position is NOT at line end
293 #
294 def __EndOfLine(self):
295 if self.CurrentLineNumber > len(self.Profile.FileLinesList):
296 return True
297 SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
298 if self.CurrentOffsetWithinLine >= SizeOfCurrentLine:
299 return True
300 else:
301 return False
302
303 ## Rewind() method
304 #
305 # Reset file data buffer to the initial state
306 #
307 # @param self The object pointer
308 #
309 def Rewind(self):
310 self.CurrentLineNumber = 1
311 self.CurrentOffsetWithinLine = 0
312
313 ## __UndoOneChar() method
314 #
315 # Go back one char in the file buffer
316 #
317 # @param self The object pointer
318 # @retval True Successfully go back one char
319 # @retval False Not able to go back one char as file beginning reached
320 #
321 def __UndoOneChar(self):
322
323 if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0:
324 return False
325 elif self.CurrentOffsetWithinLine == 0:
326 self.CurrentLineNumber -= 1
327 self.CurrentOffsetWithinLine = len(self.__CurrentLine()) - 1
328 else:
329 self.CurrentOffsetWithinLine -= 1
330 return True
331
332 ## __GetOneChar() method
333 #
334 # Move forward one char in the file buffer
335 #
336 # @param self The object pointer
337 #
338 def __GetOneChar(self):
339 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
340 self.CurrentLineNumber += 1
341 self.CurrentOffsetWithinLine = 0
342 else:
343 self.CurrentOffsetWithinLine += 1
344
345 ## __CurrentChar() method
346 #
347 # Get the char pointed to by the file buffer pointer
348 #
349 # @param self The object pointer
350 # @retval Char Current char
351 #
352 def __CurrentChar(self):
353 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine]
354
355 ## __NextChar() method
356 #
357 # Get the one char pass the char pointed to by the file buffer pointer
358 #
359 # @param self The object pointer
360 # @retval Char Next char
361 #
362 def __NextChar(self):
363 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
364 return self.Profile.FileLinesList[self.CurrentLineNumber][0]
365 else:
366 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1]
367
368 ## __SetCurrentCharValue() method
369 #
370 # Modify the value of current char
371 #
372 # @param self The object pointer
373 # @param Value The new value of current char
374 #
375 def __SetCurrentCharValue(self, Value):
376 self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value
377
378 ## __CurrentLine() method
379 #
380 # Get the list that contains current line contents
381 #
382 # @param self The object pointer
383 # @retval List current line contents
384 #
385 def __CurrentLine(self):
386 return self.Profile.FileLinesList[self.CurrentLineNumber - 1]
387
388 def __StringToList(self):
389 self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList]
390 self.Profile.FileLinesList[-1].append(' ')
391
392 def __ReplaceFragment(self, StartPos, EndPos, Value = ' '):
393 if StartPos[0] == EndPos[0]:
394 Offset = StartPos[1]
395 while Offset <= EndPos[1]:
396 self.Profile.FileLinesList[StartPos[0]][Offset] = Value
397 Offset += 1
398 return
399
400 Offset = StartPos[1]
401 while self.Profile.FileLinesList[StartPos[0]][Offset] not in ('\r', '\n'):
402 self.Profile.FileLinesList[StartPos[0]][Offset] = Value
403 Offset += 1
404
405 Line = StartPos[0]
406 while Line < EndPos[0]:
407 Offset = 0
408 while self.Profile.FileLinesList[Line][Offset] not in ('\r', '\n'):
409 self.Profile.FileLinesList[Line][Offset] = Value
410 Offset += 1
411 Line += 1
412
413 Offset = 0
414 while Offset <= EndPos[1]:
415 self.Profile.FileLinesList[EndPos[0]][Offset] = Value
416 Offset += 1
417
418
419 def __GetMacroName(self):
420 if not self.__GetNextToken():
421 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)
422 MacroName = self.__Token
423 NotFlag = False
424 if MacroName.startswith('!'):
425 NotFlag = True
426 MacroName = MacroName[1:].strip()
427
428 if not MacroName.startswith('$(') or not MacroName.endswith(')'):
429 raise Warning("Macro name expected(Please use '$(%(Token)s)' if '%(Token)s' is a macro.)" % {"Token" : MacroName},
430 self.FileName, self.CurrentLineNumber)
431 MacroName = MacroName[2:-1]
432 return MacroName, NotFlag
433
434 def __SetMacroValue(self, Macro, Value):
435 if not self.__CurSection:
436 return
437
438 MacroDict = {}
439 if not self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]]:
440 self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]] = MacroDict
441 else:
442 MacroDict = self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]]
443 MacroDict[Macro] = Value
444
445 def __GetMacroValue(self, Macro):
446 # Highest priority
447 if Macro in GlobalData.gCommandLineDefines:
448 return GlobalData.gCommandLineDefines[Macro]
449 if Macro in GlobalData.gGlobalDefines:
450 return GlobalData.gGlobalDefines[Macro]
451
452 if self.__CurSection:
453 MacroDict = self.__MacroDict[
454 self.__CurSection[0],
455 self.__CurSection[1],
456 self.__CurSection[2]
457 ]
458 if MacroDict and Macro in MacroDict:
459 return MacroDict[Macro]
460
461 # Lowest priority
462 if Macro in GlobalData.gPlatformDefines:
463 return GlobalData.gPlatformDefines[Macro]
464 return None
465
466 def __SectionHeaderParser(self, Section):
467 # [Defines]
468 # [FD.UiName]: use dummy instead if UI name is optional
469 # [FV.UiName]
470 # [Capsule.UiName]
471 # [Rule]: don't take rule section into account, macro is not allowed in this section
472 # [VTF.arch.UiName, arch]
473 # [OptionRom.DriverName]
474 self.__CurSection = []
475 Section = Section.strip()[1:-1].upper().replace(' ', '').strip('.')
476 ItemList = Section.split('.')
477 Item = ItemList[0]
478 if Item == '' or Item == 'RULE':
479 return
480
481 if Item == 'DEFINES':
482 self.__CurSection = ['COMMON', 'COMMON', 'COMMON']
483 elif Item == 'VTF' and len(ItemList) == 3:
484 UiName = ItemList[2]
485 Pos = UiName.find(',')
486 if Pos != -1:
487 UiName = UiName[:Pos]
488 self.__CurSection = ['VTF', UiName, ItemList[1]]
489 elif len(ItemList) > 1:
490 self.__CurSection = [ItemList[0], ItemList[1], 'COMMON']
491 elif len(ItemList) > 0:
492 self.__CurSection = [ItemList[0], 'DUMMY', 'COMMON']
493
494 ## PreprocessFile() method
495 #
496 # Preprocess file contents, replace comments with spaces.
497 # In the end, rewind the file buffer pointer to the beginning
498 # BUGBUG: No !include statement processing contained in this procedure
499 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
500 #
501 # @param self The object pointer
502 #
503 def PreprocessFile(self):
504
505 self.Rewind()
506 InComment = False
507 DoubleSlashComment = False
508 HashComment = False
509 # HashComment in quoted string " " is ignored.
510 InString = False
511
512 while not self.__EndOfFile():
513
514 if self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment:
515 InString = not InString
516 # meet new line, then no longer in a comment for // and '#'
517 if self.__CurrentChar() == T_CHAR_LF:
518 self.CurrentLineNumber += 1
519 self.CurrentOffsetWithinLine = 0
520 if InComment and DoubleSlashComment:
521 InComment = False
522 DoubleSlashComment = False
523 if InComment and HashComment:
524 InComment = False
525 HashComment = False
526 # check for */ comment end
527 elif InComment and not DoubleSlashComment and not HashComment and self.__CurrentChar() == T_CHAR_STAR and self.__NextChar() == T_CHAR_SLASH:
528 self.__SetCurrentCharValue(T_CHAR_SPACE)
529 self.__GetOneChar()
530 self.__SetCurrentCharValue(T_CHAR_SPACE)
531 self.__GetOneChar()
532 InComment = False
533 # set comments to spaces
534 elif InComment:
535 self.__SetCurrentCharValue(T_CHAR_SPACE)
536 self.__GetOneChar()
537 # check for // comment
538 elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH and not self.__EndOfLine():
539 InComment = True
540 DoubleSlashComment = True
541 # check for '#' comment
542 elif self.__CurrentChar() == T_CHAR_HASH and not self.__EndOfLine() and not InString:
543 InComment = True
544 HashComment = True
545 # check for /* comment start
546 elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_STAR:
547 self.__SetCurrentCharValue( T_CHAR_SPACE)
548 self.__GetOneChar()
549 self.__SetCurrentCharValue( T_CHAR_SPACE)
550 self.__GetOneChar()
551 InComment = True
552 else:
553 self.__GetOneChar()
554
555 # restore from ListOfList to ListOfString
556 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
557 self.Rewind()
558
559 ## PreprocessIncludeFile() method
560 #
561 # Preprocess file contents, replace !include statements with file contents.
562 # In the end, rewind the file buffer pointer to the beginning
563 #
564 # @param self The object pointer
565 #
566 def PreprocessIncludeFile(self):
567
568 while self.__GetNextToken():
569
570 if self.__Token == '!include':
571 IncludeLine = self.CurrentLineNumber
572 IncludeOffset = self.CurrentOffsetWithinLine - len('!include')
573 if not self.__GetNextToken():
574 raise Warning("expected include file name", self.FileName, self.CurrentLineNumber)
575 IncFileName = self.__Token
576 __IncludeMacros = {}
577 for Macro in ['WORKSPACE', 'ECP_SOURCE', 'EFI_SOURCE', 'EDK_SOURCE']:
578 MacroVal = self.__GetMacroValue(Macro)
579 if MacroVal:
580 __IncludeMacros[Macro] = MacroVal
581
582 try:
583 IncludedFile = NormPath(ReplaceMacro(IncFileName, __IncludeMacros, RaiseError=True))
584 except:
585 raise Warning("only these system environment variables are permitted to start the path of the included file: "
586 "$(WORKSPACE), $(ECP_SOURCE), $(EFI_SOURCE), $(EDK_SOURCE)",
587 self.FileName, self.CurrentLineNumber)
588 #
589 # First search the include file under the same directory as FDF file
590 #
591 IncludedFile1 = PathClass(IncludedFile, os.path.dirname(self.FileName))
592 ErrorCode = IncludedFile1.Validate()[0]
593 if ErrorCode != 0:
594 #
595 # Then search the include file under the same directory as DSC file
596 #
597 PlatformDir = ''
598 if GenFdsGlobalVariable.ActivePlatform:
599 PlatformDir = GenFdsGlobalVariable.ActivePlatform.Dir
600 elif GlobalData.gActivePlatform:
601 PlatformDir = GlobalData.gActivePlatform.MetaFile.Dir
602 IncludedFile1 = PathClass(IncludedFile, PlatformDir)
603 ErrorCode = IncludedFile1.Validate()[0]
604 if ErrorCode != 0:
605 #
606 # Also search file under the WORKSPACE directory
607 #
608 IncludedFile1 = PathClass(IncludedFile, GlobalData.gWorkspace)
609 ErrorCode = IncludedFile1.Validate()[0]
610 if ErrorCode != 0:
611 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),
612 self.FileName, self.CurrentLineNumber)
613
614 IncFileProfile = IncludeFileProfile(IncludedFile1.Path)
615
616 CurrentLine = self.CurrentLineNumber
617 CurrentOffset = self.CurrentOffsetWithinLine
618 # list index of the insertion, note that line number is 'CurrentLine + 1'
619 InsertAtLine = CurrentLine
620 IncFileProfile.InsertStartLineNumber = InsertAtLine + 1
621 # deal with remaining portions after "!include filename", if exists.
622 if self.__GetNextToken():
623 if self.CurrentLineNumber == CurrentLine:
624 RemainingLine = self.__CurrentLine()[CurrentOffset:]
625 self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine)
626 IncFileProfile.InsertAdjust += 1
627 self.CurrentLineNumber += 1
628 self.CurrentOffsetWithinLine = 0
629
630 for Line in IncFileProfile.FileLinesList:
631 self.Profile.FileLinesList.insert(InsertAtLine, Line)
632 self.CurrentLineNumber += 1
633 InsertAtLine += 1
634
635 IncludeFileList.append(IncFileProfile)
636
637 # comment out the processed include file statement
638 TempList = list(self.Profile.FileLinesList[IncludeLine - 1])
639 TempList.insert(IncludeOffset, '#')
640 self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList)
641
642 self.Rewind()
643
644 def __GetIfListCurrentItemStat(self, IfList):
645 if len(IfList) == 0:
646 return True
647
648 for Item in IfList:
649 if Item[1] == False:
650 return False
651
652 return True
653
654 ## PreprocessConditionalStatement() method
655 #
656 # Preprocess conditional statement.
657 # In the end, rewind the file buffer pointer to the beginning
658 #
659 # @param self The object pointer
660 #
661 def PreprocessConditionalStatement(self):
662 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
663 IfList = []
664 RegionLayoutLine = 0
665 ReplacedLine = -1
666 while self.__GetNextToken():
667 # Determine section name and the location dependent macro
668 if self.__GetIfListCurrentItemStat(IfList):
669 if self.__Token.startswith('['):
670 Header = self.__Token
671 if not self.__Token.endswith(']'):
672 self.__SkipToToken(']')
673 Header += self.__SkippedChars
674 if Header.find('$(') != -1:
675 raise Warning("macro cannot be used in section header", self.FileName, self.CurrentLineNumber)
676 self.__SectionHeaderParser(Header)
677 continue
678 # Replace macros except in RULE section or out of section
679 elif self.__CurSection and ReplacedLine != self.CurrentLineNumber:
680 ReplacedLine = self.CurrentLineNumber
681 self.__UndoToken()
682 CurLine = self.Profile.FileLinesList[ReplacedLine - 1]
683 PreIndex = 0
684 StartPos = CurLine.find('$(', PreIndex)
685 EndPos = CurLine.find(')', StartPos+2)
686 while StartPos != -1 and EndPos != -1 and self.__Token not in ['!ifdef', '!ifndef', '!if', '!elseif']:
687 MacroName = CurLine[StartPos+2 : EndPos]
688 MacorValue = self.__GetMacroValue(MacroName)
689 if MacorValue != None:
690 CurLine = CurLine.replace('$(' + MacroName + ')', MacorValue, 1)
691 if MacorValue.find('$(') != -1:
692 PreIndex = StartPos
693 else:
694 PreIndex = StartPos + len(MacorValue)
695 else:
696 PreIndex = EndPos + 1
697 StartPos = CurLine.find('$(', PreIndex)
698 EndPos = CurLine.find(')', StartPos+2)
699 self.Profile.FileLinesList[ReplacedLine - 1] = CurLine
700 continue
701
702 if self.__Token == 'DEFINE':
703 if self.__GetIfListCurrentItemStat(IfList):
704 if not self.__CurSection:
705 raise Warning("macro cannot be defined in Rule section or out of section", self.FileName, self.CurrentLineNumber)
706 DefineLine = self.CurrentLineNumber - 1
707 DefineOffset = self.CurrentOffsetWithinLine - len('DEFINE')
708 if not self.__GetNextToken():
709 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)
710 Macro = self.__Token
711 if not self.__IsToken( "="):
712 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
713
714 Value = self.__GetExpression()
715 self.__SetMacroValue(Macro, Value)
716 self.__WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
717 elif self.__Token == 'SET':
718 if not self.__GetIfListCurrentItemStat(IfList):
719 continue
720 SetLine = self.CurrentLineNumber - 1
721 SetOffset = self.CurrentOffsetWithinLine - len('SET')
722 PcdPair = self.__GetNextPcdName()
723 PcdName = "%s.%s" % (PcdPair[1], PcdPair[0])
724 if not self.__IsToken( "="):
725 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
726
727 Value = self.__GetExpression()
728 Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)
729
730 self.__PcdDict[PcdName] = Value
731
732 self.Profile.PcdDict[PcdPair] = Value
733 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
734 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
735
736 self.__WipeOffArea.append(((SetLine, SetOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
737 elif self.__Token in ('!ifdef', '!ifndef', '!if'):
738 IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))
739 IfList.append([IfStartPos, None, None])
740
741 CondLabel = self.__Token
742 Expression = self.__GetExpression()
743
744 if CondLabel == '!if':
745 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')
746 else:
747 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'in')
748 if CondLabel == '!ifndef':
749 ConditionSatisfied = not ConditionSatisfied
750
751 BranchDetermined = ConditionSatisfied
752 IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
753 if ConditionSatisfied:
754 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
755 elif self.__Token in ('!elseif', '!else'):
756 ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))
757 if len(IfList) <= 0:
758 raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)
759
760 if IfList[-1][1]:
761 IfList[-1] = [ElseStartPos, False, True]
762 self.__WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
763 else:
764 self.__WipeOffArea.append((IfList[-1][0], ElseStartPos))
765 IfList[-1] = [ElseStartPos, True, IfList[-1][2]]
766 if self.__Token == '!elseif':
767 Expression = self.__GetExpression()
768 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')
769 IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]]
770
771 if IfList[-1][1]:
772 if IfList[-1][2]:
773 IfList[-1][1] = False
774 else:
775 IfList[-1][2] = True
776 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
777 elif self.__Token == '!endif':
778 if len(IfList) <= 0:
779 raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)
780 if IfList[-1][1]:
781 self.__WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
782 else:
783 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
784
785 IfList.pop()
786 elif not IfList: # Don't use PCDs inside conditional directive
787 if self.CurrentLineNumber <= RegionLayoutLine:
788 # Don't try the same line twice
789 continue
790 SetPcd = ShortcutPcdPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
791 if SetPcd:
792 self.__PcdDict[SetPcd.group('name')] = SetPcd.group('value')
793 RegionLayoutLine = self.CurrentLineNumber
794 continue
795 RegionSize = RegionSizePattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
796 if not RegionSize:
797 RegionLayoutLine = self.CurrentLineNumber
798 continue
799 RegionSizeGuid = RegionSizeGuidPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber])
800 if not RegionSizeGuid:
801 RegionLayoutLine = self.CurrentLineNumber + 1
802 continue
803 self.__PcdDict[RegionSizeGuid.group('base')] = RegionSize.group('base')
804 self.__PcdDict[RegionSizeGuid.group('size')] = RegionSize.group('size')
805 RegionLayoutLine = self.CurrentLineNumber + 1
806
807 if IfList:
808 raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber)
809 self.Rewind()
810
811 def __CollectMacroPcd(self):
812 MacroDict = {}
813
814 # PCD macro
815 MacroDict.update(GlobalData.gPlatformPcds)
816 MacroDict.update(self.__PcdDict)
817
818 # Lowest priority
819 MacroDict.update(GlobalData.gPlatformDefines)
820
821 if self.__CurSection:
822 # Defines macro
823 ScopeMacro = self.__MacroDict['COMMON', 'COMMON', 'COMMON']
824 if ScopeMacro:
825 MacroDict.update(ScopeMacro)
826
827 # Section macro
828 ScopeMacro = self.__MacroDict[
829 self.__CurSection[0],
830 self.__CurSection[1],
831 self.__CurSection[2]
832 ]
833 if ScopeMacro:
834 MacroDict.update(ScopeMacro)
835
836 MacroDict.update(GlobalData.gGlobalDefines)
837 MacroDict.update(GlobalData.gCommandLineDefines)
838 # Highest priority
839
840 return MacroDict
841
842 def __EvaluateConditional(self, Expression, Line, Op = None, Value = None):
843 FileLineTuple = GetRealFileLine(self.FileName, Line)
844 MacroPcdDict = self.__CollectMacroPcd()
845 if Op == 'eval':
846 try:
847 if Value:
848 return ValueExpression(Expression, MacroPcdDict)(True)
849 else:
850 return ValueExpression(Expression, MacroPcdDict)()
851 except WrnExpression, Excpt:
852 #
853 # Catch expression evaluation warning here. We need to report
854 # the precise number of line and return the evaluation result
855 #
856 EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),
857 File=self.FileName, ExtraData=self.__CurrentLine(),
858 Line=Line)
859 return Excpt.result
860 except Exception, Excpt:
861 if hasattr(Excpt, 'Pcd'):
862 if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
863 Info = GlobalData.gPlatformOtherPcds[Excpt.Pcd]
864 raise Warning("Cannot use this PCD (%s) in an expression as"
865 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
866 " of the DSC file (%s), and it is currently defined in this section:"
867 " %s, line #: %d." % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE'], Info[0], Info[1]),
868 *FileLineTuple)
869 else:
870 raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE']),
871 *FileLineTuple)
872 else:
873 raise Warning(str(Excpt), *FileLineTuple)
874 else:
875 if Expression.startswith('$(') and Expression[-1] == ')':
876 Expression = Expression[2:-1]
877 return Expression in MacroPcdDict
878
879 ## __IsToken() method
880 #
881 # Check whether input string is found from current char position along
882 # If found, the string value is put into self.__Token
883 #
884 # @param self The object pointer
885 # @param String The string to search
886 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
887 # @retval True Successfully find string, file buffer pointer moved forward
888 # @retval False Not able to find string, file buffer pointer not changed
889 #
890 def __IsToken(self, String, IgnoreCase = False):
891 self.__SkipWhiteSpace()
892
893 # Only consider the same line, no multi-line token allowed
894 StartPos = self.CurrentOffsetWithinLine
895 index = -1
896 if IgnoreCase:
897 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())
898 else:
899 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)
900 if index == 0:
901 self.CurrentOffsetWithinLine += len(String)
902 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
903 return True
904 return False
905
906 ## __IsKeyword() method
907 #
908 # Check whether input keyword is found from current char position along, whole word only!
909 # If found, the string value is put into self.__Token
910 #
911 # @param self The object pointer
912 # @param Keyword The string to search
913 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
914 # @retval True Successfully find string, file buffer pointer moved forward
915 # @retval False Not able to find string, file buffer pointer not changed
916 #
917 def __IsKeyword(self, KeyWord, IgnoreCase = False):
918 self.__SkipWhiteSpace()
919
920 # Only consider the same line, no multi-line token allowed
921 StartPos = self.CurrentOffsetWithinLine
922 index = -1
923 if IgnoreCase:
924 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(KeyWord.upper())
925 else:
926 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(KeyWord)
927 if index == 0:
928 followingChar = self.__CurrentLine()[self.CurrentOffsetWithinLine + len(KeyWord)]
929 if not str(followingChar).isspace() and followingChar not in SEPERATOR_TUPLE:
930 return False
931 self.CurrentOffsetWithinLine += len(KeyWord)
932 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
933 return True
934 return False
935
936 def __GetExpression(self):
937 Line = self.Profile.FileLinesList[self.CurrentLineNumber - 1]
938 Index = len(Line) - 1
939 while Line[Index] in ['\r', '\n']:
940 Index -= 1
941 ExpressionString = self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:Index+1]
942 self.CurrentOffsetWithinLine += len(ExpressionString)
943 ExpressionString = ExpressionString.strip()
944 return ExpressionString
945
946 ## __GetNextWord() method
947 #
948 # Get next C name from file lines
949 # If found, the string value is put into self.__Token
950 #
951 # @param self The object pointer
952 # @retval True Successfully find a C name string, file buffer pointer moved forward
953 # @retval False Not able to find a C name string, file buffer pointer not changed
954 #
955 def __GetNextWord(self):
956 self.__SkipWhiteSpace()
957 if self.__EndOfFile():
958 return False
959
960 TempChar = self.__CurrentChar()
961 StartPos = self.CurrentOffsetWithinLine
962 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_':
963 self.__GetOneChar()
964 while not self.__EndOfLine():
965 TempChar = self.__CurrentChar()
966 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \
967 or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-':
968 self.__GetOneChar()
969
970 else:
971 break
972
973 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
974 return True
975
976 return False
977
978 ## __GetNextToken() method
979 #
980 # Get next token unit before a seperator
981 # If found, the string value is put into self.__Token
982 #
983 # @param self The object pointer
984 # @retval True Successfully find a token unit, file buffer pointer moved forward
985 # @retval False Not able to find a token unit, file buffer pointer not changed
986 #
987 def __GetNextToken(self):
988 # Skip leading spaces, if exist.
989 self.__SkipWhiteSpace()
990 if self.__EndOfFile():
991 return False
992 # Record the token start position, the position of the first non-space char.
993 StartPos = self.CurrentOffsetWithinLine
994 StartLine = self.CurrentLineNumber
995 while StartLine == self.CurrentLineNumber:
996 TempChar = self.__CurrentChar()
997 # Try to find the end char that is not a space and not in seperator tuple.
998 # That is, when we got a space or any char in the tuple, we got the end of token.
999 if not str(TempChar).isspace() and TempChar not in SEPERATOR_TUPLE:
1000 self.__GetOneChar()
1001 # if we happen to meet a seperator as the first char, we must proceed to get it.
1002 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1003 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:
1004 self.__GetOneChar()
1005 break
1006 else:
1007 break
1008 # else:
1009 # return False
1010
1011 EndPos = self.CurrentOffsetWithinLine
1012 if self.CurrentLineNumber != StartLine:
1013 EndPos = len(self.Profile.FileLinesList[StartLine-1])
1014 self.__Token = self.Profile.FileLinesList[StartLine-1][StartPos : EndPos]
1015 if StartPos != self.CurrentOffsetWithinLine:
1016 return True
1017 else:
1018 return False
1019
1020 def __GetNextOp(self):
1021 # Skip leading spaces, if exist.
1022 self.__SkipWhiteSpace()
1023 if self.__EndOfFile():
1024 return False
1025 # Record the token start position, the position of the first non-space char.
1026 StartPos = self.CurrentOffsetWithinLine
1027 while not self.__EndOfLine():
1028 TempChar = self.__CurrentChar()
1029 # Try to find the end char that is not a space
1030 if not str(TempChar).isspace():
1031 self.__GetOneChar()
1032 else:
1033 break
1034 else:
1035 return False
1036
1037 if StartPos != self.CurrentOffsetWithinLine:
1038 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
1039 return True
1040 else:
1041 return False
1042 ## __GetNextGuid() method
1043 #
1044 # Get next token unit before a seperator
1045 # If found, the GUID string is put into self.__Token
1046 #
1047 # @param self The object pointer
1048 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward
1049 # @retval False Not able to find a registry format GUID, file buffer pointer not changed
1050 #
1051 def __GetNextGuid(self):
1052
1053 if not self.__GetNextToken():
1054 return False
1055 p = re.compile('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}')
1056 if p.match(self.__Token) != None:
1057 return True
1058 else:
1059 self.__UndoToken()
1060 return False
1061
1062 ## __UndoToken() method
1063 #
1064 # Go back one token unit in file buffer
1065 #
1066 # @param self The object pointer
1067 #
1068 def __UndoToken(self):
1069 self.__UndoOneChar()
1070 while self.__CurrentChar().isspace():
1071 if not self.__UndoOneChar():
1072 self.__GetOneChar()
1073 return
1074
1075
1076 StartPos = self.CurrentOffsetWithinLine
1077 CurrentLine = self.CurrentLineNumber
1078 while CurrentLine == self.CurrentLineNumber:
1079
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 not TempChar in SEPERATOR_TUPLE:
1084 if not self.__UndoOneChar():
1085 return
1086 # if we happen to meet a seperator as the first char, we must proceed to get it.
1087 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1088 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:
1089 return
1090 else:
1091 break
1092
1093 self.__GetOneChar()
1094
1095 ## __HexDigit() method
1096 #
1097 # Whether char input is a Hex data bit
1098 #
1099 # @param self The object pointer
1100 # @param TempChar The char to test
1101 # @retval True The char is a Hex data bit
1102 # @retval False The char is NOT a Hex data bit
1103 #
1104 def __HexDigit(self, TempChar):
1105 if (TempChar >= 'a' and TempChar <= 'f') or (TempChar >= 'A' and TempChar <= 'F') \
1106 or (TempChar >= '0' and TempChar <= '9'):
1107 return True
1108 else:
1109 return False
1110
1111 def __IsHex(self, HexStr):
1112 if not HexStr.upper().startswith("0X"):
1113 return False
1114 if len(self.__Token) <= 2:
1115 return False
1116 charList = [c for c in HexStr[2 : ] if not self.__HexDigit( c)]
1117 if len(charList) == 0:
1118 return True
1119 else:
1120 return False
1121 ## __GetNextHexNumber() method
1122 #
1123 # Get next HEX data before a seperator
1124 # If found, the HEX data is put into self.__Token
1125 #
1126 # @param self The object pointer
1127 # @retval True Successfully find a HEX data, file buffer pointer moved forward
1128 # @retval False Not able to find a HEX data, file buffer pointer not changed
1129 #
1130 def __GetNextHexNumber(self):
1131 if not self.__GetNextToken():
1132 return False
1133 if self.__IsHex(self.__Token):
1134 return True
1135 else:
1136 self.__UndoToken()
1137 return False
1138
1139 ## __GetNextDecimalNumber() method
1140 #
1141 # Get next decimal data before a seperator
1142 # If found, the decimal data is put into self.__Token
1143 #
1144 # @param self The object pointer
1145 # @retval True Successfully find a decimal data, file buffer pointer moved forward
1146 # @retval False Not able to find a decimal data, file buffer pointer not changed
1147 #
1148 def __GetNextDecimalNumber(self):
1149 if not self.__GetNextToken():
1150 return False
1151 if self.__Token.isdigit():
1152 return True
1153 else:
1154 self.__UndoToken()
1155 return False
1156
1157 ## __GetNextPcdName() method
1158 #
1159 # Get next PCD token space C name and PCD C name pair before a seperator
1160 # If found, the decimal data is put into self.__Token
1161 #
1162 # @param self The object pointer
1163 # @retval Tuple PCD C name and PCD token space C name pair
1164 #
1165 def __GetNextPcdName(self):
1166 if not self.__GetNextWord():
1167 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)
1168 pcdTokenSpaceCName = self.__Token
1169
1170 if not self.__IsToken( "."):
1171 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)
1172
1173 if not self.__GetNextWord():
1174 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)
1175 pcdCName = self.__Token
1176
1177 return (pcdCName, pcdTokenSpaceCName)
1178
1179 ## __GetStringData() method
1180 #
1181 # Get string contents quoted in ""
1182 # If found, the decimal data is put into self.__Token
1183 #
1184 # @param self The object pointer
1185 # @retval True Successfully find a string data, file buffer pointer moved forward
1186 # @retval False Not able to find a string data, file buffer pointer not changed
1187 #
1188 def __GetStringData(self):
1189 if self.__Token.startswith("\"") or self.__Token.startswith("L\""):
1190 self.__UndoToken()
1191 self.__SkipToToken("\"")
1192 currentLineNumber = self.CurrentLineNumber
1193
1194 if not self.__SkipToToken("\""):
1195 raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber)
1196 if currentLineNumber != self.CurrentLineNumber:
1197 raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber)
1198 self.__Token = self.__SkippedChars.rstrip('\"')
1199 return True
1200
1201 elif self.__Token.startswith("\'") or self.__Token.startswith("L\'"):
1202 self.__UndoToken()
1203 self.__SkipToToken("\'")
1204 currentLineNumber = self.CurrentLineNumber
1205
1206 if not self.__SkipToToken("\'"):
1207 raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber)
1208 if currentLineNumber != self.CurrentLineNumber:
1209 raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber)
1210 self.__Token = self.__SkippedChars.rstrip('\'')
1211 return True
1212
1213 else:
1214 return False
1215
1216 ## __SkipToToken() method
1217 #
1218 # Search forward in file buffer for the string
1219 # The skipped chars are put into self.__SkippedChars
1220 #
1221 # @param self The object pointer
1222 # @param String The string to search
1223 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
1224 # @retval True Successfully find the string, file buffer pointer moved forward
1225 # @retval False Not able to find the string, file buffer pointer not changed
1226 #
1227 def __SkipToToken(self, String, IgnoreCase = False):
1228 StartPos = self.GetFileBufferPos()
1229
1230 self.__SkippedChars = ""
1231 while not self.__EndOfFile():
1232 index = -1
1233 if IgnoreCase:
1234 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())
1235 else:
1236 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)
1237 if index == 0:
1238 self.CurrentOffsetWithinLine += len(String)
1239 self.__SkippedChars += String
1240 return True
1241 self.__SkippedChars += str(self.__CurrentChar())
1242 self.__GetOneChar()
1243
1244 self.SetFileBufferPos( StartPos)
1245 self.__SkippedChars = ""
1246 return False
1247
1248 ## GetFileBufferPos() method
1249 #
1250 # Return the tuple of current line and offset within the line
1251 #
1252 # @param self The object pointer
1253 # @retval Tuple Line number and offset pair
1254 #
1255 def GetFileBufferPos(self):
1256 return (self.CurrentLineNumber, self.CurrentOffsetWithinLine)
1257
1258 ## SetFileBufferPos() method
1259 #
1260 # Restore the file buffer position
1261 #
1262 # @param self The object pointer
1263 # @param Pos The new file buffer position
1264 #
1265 def SetFileBufferPos(self, Pos):
1266 (self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos
1267
1268 ## Preprocess() method
1269 #
1270 # Preprocess comment, conditional directive, include directive, replace macro.
1271 # Exception will be raised if syntax error found
1272 #
1273 # @param self The object pointer
1274 #
1275 def Preprocess(self):
1276 self.__StringToList()
1277 self.PreprocessFile()
1278 self.PreprocessIncludeFile()
1279 self.__StringToList()
1280 self.PreprocessFile()
1281 self.PreprocessConditionalStatement()
1282 self.__StringToList()
1283 for Pos in self.__WipeOffArea:
1284 self.__ReplaceFragment(Pos[0], Pos[1])
1285 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
1286
1287 while self.__GetDefines():
1288 pass
1289
1290 ## ParseFile() method
1291 #
1292 # Parse the file profile buffer to extract fd, fv ... information
1293 # Exception will be raised if syntax error found
1294 #
1295 # @param self The object pointer
1296 #
1297 def ParseFile(self):
1298
1299 try:
1300 self.Preprocess()
1301 while self.__GetFd():
1302 pass
1303
1304 while self.__GetFv():
1305 pass
1306
1307 while self.__GetCapsule():
1308 pass
1309
1310 while self.__GetVtf():
1311 pass
1312
1313 while self.__GetRule():
1314 pass
1315
1316 while self.__GetOptionRom():
1317 pass
1318
1319 except Warning, X:
1320 self.__UndoToken()
1321 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1322 #'\n\tGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \
1323 X.Message += ' near line %d, column %d: %s' \
1324 % (FileLineTuple[1], self.CurrentOffsetWithinLine + 1, self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :].rstrip('\n').rstrip('\r'))
1325 raise
1326
1327 ## __GetDefines() method
1328 #
1329 # Get Defines section contents and store its data into AllMacrosList
1330 #
1331 # @param self The object pointer
1332 # @retval True Successfully find a Defines
1333 # @retval False Not able to find a Defines
1334 #
1335 def __GetDefines(self):
1336
1337 if not self.__GetNextToken():
1338 return False
1339
1340 S = self.__Token.upper()
1341 if S.startswith("[") and not S.startswith("[DEFINES"):
1342 if not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \
1343 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
1344 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
1345 self.__UndoToken()
1346 return False
1347
1348 self.__UndoToken()
1349 if not self.__IsToken("[DEFINES", True):
1350 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1351 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1352 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1353 raise Warning("expected [DEFINES", self.FileName, self.CurrentLineNumber)
1354
1355 if not self.__IsToken( "]"):
1356 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
1357
1358 while self.__GetNextWord():
1359 # handle the SET statement
1360 if self.__Token == 'SET':
1361 self.__UndoToken()
1362 self.__GetSetStatement(None)
1363 continue
1364
1365 Macro = self.__Token
1366
1367 if not self.__IsToken("="):
1368 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1369 if not self.__GetNextToken() or self.__Token.startswith('['):
1370 raise Warning("expected MACRO value", self.FileName, self.CurrentLineNumber)
1371 Value = self.__Token
1372
1373 return False
1374
1375 ## __GetFd() method
1376 #
1377 # Get FD section contents and store its data into FD dictionary of self.Profile
1378 #
1379 # @param self The object pointer
1380 # @retval True Successfully find a FD
1381 # @retval False Not able to find a FD
1382 #
1383 def __GetFd(self):
1384
1385 if not self.__GetNextToken():
1386 return False
1387
1388 S = self.__Token.upper()
1389 if S.startswith("[") and not S.startswith("[FD."):
1390 if not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \
1391 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
1392 raise Warning("Unknown section", self.FileName, self.CurrentLineNumber)
1393 self.__UndoToken()
1394 return False
1395
1396 self.__UndoToken()
1397 if not self.__IsToken("[FD.", True):
1398 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1399 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1400 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1401 raise Warning("expected [FD.]", self.FileName, self.CurrentLineNumber)
1402
1403 FdName = self.__GetUiName()
1404 if FdName == "":
1405 if len (self.Profile.FdDict) == 0:
1406 FdName = GenFdsGlobalVariable.PlatformName
1407 if FdName == "" and GlobalData.gActivePlatform:
1408 FdName = GlobalData.gActivePlatform.PlatformName
1409 self.Profile.FdNameNotSet = True
1410 else:
1411 raise Warning("expected FdName in [FD.] section", self.FileName, self.CurrentLineNumber)
1412 self.CurrentFdName = FdName.upper()
1413
1414 if self.CurrentFdName in self.Profile.FdDict:
1415 raise Warning("Unexpected the same FD name", self.FileName, self.CurrentLineNumber)
1416
1417 if not self.__IsToken( "]"):
1418 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
1419
1420 FdObj = Fd.FD()
1421 FdObj.FdUiName = self.CurrentFdName
1422 self.Profile.FdDict[self.CurrentFdName] = FdObj
1423
1424 if len (self.Profile.FdDict) > 1 and self.Profile.FdNameNotSet:
1425 raise Warning("expected all FDs have their name", self.FileName, self.CurrentLineNumber)
1426
1427 Status = self.__GetCreateFile(FdObj)
1428 if not Status:
1429 raise Warning("FD name error", self.FileName, self.CurrentLineNumber)
1430
1431 while self.__GetTokenStatements(FdObj):
1432 pass
1433 for Attr in ("BaseAddress", "Size", "ErasePolarity"):
1434 if getattr(FdObj, Attr) == None:
1435 self.__GetNextToken()
1436 raise Warning("Keyword %s missing" % Attr, self.FileName, self.CurrentLineNumber)
1437
1438 if not FdObj.BlockSizeList:
1439 FdObj.BlockSizeList.append((1, FdObj.Size, None))
1440
1441 self.__GetDefineStatements(FdObj)
1442
1443 self.__GetSetStatements(FdObj)
1444
1445 if not self.__GetRegionLayout(FdObj):
1446 raise Warning("expected region layout", self.FileName, self.CurrentLineNumber)
1447
1448 while self.__GetRegionLayout(FdObj):
1449 pass
1450 return True
1451
1452 ## __GetUiName() method
1453 #
1454 # Return the UI name of a section
1455 #
1456 # @param self The object pointer
1457 # @retval FdName UI name
1458 #
1459 def __GetUiName(self):
1460 Name = ""
1461 if self.__GetNextWord():
1462 Name = self.__Token
1463
1464 return Name
1465
1466 ## __GetCreateFile() method
1467 #
1468 # Return the output file name of object
1469 #
1470 # @param self The object pointer
1471 # @param Obj object whose data will be stored in file
1472 # @retval FdName UI name
1473 #
1474 def __GetCreateFile(self, Obj):
1475
1476 if self.__IsKeyword( "CREATE_FILE"):
1477 if not self.__IsToken( "="):
1478 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1479
1480 if not self.__GetNextToken():
1481 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)
1482
1483 FileName = self.__Token
1484 Obj.CreateFileName = FileName
1485
1486 return True
1487
1488 ## __GetTokenStatements() method
1489 #
1490 # Get token statements
1491 #
1492 # @param self The object pointer
1493 # @param Obj for whom token statement is got
1494 #
1495 def __GetTokenStatements(self, Obj):
1496 if self.__IsKeyword( "BaseAddress"):
1497 if not self.__IsToken( "="):
1498 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1499
1500 if not self.__GetNextHexNumber():
1501 raise Warning("expected Hex base address", self.FileName, self.CurrentLineNumber)
1502
1503 Obj.BaseAddress = self.__Token
1504
1505 if self.__IsToken( "|"):
1506 pcdPair = self.__GetNextPcdName()
1507 Obj.BaseAddressPcd = pcdPair
1508 self.Profile.PcdDict[pcdPair] = Obj.BaseAddress
1509 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1510 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
1511 return True
1512
1513 if self.__IsKeyword( "Size"):
1514 if not self.__IsToken( "="):
1515 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1516
1517 if not self.__GetNextHexNumber():
1518 raise Warning("expected Hex size", self.FileName, self.CurrentLineNumber)
1519
1520 Size = self.__Token
1521 if self.__IsToken( "|"):
1522 pcdPair = self.__GetNextPcdName()
1523 Obj.SizePcd = pcdPair
1524 self.Profile.PcdDict[pcdPair] = Size
1525 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1526 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
1527 Obj.Size = long(Size, 0)
1528 return True
1529
1530 if self.__IsKeyword( "ErasePolarity"):
1531 if not self.__IsToken( "="):
1532 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1533
1534 if not self.__GetNextToken():
1535 raise Warning("expected Erase Polarity", self.FileName, self.CurrentLineNumber)
1536
1537 if self.__Token != "1" and self.__Token != "0":
1538 raise Warning("expected 1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber)
1539
1540 Obj.ErasePolarity = self.__Token
1541 return True
1542
1543 return self.__GetBlockStatements(Obj)
1544
1545 ## __GetAddressStatements() method
1546 #
1547 # Get address statements
1548 #
1549 # @param self The object pointer
1550 # @param Obj for whom address statement is got
1551 # @retval True Successfully find
1552 # @retval False Not able to find
1553 #
1554 def __GetAddressStatements(self, Obj):
1555
1556 if self.__IsKeyword("BsBaseAddress"):
1557 if not self.__IsToken( "="):
1558 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1559
1560 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
1561 raise Warning("expected address", self.FileName, self.CurrentLineNumber)
1562
1563 BsAddress = long(self.__Token, 0)
1564 Obj.BsBaseAddress = BsAddress
1565
1566 if self.__IsKeyword("RtBaseAddress"):
1567 if not self.__IsToken( "="):
1568 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1569
1570 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
1571 raise Warning("expected address", self.FileName, self.CurrentLineNumber)
1572
1573 RtAddress = long(self.__Token, 0)
1574 Obj.RtBaseAddress = RtAddress
1575
1576 ## __GetBlockStatements() method
1577 #
1578 # Get block statements
1579 #
1580 # @param self The object pointer
1581 # @param Obj for whom block statement is got
1582 #
1583 def __GetBlockStatements(self, Obj):
1584 IsBlock = False
1585 while self.__GetBlockStatement(Obj):
1586 IsBlock = True
1587
1588 Item = Obj.BlockSizeList[-1]
1589 if Item[0] == None or Item[1] == None:
1590 raise Warning("expected block statement", self.FileName, self.CurrentLineNumber)
1591 return IsBlock
1592
1593 ## __GetBlockStatement() method
1594 #
1595 # Get block statement
1596 #
1597 # @param self The object pointer
1598 # @param Obj for whom block statement is got
1599 # @retval True Successfully find
1600 # @retval False Not able to find
1601 #
1602 def __GetBlockStatement(self, Obj):
1603 if not self.__IsKeyword( "BlockSize"):
1604 return False
1605
1606 if not self.__IsToken( "="):
1607 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1608
1609 if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():
1610 raise Warning("expected Hex or Integer block size", self.FileName, self.CurrentLineNumber)
1611
1612 BlockSize = self.__Token
1613 BlockSizePcd = None
1614 if self.__IsToken( "|"):
1615 PcdPair = self.__GetNextPcdName()
1616 BlockSizePcd = PcdPair
1617 self.Profile.PcdDict[PcdPair] = BlockSize
1618 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1619 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
1620 BlockSize = long(BlockSize, 0)
1621
1622 BlockNumber = None
1623 if self.__IsKeyword( "NumBlocks"):
1624 if not self.__IsToken( "="):
1625 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1626
1627 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
1628 raise Warning("expected block numbers", self.FileName, self.CurrentLineNumber)
1629
1630 BlockNumber = long(self.__Token, 0)
1631
1632 Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd))
1633 return True
1634
1635 ## __GetDefineStatements() method
1636 #
1637 # Get define statements
1638 #
1639 # @param self The object pointer
1640 # @param Obj for whom define statement is got
1641 # @retval True Successfully find
1642 # @retval False Not able to find
1643 #
1644 def __GetDefineStatements(self, Obj):
1645 while self.__GetDefineStatement( Obj):
1646 pass
1647
1648 ## __GetDefineStatement() method
1649 #
1650 # Get define statement
1651 #
1652 # @param self The object pointer
1653 # @param Obj for whom define statement is got
1654 # @retval True Successfully find
1655 # @retval False Not able to find
1656 #
1657 def __GetDefineStatement(self, Obj):
1658 if self.__IsKeyword("DEFINE"):
1659 self.__GetNextToken()
1660 Macro = self.__Token
1661 if not self.__IsToken( "="):
1662 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1663
1664 if not self.__GetNextToken():
1665 raise Warning("expected value", self.FileName, self.CurrentLineNumber)
1666
1667 Value = self.__Token
1668 Macro = '$(' + Macro + ')'
1669 Obj.DefineVarDict[Macro] = Value
1670 return True
1671
1672 return False
1673
1674 ## __GetSetStatements() method
1675 #
1676 # Get set statements
1677 #
1678 # @param self The object pointer
1679 # @param Obj for whom set statement is got
1680 # @retval True Successfully find
1681 # @retval False Not able to find
1682 #
1683 def __GetSetStatements(self, Obj):
1684 while self.__GetSetStatement(Obj):
1685 pass
1686
1687 ## __GetSetStatement() method
1688 #
1689 # Get set statement
1690 #
1691 # @param self The object pointer
1692 # @param Obj for whom set statement is got
1693 # @retval True Successfully find
1694 # @retval False Not able to find
1695 #
1696 def __GetSetStatement(self, Obj):
1697 if self.__IsKeyword("SET"):
1698 PcdPair = self.__GetNextPcdName()
1699
1700 if not self.__IsToken( "="):
1701 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1702
1703 Value = self.__GetExpression()
1704 Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)
1705
1706 if Obj:
1707 Obj.SetVarDict[PcdPair] = Value
1708 self.Profile.PcdDict[PcdPair] = Value
1709 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1710 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
1711 return True
1712
1713 return False
1714
1715 ## __CalcRegionExpr(self)
1716 #
1717 # Calculate expression for offset or size of a region
1718 #
1719 # @return: None if invalid expression
1720 # Calculated number if successfully
1721 #
1722 def __CalcRegionExpr(self):
1723 StartPos = self.GetFileBufferPos()
1724 Expr = ''
1725 PairCount = 0
1726 while not self.__EndOfFile():
1727 CurCh = self.__CurrentChar()
1728 if CurCh == '(':
1729 PairCount += 1
1730 elif CurCh == ')':
1731 PairCount -= 1
1732
1733 if CurCh in '|\r\n' and PairCount == 0:
1734 break
1735 Expr += CurCh
1736 self.__GetOneChar()
1737 try:
1738 return long(
1739 ValueExpression(Expr,
1740 self.__CollectMacroPcd()
1741 )(True),0)
1742 except Exception:
1743 self.SetFileBufferPos(StartPos)
1744 return None
1745
1746 ## __GetRegionLayout() method
1747 #
1748 # Get region layout for FD
1749 #
1750 # @param self The object pointer
1751 # @param Fd for whom region is got
1752 # @retval True Successfully find
1753 # @retval False Not able to find
1754 #
1755 def __GetRegionLayout(self, Fd):
1756 Offset = self.__CalcRegionExpr()
1757 if Offset == None:
1758 return False
1759
1760 RegionObj = Region.Region()
1761 RegionObj.Offset = Offset
1762 Fd.RegionList.append(RegionObj)
1763
1764 if not self.__IsToken( "|"):
1765 raise Warning("expected '|'", self.FileName, self.CurrentLineNumber)
1766
1767 Size = self.__CalcRegionExpr()
1768 if Size == None:
1769 raise Warning("expected Region Size", self.FileName, self.CurrentLineNumber)
1770 RegionObj.Size = Size
1771
1772 if not self.__GetNextWord():
1773 return True
1774
1775 if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE"):
1776 #
1777 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]
1778 # Or it might be next region's offset described by an expression which starts with a PCD.
1779 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size
1780 #
1781 self.__UndoToken()
1782 IsRegionPcd = (RegionSizeGuidPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]) or
1783 RegionOffsetPcdPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]))
1784 if IsRegionPcd:
1785 RegionObj.PcdOffset = self.__GetNextPcdName()
1786 self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0))
1787 self.__PcdDict['%s.%s' % (RegionObj.PcdOffset[1], RegionObj.PcdOffset[0])] = "0x%x" % RegionObj.Offset
1788 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1789 self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple
1790 if self.__IsToken( "|"):
1791 RegionObj.PcdSize = self.__GetNextPcdName()
1792 self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size
1793 self.__PcdDict['%s.%s' % (RegionObj.PcdSize[1], RegionObj.PcdSize[0])] = "0x%x" % RegionObj.Size
1794 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1795 self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple
1796
1797 if not self.__GetNextWord():
1798 return True
1799
1800 if self.__Token == "SET":
1801 self.__UndoToken()
1802 self.__GetSetStatements( RegionObj)
1803 if not self.__GetNextWord():
1804 return True
1805
1806 elif self.__Token == "FV":
1807 self.__UndoToken()
1808 self.__GetRegionFvType( RegionObj)
1809
1810 elif self.__Token == "CAPSULE":
1811 self.__UndoToken()
1812 self.__GetRegionCapType( RegionObj)
1813
1814 elif self.__Token == "FILE":
1815 self.__UndoToken()
1816 self.__GetRegionFileType( RegionObj)
1817
1818 elif self.__Token == "DATA":
1819 self.__UndoToken()
1820 self.__GetRegionDataType( RegionObj)
1821 else:
1822 self.__UndoToken()
1823 if self.__GetRegionLayout(Fd):
1824 return True
1825 raise Warning("A valid region type was not found. "
1826 "Valid types are [SET, FV, CAPSULE, FILE, DATA]. This error occurred",
1827 self.FileName, self.CurrentLineNumber)
1828
1829 return True
1830
1831 ## __GetRegionFvType() method
1832 #
1833 # Get region fv data for region
1834 #
1835 # @param self The object pointer
1836 # @param RegionObj for whom region data is got
1837 #
1838 def __GetRegionFvType(self, RegionObj):
1839
1840 if not self.__IsKeyword( "FV"):
1841 raise Warning("expected Keyword 'FV'", self.FileName, self.CurrentLineNumber)
1842
1843 if not self.__IsToken( "="):
1844 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1845
1846 if not self.__GetNextToken():
1847 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
1848
1849 RegionObj.RegionType = "FV"
1850 RegionObj.RegionDataList.append(self.__Token)
1851
1852 while self.__IsKeyword( "FV"):
1853
1854 if not self.__IsToken( "="):
1855 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1856
1857 if not self.__GetNextToken():
1858 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
1859
1860 RegionObj.RegionDataList.append(self.__Token)
1861
1862 ## __GetRegionCapType() method
1863 #
1864 # Get region capsule data for region
1865 #
1866 # @param self The object pointer
1867 # @param RegionObj for whom region data is got
1868 #
1869 def __GetRegionCapType(self, RegionObj):
1870
1871 if not self.__IsKeyword("CAPSULE"):
1872 raise Warning("expected Keyword 'CAPSULE'", self.FileName, self.CurrentLineNumber)
1873
1874 if not self.__IsToken("="):
1875 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1876
1877 if not self.__GetNextToken():
1878 raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)
1879
1880 RegionObj.RegionType = "CAPSULE"
1881 RegionObj.RegionDataList.append(self.__Token)
1882
1883 while self.__IsKeyword("CAPSULE"):
1884
1885 if not self.__IsToken("="):
1886 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1887
1888 if not self.__GetNextToken():
1889 raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)
1890
1891 RegionObj.RegionDataList.append(self.__Token)
1892
1893 ## __GetRegionFileType() method
1894 #
1895 # Get region file data for region
1896 #
1897 # @param self The object pointer
1898 # @param RegionObj for whom region data is got
1899 #
1900 def __GetRegionFileType(self, RegionObj):
1901
1902 if not self.__IsKeyword( "FILE"):
1903 raise Warning("expected Keyword 'FILE'", self.FileName, self.CurrentLineNumber)
1904
1905 if not self.__IsToken( "="):
1906 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1907
1908 if not self.__GetNextToken():
1909 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)
1910
1911 RegionObj.RegionType = "FILE"
1912 RegionObj.RegionDataList.append( self.__Token)
1913
1914 while self.__IsKeyword( "FILE"):
1915
1916 if not self.__IsToken( "="):
1917 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1918
1919 if not self.__GetNextToken():
1920 raise Warning("expected FILE name", self.FileName, self.CurrentLineNumber)
1921
1922 RegionObj.RegionDataList.append(self.__Token)
1923
1924 ## __GetRegionDataType() method
1925 #
1926 # Get region array data for region
1927 #
1928 # @param self The object pointer
1929 # @param RegionObj for whom region data is got
1930 #
1931 def __GetRegionDataType(self, RegionObj):
1932
1933 if not self.__IsKeyword( "DATA"):
1934 raise Warning("expected Region Data type", self.FileName, self.CurrentLineNumber)
1935
1936 if not self.__IsToken( "="):
1937 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1938
1939 if not self.__IsToken( "{"):
1940 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
1941
1942 if not self.__GetNextHexNumber():
1943 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)
1944
1945 if len(self.__Token) > 18:
1946 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)
1947
1948 # convert hex string value to byte hex string array
1949 AllString = self.__Token
1950 AllStrLen = len (AllString)
1951 DataString = ""
1952 while AllStrLen > 4:
1953 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + ","
1954 AllStrLen = AllStrLen - 2
1955 DataString = DataString + AllString[:AllStrLen] + ","
1956
1957 # byte value array
1958 if len (self.__Token) <= 4:
1959 while self.__IsToken(","):
1960 if not self.__GetNextHexNumber():
1961 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
1962 if len(self.__Token) > 4:
1963 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
1964 DataString += self.__Token
1965 DataString += ","
1966
1967 if not self.__IsToken( "}"):
1968 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
1969
1970 DataString = DataString.rstrip(",")
1971 RegionObj.RegionType = "DATA"
1972 RegionObj.RegionDataList.append( DataString)
1973
1974 while self.__IsKeyword( "DATA"):
1975
1976 if not self.__IsToken( "="):
1977 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1978
1979 if not self.__IsToken( "{"):
1980 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
1981
1982 if not self.__GetNextHexNumber():
1983 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)
1984
1985 if len(self.__Token) > 18:
1986 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)
1987
1988 # convert hex string value to byte hex string array
1989 AllString = self.__Token
1990 AllStrLen = len (AllString)
1991 DataString = ""
1992 while AllStrLen > 4:
1993 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + ","
1994 AllStrLen = AllStrLen - 2
1995 DataString = DataString + AllString[:AllStrLen] + ","
1996
1997 # byte value array
1998 if len (self.__Token) <= 4:
1999 while self.__IsToken(","):
2000 if not self.__GetNextHexNumber():
2001 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
2002 if len(self.__Token) > 4:
2003 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
2004 DataString += self.__Token
2005 DataString += ","
2006
2007 if not self.__IsToken( "}"):
2008 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2009
2010 DataString = DataString.rstrip(",")
2011 RegionObj.RegionDataList.append( DataString)
2012
2013 ## __GetFv() method
2014 #
2015 # Get FV section contents and store its data into FV dictionary of self.Profile
2016 #
2017 # @param self The object pointer
2018 # @retval True Successfully find a FV
2019 # @retval False Not able to find a FV
2020 #
2021 def __GetFv(self):
2022 if not self.__GetNextToken():
2023 return False
2024
2025 S = self.__Token.upper()
2026 if S.startswith("[") and not S.startswith("[FV."):
2027 if not S.startswith("[CAPSULE.") \
2028 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
2029 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
2030 self.__UndoToken()
2031 return False
2032
2033 self.__UndoToken()
2034 if not self.__IsToken("[FV.", True):
2035 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
2036 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2037 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2038 raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2039
2040 FvName = self.__GetUiName()
2041 self.CurrentFvName = FvName.upper()
2042
2043 if not self.__IsToken( "]"):
2044 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
2045
2046 FvObj = Fv.FV()
2047 FvObj.UiFvName = self.CurrentFvName
2048 self.Profile.FvDict[self.CurrentFvName] = FvObj
2049
2050 Status = self.__GetCreateFile(FvObj)
2051 if not Status:
2052 raise Warning("FV name error", self.FileName, self.CurrentLineNumber)
2053
2054 self.__GetDefineStatements(FvObj)
2055
2056 self.__GetAddressStatements(FvObj)
2057
2058 FvObj.FvExtEntryTypeValue = []
2059 FvObj.FvExtEntryType = []
2060 FvObj.FvExtEntryData = []
2061 while True:
2062 self.__GetSetStatements(FvObj)
2063
2064 if not (self.__GetBlockStatement(FvObj) or self.__GetFvBaseAddress(FvObj) or
2065 self.__GetFvForceRebase(FvObj) or self.__GetFvAlignment(FvObj) or
2066 self.__GetFvAttributes(FvObj) or self.__GetFvNameGuid(FvObj) or
2067 self.__GetFvExtEntryStatement(FvObj)):
2068 break
2069
2070 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())
2071 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())
2072
2073 while True:
2074 isInf = self.__GetInfStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())
2075 isFile = self.__GetFileStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())
2076 if not isInf and not isFile:
2077 break
2078
2079 return True
2080
2081 ## __GetFvAlignment() method
2082 #
2083 # Get alignment for FV
2084 #
2085 # @param self The object pointer
2086 # @param Obj for whom alignment is got
2087 # @retval True Successfully find a alignment statement
2088 # @retval False Not able to find a alignment statement
2089 #
2090 def __GetFvAlignment(self, Obj):
2091
2092 if not self.__IsKeyword( "FvAlignment"):
2093 return False
2094
2095 if not self.__IsToken( "="):
2096 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2097
2098 if not self.__GetNextToken():
2099 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)
2100
2101 if self.__Token.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
2102 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
2103 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
2104 "1G", "2G"):
2105 raise Warning("Unknown alignment value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2106 Obj.FvAlignment = self.__Token
2107 return True
2108
2109 ## __GetFvBaseAddress() method
2110 #
2111 # Get BaseAddress for FV
2112 #
2113 # @param self The object pointer
2114 # @param Obj for whom FvBaseAddress is got
2115 # @retval True Successfully find a FvBaseAddress statement
2116 # @retval False Not able to find a FvBaseAddress statement
2117 #
2118 def __GetFvBaseAddress(self, Obj):
2119
2120 if not self.__IsKeyword("FvBaseAddress"):
2121 return False
2122
2123 if not self.__IsToken( "="):
2124 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2125
2126 if not self.__GetNextToken():
2127 raise Warning("expected FV base address value", self.FileName, self.CurrentLineNumber)
2128
2129 IsValidBaseAddrValue = re.compile('^0[x|X][0-9a-fA-F]+')
2130
2131 if not IsValidBaseAddrValue.match(self.__Token.upper()):
2132 raise Warning("Unknown FV base address value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2133 Obj.FvBaseAddress = self.__Token
2134 return True
2135
2136 ## __GetFvForceRebase() method
2137 #
2138 # Get FvForceRebase for FV
2139 #
2140 # @param self The object pointer
2141 # @param Obj for whom FvForceRebase is got
2142 # @retval True Successfully find a FvForceRebase statement
2143 # @retval False Not able to find a FvForceRebase statement
2144 #
2145 def __GetFvForceRebase(self, Obj):
2146
2147 if not self.__IsKeyword("FvForceRebase"):
2148 return False
2149
2150 if not self.__IsToken( "="):
2151 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2152
2153 if not self.__GetNextToken():
2154 raise Warning("expected FvForceRebase value", self.FileName, self.CurrentLineNumber)
2155
2156 if self.__Token.upper() not in ["TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"]:
2157 raise Warning("Unknown FvForceRebase value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2158
2159 if self.__Token.upper() in ["TRUE", "1", "0X1", "0X01"]:
2160 Obj.FvForceRebase = True
2161 elif self.__Token.upper() in ["FALSE", "0", "0X0", "0X00"]:
2162 Obj.FvForceRebase = False
2163 else:
2164 Obj.FvForceRebase = None
2165
2166 return True
2167
2168
2169 ## __GetFvAttributes() method
2170 #
2171 # Get attributes for FV
2172 #
2173 # @param self The object pointer
2174 # @param Obj for whom attribute is got
2175 # @retval None
2176 #
2177 def __GetFvAttributes(self, FvObj):
2178 IsWordToken = False
2179 while self.__GetNextWord():
2180 IsWordToken = True
2181 name = self.__Token
2182 if name not in ("ERASE_POLARITY", "MEMORY_MAPPED", \
2183 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
2184 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
2185 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
2186 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
2187 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT"):
2188 self.__UndoToken()
2189 return False
2190
2191 if not self.__IsToken( "="):
2192 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2193
2194 if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
2195 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)
2196
2197 FvObj.FvAttributeDict[name] = self.__Token
2198
2199 return IsWordToken
2200
2201 ## __GetFvNameGuid() method
2202 #
2203 # Get FV GUID for FV
2204 #
2205 # @param self The object pointer
2206 # @param Obj for whom GUID is got
2207 # @retval None
2208 #
2209 def __GetFvNameGuid(self, FvObj):
2210
2211 if not self.__IsKeyword( "FvNameGuid"):
2212 return False
2213
2214 if not self.__IsToken( "="):
2215 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2216
2217 if not self.__GetNextGuid():
2218 raise Warning("expected FV GUID value", self.FileName, self.CurrentLineNumber)
2219
2220 FvObj.FvNameGuid = self.__Token
2221
2222 return True
2223
2224 def __GetFvExtEntryStatement(self, FvObj):
2225
2226 if not self.__IsKeyword( "FV_EXT_ENTRY"):
2227 return False
2228
2229 if not self.__IsKeyword ("TYPE"):
2230 raise Warning("expected 'TYPE'", self.FileName, self.CurrentLineNumber)
2231
2232 if not self.__IsToken( "="):
2233 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2234
2235 if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():
2236 raise Warning("expected Hex FV extension entry type value At Line ", self.FileName, self.CurrentLineNumber)
2237
2238 FvObj.FvExtEntryTypeValue += [self.__Token]
2239
2240 if not self.__IsToken( "{"):
2241 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2242
2243 if not self.__IsKeyword ("FILE") and not self.__IsKeyword ("DATA"):
2244 raise Warning("expected 'FILE' or 'DATA'", self.FileName, self.CurrentLineNumber)
2245
2246 FvObj.FvExtEntryType += [self.__Token]
2247
2248 if self.__Token == 'DATA':
2249
2250 if not self.__IsToken( "="):
2251 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2252
2253 if not self.__IsToken( "{"):
2254 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2255
2256 if not self.__GetNextHexNumber():
2257 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)
2258
2259 if len(self.__Token) > 4:
2260 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
2261
2262 DataString = self.__Token
2263 DataString += ","
2264
2265 while self.__IsToken(","):
2266 if not self.__GetNextHexNumber():
2267 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
2268 if len(self.__Token) > 4:
2269 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
2270 DataString += self.__Token
2271 DataString += ","
2272
2273 if not self.__IsToken( "}"):
2274 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2275
2276 if not self.__IsToken( "}"):
2277 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2278
2279 DataString = DataString.rstrip(",")
2280 FvObj.FvExtEntryData += [DataString]
2281
2282 if self.__Token == 'FILE':
2283
2284 if not self.__IsToken( "="):
2285 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2286
2287 if not self.__GetNextToken():
2288 raise Warning("expected FV Extension Entry file path At Line ", self.FileName, self.CurrentLineNumber)
2289
2290 FvObj.FvExtEntryData += [self.__Token]
2291
2292 if not self.__IsToken( "}"):
2293 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2294
2295 return True
2296
2297 ## __GetAprioriSection() method
2298 #
2299 # Get token statements
2300 #
2301 # @param self The object pointer
2302 # @param FvObj for whom apriori is got
2303 # @param MacroDict dictionary used to replace macro
2304 # @retval True Successfully find apriori statement
2305 # @retval False Not able to find apriori statement
2306 #
2307 def __GetAprioriSection(self, FvObj, MacroDict = {}):
2308
2309 if not self.__IsKeyword( "APRIORI"):
2310 return False
2311
2312 if not self.__IsKeyword("PEI") and not self.__IsKeyword("DXE"):
2313 raise Warning("expected Apriori file type", self.FileName, self.CurrentLineNumber)
2314 AprType = self.__Token
2315
2316 if not self.__IsToken( "{"):
2317 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2318
2319 AprSectionObj = AprioriSection.AprioriSection()
2320 AprSectionObj.AprioriType = AprType
2321
2322 self.__GetDefineStatements(AprSectionObj)
2323 MacroDict.update(AprSectionObj.DefineVarDict)
2324
2325 while True:
2326 IsInf = self.__GetInfStatement( AprSectionObj, MacroDict = MacroDict)
2327 IsFile = self.__GetFileStatement( AprSectionObj)
2328 if not IsInf and not IsFile:
2329 break
2330
2331 if not self.__IsToken( "}"):
2332 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2333
2334 FvObj.AprioriSectionList.append(AprSectionObj)
2335 return True
2336
2337 ## __GetInfStatement() method
2338 #
2339 # Get INF statements
2340 #
2341 # @param self The object pointer
2342 # @param Obj for whom inf statement is got
2343 # @param MacroDict dictionary used to replace macro
2344 # @retval True Successfully find inf statement
2345 # @retval False Not able to find inf statement
2346 #
2347 def __GetInfStatement(self, Obj, ForCapsule = False, MacroDict = {}):
2348
2349 if not self.__IsKeyword( "INF"):
2350 return False
2351
2352 ffsInf = FfsInfStatement.FfsInfStatement()
2353 self.__GetInfOptions( ffsInf)
2354
2355 if not self.__GetNextToken():
2356 raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)
2357 ffsInf.InfFileName = self.__Token
2358
2359 ffsInf.CurrentLineNum = self.CurrentLineNumber
2360 ffsInf.CurrentLineContent = self.__CurrentLine()
2361
2362 #Replace $(SAPCE) with real space
2363 ffsInf.InfFileName = ffsInf.InfFileName.replace('$(SPACE)', ' ')
2364
2365 if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:
2366 #do case sensitive check for file path
2367 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
2368 if ErrorCode != 0:
2369 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
2370
2371 if not ffsInf.InfFileName in self.Profile.InfList:
2372 self.Profile.InfList.append(ffsInf.InfFileName)
2373 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
2374 self.Profile.InfFileLineList.append(FileLineTuple)
2375
2376 if self.__IsToken('|'):
2377 if self.__IsKeyword('RELOCS_STRIPPED'):
2378 ffsInf.KeepReloc = False
2379 elif self.__IsKeyword('RELOCS_RETAINED'):
2380 ffsInf.KeepReloc = True
2381 else:
2382 raise Warning("Unknown reloc strip flag '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2383
2384 if ForCapsule:
2385 capsuleFfs = CapsuleData.CapsuleFfs()
2386 capsuleFfs.Ffs = ffsInf
2387 Obj.CapsuleDataList.append(capsuleFfs)
2388 else:
2389 Obj.FfsList.append(ffsInf)
2390 return True
2391
2392 ## __GetInfOptions() method
2393 #
2394 # Get options for INF
2395 #
2396 # @param self The object pointer
2397 # @param FfsInfObj for whom option is got
2398 #
2399 def __GetInfOptions(self, FfsInfObj):
2400 if self.__IsKeyword("FILE_GUID"):
2401 if not self.__IsToken("="):
2402 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2403 if not self.__GetNextGuid():
2404 raise Warning("expected GUID value", self.FileName, self.CurrentLineNumber)
2405 FfsInfObj.OverrideGuid = self.__Token
2406
2407 if self.__IsKeyword( "RuleOverride"):
2408 if not self.__IsToken( "="):
2409 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2410 if not self.__GetNextToken():
2411 raise Warning("expected Rule name", self.FileName, self.CurrentLineNumber)
2412 FfsInfObj.Rule = self.__Token
2413
2414 if self.__IsKeyword( "VERSION"):
2415 if not self.__IsToken( "="):
2416 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2417 if not self.__GetNextToken():
2418 raise Warning("expected Version", self.FileName, self.CurrentLineNumber)
2419
2420 if self.__GetStringData():
2421 FfsInfObj.Version = self.__Token
2422
2423 if self.__IsKeyword( "UI"):
2424 if not self.__IsToken( "="):
2425 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2426 if not self.__GetNextToken():
2427 raise Warning("expected UI name", self.FileName, self.CurrentLineNumber)
2428
2429 if self.__GetStringData():
2430 FfsInfObj.Ui = self.__Token
2431
2432 if self.__IsKeyword( "USE"):
2433 if not self.__IsToken( "="):
2434 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2435 if not self.__GetNextToken():
2436 raise Warning("expected ARCH name", self.FileName, self.CurrentLineNumber)
2437 FfsInfObj.UseArch = self.__Token
2438
2439
2440 if self.__GetNextToken():
2441 p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
2442 if p.match(self.__Token) and p.match(self.__Token).span()[1] == len(self.__Token):
2443 FfsInfObj.KeyStringList.append(self.__Token)
2444 if not self.__IsToken(","):
2445 return
2446 else:
2447 self.__UndoToken()
2448 return
2449
2450 while self.__GetNextToken():
2451 if not p.match(self.__Token):
2452 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
2453 FfsInfObj.KeyStringList.append(self.__Token)
2454
2455 if not self.__IsToken(","):
2456 break
2457
2458 ## __GetFileStatement() method
2459 #
2460 # Get FILE statements
2461 #
2462 # @param self The object pointer
2463 # @param Obj for whom FILE statement is got
2464 # @param MacroDict dictionary used to replace macro
2465 # @retval True Successfully find FILE statement
2466 # @retval False Not able to find FILE statement
2467 #
2468 def __GetFileStatement(self, Obj, ForCapsule = False, MacroDict = {}):
2469
2470 if not self.__IsKeyword( "FILE"):
2471 return False
2472
2473 if not self.__GetNextWord():
2474 raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)
2475
2476 if ForCapsule and self.__Token == 'DATA':
2477 self.__UndoToken()
2478 self.__UndoToken()
2479 return False
2480
2481 FfsFileObj = FfsFileStatement.FileStatement()
2482 FfsFileObj.FvFileType = self.__Token
2483
2484 if not self.__IsToken( "="):
2485 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2486
2487 if not self.__GetNextGuid():
2488 if not self.__GetNextWord():
2489 raise Warning("expected File GUID", self.FileName, self.CurrentLineNumber)
2490 if self.__Token == 'PCD':
2491 if not self.__IsToken( "("):
2492 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
2493 PcdPair = self.__GetNextPcdName()
2494 if not self.__IsToken( ")"):
2495 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
2496 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
2497
2498 FfsFileObj.NameGuid = self.__Token
2499
2500 self.__GetFilePart( FfsFileObj, MacroDict.copy())
2501
2502 if ForCapsule:
2503 capsuleFfs = CapsuleData.CapsuleFfs()
2504 capsuleFfs.Ffs = FfsFileObj
2505 Obj.CapsuleDataList.append(capsuleFfs)
2506 else:
2507 Obj.FfsList.append(FfsFileObj)
2508
2509 return True
2510
2511 ## __FileCouldHaveRelocFlag() method
2512 #
2513 # Check whether reloc strip flag can be set for a file type.
2514 #
2515 # @param self The object pointer
2516 # @param FileType The file type to check with
2517 # @retval True This type could have relocation strip flag
2518 # @retval False No way to have it
2519 #
2520
2521 def __FileCouldHaveRelocFlag (self, FileType):
2522 if FileType in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'):
2523 return True
2524 else:
2525 return False
2526
2527 ## __SectionCouldHaveRelocFlag() method
2528 #
2529 # Check whether reloc strip flag can be set for a section type.
2530 #
2531 # @param self The object pointer
2532 # @param SectionType The section type to check with
2533 # @retval True This type could have relocation strip flag
2534 # @retval False No way to have it
2535 #
2536
2537 def __SectionCouldHaveRelocFlag (self, SectionType):
2538 if SectionType in ('TE', 'PE32'):
2539 return True
2540 else:
2541 return False
2542
2543 ## __GetFilePart() method
2544 #
2545 # Get components for FILE statement
2546 #
2547 # @param self The object pointer
2548 # @param FfsFileObj for whom component is got
2549 # @param MacroDict dictionary used to replace macro
2550 #
2551 def __GetFilePart(self, FfsFileObj, MacroDict = {}):
2552
2553 self.__GetFileOpts( FfsFileObj)
2554
2555 if not self.__IsToken("{"):
2556 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
2557 if self.__FileCouldHaveRelocFlag(FfsFileObj.FvFileType):
2558 if self.__Token == 'RELOCS_STRIPPED':
2559 FfsFileObj.KeepReloc = False
2560 else:
2561 FfsFileObj.KeepReloc = True
2562 else:
2563 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
2564
2565 if not self.__IsToken("{"):
2566 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2567
2568 if not self.__GetNextToken():
2569 raise Warning("expected File name or section data", self.FileName, self.CurrentLineNumber)
2570
2571 if self.__Token == "FV":
2572 if not self.__IsToken( "="):
2573 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2574 if not self.__GetNextToken():
2575 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
2576 FfsFileObj.FvName = self.__Token
2577
2578 elif self.__Token == "FD":
2579 if not self.__IsToken( "="):
2580 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2581 if not self.__GetNextToken():
2582 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)
2583 FfsFileObj.FdName = self.__Token
2584
2585 elif self.__Token in ("DEFINE", "APRIORI", "SECTION"):
2586 self.__UndoToken()
2587 self.__GetSectionData( FfsFileObj, MacroDict)
2588 else:
2589 FfsFileObj.CurrentLineNum = self.CurrentLineNumber
2590 FfsFileObj.CurrentLineContent = self.__CurrentLine()
2591 FfsFileObj.FileName = self.__Token.replace('$(SPACE)', ' ')
2592 self.__VerifyFile(FfsFileObj.FileName)
2593
2594 if not self.__IsToken( "}"):
2595 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2596
2597 ## __GetFileOpts() method
2598 #
2599 # Get options for FILE statement
2600 #
2601 # @param self The object pointer
2602 # @param FfsFileObj for whom options is got
2603 #
2604 def __GetFileOpts(self, FfsFileObj):
2605
2606 if self.__GetNextToken():
2607 Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
2608 if Pattern.match(self.__Token):
2609 FfsFileObj.KeyStringList.append(self.__Token)
2610 if self.__IsToken(","):
2611 while self.__GetNextToken():
2612 if not Pattern.match(self.__Token):
2613 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
2614 FfsFileObj.KeyStringList.append(self.__Token)
2615
2616 if not self.__IsToken(","):
2617 break
2618
2619 else:
2620 self.__UndoToken()
2621
2622 if self.__IsKeyword( "FIXED", True):
2623 FfsFileObj.Fixed = True
2624
2625 if self.__IsKeyword( "CHECKSUM", True):
2626 FfsFileObj.CheckSum = True
2627
2628 if self.__GetAlignment():
2629 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2630 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2631 #For FFS, Auto is default option same to ""
2632 if not self.__Token == "Auto":
2633 FfsFileObj.Alignment = self.__Token
2634
2635 ## __GetAlignment() method
2636 #
2637 # Return the alignment value
2638 #
2639 # @param self The object pointer
2640 # @retval True Successfully find alignment
2641 # @retval False Not able to find alignment
2642 #
2643 def __GetAlignment(self):
2644 if self.__IsKeyword( "Align", True):
2645 if not self.__IsToken( "="):
2646 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2647
2648 if not self.__GetNextToken():
2649 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)
2650 return True
2651
2652 return False
2653
2654 ## __GetFilePart() method
2655 #
2656 # Get section data for FILE statement
2657 #
2658 # @param self The object pointer
2659 # @param FfsFileObj for whom section is got
2660 # @param MacroDict dictionary used to replace macro
2661 #
2662 def __GetSectionData(self, FfsFileObj, MacroDict = {}):
2663 Dict = {}
2664 Dict.update(MacroDict)
2665
2666 self.__GetDefineStatements(FfsFileObj)
2667
2668 Dict.update(FfsFileObj.DefineVarDict)
2669 self.__GetAprioriSection(FfsFileObj, Dict.copy())
2670 self.__GetAprioriSection(FfsFileObj, Dict.copy())
2671
2672 while True:
2673 IsLeafSection = self.__GetLeafSection(FfsFileObj, Dict)
2674 IsEncapSection = self.__GetEncapsulationSec(FfsFileObj)
2675 if not IsLeafSection and not IsEncapSection:
2676 break
2677
2678 ## __GetLeafSection() method
2679 #
2680 # Get leaf section for Obj
2681 #
2682 # @param self The object pointer
2683 # @param Obj for whom leaf section is got
2684 # @param MacroDict dictionary used to replace macro
2685 # @retval True Successfully find section statement
2686 # @retval False Not able to find section statement
2687 #
2688 def __GetLeafSection(self, Obj, MacroDict = {}):
2689
2690 OldPos = self.GetFileBufferPos()
2691
2692 if not self.__IsKeyword( "SECTION"):
2693 if len(Obj.SectionList) == 0:
2694 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)
2695 else:
2696 return False
2697
2698 AlignValue = None
2699 if self.__GetAlignment():
2700 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2701 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2702 AlignValue = self.__Token
2703
2704 BuildNum = None
2705 if self.__IsKeyword( "BUILD_NUM"):
2706 if not self.__IsToken( "="):
2707 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2708
2709 if not self.__GetNextToken():
2710 raise Warning("expected Build number value", self.FileName, self.CurrentLineNumber)
2711
2712 BuildNum = self.__Token
2713
2714 if self.__IsKeyword( "VERSION"):
2715 if AlignValue == 'Auto':
2716 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2717 if not self.__IsToken( "="):
2718 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2719 if not self.__GetNextToken():
2720 raise Warning("expected version", self.FileName, self.CurrentLineNumber)
2721 VerSectionObj = VerSection.VerSection()
2722 VerSectionObj.Alignment = AlignValue
2723 VerSectionObj.BuildNum = BuildNum
2724 if self.__GetStringData():
2725 VerSectionObj.StringData = self.__Token
2726 else:
2727 VerSectionObj.FileName = self.__Token
2728 Obj.SectionList.append(VerSectionObj)
2729
2730 elif self.__IsKeyword( "UI"):
2731 if AlignValue == 'Auto':
2732 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2733 if not self.__IsToken( "="):
2734 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2735 if not self.__GetNextToken():
2736 raise Warning("expected UI", self.FileName, self.CurrentLineNumber)
2737 UiSectionObj = UiSection.UiSection()
2738 UiSectionObj.Alignment = AlignValue
2739 if self.__GetStringData():
2740 UiSectionObj.StringData = self.__Token
2741 else:
2742 UiSectionObj.FileName = self.__Token
2743 Obj.SectionList.append(UiSectionObj)
2744
2745 elif self.__IsKeyword( "FV_IMAGE"):
2746 if AlignValue == 'Auto':
2747 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2748 if not self.__IsToken( "="):
2749 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2750 if not self.__GetNextToken():
2751 raise Warning("expected FV name or FV file path", self.FileName, self.CurrentLineNumber)
2752
2753 FvName = self.__Token
2754 FvObj = None
2755
2756 if self.__IsToken( "{"):
2757 FvObj = Fv.FV()
2758 FvObj.UiFvName = FvName.upper()
2759 self.__GetDefineStatements(FvObj)
2760 MacroDict.update(FvObj.DefineVarDict)
2761 self.__GetBlockStatement(FvObj)
2762 self.__GetSetStatements(FvObj)
2763 self.__GetFvAlignment(FvObj)
2764 self.__GetFvAttributes(FvObj)
2765 self.__GetAprioriSection(FvObj, MacroDict.copy())
2766 self.__GetAprioriSection(FvObj, MacroDict.copy())
2767
2768 while True:
2769 IsInf = self.__GetInfStatement(FvObj, MacroDict.copy())
2770 IsFile = self.__GetFileStatement(FvObj, MacroDict.copy())
2771 if not IsInf and not IsFile:
2772 break
2773
2774 if not self.__IsToken( "}"):
2775 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2776
2777 FvImageSectionObj = FvImageSection.FvImageSection()
2778 FvImageSectionObj.Alignment = AlignValue
2779 if FvObj != None:
2780 FvImageSectionObj.Fv = FvObj
2781 FvImageSectionObj.FvName = None
2782 else:
2783 FvImageSectionObj.FvName = FvName.upper()
2784 FvImageSectionObj.FvFileName = FvName
2785
2786 Obj.SectionList.append(FvImageSectionObj)
2787
2788 elif self.__IsKeyword("PEI_DEPEX_EXP") or self.__IsKeyword("DXE_DEPEX_EXP") or self.__IsKeyword("SMM_DEPEX_EXP"):
2789 if AlignValue == 'Auto':
2790 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2791 DepexSectionObj = DepexSection.DepexSection()
2792 DepexSectionObj.Alignment = AlignValue
2793 DepexSectionObj.DepexType = self.__Token
2794
2795 if not self.__IsToken( "="):
2796 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2797 if not self.__IsToken( "{"):
2798 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2799 if not self.__SkipToToken( "}"):
2800 raise Warning("expected Depex expression ending '}'", self.FileName, self.CurrentLineNumber)
2801
2802 DepexSectionObj.Expression = self.__SkippedChars.rstrip('}')
2803 Obj.SectionList.append(DepexSectionObj)
2804
2805 else:
2806 if not self.__GetNextWord():
2807 raise Warning("expected section type", self.FileName, self.CurrentLineNumber)
2808
2809 # Encapsulation section appear, UndoToken and return
2810 if self.__Token == "COMPRESS" or self.__Token == "GUIDED":
2811 self.SetFileBufferPos(OldPos)
2812 return False
2813
2814 if self.__Token not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
2815 "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"):
2816 raise Warning("Unknown section type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2817 if AlignValue == 'Auto'and (not self.__Token == 'PE32') and (not self.__Token == 'TE'):
2818 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2819
2820 # DataSection
2821 DataSectionObj = DataSection.DataSection()
2822 DataSectionObj.Alignment = AlignValue
2823 DataSectionObj.SecType = self.__Token
2824
2825 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
2826 if self.__FileCouldHaveRelocFlag(Obj.FvFileType) and self.__SectionCouldHaveRelocFlag(DataSectionObj.SecType):
2827 if self.__Token == 'RELOCS_STRIPPED':
2828 DataSectionObj.KeepReloc = False
2829 else:
2830 DataSectionObj.KeepReloc = True
2831 else:
2832 raise Warning("File type %s, section type %s, could not have reloc strip flag%d" % (Obj.FvFileType, DataSectionObj.SecType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
2833
2834 if self.__IsToken("="):
2835 if not self.__GetNextToken():
2836 raise Warning("expected section file path", self.FileName, self.CurrentLineNumber)
2837 DataSectionObj.SectFileName = self.__Token
2838 self.__VerifyFile(DataSectionObj.SectFileName)
2839 else:
2840 if not self.__GetCglSection(DataSectionObj):
2841 return False
2842
2843 Obj.SectionList.append(DataSectionObj)
2844
2845 return True
2846
2847 ## __VerifyFile
2848 #
2849 # Check if file exists or not:
2850 # If current phase if GenFds, the file must exist;
2851 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist
2852 # @param FileName: File path to be verified.
2853 #
2854 def __VerifyFile(self, FileName):
2855 if FileName.replace('$(WORKSPACE)', '').find('$') != -1:
2856 return
2857 if not GlobalData.gAutoGenPhase or not self.__GetMacroValue("OUTPUT_DIRECTORY") in FileName:
2858 ErrorCode, ErrorInfo = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
2859 if ErrorCode != 0:
2860 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
2861
2862 ## __GetCglSection() method
2863 #
2864 # Get compressed or GUIDed section for Obj
2865 #
2866 # @param self The object pointer
2867 # @param Obj for whom leaf section is got
2868 # @param AlignValue alignment value for complex section
2869 # @retval True Successfully find section statement
2870 # @retval False Not able to find section statement
2871 #
2872 def __GetCglSection(self, Obj, AlignValue = None):
2873
2874 if self.__IsKeyword( "COMPRESS"):
2875 type = "PI_STD"
2876 if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):
2877 type = self.__Token
2878
2879 if not self.__IsToken("{"):
2880 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2881
2882 CompressSectionObj = CompressSection.CompressSection()
2883 CompressSectionObj.Alignment = AlignValue
2884 CompressSectionObj.CompType = type
2885 # Recursive sections...
2886 while True:
2887 IsLeafSection = self.__GetLeafSection(CompressSectionObj)
2888 IsEncapSection = self.__GetEncapsulationSec(CompressSectionObj)
2889 if not IsLeafSection and not IsEncapSection:
2890 break
2891
2892
2893 if not self.__IsToken( "}"):
2894 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2895 Obj.SectionList.append(CompressSectionObj)
2896
2897 # else:
2898 # raise Warning("Compress type not known")
2899
2900 return True
2901
2902 elif self.__IsKeyword( "GUIDED"):
2903 GuidValue = None
2904 if self.__GetNextGuid():
2905 GuidValue = self.__Token
2906
2907 AttribDict = self.__GetGuidAttrib()
2908 if not self.__IsToken("{"):
2909 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2910 GuidSectionObj = GuidSection.GuidSection()
2911 GuidSectionObj.Alignment = AlignValue
2912 GuidSectionObj.NameGuid = GuidValue
2913 GuidSectionObj.SectionType = "GUIDED"
2914 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
2915 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
2916 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]
2917 # Recursive sections...
2918 while True:
2919 IsLeafSection = self.__GetLeafSection(GuidSectionObj)
2920 IsEncapSection = self.__GetEncapsulationSec(GuidSectionObj)
2921 if not IsLeafSection and not IsEncapSection:
2922 break
2923
2924 if not self.__IsToken( "}"):
2925 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2926 Obj.SectionList.append(GuidSectionObj)
2927
2928 return True
2929
2930 return False
2931
2932 ## __GetGuidAttri() method
2933 #
2934 # Get attributes for GUID section
2935 #
2936 # @param self The object pointer
2937 # @retval AttribDict Dictionary of key-value pair of section attributes
2938 #
2939 def __GetGuidAttrib(self):
2940
2941 AttribDict = {}
2942 AttribDict["PROCESSING_REQUIRED"] = "NONE"
2943 AttribDict["AUTH_STATUS_VALID"] = "NONE"
2944 AttribDict["EXTRA_HEADER_SIZE"] = -1
2945 while self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID") \
2946 or self.__IsKeyword("EXTRA_HEADER_SIZE"):
2947 AttribKey = self.__Token
2948
2949 if not self.__IsToken("="):
2950 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2951
2952 if not self.__GetNextToken():
2953 raise Warning("expected TRUE(1)/FALSE(0)/Number", self.FileName, self.CurrentLineNumber)
2954 elif AttribKey == "EXTRA_HEADER_SIZE":
2955 Base = 10
2956 if self.__Token[0:2].upper() == "0X":
2957 Base = 16
2958 try:
2959 AttribDict[AttribKey] = int(self.__Token, Base)
2960 continue
2961 except ValueError:
2962 raise Warning("expected Number", self.FileName, self.CurrentLineNumber)
2963 elif self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
2964 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)
2965 AttribDict[AttribKey] = self.__Token
2966
2967 return AttribDict
2968
2969 ## __GetEncapsulationSec() method
2970 #
2971 # Get encapsulation section for FILE
2972 #
2973 # @param self The object pointer
2974 # @param FfsFile for whom section is got
2975 # @retval True Successfully find section statement
2976 # @retval False Not able to find section statement
2977 #
2978 def __GetEncapsulationSec(self, FfsFileObj):
2979
2980 OldPos = self.GetFileBufferPos()
2981 if not self.__IsKeyword( "SECTION"):
2982 if len(FfsFileObj.SectionList) == 0:
2983 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)
2984 else:
2985 return False
2986
2987 AlignValue = None
2988 if self.__GetAlignment():
2989 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2990 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2991 AlignValue = self.__Token
2992
2993 if not self.__GetCglSection(FfsFileObj, AlignValue):
2994 self.SetFileBufferPos(OldPos)
2995 return False
2996 else:
2997 return True
2998
2999 ## __GetCapsule() method
3000 #
3001 # Get capsule section contents and store its data into capsule list of self.Profile
3002 #
3003 # @param self The object pointer
3004 # @retval True Successfully find a capsule
3005 # @retval False Not able to find a capsule
3006 #
3007 def __GetCapsule(self):
3008
3009 if not self.__GetNextToken():
3010 return False
3011
3012 S = self.__Token.upper()
3013 if S.startswith("[") and not S.startswith("[CAPSULE."):
3014 if not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
3015 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
3016 self.__UndoToken()
3017 return False
3018
3019 self.__UndoToken()
3020 if not self.__IsToken("[CAPSULE.", True):
3021 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
3022 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3023 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3024 raise Warning("expected [Capsule.]", self.FileName, self.CurrentLineNumber)
3025
3026 CapsuleObj = Capsule.Capsule()
3027
3028 CapsuleName = self.__GetUiName()
3029 if not CapsuleName:
3030 raise Warning("expected capsule name", self.FileName, self.CurrentLineNumber)
3031
3032 CapsuleObj.UiCapsuleName = CapsuleName.upper()
3033
3034 if not self.__IsToken( "]"):
3035 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
3036
3037 if self.__IsKeyword("CREATE_FILE"):
3038 if not self.__IsToken( "="):
3039 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3040
3041 if not self.__GetNextToken():
3042 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)
3043
3044 CapsuleObj.CreateFile = self.__Token
3045
3046 self.__GetCapsuleStatements(CapsuleObj)
3047 self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj
3048 return True
3049
3050 ## __GetCapsuleStatements() method
3051 #
3052 # Get statements for capsule
3053 #
3054 # @param self The object pointer
3055 # @param Obj for whom statements are got
3056 #
3057 def __GetCapsuleStatements(self, Obj):
3058 self.__GetCapsuleTokens(Obj)
3059 self.__GetDefineStatements(Obj)
3060 self.__GetSetStatements(Obj)
3061 self.__GetCapsuleData(Obj)
3062
3063 ## __GetCapsuleTokens() method
3064 #
3065 # Get token statements for capsule
3066 #
3067 # @param self The object pointer
3068 # @param Obj for whom token statements are got
3069 #
3070 def __GetCapsuleTokens(self, Obj):
3071 if not self.__GetNextToken():
3072 return False
3073 while self.__Token in ("CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS"):
3074 Name = self.__Token.strip()
3075 if not self.__IsToken("="):
3076 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3077 if not self.__GetNextToken():
3078 raise Warning("expected value", self.FileName, self.CurrentLineNumber)
3079 if Name == 'CAPSULE_FLAGS':
3080 if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
3081 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)
3082 Value = self.__Token.strip()
3083 while self.__IsToken(","):
3084 Value += ','
3085 if not self.__GetNextToken():
3086 raise Warning("expected value", self.FileName, self.CurrentLineNumber)
3087 if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
3088 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)
3089 Value += self.__Token.strip()
3090 elif Name == 'OEM_CAPSULE_FLAGS':
3091 Value = self.__Token.strip()
3092 if not Value.upper().startswith('0X'):
3093 raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)
3094 try:
3095 Value = int(Value, 0)
3096 except ValueError:
3097 raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)
3098 if not 0x0000 <= Value <= 0xFFFF:
3099 raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)
3100 Value = self.__Token.strip()
3101 else:
3102 Value = self.__Token.strip()
3103 Obj.TokensDict[Name] = Value
3104 if not self.__GetNextToken():
3105 return False
3106 self.__UndoToken()
3107
3108 ## __GetCapsuleData() method
3109 #
3110 # Get capsule data for capsule
3111 #
3112 # @param self The object pointer
3113 # @param Obj for whom capsule data are got
3114 #
3115 def __GetCapsuleData(self, Obj):
3116
3117 while True:
3118 IsInf = self.__GetInfStatement(Obj, True)
3119 IsFile = self.__GetFileStatement(Obj, True)
3120 IsFv = self.__GetFvStatement(Obj)
3121 IsFd = self.__GetFdStatement(Obj)
3122 IsAnyFile = self.__GetAnyFileStatement(Obj)
3123 IsAfile = self.__GetAfileStatement(Obj)
3124 if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile or IsAfile):
3125 break
3126
3127 ## __GetFvStatement() method
3128 #
3129 # Get FV for capsule
3130 #
3131 # @param self The object pointer
3132 # @param CapsuleObj for whom FV is got
3133 # @retval True Successfully find a FV statement
3134 # @retval False Not able to find a FV statement
3135 #
3136 def __GetFvStatement(self, CapsuleObj):
3137
3138 if not self.__IsKeyword("FV"):
3139 return False
3140
3141 if not self.__IsToken("="):
3142 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3143
3144 if not self.__GetNextToken():
3145 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
3146
3147 if self.__Token.upper() not in self.Profile.FvDict.keys():
3148 raise Warning("FV name does not exist", self.FileName, self.CurrentLineNumber)
3149
3150 CapsuleFv = CapsuleData.CapsuleFv()
3151 CapsuleFv.FvName = self.__Token
3152 CapsuleObj.CapsuleDataList.append(CapsuleFv)
3153 return True
3154
3155 ## __GetFdStatement() method
3156 #
3157 # Get FD for capsule
3158 #
3159 # @param self The object pointer
3160 # @param CapsuleObj for whom FD is got
3161 # @retval True Successfully find a FD statement
3162 # @retval False Not able to find a FD statement
3163 #
3164 def __GetFdStatement(self, CapsuleObj):
3165
3166 if not self.__IsKeyword("FD"):
3167 return False
3168
3169 if not self.__IsToken("="):
3170 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3171
3172 if not self.__GetNextToken():
3173 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)
3174
3175 if self.__Token.upper() not in self.Profile.FdDict.keys():
3176 raise Warning("FD name does not exist", self.FileName, self.CurrentLineNumber)
3177
3178 CapsuleFd = CapsuleData.CapsuleFd()
3179 CapsuleFd.FdName = self.__Token
3180 CapsuleObj.CapsuleDataList.append(CapsuleFd)
3181 return True
3182
3183 ## __GetAnyFileStatement() method
3184 #
3185 # Get AnyFile for capsule
3186 #
3187 # @param self The object pointer
3188 # @param CapsuleObj for whom AnyFile is got
3189 # @retval True Successfully find a Anyfile statement
3190 # @retval False Not able to find a AnyFile statement
3191 #
3192 def __GetAnyFileStatement(self, CapsuleObj):
3193
3194 if not self.__IsKeyword("FILE"):
3195 return False
3196
3197 if not self.__IsKeyword("DATA"):
3198 self.__UndoToken()
3199 return False
3200
3201 if not self.__IsToken("="):
3202 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3203
3204 if not self.__GetNextToken():
3205 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)
3206
3207 AnyFileName = self.__Token
3208 AnyFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AnyFileName)
3209 if not os.path.exists(AnyFileName):
3210 raise Warning("File %s not exists"%AnyFileName, self.FileName, self.CurrentLineNumber)
3211
3212 CapsuleAnyFile = CapsuleData.CapsuleAnyFile()
3213 CapsuleAnyFile.FileName = AnyFileName
3214 CapsuleObj.CapsuleDataList.append(CapsuleAnyFile)
3215 return True
3216
3217 ## __GetAfileStatement() method
3218 #
3219 # Get Afile for capsule
3220 #
3221 # @param self The object pointer
3222 # @param CapsuleObj for whom Afile is got
3223 # @retval True Successfully find a Afile statement
3224 # @retval False Not able to find a Afile statement
3225 #
3226 def __GetAfileStatement(self, CapsuleObj):
3227
3228 if not self.__IsKeyword("APPEND"):
3229 return False
3230
3231 if not self.__IsToken("="):
3232 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3233
3234 if not self.__GetNextToken():