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