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