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