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