]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/FdfParser.py
Sync BaseTools Trunk (version r2387) to EDKII main trunk.
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FdfParser.py
1 ## @file
2 # parse FDF file
3 #
4 # Copyright (c) 2007 - 2010, 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
54 import re
55 import os
56
57 ##define T_CHAR_SPACE ' '
58 ##define T_CHAR_NULL '\0'
59 ##define T_CHAR_CR '\r'
60 ##define T_CHAR_TAB '\t'
61 ##define T_CHAR_LF '\n'
62 ##define T_CHAR_SLASH '/'
63 ##define T_CHAR_BACKSLASH '\\'
64 ##define T_CHAR_DOUBLE_QUOTE '\"'
65 ##define T_CHAR_SINGLE_QUOTE '\''
66 ##define T_CHAR_STAR '*'
67 ##define T_CHAR_HASH '#'
68
69 (T_CHAR_SPACE, T_CHAR_NULL, T_CHAR_CR, T_CHAR_TAB, T_CHAR_LF, T_CHAR_SLASH, \
70 T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_HASH) = \
71 (' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#')
72
73 SEPERATOR_TUPLE = ('=', '|', ',', '{', '}')
74
75 RegionSizePattern = re.compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
76 RegionSizeGuidPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*\|\s*(?P<size>\w+\.\w+)\s*")
77
78 IncludeFileList = []
79 # Macro passed from command line, which has greatest priority and can NOT be overridden by those in FDF
80 InputMacroDict = {}
81 # All Macro values when parsing file, not replace existing Macro
82 AllMacroList = []
83
84 def GetRealFileLine (File, Line):
85
86 InsertedLines = 0
87 for Profile in IncludeFileList:
88 if Line >= Profile.InsertStartLineNumber and Line < Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList):
89 return (Profile.FileName, Line - Profile.InsertStartLineNumber + 1)
90 if Line >= Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList):
91 InsertedLines += Profile.InsertAdjust + len(Profile.FileLinesList)
92
93 return (File, Line - InsertedLines)
94
95 ## The exception class that used to report error messages when parsing FDF
96 #
97 # Currently the "ToolName" is set to be "FDF Parser".
98 #
99 class Warning (Exception):
100 ## The constructor
101 #
102 # @param self The object pointer
103 # @param Str The message to record
104 # @param File The FDF name
105 # @param Line The Line number that error occurs
106 #
107 def __init__(self, Str, File = None, Line = None):
108
109 FileLineTuple = GetRealFileLine(File, Line)
110 self.FileName = FileLineTuple[0]
111 self.LineNumber = FileLineTuple[1]
112 self.Message = Str
113 self.ToolName = 'FdfParser'
114
115 def __str__(self):
116 return self.Message
117
118 ## The MACRO class that used to record macro value data when parsing include file
119 #
120 #
121 class MacroProfile :
122 ## The constructor
123 #
124 # @param self The object pointer
125 # @param FileName The file that to be parsed
126 #
127 def __init__(self, FileName, Line):
128 self.FileName = FileName
129 self.DefinedAtLine = Line
130 self.MacroName = None
131 self.MacroValue = None
132
133 ## The Include file content class that used to record file data when parsing include file
134 #
135 # May raise Exception when opening file.
136 #
137 class IncludeFileProfile :
138 ## The constructor
139 #
140 # @param self The object pointer
141 # @param FileName The file that to be parsed
142 #
143 def __init__(self, FileName):
144 self.FileName = FileName
145 self.FileLinesList = []
146 try:
147 fsock = open(FileName, "rb", 0)
148 try:
149 self.FileLinesList = fsock.readlines()
150 finally:
151 fsock.close()
152
153 except:
154 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)
155
156 self.InsertStartLineNumber = None
157 self.InsertAdjust = 0
158
159 ## The FDF content class that used to record file data when parsing FDF
160 #
161 # May raise Exception when opening file.
162 #
163 class FileProfile :
164 ## The constructor
165 #
166 # @param self The object pointer
167 # @param FileName The file that to be parsed
168 #
169 def __init__(self, FileName):
170 self.FileLinesList = []
171 try:
172 fsock = open(FileName, "rb", 0)
173 try:
174 self.FileLinesList = fsock.readlines()
175 finally:
176 fsock.close()
177
178 except:
179 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)
180
181
182 self.PcdDict = {}
183 self.InfList = []
184
185 self.FdDict = {}
186 self.FdNameNotSet = False
187 self.FvDict = {}
188 self.CapsuleDict = {}
189 self.VtfList = []
190 self.RuleDict = {}
191 self.OptRomDict = {}
192
193 ## The syntax parser for FDF
194 #
195 # PreprocessFile method should be called prior to ParseFile
196 # CycleReferenceCheck method can detect cycles in FDF contents
197 #
198 # GetNext*** procedures mean these procedures will get next token first, then make judgement.
199 # Get*** procedures mean these procedures will make judgement on current token only.
200 #
201 class FdfParser:
202 ## The constructor
203 #
204 # @param self The object pointer
205 # @param FileName The file that to be parsed
206 #
207 def __init__(self, FileName):
208 self.Profile = FileProfile(FileName)
209 self.FileName = FileName
210 self.CurrentLineNumber = 1
211 self.CurrentOffsetWithinLine = 0
212 self.CurrentFdName = None
213 self.CurrentFvName = None
214 self.__Token = ""
215 self.__SkippedChars = ""
216
217 self.__WipeOffArea = []
218 if GenFdsGlobalVariable.WorkSpaceDir == '':
219 GenFdsGlobalVariable.WorkSpaceDir = os.getenv("WORKSPACE")
220
221 InputMacroDict.update(GlobalData.gPlatformDefines)
222 InputMacroDict.update(GlobalData.gGlobalDefines)
223 InputMacroDict.update(GlobalData.gCommandLineDefines)
224
225 ## __IsWhiteSpace() method
226 #
227 # Whether char at current FileBufferPos is whitespace
228 #
229 # @param self The object pointer
230 # @param Char The char to test
231 # @retval True The char is a kind of white space
232 # @retval False The char is NOT a kind of white space
233 #
234 def __IsWhiteSpace(self, Char):
235 if Char in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_SPACE, T_CHAR_TAB, T_CHAR_LF):
236 return True
237 else:
238 return False
239
240 ## __SkipWhiteSpace() method
241 #
242 # Skip white spaces from current char, return number of chars skipped
243 #
244 # @param self The object pointer
245 # @retval Count The number of chars skipped
246 #
247 def __SkipWhiteSpace(self):
248 Count = 0
249 while not self.__EndOfFile():
250 Count += 1
251 if self.__CurrentChar() in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_LF, T_CHAR_SPACE, T_CHAR_TAB):
252 self.__SkippedChars += str(self.__CurrentChar())
253 self.__GetOneChar()
254
255 else:
256 Count = Count - 1
257 return Count
258
259 ## __EndOfFile() method
260 #
261 # Judge current buffer pos is at file end
262 #
263 # @param self The object pointer
264 # @retval True Current File buffer position is at file end
265 # @retval False Current File buffer position is NOT at file end
266 #
267 def __EndOfFile(self):
268 NumberOfLines = len(self.Profile.FileLinesList)
269 SizeOfLastLine = len(self.Profile.FileLinesList[-1])
270 if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1:
271 return True
272 elif self.CurrentLineNumber > NumberOfLines:
273 return True
274 else:
275 return False
276
277 ## __EndOfLine() method
278 #
279 # Judge current buffer pos is at line end
280 #
281 # @param self The object pointer
282 # @retval True Current File buffer position is at line end
283 # @retval False Current File buffer position is NOT at line end
284 #
285 def __EndOfLine(self):
286 if self.CurrentLineNumber > len(self.Profile.FileLinesList):
287 return True
288 SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
289 if self.CurrentOffsetWithinLine >= SizeOfCurrentLine:
290 return True
291 else:
292 return False
293
294 ## Rewind() method
295 #
296 # Reset file data buffer to the initial state
297 #
298 # @param self The object pointer
299 #
300 def Rewind(self):
301 self.CurrentLineNumber = 1
302 self.CurrentOffsetWithinLine = 0
303
304 ## __UndoOneChar() method
305 #
306 # Go back one char in the file buffer
307 #
308 # @param self The object pointer
309 # @retval True Successfully go back one char
310 # @retval False Not able to go back one char as file beginning reached
311 #
312 def __UndoOneChar(self):
313
314 if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0:
315 return False
316 elif self.CurrentOffsetWithinLine == 0:
317 self.CurrentLineNumber -= 1
318 self.CurrentOffsetWithinLine = len(self.__CurrentLine()) - 1
319 else:
320 self.CurrentOffsetWithinLine -= 1
321 return True
322
323 ## __GetOneChar() method
324 #
325 # Move forward one char in the file buffer
326 #
327 # @param self The object pointer
328 #
329 def __GetOneChar(self):
330 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
331 self.CurrentLineNumber += 1
332 self.CurrentOffsetWithinLine = 0
333 else:
334 self.CurrentOffsetWithinLine += 1
335
336 ## __CurrentChar() method
337 #
338 # Get the char pointed to by the file buffer pointer
339 #
340 # @param self The object pointer
341 # @retval Char Current char
342 #
343 def __CurrentChar(self):
344 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine]
345
346 ## __NextChar() method
347 #
348 # Get the one char pass the char pointed to by the file buffer pointer
349 #
350 # @param self The object pointer
351 # @retval Char Next char
352 #
353 def __NextChar(self):
354 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
355 return self.Profile.FileLinesList[self.CurrentLineNumber][0]
356 else:
357 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1]
358
359 ## __SetCurrentCharValue() method
360 #
361 # Modify the value of current char
362 #
363 # @param self The object pointer
364 # @param Value The new value of current char
365 #
366 def __SetCurrentCharValue(self, Value):
367 self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value
368
369 ## __CurrentLine() method
370 #
371 # Get the list that contains current line contents
372 #
373 # @param self The object pointer
374 # @retval List current line contents
375 #
376 def __CurrentLine(self):
377 return self.Profile.FileLinesList[self.CurrentLineNumber - 1]
378
379 def __StringToList(self):
380 self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList]
381 self.Profile.FileLinesList[-1].append(' ')
382
383 def __ReplaceMacros(self, Str, File, Line):
384 MacroEnd = 0
385 while Str.find('$(', MacroEnd) >= 0:
386 MacroStart = Str.find('$(', MacroEnd)
387 if Str.find(')', MacroStart) > 0:
388 MacroEnd = Str.find(')', MacroStart)
389 Name = Str[MacroStart + 2 : MacroEnd]
390 Value = None
391 if Name in InputMacroDict:
392 Value = InputMacroDict[Name]
393
394 else:
395 for Profile in AllMacroList:
396 if Profile.FileName == File and Profile.MacroName == Name and Profile.DefinedAtLine <= Line:
397 Value = Profile.MacroValue
398
399 if Value != None:
400 Str = Str.replace('$(' + Name + ')', Value)
401 MacroEnd = MacroStart + len(Value)
402
403 else:
404 raise Warning("Macro not complete", self.FileName, self.CurrentLineNumber)
405 return Str
406
407 def __ReplaceFragment(self, StartPos, EndPos, Value = ' '):
408 if StartPos[0] == EndPos[0]:
409 Offset = StartPos[1]
410 while Offset <= EndPos[1]:
411 self.Profile.FileLinesList[StartPos[0]][Offset] = Value
412 Offset += 1
413 return
414
415 Offset = StartPos[1]
416 while self.Profile.FileLinesList[StartPos[0]][Offset] not in ('\r', '\n'):
417 self.Profile.FileLinesList[StartPos[0]][Offset] = Value
418 Offset += 1
419
420 Line = StartPos[0]
421 while Line < EndPos[0]:
422 Offset = 0
423 while self.Profile.FileLinesList[Line][Offset] not in ('\r', '\n'):
424 self.Profile.FileLinesList[Line][Offset] = Value
425 Offset += 1
426 Line += 1
427
428 Offset = 0
429 while Offset <= EndPos[1]:
430 self.Profile.FileLinesList[EndPos[0]][Offset] = Value
431 Offset += 1
432
433
434 def __GetMacroName(self):
435 if not self.__GetNextToken():
436 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)
437 MacroName = self.__Token
438 NotFlag = False
439 if MacroName.startswith('!'):
440 NotFlag = True
441 MacroName = MacroName[1:].strip()
442
443 if not MacroName.startswith('$(') or not MacroName.endswith(')'):
444 raise Warning("Macro name expected(Please use '$(%(Token)s)' if '%(Token)s' is a macro.)" % {"Token" : MacroName},
445 self.FileName, self.CurrentLineNumber)
446 MacroName = MacroName[2:-1]
447 return MacroName, NotFlag
448
449 ## PreprocessFile() method
450 #
451 # Preprocess file contents, replace comments with spaces.
452 # In the end, rewind the file buffer pointer to the beginning
453 # BUGBUG: No !include statement processing contained in this procedure
454 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
455 #
456 # @param self The object pointer
457 #
458 def PreprocessFile(self):
459
460 self.Rewind()
461 InComment = False
462 DoubleSlashComment = False
463 HashComment = False
464 # HashComment in quoted string " " is ignored.
465 InString = False
466
467 while not self.__EndOfFile():
468
469 if self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment:
470 InString = not InString
471 # meet new line, then no longer in a comment for // and '#'
472 if self.__CurrentChar() == T_CHAR_LF:
473 self.CurrentLineNumber += 1
474 self.CurrentOffsetWithinLine = 0
475 if InComment and DoubleSlashComment:
476 InComment = False
477 DoubleSlashComment = False
478 if InComment and HashComment:
479 InComment = False
480 HashComment = False
481 # check for */ comment end
482 elif InComment and not DoubleSlashComment and not HashComment and self.__CurrentChar() == T_CHAR_STAR and self.__NextChar() == T_CHAR_SLASH:
483 self.__SetCurrentCharValue(T_CHAR_SPACE)
484 self.__GetOneChar()
485 self.__SetCurrentCharValue(T_CHAR_SPACE)
486 self.__GetOneChar()
487 InComment = False
488 # set comments to spaces
489 elif InComment:
490 self.__SetCurrentCharValue(T_CHAR_SPACE)
491 self.__GetOneChar()
492 # check for // comment
493 elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH and not self.__EndOfLine():
494 InComment = True
495 DoubleSlashComment = True
496 # check for '#' comment
497 elif self.__CurrentChar() == T_CHAR_HASH and not self.__EndOfLine() and not InString:
498 InComment = True
499 HashComment = True
500 # check for /* comment start
501 elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_STAR:
502 self.__SetCurrentCharValue( T_CHAR_SPACE)
503 self.__GetOneChar()
504 self.__SetCurrentCharValue( T_CHAR_SPACE)
505 self.__GetOneChar()
506 InComment = True
507 else:
508 self.__GetOneChar()
509
510 # restore from ListOfList to ListOfString
511 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
512 self.Rewind()
513
514 ## PreprocessIncludeFile() method
515 #
516 # Preprocess file contents, replace !include statements with file contents.
517 # In the end, rewind the file buffer pointer to the beginning
518 #
519 # @param self The object pointer
520 #
521 def PreprocessIncludeFile(self):
522
523 while self.__GetNextToken():
524
525 if self.__Token == '!include':
526 IncludeLine = self.CurrentLineNumber
527 IncludeOffset = self.CurrentOffsetWithinLine - len('!include')
528 if not self.__GetNextToken():
529 raise Warning("expected include file name", self.FileName, self.CurrentLineNumber)
530 IncFileName = self.__Token
531 if not os.path.isabs(IncFileName):
532 if IncFileName.startswith('$(WORKSPACE)'):
533 Str = IncFileName.replace('$(WORKSPACE)', os.environ.get('WORKSPACE'))
534 if os.path.exists(Str):
535 if not os.path.isabs(Str):
536 Str = os.path.abspath(Str)
537 IncFileName = Str
538 else:
539 # file is in the same dir with FDF file
540 FullFdf = self.FileName
541 if not os.path.isabs(self.FileName):
542 FullFdf = os.path.join(os.environ.get('WORKSPACE'), self.FileName)
543
544 IncFileName = os.path.join(os.path.dirname(FullFdf), IncFileName)
545
546 if not os.path.exists(os.path.normpath(IncFileName)):
547 raise Warning("Include file not exists", self.FileName, self.CurrentLineNumber)
548
549 IncFileProfile = IncludeFileProfile(os.path.normpath(IncFileName))
550
551 CurrentLine = self.CurrentLineNumber
552 CurrentOffset = self.CurrentOffsetWithinLine
553 # list index of the insertion, note that line number is 'CurrentLine + 1'
554 InsertAtLine = CurrentLine
555 IncFileProfile.InsertStartLineNumber = InsertAtLine + 1
556 # deal with remaining portions after "!include filename", if exists.
557 if self.__GetNextToken():
558 if self.CurrentLineNumber == CurrentLine:
559 RemainingLine = self.__CurrentLine()[CurrentOffset:]
560 self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine)
561 IncFileProfile.InsertAdjust += 1
562 self.CurrentLineNumber += 1
563 self.CurrentOffsetWithinLine = 0
564
565 for Line in IncFileProfile.FileLinesList:
566 self.Profile.FileLinesList.insert(InsertAtLine, Line)
567 self.CurrentLineNumber += 1
568 InsertAtLine += 1
569
570 IncludeFileList.append(IncFileProfile)
571
572 # comment out the processed include file statement
573 TempList = list(self.Profile.FileLinesList[IncludeLine - 1])
574 TempList.insert(IncludeOffset, '#')
575 self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList)
576
577 self.Rewind()
578
579 def __GetIfListCurrentItemStat(self, IfList):
580 if len(IfList) == 0:
581 return True
582
583 for Item in IfList:
584 if Item[1] == False:
585 return False
586
587 return True
588
589 ## PreprocessConditionalStatement() method
590 #
591 # Preprocess conditional statement.
592 # In the end, rewind the file buffer pointer to the beginning
593 #
594 # @param self The object pointer
595 #
596 def PreprocessConditionalStatement(self):
597 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
598 IfList = []
599 RegionLayoutLine = 0
600 while self.__GetNextToken():
601 if self.__Token == 'DEFINE':
602 if self.__GetIfListCurrentItemStat(IfList):
603 DefineLine = self.CurrentLineNumber - 1
604 DefineOffset = self.CurrentOffsetWithinLine - len('DEFINE')
605 if not self.__GetNextToken():
606 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)
607 Macro = self.__Token
608 if not self.__IsToken( "="):
609 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
610
611 if not self.__GetNextToken():
612 raise Warning("expected value", self.FileName, self.CurrentLineNumber)
613
614 if self.__GetStringData():
615 pass
616 Value = self.__Token
617 if not Macro in InputMacroDict:
618 FileLineTuple = GetRealFileLine(self.FileName, DefineLine + 1)
619 MacProfile = MacroProfile(FileLineTuple[0], FileLineTuple[1])
620 MacProfile.MacroName = Macro
621 MacProfile.MacroValue = Value
622 AllMacroList.append(MacProfile)
623 InputMacroDict[MacProfile.MacroName] = MacProfile.MacroValue
624 self.__WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
625 elif self.__Token == 'SET':
626 PcdPair = self.__GetNextPcdName()
627 PcdName = "%s.%s" % (PcdPair[1], PcdPair[0])
628 if not self.__IsToken( "="):
629 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
630
631 if not self.__GetNextToken():
632 raise Warning("expected value", self.FileName, self.CurrentLineNumber)
633
634 Value = self.__Token
635 if Value.startswith("{"):
636 # deal with value with {}
637 if not self.__SkipToToken( "}"):
638 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
639 Value += self.__SkippedChars
640
641 InputMacroDict[PcdName] = Value
642 elif self.__Token in ('!ifdef', '!ifndef', '!if'):
643 IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))
644 IfList.append([IfStartPos, None, None])
645
646 CondLabel = self.__Token
647 Expression = self.__GetExpression()
648
649 if CondLabel == '!if':
650 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')
651 else:
652 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'in')
653 if CondLabel == '!ifndef':
654 ConditionSatisfied = not ConditionSatisfied
655
656 BranchDetermined = ConditionSatisfied
657 IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
658 if ConditionSatisfied:
659 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
660 elif self.__Token in ('!elseif', '!else'):
661 ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))
662 if len(IfList) <= 0:
663 raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)
664
665 if IfList[-1][1]:
666 IfList[-1] = [ElseStartPos, False, True]
667 self.__WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
668 else:
669 self.__WipeOffArea.append((IfList[-1][0], ElseStartPos))
670 IfList[-1] = [ElseStartPos, True, IfList[-1][2]]
671 if self.__Token == '!elseif':
672 Expression = self.__GetExpression()
673 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')
674 IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]]
675
676 if IfList[-1][1]:
677 if IfList[-1][2]:
678 IfList[-1][1] = False
679 else:
680 IfList[-1][2] = True
681 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
682 elif self.__Token == '!endif':
683 if IfList[-1][1]:
684 self.__WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
685 else:
686 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
687
688 IfList.pop()
689 elif not IfList: # Don't use PCDs inside conditional directive
690 if self.CurrentLineNumber <= RegionLayoutLine:
691 # Don't try the same line twice
692 continue
693 RegionSize = RegionSizePattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
694 if not RegionSize:
695 RegionLayoutLine = self.CurrentLineNumber
696 continue
697 RegionSizeGuid = RegionSizeGuidPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber])
698 if not RegionSizeGuid:
699 RegionLayoutLine = self.CurrentLineNumber + 1
700 continue
701 InputMacroDict[RegionSizeGuid.group('base')] = RegionSize.group('base')
702 InputMacroDict[RegionSizeGuid.group('size')] = RegionSize.group('size')
703 RegionLayoutLine = self.CurrentLineNumber + 1
704
705 if IfList:
706 raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber)
707 self.Rewind()
708
709 def __EvaluateConditional(self, Expression, Line, Op = None, Value = None):
710 FileLineTuple = GetRealFileLine(self.FileName, Line)
711 if Op == 'eval':
712 try:
713 return ValueExpression(Expression, InputMacroDict)()
714 except SymbolNotFound:
715 return False
716 except WrnExpression, Excpt:
717 #
718 # Catch expression evaluation warning here. We need to report
719 # the precise number of line and return the evaluation result
720 #
721 EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),
722 File=self.FileName, ExtraData=self.__CurrentLine(),
723 Line=Line)
724 return Excpt.result
725 except Exception, Excpt:
726 raise Warning("Invalid expression", *FileLineTuple)
727 else:
728 if Expression.startswith('$(') and Expression[-1] == ')':
729 Expression = Expression[2:-1]
730 return Expression in InputMacroDict
731
732 ## __IsToken() method
733 #
734 # Check whether input string is found from current char position along
735 # If found, the string value is put into self.__Token
736 #
737 # @param self The object pointer
738 # @param String The string to search
739 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
740 # @retval True Successfully find string, file buffer pointer moved forward
741 # @retval False Not able to find string, file buffer pointer not changed
742 #
743 def __IsToken(self, String, IgnoreCase = False):
744 self.__SkipWhiteSpace()
745
746 # Only consider the same line, no multi-line token allowed
747 StartPos = self.CurrentOffsetWithinLine
748 index = -1
749 if IgnoreCase:
750 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())
751 else:
752 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)
753 if index == 0:
754 self.CurrentOffsetWithinLine += len(String)
755 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
756 return True
757 return False
758
759 ## __IsKeyword() method
760 #
761 # Check whether input keyword is found from current char position along, whole word only!
762 # If found, the string value is put into self.__Token
763 #
764 # @param self The object pointer
765 # @param Keyword The string to search
766 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
767 # @retval True Successfully find string, file buffer pointer moved forward
768 # @retval False Not able to find string, file buffer pointer not changed
769 #
770 def __IsKeyword(self, KeyWord, IgnoreCase = False):
771 self.__SkipWhiteSpace()
772
773 # Only consider the same line, no multi-line token allowed
774 StartPos = self.CurrentOffsetWithinLine
775 index = -1
776 if IgnoreCase:
777 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(KeyWord.upper())
778 else:
779 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(KeyWord)
780 if index == 0:
781 followingChar = self.__CurrentLine()[self.CurrentOffsetWithinLine + len(KeyWord)]
782 if not str(followingChar).isspace() and followingChar not in SEPERATOR_TUPLE:
783 return False
784 self.CurrentOffsetWithinLine += len(KeyWord)
785 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
786 return True
787 return False
788
789 def __GetExpression(self):
790 Line = self.Profile.FileLinesList[self.CurrentLineNumber - 1]
791 Index = len(Line) - 1
792 while Line[Index] in ['\r', '\n']:
793 Index -= 1
794 ExpressionString = self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:Index+1]
795 self.CurrentOffsetWithinLine += len(ExpressionString)
796 ExpressionString = ExpressionString.strip()
797 return ExpressionString
798
799 ## __GetNextWord() method
800 #
801 # Get next C name from file lines
802 # If found, the string value is put into self.__Token
803 #
804 # @param self The object pointer
805 # @retval True Successfully find a C name string, file buffer pointer moved forward
806 # @retval False Not able to find a C name string, file buffer pointer not changed
807 #
808 def __GetNextWord(self):
809 self.__SkipWhiteSpace()
810 if self.__EndOfFile():
811 return False
812
813 TempChar = self.__CurrentChar()
814 StartPos = self.CurrentOffsetWithinLine
815 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_':
816 self.__GetOneChar()
817 while not self.__EndOfLine():
818 TempChar = self.__CurrentChar()
819 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \
820 or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-':
821 self.__GetOneChar()
822
823 else:
824 break
825
826 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
827 return True
828
829 return False
830
831 ## __GetNextToken() method
832 #
833 # Get next token unit before a seperator
834 # If found, the string value is put into self.__Token
835 #
836 # @param self The object pointer
837 # @retval True Successfully find a token unit, file buffer pointer moved forward
838 # @retval False Not able to find a token unit, file buffer pointer not changed
839 #
840 def __GetNextToken(self):
841 # Skip leading spaces, if exist.
842 self.__SkipWhiteSpace()
843 if self.__EndOfFile():
844 return False
845 # Record the token start position, the position of the first non-space char.
846 StartPos = self.CurrentOffsetWithinLine
847 StartLine = self.CurrentLineNumber
848 while not self.__EndOfLine():
849 TempChar = self.__CurrentChar()
850 # Try to find the end char that is not a space and not in seperator tuple.
851 # That is, when we got a space or any char in the tuple, we got the end of token.
852 if not str(TempChar).isspace() and TempChar not in SEPERATOR_TUPLE:
853 self.__GetOneChar()
854 # if we happen to meet a seperator as the first char, we must proceed to get it.
855 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
856 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:
857 self.__GetOneChar()
858 break
859 else:
860 break
861 # else:
862 # return False
863
864 EndPos = self.CurrentOffsetWithinLine
865 if self.CurrentLineNumber != StartLine:
866 EndPos = len(self.Profile.FileLinesList[StartLine-1])
867 self.__Token = self.Profile.FileLinesList[StartLine-1][StartPos : EndPos]
868 if StartPos != self.CurrentOffsetWithinLine:
869 return True
870 else:
871 return False
872
873 def __GetNextOp(self):
874 # Skip leading spaces, if exist.
875 self.__SkipWhiteSpace()
876 if self.__EndOfFile():
877 return False
878 # Record the token start position, the position of the first non-space char.
879 StartPos = self.CurrentOffsetWithinLine
880 while not self.__EndOfLine():
881 TempChar = self.__CurrentChar()
882 # Try to find the end char that is not a space
883 if not str(TempChar).isspace():
884 self.__GetOneChar()
885 else:
886 break
887 else:
888 return False
889
890 if StartPos != self.CurrentOffsetWithinLine:
891 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
892 return True
893 else:
894 return False
895 ## __GetNextGuid() method
896 #
897 # Get next token unit before a seperator
898 # If found, the GUID string is put into self.__Token
899 #
900 # @param self The object pointer
901 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward
902 # @retval False Not able to find a registry format GUID, file buffer pointer not changed
903 #
904 def __GetNextGuid(self):
905
906 if not self.__GetNextToken():
907 return False
908 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}')
909 if p.match(self.__Token) != None:
910 return True
911 else:
912 self.__UndoToken()
913 return False
914
915 ## __UndoToken() method
916 #
917 # Go back one token unit in file buffer
918 #
919 # @param self The object pointer
920 #
921 def __UndoToken(self):
922 self.__UndoOneChar()
923 while self.__CurrentChar().isspace():
924 if not self.__UndoOneChar():
925 self.__GetOneChar()
926 return
927
928
929 StartPos = self.CurrentOffsetWithinLine
930 CurrentLine = self.CurrentLineNumber
931 while CurrentLine == self.CurrentLineNumber:
932
933 TempChar = self.__CurrentChar()
934 # Try to find the end char that is not a space and not in seperator tuple.
935 # That is, when we got a space or any char in the tuple, we got the end of token.
936 if not str(TempChar).isspace() and not TempChar in SEPERATOR_TUPLE:
937 if not self.__UndoOneChar():
938 break
939 # if we happen to meet a seperator as the first char, we must proceed to get it.
940 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
941 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:
942 return
943 else:
944 break
945
946 self.__GetOneChar()
947
948 ## __HexDigit() method
949 #
950 # Whether char input is a Hex data bit
951 #
952 # @param self The object pointer
953 # @param TempChar The char to test
954 # @retval True The char is a Hex data bit
955 # @retval False The char is NOT a Hex data bit
956 #
957 def __HexDigit(self, TempChar):
958 if (TempChar >= 'a' and TempChar <= 'f') or (TempChar >= 'A' and TempChar <= 'F') \
959 or (TempChar >= '0' and TempChar <= '9'):
960 return True
961 else:
962 return False
963
964 def __IsHex(self, HexStr):
965 if not HexStr.upper().startswith("0X"):
966 return False
967 if len(self.__Token) <= 2:
968 return False
969 charList = [c for c in HexStr[2 : ] if not self.__HexDigit( c)]
970 if len(charList) == 0:
971 return True
972 else:
973 return False
974 ## __GetNextHexNumber() method
975 #
976 # Get next HEX data before a seperator
977 # If found, the HEX data is put into self.__Token
978 #
979 # @param self The object pointer
980 # @retval True Successfully find a HEX data, file buffer pointer moved forward
981 # @retval False Not able to find a HEX data, file buffer pointer not changed
982 #
983 def __GetNextHexNumber(self):
984 if not self.__GetNextToken():
985 return False
986 if self.__IsHex(self.__Token):
987 return True
988 else:
989 self.__UndoToken()
990 return False
991
992 ## __GetNextDecimalNumber() method
993 #
994 # Get next decimal data before a seperator
995 # If found, the decimal data is put into self.__Token
996 #
997 # @param self The object pointer
998 # @retval True Successfully find a decimal data, file buffer pointer moved forward
999 # @retval False Not able to find a decimal data, file buffer pointer not changed
1000 #
1001 def __GetNextDecimalNumber(self):
1002 if not self.__GetNextToken():
1003 return False
1004 if self.__Token.isdigit():
1005 return True
1006 else:
1007 self.__UndoToken()
1008 return False
1009
1010 ## __GetNextPcdName() method
1011 #
1012 # Get next PCD token space C name and PCD C name pair before a seperator
1013 # If found, the decimal data is put into self.__Token
1014 #
1015 # @param self The object pointer
1016 # @retval Tuple PCD C name and PCD token space C name pair
1017 #
1018 def __GetNextPcdName(self):
1019 if not self.__GetNextWord():
1020 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)
1021 pcdTokenSpaceCName = self.__Token
1022
1023 if not self.__IsToken( "."):
1024 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)
1025
1026 if not self.__GetNextWord():
1027 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)
1028 pcdCName = self.__Token
1029
1030 return (pcdCName, pcdTokenSpaceCName)
1031
1032 ## __GetStringData() method
1033 #
1034 # Get string contents quoted in ""
1035 # If found, the decimal data is put into self.__Token
1036 #
1037 # @param self The object pointer
1038 # @retval True Successfully find a string data, file buffer pointer moved forward
1039 # @retval False Not able to find a string data, file buffer pointer not changed
1040 #
1041 def __GetStringData(self):
1042 if self.__Token.startswith("\"") or self.__Token.startswith("L\""):
1043 self.__UndoToken()
1044 self.__SkipToToken("\"")
1045 currentLineNumber = self.CurrentLineNumber
1046
1047 if not self.__SkipToToken("\""):
1048 raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber)
1049 if currentLineNumber != self.CurrentLineNumber:
1050 raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber)
1051 self.__Token = self.__SkippedChars.rstrip('\"')
1052 return True
1053
1054 elif self.__Token.startswith("\'") or self.__Token.startswith("L\'"):
1055 self.__UndoToken()
1056 self.__SkipToToken("\'")
1057 currentLineNumber = self.CurrentLineNumber
1058
1059 if not self.__SkipToToken("\'"):
1060 raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber)
1061 if currentLineNumber != self.CurrentLineNumber:
1062 raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber)
1063 self.__Token = self.__SkippedChars.rstrip('\'')
1064 return True
1065
1066 else:
1067 return False
1068
1069 ## __SkipToToken() method
1070 #
1071 # Search forward in file buffer for the string
1072 # The skipped chars are put into self.__SkippedChars
1073 #
1074 # @param self The object pointer
1075 # @param String The string to search
1076 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
1077 # @retval True Successfully find the string, file buffer pointer moved forward
1078 # @retval False Not able to find the string, file buffer pointer not changed
1079 #
1080 def __SkipToToken(self, String, IgnoreCase = False):
1081 StartPos = self.GetFileBufferPos()
1082
1083 self.__SkippedChars = ""
1084 while not self.__EndOfFile():
1085 index = -1
1086 if IgnoreCase:
1087 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())
1088 else:
1089 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)
1090 if index == 0:
1091 self.CurrentOffsetWithinLine += len(String)
1092 self.__SkippedChars += String
1093 return True
1094 self.__SkippedChars += str(self.__CurrentChar())
1095 self.__GetOneChar()
1096
1097 self.SetFileBufferPos( StartPos)
1098 self.__SkippedChars = ""
1099 return False
1100
1101 ## GetFileBufferPos() method
1102 #
1103 # Return the tuple of current line and offset within the line
1104 #
1105 # @param self The object pointer
1106 # @retval Tuple Line number and offset pair
1107 #
1108 def GetFileBufferPos(self):
1109 return (self.CurrentLineNumber, self.CurrentOffsetWithinLine)
1110
1111 ## SetFileBufferPos() method
1112 #
1113 # Restore the file buffer position
1114 #
1115 # @param self The object pointer
1116 # @param Pos The new file buffer position
1117 #
1118 def SetFileBufferPos(self, Pos):
1119 (self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos
1120
1121 ## ParseFile() method
1122 #
1123 # Parse the file profile buffer to extract fd, fv ... information
1124 # Exception will be raised if syntax error found
1125 #
1126 # @param self The object pointer
1127 #
1128 def ParseFile(self):
1129
1130 try:
1131 self.__StringToList()
1132 self.PreprocessFile()
1133 self.PreprocessIncludeFile()
1134 self.__StringToList()
1135 self.PreprocessFile()
1136 self.PreprocessConditionalStatement()
1137 self.__StringToList()
1138 for Pos in self.__WipeOffArea:
1139 self.__ReplaceFragment(Pos[0], Pos[1])
1140 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
1141
1142 while self.__GetDefines():
1143 pass
1144
1145 Index = 0
1146 while Index < len(self.Profile.FileLinesList):
1147 FileLineTuple = GetRealFileLine(self.FileName, Index + 1)
1148 self.Profile.FileLinesList[Index] = self.__ReplaceMacros(self.Profile.FileLinesList[Index], FileLineTuple[0], FileLineTuple[1])
1149 Index += 1
1150
1151 while self.__GetFd():
1152 pass
1153
1154 while self.__GetFv():
1155 pass
1156
1157 while self.__GetCapsule():
1158 pass
1159
1160 while self.__GetVtf():
1161 pass
1162
1163 while self.__GetRule():
1164 pass
1165
1166 while self.__GetOptionRom():
1167 pass
1168
1169 except Warning, X:
1170 self.__UndoToken()
1171 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1172 #'\n\tGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \
1173 X.Message += ' near line %d, column %d: %s' \
1174 % (FileLineTuple[1], self.CurrentOffsetWithinLine + 1, self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :].rstrip('\n').rstrip('\r'))
1175 raise
1176
1177 ## __GetDefines() method
1178 #
1179 # Get Defines section contents and store its data into AllMacrosList
1180 #
1181 # @param self The object pointer
1182 # @retval True Successfully find a Defines
1183 # @retval False Not able to find a Defines
1184 #
1185 def __GetDefines(self):
1186
1187 if not self.__GetNextToken():
1188 return False
1189
1190 S = self.__Token.upper()
1191 if S.startswith("[") and not S.startswith("[DEFINES"):
1192 if not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \
1193 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
1194 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)
1195 self.__UndoToken()
1196 return False
1197
1198 self.__UndoToken()
1199 if not self.__IsToken("[DEFINES", True):
1200 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1201 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1202 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1203 raise Warning("expected [DEFINES", self.FileName, self.CurrentLineNumber)
1204
1205 if not self.__IsToken( "]"):
1206 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
1207
1208 while self.__GetNextWord():
1209 # handle the SET statement
1210 if self.__Token == 'SET':
1211 self.__UndoToken()
1212 self.__GetSetStatement(None)
1213 continue
1214
1215 Macro = self.__Token
1216
1217 if not self.__IsToken("="):
1218 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1219 if not self.__GetNextToken() or self.__Token.startswith('['):
1220 raise Warning("expected MACRO value", self.FileName, self.CurrentLineNumber)
1221 Value = self.__Token
1222 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1223 MacProfile = MacroProfile(FileLineTuple[0], FileLineTuple[1])
1224 MacProfile.MacroName = Macro
1225 MacProfile.MacroValue = Value
1226 AllMacroList.append(MacProfile)
1227
1228 return False
1229
1230 ## __GetFd() method
1231 #
1232 # Get FD section contents and store its data into FD dictionary of self.Profile
1233 #
1234 # @param self The object pointer
1235 # @retval True Successfully find a FD
1236 # @retval False Not able to find a FD
1237 #
1238 def __GetFd(self):
1239
1240 if not self.__GetNextToken():
1241 return False
1242
1243 S = self.__Token.upper()
1244 if S.startswith("[") and not S.startswith("[FD."):
1245 if not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \
1246 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
1247 raise Warning("Unknown section", self.FileName, self.CurrentLineNumber)
1248 self.__UndoToken()
1249 return False
1250
1251 self.__UndoToken()
1252 if not self.__IsToken("[FD.", True):
1253 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1254 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1255 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1256 raise Warning("expected [FD.]", self.FileName, self.CurrentLineNumber)
1257
1258 FdName = self.__GetUiName()
1259 if FdName == "":
1260 if len (self.Profile.FdDict) == 0:
1261 FdName = GenFdsGlobalVariable.PlatformName
1262 self.Profile.FdNameNotSet = True
1263 else:
1264 raise Warning("expected FdName in [FD.] section", self.FileName, self.CurrentLineNumber)
1265 self.CurrentFdName = FdName.upper()
1266
1267 if self.CurrentFdName in self.Profile.FdDict:
1268 raise Warning("Unexpected the same FD name", self.FileName, self.CurrentLineNumber)
1269
1270 if not self.__IsToken( "]"):
1271 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
1272
1273 FdObj = Fd.FD()
1274 FdObj.FdUiName = self.CurrentFdName
1275 self.Profile.FdDict[self.CurrentFdName] = FdObj
1276
1277 if len (self.Profile.FdDict) > 1 and self.Profile.FdNameNotSet:
1278 raise Warning("expected all FDs have their name", self.FileName, self.CurrentLineNumber)
1279
1280 Status = self.__GetCreateFile(FdObj)
1281 if not Status:
1282 raise Warning("FD name error", self.FileName, self.CurrentLineNumber)
1283
1284 self.__GetTokenStatements(FdObj)
1285
1286 self.__GetDefineStatements(FdObj)
1287
1288 self.__GetSetStatements(FdObj)
1289
1290 if not self.__GetRegionLayout(FdObj):
1291 raise Warning("expected region layout", self.FileName, self.CurrentLineNumber)
1292
1293 while self.__GetRegionLayout(FdObj):
1294 pass
1295 return True
1296
1297 ## __GetUiName() method
1298 #
1299 # Return the UI name of a section
1300 #
1301 # @param self The object pointer
1302 # @retval FdName UI name
1303 #
1304 def __GetUiName(self):
1305 Name = ""
1306 if self.__GetNextWord():
1307 Name = self.__Token
1308
1309 return Name
1310
1311 ## __GetCreateFile() method
1312 #
1313 # Return the output file name of object
1314 #
1315 # @param self The object pointer
1316 # @param Obj object whose data will be stored in file
1317 # @retval FdName UI name
1318 #
1319 def __GetCreateFile(self, Obj):
1320
1321 if self.__IsKeyword( "CREATE_FILE"):
1322 if not self.__IsToken( "="):
1323 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1324
1325 if not self.__GetNextToken():
1326 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)
1327
1328 FileName = self.__Token
1329 Obj.CreateFileName = FileName
1330
1331 return True
1332
1333 ## __GetTokenStatements() method
1334 #
1335 # Get token statements
1336 #
1337 # @param self The object pointer
1338 # @param Obj for whom token statement is got
1339 #
1340 def __GetTokenStatements(self, Obj):
1341 if not self.__IsKeyword( "BaseAddress"):
1342 raise Warning("BaseAddress missing", self.FileName, self.CurrentLineNumber)
1343
1344 if not self.__IsToken( "="):
1345 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1346
1347 if not self.__GetNextHexNumber():
1348 raise Warning("expected Hex base address", self.FileName, self.CurrentLineNumber)
1349
1350 Obj.BaseAddress = self.__Token
1351
1352 if self.__IsToken( "|"):
1353 pcdPair = self.__GetNextPcdName()
1354 Obj.BaseAddressPcd = pcdPair
1355 self.Profile.PcdDict[pcdPair] = Obj.BaseAddress
1356
1357 if not self.__IsKeyword( "Size"):
1358 raise Warning("Size missing", self.FileName, self.CurrentLineNumber)
1359
1360 if not self.__IsToken( "="):
1361 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1362
1363 if not self.__GetNextHexNumber():
1364 raise Warning("expected Hex size", self.FileName, self.CurrentLineNumber)
1365
1366
1367 Size = self.__Token
1368 if self.__IsToken( "|"):
1369 pcdPair = self.__GetNextPcdName()
1370 Obj.SizePcd = pcdPair
1371 self.Profile.PcdDict[pcdPair] = Size
1372 Obj.Size = long(Size, 0)
1373
1374 if not self.__IsKeyword( "ErasePolarity"):
1375 raise Warning("ErasePolarity missing", self.FileName, self.CurrentLineNumber)
1376
1377 if not self.__IsToken( "="):
1378 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1379
1380 if not self.__GetNextToken():
1381 raise Warning("expected Erase Polarity", self.FileName, self.CurrentLineNumber)
1382
1383 if self.__Token != "1" and self.__Token != "0":
1384 raise Warning("expected 1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber)
1385
1386 Obj.ErasePolarity = self.__Token
1387
1388 self.__GetBlockStatements(Obj)
1389
1390 ## __GetAddressStatements() method
1391 #
1392 # Get address statements
1393 #
1394 # @param self The object pointer
1395 # @param Obj for whom address statement is got
1396 # @retval True Successfully find
1397 # @retval False Not able to find
1398 #
1399 def __GetAddressStatements(self, Obj):
1400
1401 if self.__IsKeyword("BsBaseAddress"):
1402 if not self.__IsToken( "="):
1403 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1404
1405 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
1406 raise Warning("expected address", self.FileName, self.CurrentLineNumber)
1407
1408 BsAddress = long(self.__Token, 0)
1409 Obj.BsBaseAddress = BsAddress
1410
1411 if self.__IsKeyword("RtBaseAddress"):
1412 if not self.__IsToken( "="):
1413 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1414
1415 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
1416 raise Warning("expected address", self.FileName, self.CurrentLineNumber)
1417
1418 RtAddress = long(self.__Token, 0)
1419 Obj.RtBaseAddress = RtAddress
1420
1421 ## __GetBlockStatements() method
1422 #
1423 # Get block statements
1424 #
1425 # @param self The object pointer
1426 # @param Obj for whom block statement is got
1427 #
1428 def __GetBlockStatements(self, Obj):
1429
1430 if not self.__GetBlockStatement(Obj):
1431 #set default block size is 1
1432 Obj.BlockSizeList.append((1, Obj.Size, None))
1433 return
1434
1435 while self.__GetBlockStatement(Obj):
1436 pass
1437
1438 for Item in Obj.BlockSizeList:
1439 if Item[0] == None or Item[1] == None:
1440 raise Warning("expected block statement", self.FileName, self.CurrentLineNumber)
1441
1442 ## __GetBlockStatement() method
1443 #
1444 # Get block statement
1445 #
1446 # @param self The object pointer
1447 # @param Obj for whom block statement is got
1448 # @retval True Successfully find
1449 # @retval False Not able to find
1450 #
1451 def __GetBlockStatement(self, Obj):
1452 if not self.__IsKeyword( "BlockSize"):
1453 return False
1454
1455 if not self.__IsToken( "="):
1456 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1457
1458 if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():
1459 raise Warning("expected Hex or Integer block size", self.FileName, self.CurrentLineNumber)
1460
1461 BlockSize = self.__Token
1462 BlockSizePcd = None
1463 if self.__IsToken( "|"):
1464 PcdPair = self.__GetNextPcdName()
1465 BlockSizePcd = PcdPair
1466 self.Profile.PcdDict[PcdPair] = BlockSize
1467 BlockSize = long(BlockSize, 0)
1468
1469 BlockNumber = None
1470 if self.__IsKeyword( "NumBlocks"):
1471 if not self.__IsToken( "="):
1472 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1473
1474 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
1475 raise Warning("expected block numbers", self.FileName, self.CurrentLineNumber)
1476
1477 BlockNumber = long(self.__Token, 0)
1478
1479 Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd))
1480 return True
1481
1482 ## __GetDefineStatements() method
1483 #
1484 # Get define statements
1485 #
1486 # @param self The object pointer
1487 # @param Obj for whom define statement is got
1488 # @retval True Successfully find
1489 # @retval False Not able to find
1490 #
1491 def __GetDefineStatements(self, Obj):
1492 while self.__GetDefineStatement( Obj):
1493 pass
1494
1495 ## __GetDefineStatement() method
1496 #
1497 # Get define statement
1498 #
1499 # @param self The object pointer
1500 # @param Obj for whom define statement is got
1501 # @retval True Successfully find
1502 # @retval False Not able to find
1503 #
1504 def __GetDefineStatement(self, Obj):
1505 if self.__IsKeyword("DEFINE"):
1506 self.__GetNextToken()
1507 Macro = self.__Token
1508 if not self.__IsToken( "="):
1509 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1510
1511 if not self.__GetNextToken():
1512 raise Warning("expected value", self.FileName, self.CurrentLineNumber)
1513
1514 Value = self.__Token
1515 Macro = '$(' + Macro + ')'
1516 Obj.DefineVarDict[Macro] = Value
1517 return True
1518
1519 return False
1520
1521 ## __GetSetStatements() method
1522 #
1523 # Get set statements
1524 #
1525 # @param self The object pointer
1526 # @param Obj for whom set statement is got
1527 # @retval True Successfully find
1528 # @retval False Not able to find
1529 #
1530 def __GetSetStatements(self, Obj):
1531 while self.__GetSetStatement(Obj):
1532 pass
1533
1534 ## __GetSetStatement() method
1535 #
1536 # Get set statement
1537 #
1538 # @param self The object pointer
1539 # @param Obj for whom set statement is got
1540 # @retval True Successfully find
1541 # @retval False Not able to find
1542 #
1543 def __GetSetStatement(self, Obj):
1544 if self.__IsKeyword("SET"):
1545 PcdPair = self.__GetNextPcdName()
1546
1547 if not self.__IsToken( "="):
1548 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1549
1550 if not self.__GetNextToken():
1551 raise Warning("expected value", self.FileName, self.CurrentLineNumber)
1552
1553 Value = self.__Token
1554 if Value.startswith("{"):
1555 # deal with value with {}
1556 if not self.__SkipToToken( "}"):
1557 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
1558 Value += self.__SkippedChars
1559
1560 if Obj:
1561 Obj.SetVarDict[PcdPair] = Value
1562 self.Profile.PcdDict[PcdPair] = Value
1563 return True
1564
1565 return False
1566
1567 ## __GetRegionLayout() method
1568 #
1569 # Get region layout for FD
1570 #
1571 # @param self The object pointer
1572 # @param Fd for whom region is got
1573 # @retval True Successfully find
1574 # @retval False Not able to find
1575 #
1576 def __GetRegionLayout(self, Fd):
1577 if not self.__GetNextHexNumber():
1578 return False
1579
1580 RegionObj = Region.Region()
1581 RegionObj.Offset = long(self.__Token, 0)
1582 Fd.RegionList.append(RegionObj)
1583
1584 if not self.__IsToken( "|"):
1585 raise Warning("expected '|'", self.FileName, self.CurrentLineNumber)
1586
1587 if not self.__GetNextHexNumber():
1588 raise Warning("expected Region Size", self.FileName, self.CurrentLineNumber)
1589 RegionObj.Size = long(self.__Token, 0)
1590
1591 if not self.__GetNextWord():
1592 return True
1593
1594 if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE"):
1595 self.__UndoToken()
1596 RegionObj.PcdOffset = self.__GetNextPcdName()
1597 self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0))
1598 if self.__IsToken( "|"):
1599 RegionObj.PcdSize = self.__GetNextPcdName()
1600 self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size
1601
1602 if not self.__GetNextWord():
1603 return True
1604
1605 if self.__Token == "SET":
1606 self.__UndoToken()
1607 self.__GetSetStatements( RegionObj)
1608 if not self.__GetNextWord():
1609 return True
1610
1611 elif self.__Token == "FV":
1612 self.__UndoToken()
1613 self.__GetRegionFvType( RegionObj)
1614
1615 elif self.__Token == "CAPSULE":
1616 self.__UndoToken()
1617 self.__GetRegionCapType( RegionObj)
1618
1619 elif self.__Token == "FILE":
1620 self.__UndoToken()
1621 self.__GetRegionFileType( RegionObj)
1622
1623 elif self.__Token == "DATA":
1624 self.__UndoToken()
1625 self.__GetRegionDataType( RegionObj)
1626 else:
1627 raise Warning("A valid region type was not found. "
1628 "Valid types are [SET, FV, CAPSULE, FILE, DATA]. This error occurred",
1629 self.FileName, self.CurrentLineNumber)
1630
1631 return True
1632
1633 ## __GetRegionFvType() method
1634 #
1635 # Get region fv data for region
1636 #
1637 # @param self The object pointer
1638 # @param RegionObj for whom region data is got
1639 #
1640 def __GetRegionFvType(self, RegionObj):
1641
1642 if not self.__IsKeyword( "FV"):
1643 raise Warning("expected Keyword 'FV'", self.FileName, self.CurrentLineNumber)
1644
1645 if not self.__IsToken( "="):
1646 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1647
1648 if not self.__GetNextToken():
1649 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
1650
1651 RegionObj.RegionType = "FV"
1652 RegionObj.RegionDataList.append(self.__Token)
1653
1654 while self.__IsKeyword( "FV"):
1655
1656 if not self.__IsToken( "="):
1657 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1658
1659 if not self.__GetNextToken():
1660 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
1661
1662 RegionObj.RegionDataList.append(self.__Token)
1663
1664 ## __GetRegionCapType() method
1665 #
1666 # Get region capsule data for region
1667 #
1668 # @param self The object pointer
1669 # @param RegionObj for whom region data is got
1670 #
1671 def __GetRegionCapType(self, RegionObj):
1672
1673 if not self.__IsKeyword("CAPSULE"):
1674 raise Warning("expected Keyword 'CAPSULE'", self.FileName, self.CurrentLineNumber)
1675
1676 if not self.__IsToken("="):
1677 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1678
1679 if not self.__GetNextToken():
1680 raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)
1681
1682 RegionObj.RegionType = "CAPSULE"
1683 RegionObj.RegionDataList.append(self.__Token)
1684
1685 while self.__IsKeyword("CAPSULE"):
1686
1687 if not self.__IsToken("="):
1688 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1689
1690 if not self.__GetNextToken():
1691 raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)
1692
1693 RegionObj.RegionDataList.append(self.__Token)
1694
1695 ## __GetRegionFileType() method
1696 #
1697 # Get region file data for region
1698 #
1699 # @param self The object pointer
1700 # @param RegionObj for whom region data is got
1701 #
1702 def __GetRegionFileType(self, RegionObj):
1703
1704 if not self.__IsKeyword( "FILE"):
1705 raise Warning("expected Keyword 'FILE'", self.FileName, self.CurrentLineNumber)
1706
1707 if not self.__IsToken( "="):
1708 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1709
1710 if not self.__GetNextToken():
1711 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)
1712
1713 RegionObj.RegionType = "FILE"
1714 RegionObj.RegionDataList.append( self.__Token)
1715
1716 while self.__IsKeyword( "FILE"):
1717
1718 if not self.__IsToken( "="):
1719 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1720
1721 if not self.__GetNextToken():
1722 raise Warning("expected FILE name", self.FileName, self.CurrentLineNumber)
1723
1724 RegionObj.RegionDataList.append(self.__Token)
1725
1726 ## __GetRegionDataType() method
1727 #
1728 # Get region array data for region
1729 #
1730 # @param self The object pointer
1731 # @param RegionObj for whom region data is got
1732 #
1733 def __GetRegionDataType(self, RegionObj):
1734
1735 if not self.__IsKeyword( "DATA"):
1736 raise Warning("expected Region Data type", self.FileName, self.CurrentLineNumber)
1737
1738 if not self.__IsToken( "="):
1739 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1740
1741 if not self.__IsToken( "{"):
1742 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
1743
1744 if not self.__GetNextHexNumber():
1745 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)
1746
1747 if len(self.__Token) > 18:
1748 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)
1749
1750 # convert hex string value to byte hex string array
1751 AllString = self.__Token
1752 AllStrLen = len (AllString)
1753 DataString = ""
1754 while AllStrLen > 4:
1755 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + ","
1756 AllStrLen = AllStrLen - 2
1757 DataString = DataString + AllString[:AllStrLen] + ","
1758
1759 # byte value array
1760 if len (self.__Token) <= 4:
1761 while self.__IsToken(","):
1762 if not self.__GetNextHexNumber():
1763 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
1764 if len(self.__Token) > 4:
1765 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
1766 DataString += self.__Token
1767 DataString += ","
1768
1769 if not self.__IsToken( "}"):
1770 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
1771
1772 DataString = DataString.rstrip(",")
1773 RegionObj.RegionType = "DATA"
1774 RegionObj.RegionDataList.append( DataString)
1775
1776 while self.__IsKeyword( "DATA"):
1777
1778 if not self.__IsToken( "="):
1779 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1780
1781 if not self.__IsToken( "{"):
1782 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
1783
1784 if not self.__GetNextHexNumber():
1785 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)
1786
1787 if len(self.__Token) > 18:
1788 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)
1789
1790 # convert hex string value to byte hex string array
1791 AllString = self.__Token
1792 AllStrLen = len (AllString)
1793 DataString = ""
1794 while AllStrLen > 4:
1795 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + ","
1796 AllStrLen = AllStrLen - 2
1797 DataString = DataString + AllString[:AllStrLen] + ","
1798
1799 # byte value array
1800 if len (self.__Token) <= 4:
1801 while self.__IsToken(","):
1802 if not self.__GetNextHexNumber():
1803 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
1804 if len(self.__Token) > 4:
1805 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
1806 DataString += self.__Token
1807 DataString += ","
1808
1809 if not self.__IsToken( "}"):
1810 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
1811
1812 DataString = DataString.rstrip(",")
1813 RegionObj.RegionDataList.append( DataString)
1814
1815 ## __GetFv() method
1816 #
1817 # Get FV section contents and store its data into FV dictionary of self.Profile
1818 #
1819 # @param self The object pointer
1820 # @retval True Successfully find a FV
1821 # @retval False Not able to find a FV
1822 #
1823 def __GetFv(self):
1824 if not self.__GetNextToken():
1825 return False
1826
1827 S = self.__Token.upper()
1828 if S.startswith("[") and not S.startswith("[FV."):
1829 if not S.startswith("[CAPSULE.") \
1830 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
1831 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
1832 self.__UndoToken()
1833 return False
1834
1835 self.__UndoToken()
1836 if not self.__IsToken("[FV.", True):
1837 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1838 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1839 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1840 raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
1841
1842 FvName = self.__GetUiName()
1843 self.CurrentFvName = FvName.upper()
1844
1845 if not self.__IsToken( "]"):
1846 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
1847
1848 FvObj = Fv.FV()
1849 FvObj.UiFvName = self.CurrentFvName
1850 self.Profile.FvDict[self.CurrentFvName] = FvObj
1851
1852 Status = self.__GetCreateFile(FvObj)
1853 if not Status:
1854 raise Warning("FV name error", self.FileName, self.CurrentLineNumber)
1855
1856 self.__GetDefineStatements(FvObj)
1857
1858 self.__GetAddressStatements(FvObj)
1859
1860 while self.__GetBlockStatement(FvObj):
1861 pass
1862
1863 self.__GetSetStatements(FvObj)
1864
1865 self.__GetFvBaseAddress(FvObj)
1866
1867 self.__GetFvForceRebase(FvObj)
1868
1869 self.__GetFvAlignment(FvObj)
1870
1871 self.__GetFvAttributes(FvObj)
1872
1873 self.__GetFvNameGuid(FvObj)
1874
1875 FvObj.FvExtEntryTypeValue = []
1876 FvObj.FvExtEntryType = []
1877 FvObj.FvExtEntryData = []
1878 while True:
1879 isFvExtEntry = self.__GetFvExtEntryStatement(FvObj)
1880 if not isFvExtEntry:
1881 break
1882
1883 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())
1884 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())
1885
1886 while True:
1887 isInf = self.__GetInfStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())
1888 isFile = self.__GetFileStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())
1889 if not isInf and not isFile:
1890 break
1891
1892 return True
1893
1894 ## __GetFvAlignment() method
1895 #
1896 # Get alignment for FV
1897 #
1898 # @param self The object pointer
1899 # @param Obj for whom alignment is got
1900 # @retval True Successfully find a alignment statement
1901 # @retval False Not able to find a alignment statement
1902 #
1903 def __GetFvAlignment(self, Obj):
1904
1905 if not self.__IsKeyword( "FvAlignment"):
1906 return False
1907
1908 if not self.__IsToken( "="):
1909 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1910
1911 if not self.__GetNextToken():
1912 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)
1913
1914 if self.__Token.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
1915 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
1916 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
1917 "1G", "2G"):
1918 raise Warning("Unknown alignment value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
1919 Obj.FvAlignment = self.__Token
1920 return True
1921
1922 ## __GetFvBaseAddress() method
1923 #
1924 # Get BaseAddress for FV
1925 #
1926 # @param self The object pointer
1927 # @param Obj for whom FvBaseAddress is got
1928 # @retval True Successfully find a FvBaseAddress statement
1929 # @retval False Not able to find a FvBaseAddress statement
1930 #
1931 def __GetFvBaseAddress(self, Obj):
1932
1933 if not self.__IsKeyword("FvBaseAddress"):
1934 return False
1935
1936 if not self.__IsToken( "="):
1937 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1938
1939 if not self.__GetNextToken():
1940 raise Warning("expected FV base address value", self.FileName, self.CurrentLineNumber)
1941
1942 IsValidBaseAddrValue = re.compile('^0[x|X][0-9a-fA-F]+')
1943
1944 if not IsValidBaseAddrValue.match(self.__Token.upper()):
1945 raise Warning("Unknown FV base address value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
1946 Obj.FvBaseAddress = self.__Token
1947 return True
1948
1949 ## __GetFvForceRebase() method
1950 #
1951 # Get FvForceRebase for FV
1952 #
1953 # @param self The object pointer
1954 # @param Obj for whom FvForceRebase is got
1955 # @retval True Successfully find a FvForceRebase statement
1956 # @retval False Not able to find a FvForceRebase statement
1957 #
1958 def __GetFvForceRebase(self, Obj):
1959
1960 if not self.__IsKeyword("FvForceRebase"):
1961 return False
1962
1963 if not self.__IsToken( "="):
1964 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1965
1966 if not self.__GetNextToken():
1967 raise Warning("expected FvForceRebase value", self.FileName, self.CurrentLineNumber)
1968
1969 if self.__Token.upper() not in ["TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"]:
1970 raise Warning("Unknown FvForceRebase value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
1971
1972 if self.__Token.upper() in ["TRUE", "1", "0X1", "0X01"]:
1973 Obj.FvForceRebase = True
1974 elif self.__Token.upper() in ["FALSE", "0", "0X0", "0X00"]:
1975 Obj.FvForceRebase = False
1976 else:
1977 Obj.FvForceRebase = None
1978
1979 return True
1980
1981
1982 ## __GetFvAttributes() method
1983 #
1984 # Get attributes for FV
1985 #
1986 # @param self The object pointer
1987 # @param Obj for whom attribute is got
1988 # @retval None
1989 #
1990 def __GetFvAttributes(self, FvObj):
1991
1992 while self.__GetNextWord():
1993 name = self.__Token
1994 if name not in ("ERASE_POLARITY", "MEMORY_MAPPED", \
1995 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
1996 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
1997 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
1998 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
1999 "WRITE_POLICY_RELIABLE"):
2000 self.__UndoToken()
2001 return
2002
2003 if not self.__IsToken( "="):
2004 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2005
2006 if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
2007 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)
2008
2009 FvObj.FvAttributeDict[name] = self.__Token
2010
2011 return
2012
2013 ## __GetFvNameGuid() method
2014 #
2015 # Get FV GUID for FV
2016 #
2017 # @param self The object pointer
2018 # @param Obj for whom GUID is got
2019 # @retval None
2020 #
2021 def __GetFvNameGuid(self, FvObj):
2022
2023 if not self.__IsKeyword( "FvNameGuid"):
2024 return
2025
2026 if not self.__IsToken( "="):
2027 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2028
2029 if not self.__GetNextGuid():
2030 raise Warning("expected FV GUID value", self.FileName, self.CurrentLineNumber)
2031
2032 FvObj.FvNameGuid = self.__Token
2033
2034 return
2035
2036 def __GetFvExtEntryStatement(self, FvObj):
2037
2038 if not self.__IsKeyword( "FV_EXT_ENTRY"):
2039 return False
2040
2041 if not self.__IsKeyword ("TYPE"):
2042 raise Warning("expected 'TYPE'", self.FileName, self.CurrentLineNumber)
2043
2044 if not self.__IsToken( "="):
2045 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2046
2047 if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():
2048 raise Warning("expected Hex FV extension entry type value At Line ", self.FileName, self.CurrentLineNumber)
2049
2050 FvObj.FvExtEntryTypeValue += [self.__Token]
2051
2052 if not self.__IsToken( "{"):
2053 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2054
2055 if not self.__IsKeyword ("FILE") and not self.__IsKeyword ("DATA"):
2056 raise Warning("expected 'FILE' or 'DATA'", self.FileName, self.CurrentLineNumber)
2057
2058 FvObj.FvExtEntryType += [self.__Token]
2059
2060 if self.__Token == 'DATA':
2061
2062 if not self.__IsToken( "="):
2063 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2064
2065 if not self.__IsToken( "{"):
2066 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2067
2068 if not self.__GetNextHexNumber():
2069 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)
2070
2071 if len(self.__Token) > 4:
2072 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
2073
2074 DataString = self.__Token
2075 DataString += ","
2076
2077 while self.__IsToken(","):
2078 if not self.__GetNextHexNumber():
2079 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
2080 if len(self.__Token) > 4:
2081 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
2082 DataString += self.__Token
2083 DataString += ","
2084
2085 if not self.__IsToken( "}"):
2086 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2087
2088 if not self.__IsToken( "}"):
2089 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2090
2091 DataString = DataString.rstrip(",")
2092 FvObj.FvExtEntryData += [DataString]
2093
2094 if self.__Token == 'FILE':
2095
2096 if not self.__IsToken( "="):
2097 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2098
2099 if not self.__GetNextToken():
2100 raise Warning("expected FV Extension Entry file path At Line ", self.FileName, self.CurrentLineNumber)
2101
2102 FvObj.FvExtEntryData += [self.__Token]
2103
2104 if not self.__IsToken( "}"):
2105 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2106
2107 return True
2108
2109 ## __GetAprioriSection() method
2110 #
2111 # Get token statements
2112 #
2113 # @param self The object pointer
2114 # @param FvObj for whom apriori is got
2115 # @param MacroDict dictionary used to replace macro
2116 # @retval True Successfully find apriori statement
2117 # @retval False Not able to find apriori statement
2118 #
2119 def __GetAprioriSection(self, FvObj, MacroDict = {}):
2120
2121 if not self.__IsKeyword( "APRIORI"):
2122 return False
2123
2124 if not self.__IsKeyword("PEI") and not self.__IsKeyword("DXE"):
2125 raise Warning("expected Apriori file type", self.FileName, self.CurrentLineNumber)
2126 AprType = self.__Token
2127
2128 if not self.__IsToken( "{"):
2129 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2130
2131 AprSectionObj = AprioriSection.AprioriSection()
2132 AprSectionObj.AprioriType = AprType
2133
2134 self.__GetDefineStatements(AprSectionObj)
2135 MacroDict.update(AprSectionObj.DefineVarDict)
2136
2137 while True:
2138 IsInf = self.__GetInfStatement( AprSectionObj, MacroDict = MacroDict)
2139 IsFile = self.__GetFileStatement( AprSectionObj)
2140 if not IsInf and not IsFile:
2141 break
2142
2143 if not self.__IsToken( "}"):
2144 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2145
2146 FvObj.AprioriSectionList.append(AprSectionObj)
2147 return True
2148
2149 ## __GetInfStatement() method
2150 #
2151 # Get INF statements
2152 #
2153 # @param self The object pointer
2154 # @param Obj for whom inf statement is got
2155 # @param MacroDict dictionary used to replace macro
2156 # @retval True Successfully find inf statement
2157 # @retval False Not able to find inf statement
2158 #
2159 def __GetInfStatement(self, Obj, ForCapsule = False, MacroDict = {}):
2160
2161 if not self.__IsKeyword( "INF"):
2162 return False
2163
2164 ffsInf = FfsInfStatement.FfsInfStatement()
2165 self.__GetInfOptions( ffsInf)
2166
2167 if not self.__GetNextToken():
2168 raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)
2169 ffsInf.InfFileName = self.__Token
2170 if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:
2171 #do case sensitive check for file path
2172 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
2173 if ErrorCode != 0:
2174 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
2175
2176 if not ffsInf.InfFileName in self.Profile.InfList:
2177 self.Profile.InfList.append(ffsInf.InfFileName)
2178
2179 if self.__IsToken('|'):
2180 if self.__IsKeyword('RELOCS_STRIPPED'):
2181 ffsInf.KeepReloc = False
2182 elif self.__IsKeyword('RELOCS_RETAINED'):
2183 ffsInf.KeepReloc = True
2184 else:
2185 raise Warning("Unknown reloc strip flag '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2186
2187 ffsInf.CurrentLineNum = self.CurrentLineNumber
2188 ffsInf.CurrentLineContent = self.__CurrentLine()
2189
2190 if ForCapsule:
2191 capsuleFfs = CapsuleData.CapsuleFfs()
2192 capsuleFfs.Ffs = ffsInf
2193 Obj.CapsuleDataList.append(capsuleFfs)
2194 else:
2195 Obj.FfsList.append(ffsInf)
2196 return True
2197
2198 ## __GetInfOptions() method
2199 #
2200 # Get options for INF
2201 #
2202 # @param self The object pointer
2203 # @param FfsInfObj for whom option is got
2204 #
2205 def __GetInfOptions(self, FfsInfObj):
2206
2207 if self.__IsKeyword( "RuleOverride"):
2208 if not self.__IsToken( "="):
2209 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2210 if not self.__GetNextToken():
2211 raise Warning("expected Rule name", self.FileName, self.CurrentLineNumber)
2212 FfsInfObj.Rule = self.__Token
2213
2214 if self.__IsKeyword( "VERSION"):
2215 if not self.__IsToken( "="):
2216 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2217 if not self.__GetNextToken():
2218 raise Warning("expected Version", self.FileName, self.CurrentLineNumber)
2219
2220 if self.__GetStringData():
2221 FfsInfObj.Version = self.__Token
2222
2223 if self.__IsKeyword( "UI"):
2224 if not self.__IsToken( "="):
2225 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2226 if not self.__GetNextToken():
2227 raise Warning("expected UI name", self.FileName, self.CurrentLineNumber)
2228
2229 if self.__GetStringData():
2230 FfsInfObj.Ui = self.__Token
2231
2232 if self.__IsKeyword( "USE"):
2233 if not self.__IsToken( "="):
2234 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2235 if not self.__GetNextToken():
2236 raise Warning("expected ARCH name", self.FileName, self.CurrentLineNumber)
2237 FfsInfObj.UseArch = self.__Token
2238
2239
2240 if self.__GetNextToken():
2241 p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
2242 if p.match(self.__Token):
2243 FfsInfObj.KeyStringList.append(self.__Token)
2244 if not self.__IsToken(","):
2245 return
2246 else:
2247 self.__UndoToken()
2248 return
2249
2250 while self.__GetNextToken():
2251 if not p.match(self.__Token):
2252 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
2253 FfsInfObj.KeyStringList.append(self.__Token)
2254
2255 if not self.__IsToken(","):
2256 break
2257
2258 ## __GetFileStatement() method
2259 #
2260 # Get FILE statements
2261 #
2262 # @param self The object pointer
2263 # @param Obj for whom FILE statement is got
2264 # @param MacroDict dictionary used to replace macro
2265 # @retval True Successfully find FILE statement
2266 # @retval False Not able to find FILE statement
2267 #
2268 def __GetFileStatement(self, Obj, ForCapsule = False, MacroDict = {}):
2269
2270 if not self.__IsKeyword( "FILE"):
2271 return False
2272
2273 if not self.__GetNextWord():
2274 raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)
2275
2276 if ForCapsule and self.__Token == 'DATA':
2277 self.__UndoToken()
2278 self.__UndoToken()
2279 return False
2280
2281 FfsFileObj = FfsFileStatement.FileStatement()
2282 FfsFileObj.FvFileType = self.__Token
2283
2284 if not self.__IsToken( "="):
2285 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2286
2287 if not self.__GetNextGuid():
2288 if not self.__GetNextWord():
2289 raise Warning("expected File GUID", self.FileName, self.CurrentLineNumber)
2290 if self.__Token == 'PCD':
2291 if not self.__IsToken( "("):
2292 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
2293 PcdPair = self.__GetNextPcdName()
2294 if not self.__IsToken( ")"):
2295 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
2296 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
2297
2298 FfsFileObj.NameGuid = self.__Token
2299
2300 FfsFileObj.CurrentLineNum = self.CurrentLineNumber
2301 FfsFileObj.CurrentLineContent = self.__CurrentLine()
2302
2303 self.__GetFilePart( FfsFileObj, MacroDict.copy())
2304
2305 if ForCapsule:
2306 capsuleFfs = CapsuleData.CapsuleFfs()
2307 capsuleFfs.Ffs = FfsFileObj
2308 Obj.CapsuleDataList.append(capsuleFfs)
2309 else:
2310 Obj.FfsList.append(FfsFileObj)
2311
2312 return True
2313
2314 ## __FileCouldHaveRelocFlag() method
2315 #
2316 # Check whether reloc strip flag can be set for a file type.
2317 #
2318 # @param self The object pointer
2319 # @param FileType The file type to check with
2320 # @retval True This type could have relocation strip flag
2321 # @retval False No way to have it
2322 #
2323
2324 def __FileCouldHaveRelocFlag (self, FileType):
2325 if FileType in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'):
2326 return True
2327 else:
2328 return False
2329
2330 ## __SectionCouldHaveRelocFlag() method
2331 #
2332 # Check whether reloc strip flag can be set for a section type.
2333 #
2334 # @param self The object pointer
2335 # @param SectionType The section type to check with
2336 # @retval True This type could have relocation strip flag
2337 # @retval False No way to have it
2338 #
2339
2340 def __SectionCouldHaveRelocFlag (self, SectionType):
2341 if SectionType in ('TE', 'PE32'):
2342 return True
2343 else:
2344 return False
2345
2346 ## __GetFilePart() method
2347 #
2348 # Get components for FILE statement
2349 #
2350 # @param self The object pointer
2351 # @param FfsFileObj for whom component is got
2352 # @param MacroDict dictionary used to replace macro
2353 #
2354 def __GetFilePart(self, FfsFileObj, MacroDict = {}):
2355
2356 self.__GetFileOpts( FfsFileObj)
2357
2358 if not self.__IsToken("{"):
2359 # if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
2360 # if self.__FileCouldHaveRelocFlag(FfsFileObj.FvFileType):
2361 # if self.__Token == 'RELOCS_STRIPPED':
2362 # FfsFileObj.KeepReloc = False
2363 # else:
2364 # FfsFileObj.KeepReloc = True
2365 # else:
2366 # raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
2367 #
2368 # if not self.__IsToken("{"):
2369 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2370
2371 if not self.__GetNextToken():
2372 raise Warning("expected File name or section data", self.FileName, self.CurrentLineNumber)
2373
2374 if self.__Token == "FV":
2375 if not self.__IsToken( "="):
2376 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2377 if not self.__GetNextToken():
2378 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
2379 FfsFileObj.FvName = self.__Token
2380
2381 elif self.__Token == "FD":
2382 if not self.__IsToken( "="):
2383 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2384 if not self.__GetNextToken():
2385 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)
2386 FfsFileObj.FdName = self.__Token
2387
2388 elif self.__Token in ("DEFINE", "APRIORI", "SECTION"):
2389 self.__UndoToken()
2390 self.__GetSectionData( FfsFileObj, MacroDict)
2391 else:
2392 FfsFileObj.FileName = self.__Token
2393 if FfsFileObj.FileName.replace('$(WORKSPACE)', '').find('$') == -1:
2394 #
2395 # For file in OUTPUT_DIRECTORY will not check whether it exist or not at AutoGen phase.
2396 #
2397 if not GlobalData.gAutoGenPhase:
2398 #do case sensitive check for file path
2399 ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
2400 if ErrorCode != 0:
2401 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
2402 else:
2403 if not InputMacroDict["OUTPUT_DIRECTORY"] in FfsFileObj.FileName:
2404 #do case sensitive check for file path
2405 ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
2406 if ErrorCode != 0:
2407 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
2408
2409
2410 if not self.__IsToken( "}"):
2411 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2412
2413 ## __GetFileOpts() method
2414 #
2415 # Get options for FILE statement
2416 #
2417 # @param self The object pointer
2418 # @param FfsFileObj for whom options is got
2419 #
2420 def __GetFileOpts(self, FfsFileObj):
2421
2422 if self.__GetNextToken():
2423 Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
2424 if Pattern.match(self.__Token):
2425 FfsFileObj.KeyStringList.append(self.__Token)
2426 if self.__IsToken(","):
2427 while self.__GetNextToken():
2428 if not Pattern.match(self.__Token):
2429 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
2430 FfsFileObj.KeyStringList.append(self.__Token)
2431
2432 if not self.__IsToken(","):
2433 break
2434
2435 else:
2436 self.__UndoToken()
2437
2438 if self.__IsKeyword( "FIXED", True):
2439 FfsFileObj.Fixed = True
2440
2441 if self.__IsKeyword( "CHECKSUM", True):
2442 FfsFileObj.CheckSum = True
2443
2444 if self.__GetAlignment():
2445 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2446 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2447 #For FFS, Auto is default option same to ""
2448 if not self.__Token == "Auto":
2449 FfsFileObj.Alignment = self.__Token
2450
2451 ## __GetAlignment() method
2452 #
2453 # Return the alignment value
2454 #
2455 # @param self The object pointer
2456 # @retval True Successfully find alignment
2457 # @retval False Not able to find alignment
2458 #
2459 def __GetAlignment(self):
2460 if self.__IsKeyword( "Align", True):
2461 if not self.__IsToken( "="):
2462 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2463
2464 if not self.__GetNextToken():
2465 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)
2466 return True
2467
2468 return False
2469
2470 ## __GetFilePart() method
2471 #
2472 # Get section data for FILE statement
2473 #
2474 # @param self The object pointer
2475 # @param FfsFileObj for whom section is got
2476 # @param MacroDict dictionary used to replace macro
2477 #
2478 def __GetSectionData(self, FfsFileObj, MacroDict = {}):
2479 Dict = {}
2480 Dict.update(MacroDict)
2481
2482 self.__GetDefineStatements(FfsFileObj)
2483
2484 Dict.update(FfsFileObj.DefineVarDict)
2485 self.__GetAprioriSection(FfsFileObj, Dict.copy())
2486 self.__GetAprioriSection(FfsFileObj, Dict.copy())
2487
2488 while True:
2489 IsLeafSection = self.__GetLeafSection(FfsFileObj, Dict)
2490 IsEncapSection = self.__GetEncapsulationSec(FfsFileObj)
2491 if not IsLeafSection and not IsEncapSection:
2492 break
2493
2494 ## __GetLeafSection() method
2495 #
2496 # Get leaf section for Obj
2497 #
2498 # @param self The object pointer
2499 # @param Obj for whom leaf section is got
2500 # @param MacroDict dictionary used to replace macro
2501 # @retval True Successfully find section statement
2502 # @retval False Not able to find section statement
2503 #
2504 def __GetLeafSection(self, Obj, MacroDict = {}):
2505
2506 OldPos = self.GetFileBufferPos()
2507
2508 if not self.__IsKeyword( "SECTION"):
2509 if len(Obj.SectionList) == 0:
2510 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)
2511 else:
2512 return False
2513
2514 AlignValue = None
2515 if self.__GetAlignment():
2516 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2517 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2518 AlignValue = self.__Token
2519
2520 BuildNum = None
2521 if self.__IsKeyword( "BUILD_NUM"):
2522 if not self.__IsToken( "="):
2523 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2524
2525 if not self.__GetNextToken():
2526 raise Warning("expected Build number value", self.FileName, self.CurrentLineNumber)
2527
2528 BuildNum = self.__Token
2529
2530 if self.__IsKeyword( "VERSION"):
2531 if AlignValue == 'Auto':
2532 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2533 if not self.__IsToken( "="):
2534 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2535 if not self.__GetNextToken():
2536 raise Warning("expected version", self.FileName, self.CurrentLineNumber)
2537 VerSectionObj = VerSection.VerSection()
2538 VerSectionObj.Alignment = AlignValue
2539 VerSectionObj.BuildNum = BuildNum
2540 if self.__GetStringData():
2541 VerSectionObj.StringData = self.__Token
2542 else:
2543 VerSectionObj.FileName = self.__Token
2544 Obj.SectionList.append(VerSectionObj)
2545
2546 elif self.__IsKeyword( "UI"):
2547 if AlignValue == 'Auto':
2548 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2549 if not self.__IsToken( "="):
2550 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2551 if not self.__GetNextToken():
2552 raise Warning("expected UI", self.FileName, self.CurrentLineNumber)
2553 UiSectionObj = UiSection.UiSection()
2554 UiSectionObj.Alignment = AlignValue
2555 if self.__GetStringData():
2556 UiSectionObj.StringData = self.__Token
2557 else:
2558 UiSectionObj.FileName = self.__Token
2559 Obj.SectionList.append(UiSectionObj)
2560
2561 elif self.__IsKeyword( "FV_IMAGE"):
2562 if AlignValue == 'Auto':
2563 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2564 if not self.__IsToken( "="):
2565 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2566 if not self.__GetNextToken():
2567 raise Warning("expected FV name or FV file path", self.FileName, self.CurrentLineNumber)
2568
2569 FvName = self.__Token
2570 FvObj = None
2571
2572 if self.__IsToken( "{"):
2573 FvObj = Fv.FV()
2574 FvObj.UiFvName = FvName.upper()
2575 self.__GetDefineStatements(FvObj)
2576 MacroDict.update(FvObj.DefineVarDict)
2577 self.__GetBlockStatement(FvObj)
2578 self.__GetSetStatements(FvObj)
2579 self.__GetFvAlignment(FvObj)
2580 self.__GetFvAttributes(FvObj)
2581 self.__GetAprioriSection(FvObj, MacroDict.copy())
2582 self.__GetAprioriSection(FvObj, MacroDict.copy())
2583
2584 while True:
2585 IsInf = self.__GetInfStatement(FvObj, MacroDict.copy())
2586 IsFile = self.__GetFileStatement(FvObj, MacroDict.copy())
2587 if not IsInf and not IsFile:
2588 break
2589
2590 if not self.__IsToken( "}"):
2591 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2592
2593 FvImageSectionObj = FvImageSection.FvImageSection()
2594 FvImageSectionObj.Alignment = AlignValue
2595 if FvObj != None:
2596 FvImageSectionObj.Fv = FvObj
2597 FvImageSectionObj.FvName = None
2598 else:
2599 FvImageSectionObj.FvName = FvName.upper()
2600 FvImageSectionObj.FvFileName = FvName
2601
2602 Obj.SectionList.append(FvImageSectionObj)
2603
2604 elif self.__IsKeyword("PEI_DEPEX_EXP") or self.__IsKeyword("DXE_DEPEX_EXP") or self.__IsKeyword("SMM_DEPEX_EXP"):
2605 if AlignValue == 'Auto':
2606 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2607 DepexSectionObj = DepexSection.DepexSection()
2608 DepexSectionObj.Alignment = AlignValue
2609 DepexSectionObj.DepexType = self.__Token
2610
2611 if not self.__IsToken( "="):
2612 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2613 if not self.__IsToken( "{"):
2614 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2615 if not self.__SkipToToken( "}"):
2616 raise Warning("expected Depex expression ending '}'", self.FileName, self.CurrentLineNumber)
2617
2618 DepexSectionObj.Expression = self.__SkippedChars.rstrip('}')
2619 Obj.SectionList.append(DepexSectionObj)
2620
2621 else:
2622 if not self.__GetNextWord():
2623 raise Warning("expected section type", self.FileName, self.CurrentLineNumber)
2624
2625 # Encapsulation section appear, UndoToken and return
2626 if self.__Token == "COMPRESS" or self.__Token == "GUIDED":
2627 self.SetFileBufferPos(OldPos)
2628 return False
2629
2630 if self.__Token not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
2631 "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"):
2632 raise Warning("Unknown section type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2633 if AlignValue == 'Auto'and (not self.__Token == 'PE32') and (not self.__Token == 'TE'):
2634 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2635
2636 # DataSection
2637 DataSectionObj = DataSection.DataSection()
2638 DataSectionObj.Alignment = AlignValue
2639 DataSectionObj.SecType = self.__Token
2640
2641 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
2642 if self.__FileCouldHaveRelocFlag(Obj.FvFileType) and self.__SectionCouldHaveRelocFlag(DataSectionObj.SecType):
2643 if self.__Token == 'RELOCS_STRIPPED':
2644 DataSectionObj.KeepReloc = False
2645 else:
2646 DataSectionObj.KeepReloc = True
2647 else:
2648 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)
2649
2650 if self.__IsToken("="):
2651 if not self.__GetNextToken():
2652 raise Warning("expected section file path", self.FileName, self.CurrentLineNumber)
2653 DataSectionObj.SectFileName = self.__Token
2654 if DataSectionObj.SectFileName.replace('$(WORKSPACE)', '').find('$') == -1:
2655 #do case sensitive check for file path
2656 ErrorCode, ErrorInfo = PathClass(NormPath(DataSectionObj.SectFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
2657 if ErrorCode != 0:
2658 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
2659 else:
2660 if not self.__GetCglSection(DataSectionObj):
2661 return False
2662
2663 Obj.SectionList.append(DataSectionObj)
2664
2665 return True
2666
2667 ## __GetCglSection() method
2668 #
2669 # Get compressed or GUIDed section for Obj
2670 #
2671 # @param self The object pointer
2672 # @param Obj for whom leaf section is got
2673 # @param AlignValue alignment value for complex section
2674 # @retval True Successfully find section statement
2675 # @retval False Not able to find section statement
2676 #
2677 def __GetCglSection(self, Obj, AlignValue = None):
2678
2679 if self.__IsKeyword( "COMPRESS"):
2680 type = "PI_STD"
2681 if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):
2682 type = self.__Token
2683
2684 if not self.__IsToken("{"):
2685 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2686
2687 CompressSectionObj = CompressSection.CompressSection()
2688 CompressSectionObj.Alignment = AlignValue
2689 CompressSectionObj.CompType = type
2690 # Recursive sections...
2691 while True:
2692 IsLeafSection = self.__GetLeafSection(CompressSectionObj)
2693 IsEncapSection = self.__GetEncapsulationSec(CompressSectionObj)
2694 if not IsLeafSection and not IsEncapSection:
2695 break
2696
2697
2698 if not self.__IsToken( "}"):
2699 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2700 Obj.SectionList.append(CompressSectionObj)
2701
2702 # else:
2703 # raise Warning("Compress type not known")
2704
2705 return True
2706
2707 elif self.__IsKeyword( "GUIDED"):
2708 GuidValue = None
2709 if self.__GetNextGuid():
2710 GuidValue = self.__Token
2711
2712 AttribDict = self.__GetGuidAttrib()
2713 if not self.__IsToken("{"):
2714 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2715 GuidSectionObj = GuidSection.GuidSection()
2716 GuidSectionObj.Alignment = AlignValue
2717 GuidSectionObj.NameGuid = GuidValue
2718 GuidSectionObj.SectionType = "GUIDED"
2719 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
2720 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
2721 # Recursive sections...
2722 while True:
2723 IsLeafSection = self.__GetLeafSection(GuidSectionObj)
2724 IsEncapSection = self.__GetEncapsulationSec(GuidSectionObj)
2725 if not IsLeafSection and not IsEncapSection:
2726 break
2727
2728 if not self.__IsToken( "}"):
2729 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2730 Obj.SectionList.append(GuidSectionObj)
2731
2732 return True
2733
2734 return False
2735
2736 ## __GetGuidAttri() method
2737 #
2738 # Get attributes for GUID section
2739 #
2740 # @param self The object pointer
2741 # @retval AttribDict Dictionary of key-value pair of section attributes
2742 #
2743 def __GetGuidAttrib(self):
2744
2745 AttribDict = {}
2746 AttribDict["PROCESSING_REQUIRED"] = "NONE"
2747 AttribDict["AUTH_STATUS_VALID"] = "NONE"
2748 if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"):
2749 AttribKey = self.__Token
2750
2751 if not self.__IsToken("="):
2752 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2753
2754 if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
2755 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)
2756 AttribDict[AttribKey] = self.__Token
2757
2758 if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"):
2759 AttribKey = self.__Token
2760
2761 if not self.__IsToken("="):
2762 raise Warning("expected '='")
2763
2764 if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
2765 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)
2766 AttribDict[AttribKey] = self.__Token
2767
2768 return AttribDict
2769
2770 ## __GetEncapsulationSec() method
2771 #
2772 # Get encapsulation section for FILE
2773 #
2774 # @param self The object pointer
2775 # @param FfsFile for whom section is got
2776 # @retval True Successfully find section statement
2777 # @retval False Not able to find section statement
2778 #
2779 def __GetEncapsulationSec(self, FfsFileObj):
2780
2781 OldPos = self.GetFileBufferPos()
2782 if not self.__IsKeyword( "SECTION"):
2783 if len(FfsFileObj.SectionList) == 0:
2784 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)
2785 else:
2786 return False
2787
2788 AlignValue = None
2789 if self.__GetAlignment():
2790 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2791 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2792 AlignValue = self.__Token
2793
2794 if not self.__GetCglSection(FfsFileObj, AlignValue):
2795 self.SetFileBufferPos(OldPos)
2796 return False
2797 else:
2798 return True
2799
2800 ## __GetCapsule() method
2801 #
2802 # Get capsule section contents and store its data into capsule list of self.Profile
2803 #
2804 # @param self The object pointer
2805 # @retval True Successfully find a capsule
2806 # @retval False Not able to find a capsule
2807 #
2808 def __GetCapsule(self):
2809
2810 if not self.__GetNextToken():
2811 return False
2812
2813 S = self.__Token.upper()
2814 if S.startswith("[") and not S.startswith("[CAPSULE."):
2815 if not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
2816 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
2817 self.__UndoToken()
2818 return False
2819
2820 self.__UndoToken()
2821 if not self.__IsToken("[CAPSULE.", True):
2822 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
2823 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2824 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2825 raise Warning("expected [Capsule.]", self.FileName, self.CurrentLineNumber)
2826
2827 CapsuleObj = Capsule.Capsule()
2828
2829 CapsuleName = self.__GetUiName()
2830 if not CapsuleName:
2831 raise Warning("expected capsule name", self.FileName, self.CurrentLineNumber)
2832
2833 CapsuleObj.UiCapsuleName = CapsuleName.upper()
2834
2835 if not self.__IsToken( "]"):
2836 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
2837
2838 if self.__IsKeyword("CREATE_FILE"):
2839 if not self.__IsToken( "="):
2840 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2841
2842 if not self.__GetNextToken():
2843 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)
2844
2845 CapsuleObj.CreateFile = self.__Token
2846
2847 self.__GetCapsuleStatements(CapsuleObj)
2848 self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj
2849 return True
2850
2851 ## __GetCapsuleStatements() method
2852 #
2853 # Get statements for capsule
2854 #
2855 # @param self The object pointer
2856 # @param Obj for whom statements are got
2857 #
2858 def __GetCapsuleStatements(self, Obj):
2859 self.__GetCapsuleTokens(Obj)
2860 self.__GetDefineStatements(Obj)
2861 self.__GetSetStatements(Obj)
2862 self.__GetCapsuleData(Obj)
2863
2864 ## __GetCapsuleTokens() method
2865 #
2866 # Get token statements for capsule
2867 #
2868 # @param self The object pointer
2869 # @param Obj for whom token statements are got
2870 #
2871 def __GetCapsuleTokens(self, Obj):
2872 if not self.__GetNextToken():
2873 return False
2874 while self.__Token in ("CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS"):
2875 Name = self.__Token.strip()
2876 if not self.__IsToken("="):
2877 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2878 if not self.__GetNextToken():
2879 raise Warning("expected value", self.FileName, self.CurrentLineNumber)
2880 if Name == 'CAPSULE_FLAGS':
2881 if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
2882 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)
2883 Value = self.__Token.strip()
2884 while self.__IsToken(","):
2885 Value += ','
2886 if not self.__GetNextToken():
2887 raise Warning("expected value", self.FileName, self.CurrentLineNumber)
2888 if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
2889 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)
2890 Value += self.__Token.strip()
2891 else:
2892 Value = self.__Token.strip()
2893 Obj.TokensDict[Name] = Value
2894 if not self.__GetNextToken():
2895 return False
2896 self.__UndoToken()
2897
2898 ## __GetCapsuleData() method
2899 #
2900 # Get capsule data for capsule
2901 #
2902 # @param self The object pointer
2903 # @param Obj for whom capsule data are got
2904 #
2905 def __GetCapsuleData(self, Obj):
2906
2907 while True:
2908 IsInf = self.__GetInfStatement(Obj, True)
2909 IsFile = self.__GetFileStatement(Obj, True)
2910 IsFv = self.__GetFvStatement(Obj)
2911 IsFd = self.__GetFdStatement(Obj)
2912 IsAnyFile = self.__GetAnyFileStatement(Obj)
2913 if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile):
2914 break
2915
2916 ## __GetFvStatement() method
2917 #
2918 # Get FV for capsule
2919 #
2920 # @param self The object pointer
2921 # @param CapsuleObj for whom FV is got
2922 # @retval True Successfully find a FV statement
2923 # @retval False Not able to find a FV statement
2924 #
2925 def __GetFvStatement(self, CapsuleObj):
2926
2927 if not self.__IsKeyword("FV"):
2928 return False
2929
2930 if not self.__IsToken("="):
2931 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2932
2933 if not self.__GetNextToken():
2934 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
2935
2936 CapsuleFv = CapsuleData.CapsuleFv()
2937 CapsuleFv.FvName = self.__Token
2938 CapsuleObj.CapsuleDataList.append(CapsuleFv)
2939 return True
2940
2941 ## __GetFdStatement() method
2942 #
2943 # Get FD for capsule
2944 #
2945 # @param self The object pointer
2946 # @param CapsuleObj for whom FD is got
2947 # @retval True Successfully find a FD statement
2948 # @retval False Not able to find a FD statement
2949 #
2950 def __GetFdStatement(self, CapsuleObj):
2951
2952 if not self.__IsKeyword("FD"):
2953 return False
2954
2955 if not self.__IsToken("="):
2956 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2957
2958 if not self.__GetNextToken():
2959 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)
2960
2961 CapsuleFd = CapsuleData.CapsuleFd()
2962 CapsuleFd.FdName = self.__Token
2963 CapsuleObj.CapsuleDataList.append(CapsuleFd)
2964 return True
2965
2966 ## __GetAnyFileStatement() method
2967 #
2968 # Get AnyFile for capsule
2969 #
2970 # @param self The object pointer
2971 # @param CapsuleObj for whom AnyFile is got
2972 # @retval True Successfully find a Anyfile statement
2973 # @retval False Not able to find a AnyFile statement
2974 #
2975 def __GetAnyFileStatement(self, CapsuleObj):
2976
2977 if not self.__IsKeyword("FILE"):
2978 return False
2979
2980 if not self.__IsKeyword("DATA"):
2981 self.__UndoToken()
2982 return False
2983
2984 if not self.__IsToken("="):
2985 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2986
2987 if not self.__GetNextToken():
2988 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)
2989
2990 AnyFileName = self.__Token
2991 AnyFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AnyFileName)
2992 if not os.path.exists(AnyFileName):
2993 raise Warning("File %s not exists"%AnyFileName, self.FileName, self.CurrentLineNumber)
2994
2995 CapsuleAnyFile = CapsuleData.CapsuleAnyFile()
2996 CapsuleAnyFile.FileName = AnyFileName
2997 CapsuleObj.CapsuleDataList.append(CapsuleAnyFile)
2998 return True
2999
3000 ## __GetRule() method
3001 #
3002 # Get Rule section contents and store its data into rule list of self.Profile
3003 #
3004 # @param self The object pointer
3005 # @retval True Successfully find a Rule
3006 # @retval False Not able to find a Rule
3007 #
3008 def __GetRule(self):
3009
3010 if not self.__GetNextToken():
3011 return False
3012
3013 S = self.__Token.upper()
3014 if S.startswith("[") and not S.startswith("[RULE."):
3015 if not S.startswith("[OPTIONROM."):
3016 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
3017 self.__UndoToken()
3018 return False
3019 self.__UndoToken()
3020 if not self.__IsToken("[Rule.", 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 [Rule.]", self.FileName, self.CurrentLineNumber)
3025
3026 if not self.__SkipToToken("."):
3027 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
3028
3029 Arch = self.__SkippedChars.rstrip(".")
3030 if Arch.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "COMMON"):
3031 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)
3032
3033 ModuleType = self.__GetModuleType()
3034
3035 TemplateName = ""
3036 if self.__IsToken("."):
3037 if not self.__GetNextWord():
3038 raise Warning("expected template name", self.FileName, self.CurrentLineNumber)
3039 TemplateName = self.__Token
3040
3041 if not self.__IsToken( "]"):
3042 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
3043
3044 RuleObj = self.__GetRuleFileStatements()
3045 RuleObj.Arch = Arch.upper()
3046 RuleObj.ModuleType = ModuleType
3047 RuleObj.TemplateName = TemplateName
3048 if TemplateName == '' :
3049 self.Profile.RuleDict['RULE' + \
3050 '.' + \
3051 Arch.upper() + \
3052 '.' + \
3053 ModuleType.upper() ] = RuleObj
3054 else :
3055 self.Profile.RuleDict['RULE' + \
3056 '.' + \
3057 Arch.upper() + \
3058 '.' + \
3059 ModuleType.upper() + \
3060 '.' + \
3061 TemplateName.upper() ] = RuleObj
3062 # self.Profile.RuleList.append(rule)
3063 return True
3064
3065 ## __GetModuleType() method
3066 #
3067 # Return the module type
3068 #
3069 # @param self The object pointer
3070 # @retval string module type
3071 #
3072 def __GetModuleType(self):
3073
3074 if not self.__GetNextWord():
3075 raise Warning("expected Module type", self.FileName, self.CurrentLineNumber)
3076 if self.__Token.upper() not in ("SEC", "PEI_CORE", "PEIM", "DXE_CORE", \
3077 "DXE_DRIVER", "DXE_SAL_DRIVER", \
3078 "DXE_SMM_DRIVER", "DXE_RUNTIME_DRIVER", \
3079 "UEFI_DRIVER", "UEFI_APPLICATION", "USER_DEFINED", "DEFAULT", "BASE", \
3080 "SECURITY_CORE", "COMBINED_PEIM_DRIVER", "PIC_PEIM", "RELOCATABLE_PEIM", \
3081 "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION", "ACPITABLE", "SMM_CORE"):
3082 raise Warning("Unknown Module type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3083 return self.__Token
3084
3085 ## __GetFileExtension() method
3086 #
3087 # Return the file extension
3088 #
3089 # @param self The object pointer
3090 # @retval string file name extension
3091 #
3092 def __GetFileExtension(self):
3093 if not self.__IsToken("."):
3094 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
3095
3096 Ext = ""
3097 if self.__GetNextToken():
3098 Pattern = re.compile(r'([a-zA-Z][a-zA-Z0-9]*)')
3099 if Pattern.match(self.__Token):
3100 Ext = self.__Token
3101 return '.' + Ext
3102 else:
3103 raise Warning("Unknown file extension '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3104
3105 else:
3106 raise Warning("expected file extension", self.FileName, self.CurrentLineNumber)
3107
3108 ## __GetRuleFileStatement() method
3109 #
3110 # Get rule contents
3111 #
3112 # @param self The object pointer
3113 # @retval Rule Rule object
3114 #
3115 def __GetRuleFileStatements(self):
3116
3117 if not self.__IsKeyword("FILE"):
3118 raise Warning("expected FILE", self.FileName, self.CurrentLineNumber)
3119
3120 if not self.__GetNextWord():
3121 raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)
3122
3123 Type = self.__Token.strip().upper()
3124 if Type not in ("RAW", "FREEFORM", "SEC", "PEI_CORE", "PEIM",\
3125 "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE", "SMM", "SMM_CORE"):
3126 raise Warning("Unknown FV type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3127
3128 if not self.__IsToken("="):
3129 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3130
3131 if not self.__IsKeyword("$(NAMED_GUID)"):
3132 if not self.__GetNextWord():
3133 raise Warning("expected $(NAMED_GUID)", self.FileName, self.CurrentLineNumber)
3134 if self.__Token == 'PCD':
3135 if not self.__IsToken( "("):
3136 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
3137 PcdPair = self.__GetNextPcdName()
3138 if not self.__IsToken( ")"):
3139 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
3140 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
3141
3142 NameGuid = self.__Token
3143
3144 KeepReloc = None
3145 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
3146 if self.__FileCouldHaveRelocFlag(Type):
3147 if self.__Token == 'RELOCS_STRIPPED':
3148 KeepReloc = False
3149 else:
3150 KeepReloc = True
3151 else:
3152 raise Warning("File type %s could not have reloc strip flag%d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3153
3154 KeyStringList = []
3155 if self.__GetNextToken():
3156 Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
3157 if Pattern.match(self.__Token):
3158 KeyStringList.append(self.__Token)
3159 if self.__IsToken(","):
3160 while self.__GetNextToken():
3161 if not Pattern.match(self.__Token):
3162 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
3163 KeyStringList.append(self.__Token)
3164
3165 if not self.__IsToken(","):
3166 break
3167
3168 else:
3169 self.__UndoToken()
3170
3171
3172 Fixed = False
3173 if self.__IsKeyword("Fixed", True):
3174 Fixed = True
3175
3176 CheckSum = False
3177 if self.__IsKeyword("CheckSum", True):
3178 CheckSum = True
3179
3180 AlignValue = ""
3181 if self.__GetAlignment():
3182 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3183 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3184 #For FFS, Auto is default option same to ""
3185 if not self.__Token == "Auto":
3186 AlignValue = self.__Token
3187
3188 if self.__IsToken("{"):
3189 # Complex file rule expected
3190 Rule = RuleComplexFile.RuleComplexFile()
3191 Rule.FvFileType = Type
3192 Rule.NameGuid = NameGuid
3193 Rule.Alignment = AlignValue
3194 Rule.CheckSum = CheckSum
3195 Rule.Fixed = Fixed
3196 Rule.KeyStringList = KeyStringList
3197 if KeepReloc != None:
3198 Rule.KeepReloc = KeepReloc
3199
3200 while True:
3201 IsEncapsulate = self.__GetRuleEncapsulationSection(Rule)
3202 IsLeaf = self.__GetEfiSection(Rule)
3203 if not IsEncapsulate and not IsLeaf:
3204 break
3205
3206 if not self.__IsToken("}"):
3207 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
3208
3209 return Rule
3210
3211 else:
3212 # Simple file rule expected
3213 if not self.__GetNextWord():
3214 raise Warning("expected leaf section type", self.FileName, self.CurrentLineNumber)
3215
3216 SectionName = self.__Token
3217
3218 if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3219 "UI", "PEI_DEPEX", "VERSION", "SUBTYPE_GUID", "SMM_DEPEX"):
3220 raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber)
3221
3222
3223 if self.__IsKeyword("Fixed", True):
3224 Fixed = True
3225
3226 if self.__IsKeyword("CheckSum", True):
3227 CheckSum = True
3228
3229 SectAlignment = ""
3230 if self.__GetAlignment():
3231 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3232 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3233 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
3234 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
3235 SectAlignment = self.__Token
3236
3237 Ext = None
3238 if self.__IsToken('|'):
3239 Ext = self.__GetFileExtension()
3240 elif not self.__GetNextToken():
3241 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)
3242
3243 Rule = RuleSimpleFile.RuleSimpleFile()
3244 Rule.SectionType = SectionName
3245 Rule.FvFileType = Type
3246 Rule.NameGuid = NameGuid
3247 Rule.Alignment = AlignValue
3248 Rule.SectAlignment = SectAlignment
3249 Rule.CheckSum = CheckSum
3250 Rule.Fixed = Fixed
3251 Rule.KeyStringList = KeyStringList
3252 if KeepReloc != None:
3253 Rule.KeepReloc = KeepReloc
3254 Rule.FileExtension = Ext
3255 Rule.FileName = self.__Token
3256 return Rule
3257
3258 ## __GetEfiSection() method
3259 #
3260 # Get section list for Rule
3261 #
3262 # @param self The object pointer
3263 # @param Obj for whom section is got
3264 # @retval True Successfully find section statement
3265 # @retval False Not able to find section statement
3266 #
3267 def __GetEfiSection(self, Obj):
3268
3269 OldPos = self.GetFileBufferPos()
3270 if not self.__GetNextWord():
3271 return False
3272 SectionName = self.__Token
3273
3274 if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3275 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3276 self.__UndoToken()
3277 return False
3278
3279 if SectionName == "FV_IMAGE":
3280 FvImageSectionObj = FvImageSection.FvImageSection()
3281 if self.__IsKeyword("FV_IMAGE"):
3282 pass
3283 if self.__IsToken( "{"):
3284 FvObj = Fv.FV()
3285 self.__GetDefineStatements(FvObj)
3286 self.__GetBlockStatement(FvObj)
3287 self.__GetSetStatements(FvObj)
3288 self.__GetFvAlignment(FvObj)
3289 self.__GetFvAttributes(FvObj)
3290 self.__GetAprioriSection(FvObj)
3291 self.__GetAprioriSection(FvObj)
3292
3293 while True:
3294 IsInf = self.__GetInfStatement(FvObj)
3295 IsFile = self.__GetFileStatement(FvObj)
3296 if not IsInf and not IsFile:
3297 break
3298
3299 if not self.__IsToken( "}"):
3300 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
3301 FvImageSectionObj.Fv = FvObj
3302 FvImageSectionObj.FvName = None
3303
3304 else:
3305 if not self.__IsKeyword("FV"):
3306 raise Warning("expected 'FV'", self.FileName, self.CurrentLineNumber)
3307 FvImageSectionObj.FvFileType = self.__Token
3308
3309 if self.__GetAlignment():
3310 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3311 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3312 FvImageSectionObj.Alignment = self.__Token
3313
3314 if self.__IsToken('|'):
3315 FvImageSectionObj.FvFileExtension = self.__GetFileExtension()
3316 elif self.__GetNextToken():
3317 if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3318 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3319 FvImageSectionObj.FvFileName = self.__Token
3320 else:
3321 self.__UndoToken()
3322 else:
3323 raise Warning("expected FV file name", self.FileName, self.CurrentLineNumber)
3324
3325 Obj.SectionList.append(FvImageSectionObj)
3326 return True
3327
3328 EfiSectionObj = EfiSection.EfiSection()
3329 EfiSectionObj.SectionType = SectionName
3330
3331 if not self.__GetNextToken():
3332 raise Warning("expected file type", self.FileName, self.CurrentLineNumber)
3333
3334 if self.__Token == "STRING":
3335 if not self.__RuleSectionCouldHaveString(EfiSectionObj.SectionType):
3336 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3337
3338 if not self.__IsToken('='):
3339 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3340
3341 if not self.__GetNextToken():
3342 raise Warning("expected Quoted String", self.FileName, self.CurrentLineNumber)
3343
3344 if self.__GetStringData():
3345 EfiSectionObj.StringData = self.__Token
3346
3347 if self.__IsKeyword("BUILD_NUM"):
3348 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
3349 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3350
3351 if not self.__IsToken("="):
3352 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3353 if not self.__GetNextToken():
3354 raise Warning("expected Build number", self.FileName, self.CurrentLineNumber)
3355 EfiSectionObj.BuildNum = self.__Token
3356
3357 else:
3358 EfiSectionObj.FileType = self.__Token
3359 self.__CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType)
3360
3361 if self.__IsKeyword("Optional"):
3362 if not self.__RuleSectionCouldBeOptional(EfiSectionObj.SectionType):
3363 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3364 EfiSectionObj.Optional = True
3365
3366 if self.__IsKeyword("BUILD_NUM"):
3367 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
3368 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3369
3370 if not self.__IsToken("="):
3371 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3372 if not self.__GetNextToken():
3373 raise Warning("expected Build number", self.FileName, self.CurrentLineNumber)
3374 EfiSectionObj.BuildNum = self.__Token
3375
3376 if self.__GetAlignment():
3377 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3378 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3379 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
3380 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
3381 EfiSectionObj.Alignment = self.__Token
3382
3383 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
3384 if self.__SectionCouldHaveRelocFlag(EfiSectionObj.SectionType):
3385 if self.__Token == 'RELOCS_STRIPPED':
3386 EfiSectionObj.KeepReloc = False
3387 else:
3388 EfiSectionObj.KeepReloc = True
3389 if Obj.KeepReloc != None and Obj.KeepReloc != EfiSectionObj.KeepReloc:
3390 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)
3391 else:
3392 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)
3393
3394
3395 if self.__IsToken('|'):
3396 EfiSectionObj.FileExtension = self.__GetFileExtension()
3397 elif self.__GetNextToken():
3398 if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3399 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3400
3401 if self.__Token.startswith('PCD'):
3402 self.__UndoToken()
3403 self.__GetNextWord()
3404
3405 if self.__Token == 'PCD':
3406 if not self.__IsToken( "("):
3407 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
3408 PcdPair = self.__GetNextPcdName()
3409 if not self.__IsToken( ")"):
3410 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
3411 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
3412
3413 EfiSectionObj.FileName = self.__Token
3414
3415 else:
3416 self.__UndoToken()
3417 else:
3418 raise Warning("expected section file name", self.FileName, self.CurrentLineNumber)
3419
3420 Obj.SectionList.append(EfiSectionObj)
3421 return True
3422
3423 ## __RuleSectionCouldBeOptional() method
3424 #
3425 # Get whether a section could be optional
3426 #
3427 # @param self The object pointer
3428 # @param SectionType The section type to check
3429 # @retval True section could be optional
3430 # @retval False section never optional
3431 #
3432 def __RuleSectionCouldBeOptional(self, SectionType):
3433 if SectionType in ("DXE_DEPEX", "UI", "VERSION", "PEI_DEPEX", "RAW", "SMM_DEPEX"):
3434 return True
3435 else:
3436 return False
3437
3438 ## __RuleSectionCouldHaveBuildNum() method
3439 #
3440 # Get whether a section could have build number information
3441 #
3442 # @param self The object pointer
3443 # @param SectionType The section type to check
3444 # @retval True section could have build number information
3445 # @retval False section never have build number information
3446 #
3447 def __RuleSectionCouldHaveBuildNum(self, SectionType):
3448 if SectionType in ("VERSION"):
3449 return True
3450 else:
3451 return False
3452
3453 ## __RuleSectionCouldHaveString() method
3454 #
3455 # Get whether a section could have string
3456 #
3457 # @param self The object pointer
3458 # @param SectionType The section type to check
3459 # @retval True section could have string
3460 # @retval False section never have string
3461 #
3462 def __RuleSectionCouldHaveString(self, SectionType):
3463 if SectionType in ("UI", "VERSION"):
3464 return True
3465 else:
3466 return False
3467
3468 ## __CheckRuleSectionFileType() method
3469 #
3470 # Get whether a section matches a file type
3471 #
3472 # @param self The object pointer
3473 # @param SectionType The section type to check
3474 # @param FileType The file type to check
3475 #
3476 def __CheckRuleSectionFileType(self, SectionType, FileType):
3477 if SectionType == "COMPAT16":
3478 if FileType not in ("COMPAT16", "SEC_COMPAT16"):
3479 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3480 elif SectionType == "PE32":
3481 if FileType not in ("PE32", "SEC_PE32"):
3482 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3483 elif SectionType == "PIC":
3484 if FileType not in ("PIC", "PIC"):
3485 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3486 elif SectionType == "TE":
3487 if FileType not in ("TE", "SEC_TE"):
3488 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3489 elif SectionType == "RAW":
3490 if FileType not in ("BIN", "SEC_BIN", "RAW", "ASL", "ACPI"):
3491 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3492 elif SectionType == "DXE_DEPEX" or SectionType == "SMM_DEPEX":
3493 if FileType not in ("DXE_DEPEX", "SEC_DXE_DEPEX", "SMM_DEPEX"):
3494 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3495 elif SectionType == "UI":
3496 if FileType not in ("UI", "SEC_UI"):
3497 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3498 elif SectionType == "VERSION":
3499 if FileType not in ("VERSION", "SEC_VERSION"):
3500 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3501 elif SectionType == "PEI_DEPEX":
3502 if FileType not in ("PEI_DEPEX", "SEC_PEI_DEPEX"):
3503 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3504 elif SectionType == "GUID":
3505 if FileType not in ("PE32", "SEC_GUID"):
3506 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3507
3508 ## __GetRuleEncapsulationSection() method
3509 #
3510 # Get encapsulation section for Rule
3511 #
3512 # @param self The object pointer
3513 # @param Rule for whom section is got
3514 # @retval True Successfully find section statement
3515 # @retval False Not able to find section statement
3516 #
3517 def __GetRuleEncapsulationSection(self, Rule):
3518
3519 if self.__IsKeyword( "COMPRESS"):
3520 Type = "PI_STD"
3521 if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):
3522 Type = self.__Token
3523
3524 if not self.__IsToken("{"):
3525 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
3526
3527 CompressSectionObj = CompressSection.CompressSection()
3528
3529 CompressSectionObj.CompType = Type
3530 # Recursive sections...
3531 while True:
3532 IsEncapsulate = self.__GetRuleEncapsulationSection(CompressSectionObj)
3533 IsLeaf = self.__GetEfiSection(CompressSectionObj)
3534 if not IsEncapsulate and not IsLeaf:
3535 break
3536
3537 if not self.__IsToken( "}"):
3538 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
3539 Rule.SectionList.append(CompressSectionObj)
3540
3541 return True
3542
3543 elif self.__IsKeyword( "GUIDED"):
3544 GuidValue = None
3545 if self.__GetNextGuid():
3546 GuidValue = self.__Token
3547
3548 if self.__IsKeyword( "$(NAMED_GUID)"):
3549 GuidValue = self.__Token
3550
3551 AttribDict = self.__GetGuidAttrib()
3552
3553 if not self.__IsToken("{"):
3554 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
3555 GuidSectionObj = GuidSection.GuidSection()
3556 GuidSectionObj.NameGuid = GuidValue
3557 GuidSectionObj.SectionType = "GUIDED"
3558 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
3559 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
3560
3561 # Efi sections...
3562 while True:
3563 IsEncapsulate = self.__GetRuleEncapsulationSection(GuidSectionObj)
3564 IsLeaf = self.__GetEfiSection(GuidSectionObj)
3565 if not IsEncapsulate and not IsLeaf:
3566 break
3567
3568 if not self.__IsToken( "}"):
3569 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
3570 Rule.SectionList.append(GuidSectionObj)
3571
3572 return True
3573
3574 return False
3575
3576 ## __GetVtf() method
3577 #
3578 # Get VTF section contents and store its data into VTF list of self.Profile
3579 #
3580 # @param self The object pointer
3581 # @retval True Successfully find a VTF
3582 # @retval False Not able to find a VTF
3583 #
3584 def __GetVtf(self):
3585
3586 if not self.__GetNextToken():
3587 return False
3588
3589 S = self.__Token.upper()
3590 if S.startswith("[") and not S.startswith("[VTF."):
3591 if not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
3592 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
3593 self.__UndoToken()
3594 return False
3595
3596 self.__UndoToken()
3597 if not self.__IsToken("[VTF.", True):
3598 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
3599 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3600 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3601 raise Warning("expected [VTF.]", self.FileName, self.CurrentLineNumber)
3602
3603 if not self.__SkipToToken("."):
3604 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
3605
3606 Arch = self.__SkippedChars.rstrip(".").upper()
3607 if Arch not in ("IA32", "X64", "IPF", "ARM"):
3608 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)
3609
3610 if not self.__GetNextWord():
3611 raise Warning("expected VTF name", self.FileName, self.CurrentLineNumber)
3612 Name = self.__Token.upper()
3613
3614 VtfObj = Vtf.Vtf()
3615 VtfObj.UiName = Name
3616 VtfObj.KeyArch = Arch
3617
3618 if self.__IsToken(","):
3619 if not self.__GetNextWord():
3620 raise Warning("expected Arch list", self.FileName, self.CurrentLineNumber)
3621 if self.__Token.upper() not in ("IA32", "X64", "IPF", "ARM"):
3622 raise Warning("Unknown Arch '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3623 VtfObj.ArchList = self.__Token.upper()
3624
3625 if not self.__IsToken( "]"):
3626 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
3627
3628 if self.__IsKeyword("IA32_RST_BIN"):
3629 if not self.__IsToken("="):
3630 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3631
3632 if not self.__GetNextToken():
3633 raise Warning("expected Reset file", self.FileName, self.CurrentLineNumber)
3634
3635 VtfObj.ResetBin = self.__Token
3636 if VtfObj.ResetBin.replace('$(WORKSPACE)', '').find('$') == -1:
3637 #check for file path
3638 ErrorCode, ErrorInfo = PathClass(NormPath(VtfObj.ResetBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()
3639 if ErrorCode != 0:
3640 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
3641
3642 while self.__GetComponentStatement(VtfObj):
3643 pass
3644
3645 self.Profile.VtfList.append(VtfObj)
3646 return True
3647
3648 ## __GetComponentStatement() method
3649 #
3650 # Get components in VTF
3651 #
3652 # @param self The object pointer
3653 # @param VtfObj for whom component is got
3654 # @retval True Successfully find a component
3655 # @retval False Not able to find a component
3656 #
3657 def __GetComponentStatement(self, VtfObj):
3658
3659 if not self.__IsKeyword("COMP_NAME"):
3660 return False
3661
3662 if not self.__IsToken("="):
3663 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3664
3665 if not self.__GetNextWord():
3666 raise Warning("expected Component Name", self.FileName, self.CurrentLineNumber)
3667
3668 CompStatementObj = ComponentStatement.ComponentStatement()
3669 CompStatementObj.CompName = self.__Token
3670
3671 if not self.__IsKeyword("COMP_LOC"):
3672 raise Warning("expected COMP_LOC", self.FileName, self.CurrentLineNumber)
3673
3674 if not self.__IsToken("="):
3675 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3676
3677 CompStatementObj.CompLoc = ""
3678 if self.__GetNextWord():
3679 CompStatementObj.CompLoc = self.__Token
3680 if self.__IsToken('|'):
3681 if not self.__GetNextWord():
3682 raise Warning("Expected Region Name", self.FileName, self.CurrentLineNumber)
3683
3684 if self.__Token not in ("F", "N", "S"): #, "H", "L", "PH", "PL"): not support
3685 raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3686
3687 CompStatementObj.FilePos = self.__Token
3688 else:
3689 self.CurrentLineNumber += 1
3690 self.CurrentOffsetWithinLine = 0
3691
3692 if not self.__IsKeyword("COMP_TYPE"):
3693 raise Warning("expected COMP_TYPE", self.FileName, self.CurrentLineNumber)
3694
3695 if not self.__IsToken("="):
3696 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3697
3698 if not self.__GetNextToken():
3699 raise Warning("expected Component type", self.FileName, self.CurrentLineNumber)
3700 if self.__Token not in ("FIT", "PAL_B", "PAL_A", "OEM"):
3701 if not self.__Token.startswith("0x") or len(self.__Token) < 3 or len(self.__Token) > 4 or \
3702 not self.__HexDigit(self.__Token[2]) or not self.__HexDigit(self.__Token[-1]):
3703 raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3704 CompStatementObj.CompType = self.__Token
3705
3706 if not self.__IsKeyword("COMP_VER"):
3707 raise Warning("expected COMP_VER", self.FileName, self.CurrentLineNumber)
3708
3709 if not self.__IsToken("="):
3710 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3711
3712 if not self.__GetNextToken():
3713 raise Warning("expected Component version", self.FileName, self.CurrentLineNumber)
3714
3715 Pattern = re.compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', re.DOTALL)
3716 if Pattern.match(self.__Token) == None:
3717 raise Warning("Unknown version format '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3718 CompStatementObj.CompVer = self.__Token
3719
3720 if not self.__IsKeyword("COMP_CS"):
3721 raise Warning("expected COMP_CS", self.FileName, self.CurrentLineNumber)
3722
3723 if not self.__IsToken("="):
3724 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3725
3726 if not self.__GetNextToken():
3727 raise Warning("expected Component CS", self.FileName, self.CurrentLineNumber)
3728 if self.__Token not in ("1", "0"):
3729 raise Warning("Unknown Component CS '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3730 CompStatementObj.CompCs = self.__Token
3731
3732
3733 if not self.__IsKeyword("COMP_BIN"):
3734 raise Warning("expected COMP_BIN", self.FileName, self.CurrentLineNumber)
3735
3736 if not self.__IsToken("="):
3737 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3738
3739 if not self.__GetNextToken():
3740 raise Warning("expected Component file", self.FileName, self.CurrentLineNumber)
3741
3742 CompStatementObj.CompBin = self.__Token
3743 if CompStatementObj.CompBin != '-' and CompStatementObj.CompBin.replace('$(WORKSPACE)', '').find('$') == -1:
3744 #check for file path
3745 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()
3746 if ErrorCode != 0:
3747 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
3748
3749 if not self.__IsKeyword("COMP_SYM"):
3750 raise Warning("expected COMP_SYM", self.FileName, self.CurrentLineNumber)
3751
3752 if not self.__IsToken("="):
3753 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3754
3755 if not self.__GetNextToken():
3756 raise Warning("expected Component symbol file", self.FileName, self.CurrentLineNumber)
3757
3758 CompStatementObj.CompSym = self.__Token
3759 if CompStatementObj.CompSym != '-' and CompStatementObj.CompSym.replace('$(WORKSPACE)', '').find('$') == -1:
3760 #check for file path
3761 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompSym), GenFdsGlobalVariable.WorkSpaceDir).Validate()
3762 if ErrorCode != 0:
3763 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
3764
3765 if not self.__IsKeyword("COMP_SIZE"):
3766 raise Warning("expected COMP_SIZE", self.FileName, self.CurrentLineNumber)
3767
3768 if not self.__IsToken("="):
3769 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3770
3771 if self.__IsToken("-"):
3772 CompStatementObj.CompSize = self.__Token
3773 elif self.__GetNextDecimalNumber():
3774 CompStatementObj.CompSize = self.__Token
3775 elif self.__GetNextHexNumber():
3776 CompStatementObj.CompSize = self.__Token
3777 else:
3778 raise Warning("Unknown size '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3779
3780 VtfObj.ComponentStatementList.append(CompStatementObj)
3781 return True
3782
3783 ## __GetOptionRom() method
3784 #
3785 # Get OptionROM section contents and store its data into OptionROM list of self.Profile
3786 #
3787 # @param self The object pointer
3788 # @retval True Successfully find a OptionROM
3789 # @retval False Not able to find a OptionROM
3790 #
3791 def __GetOptionRom(self):
3792
3793 if not self.__GetNextToken():
3794 return False
3795
3796 S = self.__Token.upper()
3797 if S.startswith("[") and not S.startswith("[OPTIONROM."):
3798 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
3799
3800 self.__UndoToken()
3801 if not self.__IsToken("[OptionRom.", True):
3802 raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3803
3804 OptRomName = self.__GetUiName()
3805
3806 if not self.__IsToken( "]"):
3807 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
3808
3809 OptRomObj = OptionRom.OPTIONROM()
3810 OptRomObj.DriverName = OptRomName
3811 self.Profile.OptRomDict[OptRomName] = OptRomObj
3812
3813 while True:
3814 isInf = self.__GetOptRomInfStatement(OptRomObj)
3815 isFile = self.__GetOptRomFileStatement(OptRomObj)
3816 if not isInf and not isFile:
3817 break
3818
3819 return True
3820
3821 ## __GetOptRomInfStatement() method
3822 #
3823 # Get INF statements
3824 #
3825 # @param self The object pointer
3826 # @param Obj for whom inf statement is got
3827 # @retval True Successfully find inf statement
3828 # @retval False Not able to find inf statement
3829 #
3830 def __GetOptRomInfStatement(self, Obj):
3831
3832 if not self.__IsKeyword( "INF"):
3833 return False
3834
3835 ffsInf = OptRomInfStatement.OptRomInfStatement()
3836 self.__GetInfOptions( ffsInf)
3837
3838 if not self.__GetNextToken():
3839 raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)
3840 ffsInf.InfFileName = self.__Token
3841 if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:
3842 #check for file path
3843 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
3844 if ErrorCode != 0:
3845 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
3846
3847 if not ffsInf.InfFileName in self.Profile.InfList:
3848 self.Profile.InfList.append(ffsInf.InfFileName)
3849
3850
3851 self.__GetOptRomOverrides (ffsInf)
3852
3853 Obj.FfsList.append(ffsInf)
3854 return True
3855
3856 ## __GetOptRomOverrides() method
3857 #
3858 # Get overrides for OptROM INF & FILE
3859 #
3860 # @param self The object pointer
3861 # @param FfsInfObj for whom overrides is got
3862 #
3863 def __GetOptRomOverrides(self, Obj):
3864 if self.__IsToken('{'):
3865 Overrides = OptionRom.OverrideAttribs()
3866 while True:
3867 if self.__IsKeyword( "PCI_VENDOR_ID"):
3868 if not self.__IsToken( "="):
3869 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3870 if not self.__GetNextHexNumber():
3871 raise Warning("expected Hex vendor id", self.FileName, self.CurrentLineNumber)
3872 Overrides.PciVendorId = self.__Token
3873 continue
3874
3875 if self.__IsKeyword( "PCI_CLASS_CODE"):
3876 if not self.__IsToken( "="):
3877 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3878 if not self.__GetNextHexNumber():
3879 raise Warning("expected Hex class code", self.FileName, self.CurrentLineNumber)
3880 Overrides.PciClassCode = self.__Token
3881 continue
3882
3883 if self.__IsKeyword( "PCI_DEVICE_ID"):
3884 if not self.__IsToken( "="):
3885 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3886 if not self.__GetNextHexNumber():
3887 raise Warning("expected Hex device id", self.FileName, self.CurrentLineNumber)
3888
3889 Overrides.PciDeviceId = self.__Token
3890 continue
3891
3892 if self.__IsKeyword( "PCI_REVISION"):
3893 if not self.__IsToken( "="):
3894 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3895 if not self.__GetNextHexNumber():
3896 raise Warning("expected Hex revision", self.FileName, self.CurrentLineNumber)
3897 Overrides.PciRevision = self.__Token
3898 continue
3899
3900 if self.__IsKeyword( "PCI_COMPRESS"):
3901 if not self.__IsToken( "="):
3902 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3903 if not self.__GetNextToken():
3904 raise Warning("expected TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber)
3905 Overrides.NeedCompress = self.__Token.upper() == 'TRUE'
3906 continue
3907
3908 if self.__IsToken( "}"):
3909 break
3910 else:
3911 EdkLogger.error("FdfParser", FORMAT_INVALID, File=self.FileName, Line=self.CurrentLineNumber)
3912
3913 Obj.OverrideAttribs = Overrides
3914
3915 ## __GetOptRomFileStatement() method
3916 #
3917 # Get FILE statements
3918 #
3919 # @param self The object pointer
3920 # @param Obj for whom FILE statement is got
3921 # @retval True Successfully find FILE statement
3922 # @retval False Not able to find FILE statement
3923 #
3924 def __GetOptRomFileStatement(self, Obj):
3925
3926 if not self.__IsKeyword( "FILE"):
3927 return False
3928
3929 FfsFileObj = OptRomFileStatement.OptRomFileStatement()
3930
3931 if not self.__IsKeyword("EFI") and not self.__IsKeyword("BIN"):
3932 raise Warning("expected Binary type (EFI/BIN)", self.FileName, self.CurrentLineNumber)
3933 FfsFileObj.FileType = self.__Token
3934
3935 if not self.__GetNextToken():
3936 raise Warning("expected File path", self.FileName, self.CurrentLineNumber)
3937 FfsFileObj.FileName = self.__Token
3938 if FfsFileObj.FileName.replace('$(WORKSPACE)', '').find('$') == -1:
3939 #check for file path
3940 ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
3941 if ErrorCode != 0:
3942 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
3943
3944 if FfsFileObj.FileType == 'EFI':
3945 self.__GetOptRomOverrides(FfsFileObj)
3946
3947 Obj.FfsList.append(FfsFileObj)
3948
3949 return True
3950
3951 ## __GetCapInFd() method
3952 #
3953 # Get Cap list contained in FD
3954 #
3955 # @param self The object pointer
3956 # @param FdName FD name
3957 # @retval CapList List of Capsule in FD
3958 #
3959 def __GetCapInFd (self, FdName):
3960
3961 CapList = []
3962 if FdName.upper() in self.Profile.FdDict.keys():
3963 FdObj = self.Profile.FdDict[FdName.upper()]
3964 for elementRegion in FdObj.RegionList:
3965 if elementRegion.RegionType == 'CAPSULE':
3966 for elementRegionData in elementRegion.RegionDataList:
3967 if elementRegionData.endswith(".cap"):
3968 continue
3969 if elementRegionData != None and elementRegionData.upper() not in CapList:
3970 CapList.append(elementRegionData.upper())
3971 return CapList
3972
3973 ## __GetReferencedFdCapTuple() method
3974 #
3975 # Get FV and FD list referenced by a capsule image
3976 #
3977 # @param self The object pointer
3978 # @param CapObj Capsule section to be searched
3979 # @param RefFdList referenced FD by section
3980 # @param RefFvList referenced FV by section
3981 #
3982 def __GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []):
3983
3984 for CapsuleDataObj in CapObj.CapsuleDataList :
3985 if hasattr(CapsuleDataObj, 'FvName') and CapsuleDataObj.FvName != None and CapsuleDataObj.FvName.upper() not in RefFvList:
3986 RefFvList.append (CapsuleDataObj.FvName.upper())
3987 elif hasattr(CapsuleDataObj, 'FdName') and CapsuleDataObj.FdName != None and CapsuleDataObj.FdName.upper() not in RefFdList:
3988 RefFdList.append (CapsuleDataObj.FdName.upper())
3989 elif CapsuleDataObj.Ffs != None:
3990 if isinstance(CapsuleDataObj.Ffs, FfsFileStatement.FileStatement):
3991 if CapsuleDataObj.Ffs.FvName != None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList:
3992 RefFvList.append(CapsuleDataObj.Ffs.FvName.upper())
3993 elif CapsuleDataObj.Ffs.FdName != None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList:
3994 RefFdList.append(CapsuleDataObj.Ffs.FdName.upper())
3995 else:
3996 self.__GetReferencedFdFvTupleFromSection(CapsuleDataObj.Ffs, RefFdList, RefFvList)
3997
3998 ## __GetFvInFd() method
3999 #
4000 # Get FV list contained in FD
4001 #
4002 # @param self The object pointer
4003 # @param FdName FD name
4004 # @retval FvList list of FV in FD
4005 #
4006 def __GetFvInFd (self, FdName):
4007
4008 FvList = []
4009 if FdName.upper() in self.Profile.FdDict.keys():
4010 FdObj = self.Profile.FdDict[FdName.upper()]
4011 for elementRegion in FdObj.RegionList:
4012 if elementRegion.RegionType == 'FV':
4013 for elementRegionData in elementRegion.RegionDataList:
4014 if elementRegionData.endswith(".fv"):
4015 continue
4016 if elementRegionData != None and elementRegionData.upper() not in FvList:
4017 FvList.append(elementRegionData.upper())
4018 return FvList
4019
4020 ## __GetReferencedFdFvTuple() method
4021 #
4022 # Get FD and FV list referenced by a FFS file
4023 #
4024 # @param self The object pointer
4025 # @param FfsFile contains sections to be searched
4026 # @param RefFdList referenced FD by section
4027 # @param RefFvList referenced FV by section
4028 #
4029 def __GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []):
4030
4031 for FfsObj in FvObj.FfsList:
4032 if isinstance(FfsObj, FfsFileStatement.FileStatement):
4033 if FfsObj.FvName != None and FfsObj.FvName.upper() not in RefFvList:
4034 RefFvList.append(FfsObj.FvName.upper())
4035 elif FfsObj.FdName != None and FfsObj.FdName.upper() not in RefFdList:
4036 RefFdList.append(FfsObj.FdName.upper())
4037 else:
4038 self.__GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList)
4039
4040 ## __GetReferencedFdFvTupleFromSection() method
4041 #
4042 # Get FD and FV list referenced by a FFS section
4043 #
4044 # @param self The object pointer
4045 # @param FfsFile contains sections to be searched
4046 # @param FdList referenced FD by section
4047 # @param FvList referenced FV by section
4048 #
4049 def __GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []):
4050
4051 SectionStack = []
4052 SectionStack.extend(FfsFile.SectionList)
4053 while SectionStack != []:
4054 SectionObj = SectionStack.pop()
4055 if isinstance(SectionObj, FvImageSection.FvImageSection):
4056 if SectionObj.FvName != None and SectionObj.FvName.upper() not in FvList:
4057 FvList.append(SectionObj.FvName.upper())
4058 if SectionObj.Fv != None and SectionObj.Fv.UiFvName != None and SectionObj.Fv.UiFvName.upper() not in FvList:
4059 FvList.append(SectionObj.Fv.UiFvName.upper())
4060 self.__GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList)
4061
4062 if isinstance(SectionObj, CompressSection.CompressSection) or isinstance(SectionObj, GuidSection.GuidSection):
4063 SectionStack.extend(SectionObj.SectionList)
4064
4065 ## CycleReferenceCheck() method
4066 #
4067 # Check whether cycle reference exists in FDF
4068 #
4069 # @param self The object pointer
4070 # @retval True cycle reference exists
4071 # @retval False Not exists cycle reference
4072 #
4073 def CycleReferenceCheck(self):
4074 #
4075 # Check the cycle between FV and FD image
4076 #
4077 MaxLength = len (self.Profile.FvDict)
4078 for FvName in self.Profile.FvDict.keys():
4079 LogStr = "\nCycle Reference Checking for FV: %s\n" % FvName
4080 RefFvStack = []
4081 RefFvStack.append(FvName)
4082 FdAnalyzedList = []
4083
4084 Index = 0
4085 while RefFvStack != [] and Index < MaxLength:
4086 Index = Index + 1
4087 FvNameFromStack = RefFvStack.pop()
4088 if FvNameFromStack.upper() in self.Profile.FvDict.keys():
4089 FvObj = self.Profile.FvDict[FvNameFromStack.upper()]
4090 else:
4091 continue
4092
4093 RefFdList = []
4094 RefFvList = []
4095 self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
4096
4097 for RefFdName in RefFdList:
4098 if RefFdName in FdAnalyzedList:
4099 continue
4100
4101 LogStr += "FV %s contains FD %s\n" % (FvNameFromStack, RefFdName)
4102 FvInFdList = self.__GetFvInFd(RefFdName)
4103 if FvInFdList != []:
4104 for FvNameInFd in FvInFdList:
4105 LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)
4106 if FvNameInFd not in RefFvStack:
4107 RefFvStack.append(FvNameInFd)
4108
4109 if FvName in RefFvStack or FvNameFromStack in RefFvStack:
4110 EdkLogger.info(LogStr)
4111 return True
4112 FdAnalyzedList.append(RefFdName)
4113
4114 for RefFvName in RefFvList:
4115 LogStr += "FV %s contains FV %s\n" % (FvNameFromStack, RefFvName)
4116 if RefFvName not in RefFvStack:
4117 RefFvStack.append(RefFvName)
4118
4119 if FvName in RefFvStack or FvNameFromStack in RefFvStack:
4120 EdkLogger.info(LogStr)
4121 return True
4122
4123 #
4124 # Check the cycle between Capsule and FD image
4125 #
4126 MaxLength = len (self.Profile.CapsuleDict)
4127 for CapName in self.Profile.CapsuleDict.keys():
4128 #
4129 # Capsule image to be checked.
4130 #
4131 LogStr = "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
4132 RefCapStack = []
4133 RefCapStack.append(CapName)
4134 FdAnalyzedList = []
4135 FvAnalyzedList = []
4136
4137 Index = 0
4138 while RefCapStack != [] and Index < MaxLength:
4139 Index = Index + 1
4140 CapNameFromStack = RefCapStack.pop()
4141 if CapNameFromStack.upper() in self.Profile.CapsuleDict.keys():
4142 CapObj = self.Profile.CapsuleDict[CapNameFromStack.upper()]
4143 else:
4144 continue
4145
4146 RefFvList = []
4147 RefFdList = []
4148 self.__GetReferencedFdCapTuple(CapObj, RefFdList, RefFvList)
4149
4150 FvListLength = 0
4151 FdListLength = 0
4152 while FvListLength < len (RefFvList) or FdListLength < len (RefFdList):
4153 for RefFdName in RefFdList:
4154 if RefFdName in FdAnalyzedList:
4155 continue
4156
4157 LogStr += "Capsule %s contains FD %s\n" % (CapNameFromStack, RefFdName)
4158 CapInFdList = self.__GetCapInFd(RefFdName)
4159 if CapInFdList != []:
4160 for CapNameInFd in CapInFdList:
4161 LogStr += "FD %s contains Capsule %s\n" % (RefFdName,CapNameInFd)
4162 if CapNameInFd not in RefCapStack:
4163 RefCapStack.append(CapNameInFd)
4164
4165 if CapName in RefCapStack or CapNameFromStack in RefCapStack:
4166 EdkLogger.info(LogStr)
4167 return True
4168
4169 FvInFdList = self.__GetFvInFd(RefFdName)
4170 if FvInFdList != []:
4171 for FvNameInFd in FvInFdList:
4172 LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)
4173 if FvNameInFd not in RefFvList:
4174 RefFvList.append(FvNameInFd)
4175
4176 FdAnalyzedList.append(RefFdName)
4177 #
4178 # the number of the parsed FV and FD image
4179 #
4180 FvListLength = len (RefFvList)
4181 FdListLength = len (RefFdList)
4182 for RefFvName in RefFvList:
4183 if RefFvName in FvAnalyzedList:
4184 continue
4185 LogStr += "Capsule %s contains FV %s\n" % (CapNameFromStack, RefFvName)
4186 if RefFvName.upper() in self.Profile.FvDict.keys():
4187 FvObj = self.Profile.FvDict[RefFvName.upper()]
4188 else:
4189 continue
4190 self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
4191 FvAnalyzedList.append(RefFvName)
4192
4193 return False
4194
4195 if __name__ == "__main__":
4196 import sys
4197 try:
4198 test_file = sys.argv[1]
4199 except IndexError, v:
4200 print "Usage: %s filename" % sys.argv[0]
4201 sys.exit(1)
4202
4203 parser = FdfParser(test_file)
4204 try:
4205 parser.ParseFile()
4206 parser.CycleReferenceCheck()
4207 except Warning, X:
4208 print str(X)
4209 else:
4210 print "Success!"
4211