]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Common/FdfParserLite.py
BaseTools: FdfParser & FdfParserLite refactor regular expression for GUIDs
[mirror_edk2.git] / BaseTools / Source / Python / Common / FdfParserLite.py
1 ## @file
2 # parse FDF file
3 #
4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 #
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
10 #
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 #
14
15 ##
16 # Import Modules
17 #
18 import re
19 import Common.LongFilePathOs as os
20
21 import CommonDataClass.FdfClass
22 from Common.LongFilePathSupport import OpenLongFilePath as open
23 from Common.MultipleWorkspace import MultipleWorkspace as mws
24 from Common.RangeExpression import RangeExpression
25
26 ##define T_CHAR_SPACE ' '
27 ##define T_CHAR_NULL '\0'
28 ##define T_CHAR_CR '\r'
29 ##define T_CHAR_TAB '\t'
30 ##define T_CHAR_LF '\n'
31 ##define T_CHAR_SLASH '/'
32 ##define T_CHAR_BACKSLASH '\\'
33 ##define T_CHAR_DOUBLE_QUOTE '\"'
34 ##define T_CHAR_SINGLE_QUOTE '\''
35 ##define T_CHAR_STAR '*'
36 ##define T_CHAR_HASH '#'
37
38 (T_CHAR_SPACE, T_CHAR_NULL, T_CHAR_CR, T_CHAR_TAB, T_CHAR_LF, T_CHAR_SLASH, \
39 T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_HASH) = \
40 (' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#')
41
42 SEPERATOR_TUPLE = ('=', '|', ',', '{', '}')
43
44 IncludeFileList = []
45 # Macro passed from command line, which has greatest priority and can NOT be overridden by those in FDF
46 InputMacroDict = {}
47 # All Macro values when parsing file, not replace existing Macro
48 AllMacroList = []
49
50 def GetRealFileLine (File, Line):
51
52 InsertedLines = 0
53 for Profile in IncludeFileList:
54 if Line >= Profile.InsertStartLineNumber and Line < Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList):
55 return (Profile.FileName, Line - Profile.InsertStartLineNumber + 1)
56 if Line >= Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList):
57 InsertedLines += Profile.InsertAdjust + len(Profile.FileLinesList)
58
59 return (File, Line - InsertedLines)
60
61 ## The exception class that used to report error messages when parsing FDF
62 #
63 # Currently the "ToolName" is set to be "FDF Parser".
64 #
65 class Warning (Exception):
66 ## The constructor
67 #
68 # @param self The object pointer
69 # @param Str The message to record
70 # @param File The FDF name
71 # @param Line The Line number that error occurs
72 #
73 def __init__(self, Str, File=None, Line=None):
74
75 FileLineTuple = GetRealFileLine(File, Line)
76 self.FileName = FileLineTuple[0]
77 self.LineNumber = FileLineTuple[1]
78 self.message = Str + str(self.LineNumber)
79 self.ToolName = 'FDF Parser'
80
81 ## The MACRO class that used to record macro value data when parsing include file
82 #
83 #
84 class MacroProfile :
85 ## The constructor
86 #
87 # @param self The object pointer
88 # @param FileName The file that to be parsed
89 #
90 def __init__(self, FileName, Line):
91 self.FileName = FileName
92 self.DefinedAtLine = Line
93 self.MacroName = None
94 self.MacroValue = None
95
96 ## The Include file content class that used to record file data when parsing include file
97 #
98 # May raise Exception when opening file.
99 #
100 class IncludeFileProfile :
101 ## The constructor
102 #
103 # @param self The object pointer
104 # @param FileName The file that to be parsed
105 #
106 def __init__(self, FileName):
107 self.FileName = FileName
108 self.FileLinesList = []
109 try:
110 fsock = open(FileName, "rb", 0)
111 try:
112 self.FileLinesList = fsock.readlines()
113 finally:
114 fsock.close()
115
116 except IOError:
117 raise Warning("Error when opening file %s" % FileName)
118
119 self.InsertStartLineNumber = None
120 self.InsertAdjust = 0
121
122 ## The FDF content class that used to record file data when parsing FDF
123 #
124 # May raise Exception when opening file.
125 #
126 class FileProfile :
127 ## The constructor
128 #
129 # @param self The object pointer
130 # @param FileName The file that to be parsed
131 #
132 def __init__(self, FileName):
133 self.FileLinesList = []
134 try:
135 fsock = open(FileName, "rb", 0)
136 try:
137 self.FileLinesList = fsock.readlines()
138 finally:
139 fsock.close()
140
141 except IOError:
142 raise Warning("Error when opening file %s" % FileName)
143
144 self.PcdDict = {}
145 self.InfList = []
146
147 self.PcdFileLineDict = {}
148 self.InfFileLineList = []
149
150 self.FdDict = {}
151 self.FvDict = {}
152 self.CapsuleList = []
153 # self.VtfList = []
154 # self.RuleDict = {}
155
156 ## The syntax parser for FDF
157 #
158 # PreprocessFile method should be called prior to ParseFile
159 # CycleReferenceCheck method can detect cycles in FDF contents
160 #
161 # GetNext*** procedures mean these procedures will get next token first, then make judgement.
162 # Get*** procedures mean these procedures will make judgement on current token only.
163 #
164 class FdfParser(object):
165 ## The constructor
166 #
167 # @param self The object pointer
168 # @param FileName The file that to be parsed
169 #
170 def __init__(self, FileName):
171 self.Profile = FileProfile(FileName)
172 self.FileName = FileName
173 self.CurrentLineNumber = 1
174 self.CurrentOffsetWithinLine = 0
175 self.CurrentFdName = None
176 self.CurrentFvName = None
177 self.__Token = ""
178 self.__SkippedChars = ""
179
180 self.__WipeOffArea = []
181
182 ## __IsWhiteSpace() method
183 #
184 # Whether char at current FileBufferPos is whitespace
185 #
186 # @param self The object pointer
187 # @param Char The char to test
188 # @retval True The char is a kind of white space
189 # @retval False The char is NOT a kind of white space
190 #
191 def __IsWhiteSpace(self, Char):
192 if Char in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_SPACE, T_CHAR_TAB, T_CHAR_LF):
193 return True
194 else:
195 return False
196
197 ## __SkipWhiteSpace() method
198 #
199 # Skip white spaces from current char, return number of chars skipped
200 #
201 # @param self The object pointer
202 # @retval Count The number of chars skipped
203 #
204 def __SkipWhiteSpace(self):
205 Count = 0
206 while not self.__EndOfFile():
207 Count += 1
208 if self.__CurrentChar() in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_LF, T_CHAR_SPACE, T_CHAR_TAB):
209 self.__SkippedChars += str(self.__CurrentChar())
210 self.__GetOneChar()
211
212 else:
213 Count = Count - 1
214 return Count
215
216 ## __EndOfFile() method
217 #
218 # Judge current buffer pos is at file end
219 #
220 # @param self The object pointer
221 # @retval True Current File buffer position is at file end
222 # @retval False Current File buffer position is NOT at file end
223 #
224 def __EndOfFile(self):
225 NumberOfLines = len(self.Profile.FileLinesList)
226 SizeOfLastLine = len(self.Profile.FileLinesList[-1])
227 if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1:
228 return True
229 elif self.CurrentLineNumber > NumberOfLines:
230 return True
231 else:
232 return False
233
234 ## __EndOfLine() method
235 #
236 # Judge current buffer pos is at line end
237 #
238 # @param self The object pointer
239 # @retval True Current File buffer position is at line end
240 # @retval False Current File buffer position is NOT at line end
241 #
242 def __EndOfLine(self):
243 if self.CurrentLineNumber > len(self.Profile.FileLinesList):
244 return True
245 SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
246 if self.CurrentOffsetWithinLine >= SizeOfCurrentLine:
247 return True
248 else:
249 return False
250
251 ## Rewind() method
252 #
253 # Reset file data buffer to the initial state
254 #
255 # @param self The object pointer
256 #
257 def Rewind(self):
258 self.CurrentLineNumber = 1
259 self.CurrentOffsetWithinLine = 0
260
261 ## __UndoOneChar() method
262 #
263 # Go back one char in the file buffer
264 #
265 # @param self The object pointer
266 # @retval True Successfully go back one char
267 # @retval False Not able to go back one char as file beginning reached
268 #
269 def __UndoOneChar(self):
270
271 if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0:
272 return False
273 elif self.CurrentOffsetWithinLine == 0:
274 self.CurrentLineNumber -= 1
275 self.CurrentOffsetWithinLine = len(self.__CurrentLine()) - 1
276 else:
277 self.CurrentOffsetWithinLine -= 1
278 return True
279
280 ## __GetOneChar() method
281 #
282 # Move forward one char in the file buffer
283 #
284 # @param self The object pointer
285 #
286 def __GetOneChar(self):
287 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
288 self.CurrentLineNumber += 1
289 self.CurrentOffsetWithinLine = 0
290 else:
291 self.CurrentOffsetWithinLine += 1
292
293 ## __CurrentChar() method
294 #
295 # Get the char pointed to by the file buffer pointer
296 #
297 # @param self The object pointer
298 # @retval Char Current char
299 #
300 def __CurrentChar(self):
301 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine]
302
303 ## __NextChar() method
304 #
305 # Get the one char pass the char pointed to by the file buffer pointer
306 #
307 # @param self The object pointer
308 # @retval Char Next char
309 #
310 def __NextChar(self):
311 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
312 return self.Profile.FileLinesList[self.CurrentLineNumber][0]
313 else:
314 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1]
315
316 ## __SetCurrentCharValue() method
317 #
318 # Modify the value of current char
319 #
320 # @param self The object pointer
321 # @param Value The new value of current char
322 #
323 def __SetCurrentCharValue(self, Value):
324 self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value
325
326 ## __CurrentLine() method
327 #
328 # Get the list that contains current line contents
329 #
330 # @param self The object pointer
331 # @retval List current line contents
332 #
333 def __CurrentLine(self):
334 return self.Profile.FileLinesList[self.CurrentLineNumber - 1]
335
336 def __StringToList(self):
337 self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList]
338 self.Profile.FileLinesList[-1].append(' ')
339
340 def __ReplaceMacros(self, Str, File, Line):
341 MacroEnd = 0
342 while Str.find('$(', MacroEnd) >= 0:
343 MacroStart = Str.find('$(', MacroEnd)
344 if Str.find(')', MacroStart) > 0:
345 MacroEnd = Str.find(')', MacroStart)
346 Name = Str[MacroStart + 2 : MacroEnd]
347 Value = None
348 if Name in InputMacroDict:
349 Value = InputMacroDict[Name]
350
351 else:
352 for Profile in AllMacroList:
353 if Profile.FileName == File and Profile.MacroName == Name and Profile.DefinedAtLine <= Line:
354 Value = Profile.MacroValue
355
356 if Value != None:
357 Str = Str.replace('$(' + Name + ')', Value)
358 MacroEnd = MacroStart + len(Value)
359
360 else:
361 raise Warning("Macro not complete At Line ", self.FileName, self.CurrentLineNumber)
362 return Str
363
364 def __ReplaceFragment(self, StartPos, EndPos, Value=' '):
365 if StartPos[0] == EndPos[0]:
366 Offset = StartPos[1]
367 while Offset <= EndPos[1]:
368 self.Profile.FileLinesList[StartPos[0]][Offset] = Value
369 Offset += 1
370 return
371
372 Offset = StartPos[1]
373 while self.Profile.FileLinesList[StartPos[0]][Offset] not in ('\r', '\n'):
374 self.Profile.FileLinesList[StartPos[0]][Offset] = Value
375 Offset += 1
376
377 Line = StartPos[0]
378 while Line < EndPos[0]:
379 Offset = 0
380 while self.Profile.FileLinesList[Line][Offset] not in ('\r', '\n'):
381 self.Profile.FileLinesList[Line][Offset] = Value
382 Offset += 1
383 Line += 1
384
385 Offset = 0
386 while Offset <= EndPos[1]:
387 self.Profile.FileLinesList[EndPos[0]][Offset] = Value
388 Offset += 1
389
390
391 def __GetMacroName(self):
392 if not self.__GetNextToken():
393 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber)
394 MacroName = self.__Token
395 NotFlag = False
396 if MacroName.startswith('!'):
397 NotFlag = True
398 MacroName = MacroName[1:].strip()
399
400 if not MacroName.startswith('$(') or not MacroName.endswith(')'):
401 raise Warning("Macro name expected(Please use '$(%(Token)s)' if '%(Token)s' is a macro.)" % {"Token" : MacroName},
402 self.FileName, self.CurrentLineNumber)
403 MacroName = MacroName[2:-1]
404 return MacroName, NotFlag
405
406 ## PreprocessFile() method
407 #
408 # Preprocess file contents, replace comments with spaces.
409 # In the end, rewind the file buffer pointer to the beginning
410 # BUGBUG: No !include statement processing contained in this procedure
411 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
412 #
413 # @param self The object pointer
414 #
415 def PreprocessFile(self):
416
417 self.Rewind()
418 InComment = False
419 DoubleSlashComment = False
420 HashComment = False
421 # HashComment in quoted string " " is ignored.
422 InString = False
423
424 while not self.__EndOfFile():
425
426 if self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment:
427 InString = not InString
428 # meet new line, then no longer in a comment for // and '#'
429 if self.__CurrentChar() == T_CHAR_LF:
430 self.CurrentLineNumber += 1
431 self.CurrentOffsetWithinLine = 0
432 if InComment and DoubleSlashComment:
433 InComment = False
434 DoubleSlashComment = False
435 if InComment and HashComment:
436 InComment = False
437 HashComment = False
438 # check for */ comment end
439 elif InComment and not DoubleSlashComment and not HashComment and self.__CurrentChar() == T_CHAR_STAR and self.__NextChar() == T_CHAR_SLASH:
440 self.__SetCurrentCharValue(T_CHAR_SPACE)
441 self.__GetOneChar()
442 self.__SetCurrentCharValue(T_CHAR_SPACE)
443 self.__GetOneChar()
444 InComment = False
445 # set comments to spaces
446 elif InComment:
447 self.__SetCurrentCharValue(T_CHAR_SPACE)
448 self.__GetOneChar()
449 # check for // comment
450 elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH and not self.__EndOfLine():
451 InComment = True
452 DoubleSlashComment = True
453 # check for '#' comment
454 elif self.__CurrentChar() == T_CHAR_HASH and not self.__EndOfLine() and not InString:
455 InComment = True
456 HashComment = True
457 # check for /* comment start
458 elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_STAR:
459 self.__SetCurrentCharValue( T_CHAR_SPACE)
460 self.__GetOneChar()
461 self.__SetCurrentCharValue( T_CHAR_SPACE)
462 self.__GetOneChar()
463 InComment = True
464 else:
465 self.__GetOneChar()
466
467 # restore from ListOfList to ListOfString
468 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
469 self.Rewind()
470
471 ## PreprocessIncludeFile() method
472 #
473 # Preprocess file contents, replace !include statements with file contents.
474 # In the end, rewind the file buffer pointer to the beginning
475 #
476 # @param self The object pointer
477 #
478 def PreprocessIncludeFile(self):
479
480 while self.__GetNextToken():
481
482 if self.__Token == '!include':
483 IncludeLine = self.CurrentLineNumber
484 IncludeOffset = self.CurrentOffsetWithinLine - len('!include')
485 if not self.__GetNextToken():
486 raise Warning("expected include file name At Line ", self.FileName, self.CurrentLineNumber)
487 IncFileName = self.__Token
488 if not os.path.isabs(IncFileName):
489 if IncFileName.startswith('$(WORKSPACE)'):
490 Str = mws.handleWsMacro(IncFileName)
491 Str = Str.replace('$(WORKSPACE)', os.environ.get('WORKSPACE'))
492 if os.path.exists(Str):
493 if not os.path.isabs(Str):
494 Str = os.path.abspath(Str)
495 IncFileName = Str
496 else:
497 # file is in the same dir with FDF file
498 FullFdf = self.FileName
499 if not os.path.isabs(self.FileName):
500 FullFdf = mws.join(os.environ.get('WORKSPACE'), self.FileName)
501
502 IncFileName = os.path.join(os.path.dirname(FullFdf), IncFileName)
503
504 if not os.path.exists(os.path.normpath(IncFileName)):
505 raise Warning("Include file not exists At Line ", self.FileName, self.CurrentLineNumber)
506
507 IncFileProfile = IncludeFileProfile(os.path.normpath(IncFileName))
508
509 CurrentLine = self.CurrentLineNumber
510 CurrentOffset = self.CurrentOffsetWithinLine
511 # list index of the insertion, note that line number is 'CurrentLine + 1'
512 InsertAtLine = CurrentLine
513 IncFileProfile.InsertStartLineNumber = InsertAtLine + 1
514 # deal with remaining portions after "!include filename", if exists.
515 if self.__GetNextToken():
516 if self.CurrentLineNumber == CurrentLine:
517 RemainingLine = self.__CurrentLine()[CurrentOffset:]
518 self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine)
519 IncFileProfile.InsertAdjust += 1
520 self.CurrentLineNumber += 1
521 self.CurrentOffsetWithinLine = 0
522
523 for Line in IncFileProfile.FileLinesList:
524 self.Profile.FileLinesList.insert(InsertAtLine, Line)
525 self.CurrentLineNumber += 1
526 InsertAtLine += 1
527
528 IncludeFileList.append(IncFileProfile)
529
530 # comment out the processed include file statement
531 TempList = list(self.Profile.FileLinesList[IncludeLine - 1])
532 TempList.insert(IncludeOffset, '#')
533 self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList)
534
535 self.Rewind()
536
537 ## PreprocessIncludeFile() method
538 #
539 # Preprocess file contents, replace !include statements with file contents.
540 # In the end, rewind the file buffer pointer to the beginning
541 #
542 # @param self The object pointer
543 #
544 def PreprocessConditionalStatement(self):
545 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
546 IfList = []
547 while self.__GetNextToken():
548 if self.__Token == 'DEFINE':
549 DefineLine = self.CurrentLineNumber - 1
550 DefineOffset = self.CurrentOffsetWithinLine - len('DEFINE')
551 if not self.__GetNextToken():
552 raise Warning("expected Macro name At Line ", self.FileName, self.CurrentLineNumber)
553 Macro = self.__Token
554 if not self.__IsToken( "="):
555 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
556
557 if not self.__GetNextToken():
558 raise Warning("expected value At Line ", self.FileName, self.CurrentLineNumber)
559
560 if self.__GetStringData():
561 pass
562 Value = self.__Token
563 if not Macro in InputMacroDict:
564 FileLineTuple = GetRealFileLine(self.FileName, DefineLine + 1)
565 MacProfile = MacroProfile(FileLineTuple[0], FileLineTuple[1])
566 MacProfile.MacroName = Macro
567 MacProfile.MacroValue = Value
568 AllMacroList.append(MacProfile)
569 self.__WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
570
571 elif self.__Token in ('!ifdef', '!ifndef', '!if'):
572 IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))
573 IfList.append([IfStartPos, None, None])
574 CondLabel = self.__Token
575
576 MacroName, NotFlag = self.__GetMacroName()
577 NotDefineFlag = False
578 if CondLabel == '!ifndef':
579 NotDefineFlag = True
580 if CondLabel == '!ifdef' or CondLabel == '!ifndef':
581 if NotFlag:
582 raise Warning("'NOT' operation not allowed for Macro name At Line ", self.FileName, self.CurrentLineNumber)
583
584 if CondLabel == '!if':
585
586 if not self.__GetNextOp():
587 raise Warning("expected !endif At Line ", self.FileName, self.CurrentLineNumber)
588
589 if self.__Token in ('!=', '==', '>', '<', '>=', '<='):
590 Op = self.__Token
591 if not self.__GetNextToken():
592 raise Warning("expected value At Line ", self.FileName, self.CurrentLineNumber)
593 if self.__GetStringData():
594 pass
595 MacroValue = self.__Token
596 ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, Op, MacroValue)
597 if NotFlag:
598 ConditionSatisfied = not ConditionSatisfied
599 BranchDetermined = ConditionSatisfied
600 else:
601 self.CurrentOffsetWithinLine -= len(self.__Token)
602 ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, None, 'Bool')
603 if NotFlag:
604 ConditionSatisfied = not ConditionSatisfied
605 BranchDetermined = ConditionSatisfied
606 IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
607 if ConditionSatisfied:
608 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
609
610 else:
611 ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1)
612 if NotDefineFlag:
613 ConditionSatisfied = not ConditionSatisfied
614 BranchDetermined = ConditionSatisfied
615 IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
616 if ConditionSatisfied:
617 self.__WipeOffArea.append((IfStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
618
619 elif self.__Token in ('!elseif', '!else'):
620 ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))
621 if len(IfList) <= 0:
622 raise Warning("Missing !if statement At Line ", self.FileName, self.CurrentLineNumber)
623 if IfList[-1][1]:
624 IfList[-1] = [ElseStartPos, False, True]
625 self.__WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
626 else:
627 self.__WipeOffArea.append((IfList[-1][0], ElseStartPos))
628 IfList[-1] = [ElseStartPos, True, IfList[-1][2]]
629 if self.__Token == '!elseif':
630 MacroName, NotFlag = self.__GetMacroName()
631 if not self.__GetNextOp():
632 raise Warning("expected !endif At Line ", self.FileName, self.CurrentLineNumber)
633
634 if self.__Token in ('!=', '==', '>', '<', '>=', '<='):
635 Op = self.__Token
636 if not self.__GetNextToken():
637 raise Warning("expected value At Line ", self.FileName, self.CurrentLineNumber)
638 if self.__GetStringData():
639 pass
640 MacroValue = self.__Token
641 ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, Op, MacroValue)
642 if NotFlag:
643 ConditionSatisfied = not ConditionSatisfied
644
645 else:
646 self.CurrentOffsetWithinLine -= len(self.__Token)
647 ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, None, 'Bool')
648 if NotFlag:
649 ConditionSatisfied = not ConditionSatisfied
650
651 IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]]
652
653 if IfList[-1][1]:
654 if IfList[-1][2]:
655 IfList[-1][1] = False
656 else:
657 IfList[-1][2] = True
658 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
659
660
661 elif self.__Token == '!endif':
662 if IfList[-1][1]:
663 self.__WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
664 else:
665 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
666
667 IfList.pop()
668
669
670 if len(IfList) > 0:
671 raise Warning("Missing !endif At Line ", self.FileName, self.CurrentLineNumber)
672 self.Rewind()
673
674 def __EvaluateConditional(self, Name, Line, Op = None, Value = None):
675
676 FileLineTuple = GetRealFileLine(self.FileName, Line)
677 if Name in InputMacroDict:
678 MacroValue = InputMacroDict[Name]
679 if Op == None:
680 if Value == 'Bool' and MacroValue == None or MacroValue.upper() == 'FALSE':
681 return False
682 return True
683 elif Op == '!=':
684 if Value != MacroValue:
685 return True
686 else:
687 return False
688 elif Op == '==':
689 if Value == MacroValue:
690 return True
691 else:
692 return False
693 else:
694 if (self.__IsHex(Value) or Value.isdigit()) and (self.__IsHex(MacroValue) or (MacroValue != None and MacroValue.isdigit())):
695 InputVal = long(Value, 0)
696 MacroVal = long(MacroValue, 0)
697 if Op == '>':
698 if MacroVal > InputVal:
699 return True
700 else:
701 return False
702 elif Op == '>=':
703 if MacroVal >= InputVal:
704 return True
705 else:
706 return False
707 elif Op == '<':
708 if MacroVal < InputVal:
709 return True
710 else:
711 return False
712 elif Op == '<=':
713 if MacroVal <= InputVal:
714 return True
715 else:
716 return False
717 else:
718 return False
719 else:
720 raise Warning("Value %s is not a number At Line ", self.FileName, Line)
721
722 for Profile in AllMacroList:
723 if Profile.FileName == FileLineTuple[0] and Profile.MacroName == Name and Profile.DefinedAtLine <= FileLineTuple[1]:
724 if Op == None:
725 if Value == 'Bool' and Profile.MacroValue == None or Profile.MacroValue.upper() == 'FALSE':
726 return False
727 return True
728 elif Op == '!=':
729 if Value != Profile.MacroValue:
730 return True
731 else:
732 return False
733 elif Op == '==':
734 if Value == Profile.MacroValue:
735 return True
736 else:
737 return False
738 else:
739 if (self.__IsHex(Value) or Value.isdigit()) and (self.__IsHex(Profile.MacroValue) or (Profile.MacroValue != None and Profile.MacroValue.isdigit())):
740 InputVal = long(Value, 0)
741 MacroVal = long(Profile.MacroValue, 0)
742 if Op == '>':
743 if MacroVal > InputVal:
744 return True
745 else:
746 return False
747 elif Op == '>=':
748 if MacroVal >= InputVal:
749 return True
750 else:
751 return False
752 elif Op == '<':
753 if MacroVal < InputVal:
754 return True
755 else:
756 return False
757 elif Op == '<=':
758 if MacroVal <= InputVal:
759 return True
760 else:
761 return False
762 else:
763 return False
764 else:
765 raise Warning("Value %s is not a number At Line ", self.FileName, Line)
766
767 return False
768
769 ## __IsToken() method
770 #
771 # Check whether input string is found from current char position along
772 # If found, the string value is put into self.__Token
773 #
774 # @param self The object pointer
775 # @param String The string to search
776 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
777 # @retval True Successfully find string, file buffer pointer moved forward
778 # @retval False Not able to find string, file buffer pointer not changed
779 #
780 def __IsToken(self, String, IgnoreCase = False):
781 self.__SkipWhiteSpace()
782
783 # Only consider the same line, no multi-line token allowed
784 StartPos = self.CurrentOffsetWithinLine
785 index = -1
786 if IgnoreCase:
787 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper())
788 else:
789 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String)
790 if index == 0:
791 self.CurrentOffsetWithinLine += len(String)
792 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
793 return True
794 return False
795
796 ## __IsKeyword() method
797 #
798 # Check whether input keyword is found from current char position along, whole word only!
799 # If found, the string value is put into self.__Token
800 #
801 # @param self The object pointer
802 # @param Keyword The string to search
803 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
804 # @retval True Successfully find string, file buffer pointer moved forward
805 # @retval False Not able to find string, file buffer pointer not changed
806 #
807 def __IsKeyword(self, KeyWord, IgnoreCase = False):
808 self.__SkipWhiteSpace()
809
810 # Only consider the same line, no multi-line token allowed
811 StartPos = self.CurrentOffsetWithinLine
812 index = -1
813 if IgnoreCase:
814 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(KeyWord.upper())
815 else:
816 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(KeyWord)
817 if index == 0:
818 followingChar = self.__CurrentLine()[self.CurrentOffsetWithinLine + len(KeyWord)]
819 if not str(followingChar).isspace() and followingChar not in SEPERATOR_TUPLE:
820 return False
821 self.CurrentOffsetWithinLine += len(KeyWord)
822 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
823 return True
824 return False
825
826 ## __GetNextWord() method
827 #
828 # Get next C name from file lines
829 # If found, the string value is put into self.__Token
830 #
831 # @param self The object pointer
832 # @retval True Successfully find a C name string, file buffer pointer moved forward
833 # @retval False Not able to find a C name string, file buffer pointer not changed
834 #
835 def __GetNextWord(self):
836 self.__SkipWhiteSpace()
837 if self.__EndOfFile():
838 return False
839
840 TempChar = self.__CurrentChar()
841 StartPos = self.CurrentOffsetWithinLine
842 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_':
843 self.__GetOneChar()
844 while not self.__EndOfLine():
845 TempChar = self.__CurrentChar()
846 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \
847 or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-':
848 self.__GetOneChar()
849
850 else:
851 break
852
853 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
854 return True
855
856 return False
857
858 ## __GetNextToken() method
859 #
860 # Get next token unit before a seperator
861 # If found, the string value is put into self.__Token
862 #
863 # @param self The object pointer
864 # @retval True Successfully find a token unit, file buffer pointer moved forward
865 # @retval False Not able to find a token unit, file buffer pointer not changed
866 #
867 def __GetNextToken(self):
868 # Skip leading spaces, if exist.
869 self.__SkipWhiteSpace()
870 if self.__EndOfFile():
871 return False
872 # Record the token start position, the position of the first non-space char.
873 StartPos = self.CurrentOffsetWithinLine
874 StartLine = self.CurrentLineNumber
875 while not self.__EndOfLine():
876 TempChar = self.__CurrentChar()
877 # Try to find the end char that is not a space and not in seperator tuple.
878 # That is, when we got a space or any char in the tuple, we got the end of token.
879 if not str(TempChar).isspace() and TempChar not in SEPERATOR_TUPLE:
880 self.__GetOneChar()
881 # if we happen to meet a seperator as the first char, we must proceed to get it.
882 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
883 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE:
884 self.__GetOneChar()
885 break
886 else:
887 break
888 # else:
889 # return False
890
891 EndPos = self.CurrentOffsetWithinLine
892 if self.CurrentLineNumber != StartLine:
893 EndPos = len(self.Profile.FileLinesList[StartLine-1])
894 self.__Token = self.Profile.FileLinesList[StartLine-1][StartPos : EndPos]
895 if StartPos != self.CurrentOffsetWithinLine:
896 return True
897 else:
898 return False
899
900 def __GetNextOp(self):
901 # Skip leading spaces, if exist.
902 self.__SkipWhiteSpace()
903 if self.__EndOfFile():
904 return False
905 # Record the token start position, the position of the first non-space char.
906 StartPos = self.CurrentOffsetWithinLine
907 while not self.__EndOfLine():
908 TempChar = self.__CurrentChar()
909 # Try to find the end char that is not a space
910 if not str(TempChar).isspace():
911 self.__GetOneChar()
912 else:
913 break
914 else:
915 return False
916
917 if StartPos != self.CurrentOffsetWithinLine:
918 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
919 return True
920 else:
921 return False
922 ## __GetNextGuid() method
923 #
924 # Get next token unit before a seperator
925 # If found, the GUID string is put into self.__Token
926 #
927 # @param self The object pointer
928 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward
929 # @retval False Not able to find a registry format GUID, file buffer pointer not changed
930 #
931 def __GetNextGuid(self):
932
933 if not self.__GetNextToken():
934 return False
935 if RangeExpression.RegGuidPattern.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", "128K",
2344 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
2345 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2346 AlignValue = self.__Token
2347
2348 BuildNum = None
2349 if self.__IsKeyword( "BUILD_NUM"):
2350 if not self.__IsToken( "="):
2351 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2352
2353 if not self.__GetNextToken():
2354 raise Warning("expected Build number value At Line ", self.FileName, self.CurrentLineNumber)
2355
2356 BuildNum = self.__Token
2357
2358 if self.__IsKeyword( "VERSION"):
2359 if AlignValue == 'Auto':
2360 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2361 if not self.__IsToken( "="):
2362 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2363 if not self.__GetNextToken():
2364 raise Warning("expected version At Line ", self.FileName, self.CurrentLineNumber)
2365 VerSectionObj = CommonDataClass.FdfClass.VerSectionClassObject()
2366 VerSectionObj.Alignment = AlignValue
2367 VerSectionObj.BuildNum = BuildNum
2368 if self.__GetStringData():
2369 VerSectionObj.StringData = self.__Token
2370 else:
2371 VerSectionObj.FileName = self.__Token
2372 Obj.SectionList.append(VerSectionObj)
2373
2374 elif self.__IsKeyword( "UI"):
2375 if AlignValue == 'Auto':
2376 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2377 if not self.__IsToken( "="):
2378 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2379 if not self.__GetNextToken():
2380 raise Warning("expected UI At Line ", self.FileName, self.CurrentLineNumber)
2381 UiSectionObj = CommonDataClass.FdfClass.UiSectionClassObject()
2382 UiSectionObj.Alignment = AlignValue
2383 if self.__GetStringData():
2384 UiSectionObj.StringData = self.__Token
2385 else:
2386 UiSectionObj.FileName = self.__Token
2387 Obj.SectionList.append(UiSectionObj)
2388
2389 elif self.__IsKeyword( "FV_IMAGE"):
2390 if AlignValue == 'Auto':
2391 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2392 if not self.__IsToken( "="):
2393 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2394 if not self.__GetNextWord():
2395 raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber)
2396
2397 FvName = self.__Token.upper()
2398 FvObj = None
2399
2400 if self.__IsToken( "{"):
2401 FvObj = Fv.FV()
2402 FvObj.UiFvName = FvName
2403 self.__GetDefineStatements(FvObj)
2404 MacroDict.update(FvObj.DefineVarDict)
2405 self.__GetBlockStatement(FvObj)
2406 self.__GetSetStatements(FvObj)
2407 self.__GetFvAlignment(FvObj)
2408 self.__GetFvAttributes(FvObj)
2409 self.__GetAprioriSection(FvObj, MacroDict.copy())
2410 self.__GetAprioriSection(FvObj, MacroDict.copy())
2411
2412 while True:
2413 IsInf = self.__GetInfStatement(FvObj, MacroDict.copy())
2414 IsFile = self.__GetFileStatement(FvObj, MacroDict.copy())
2415 if not IsInf and not IsFile:
2416 break
2417
2418 if not self.__IsToken( "}"):
2419 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
2420
2421 FvImageSectionObj = CommonDataClass.FdfClass.FvImageSectionClassObject()
2422 FvImageSectionObj.Alignment = AlignValue
2423 if FvObj != None:
2424 FvImageSectionObj.Fv = FvObj
2425 FvImageSectionObj.FvName = None
2426 else:
2427 FvImageSectionObj.FvName = FvName
2428
2429 Obj.SectionList.append(FvImageSectionObj)
2430
2431 elif self.__IsKeyword("PEI_DEPEX_EXP") or self.__IsKeyword("DXE_DEPEX_EXP") or self.__IsKeyword("SMM_DEPEX_EXP"):
2432 if AlignValue == 'Auto':
2433 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2434 DepexSectionObj = CommonDataClass.FdfClass.DepexSectionClassObject()
2435 DepexSectionObj.Alignment = AlignValue
2436 DepexSectionObj.DepexType = self.__Token
2437
2438 if not self.__IsToken( "="):
2439 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2440 if not self.__IsToken( "{"):
2441 raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
2442 if not self.__SkipToToken( "}"):
2443 raise Warning("expected Depex expression ending '}' At Line ", self.FileName, self.CurrentLineNumber)
2444
2445 DepexSectionObj.Expression = self.__SkippedChars.rstrip('}')
2446 Obj.SectionList.append(DepexSectionObj)
2447
2448 else:
2449
2450 if not self.__GetNextWord():
2451 raise Warning("expected section type At Line ", self.FileName, self.CurrentLineNumber)
2452
2453 # Encapsulation section appear, UndoToken and return
2454 if self.__Token == "COMPRESS" or self.__Token == "GUIDED":
2455 self.SetFileBufferPos(OldPos)
2456 return False
2457
2458 if self.__Token not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
2459 "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"):
2460 raise Warning("Unknown section type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2461 if AlignValue == 'Auto'and (not self.__Token == 'PE32') and (not self.__Token == 'TE'):
2462 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2463 # DataSection
2464 DataSectionObj = CommonDataClass.FdfClass.DataSectionClassObject()
2465 DataSectionObj.Alignment = AlignValue
2466 DataSectionObj.SecType = self.__Token
2467
2468 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
2469 if self.__FileCouldHaveRelocFlag(Obj.FvFileType) and self.__SectionCouldHaveRelocFlag(DataSectionObj.SecType):
2470 if self.__Token == 'RELOCS_STRIPPED':
2471 DataSectionObj.KeepReloc = False
2472 else:
2473 DataSectionObj.KeepReloc = True
2474 else:
2475 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)
2476
2477 if self.__IsToken("="):
2478 if not self.__GetNextToken():
2479 raise Warning("expected section file path At Line ", self.FileName, self.CurrentLineNumber)
2480 DataSectionObj.SectFileName = self.__Token
2481 else:
2482 if not self.__GetCglSection(DataSectionObj):
2483 return False
2484
2485 Obj.SectionList.append(DataSectionObj)
2486
2487 return True
2488
2489 ## __GetCglSection() method
2490 #
2491 # Get compressed or GUIDed section for Obj
2492 #
2493 # @param self The object pointer
2494 # @param Obj for whom leaf section is got
2495 # @param AlignValue alignment value for complex section
2496 # @retval True Successfully find section statement
2497 # @retval False Not able to find section statement
2498 #
2499 def __GetCglSection(self, Obj, AlignValue = None):
2500
2501 if self.__IsKeyword( "COMPRESS"):
2502 type = "PI_STD"
2503 if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):
2504 type = self.__Token
2505
2506 if not self.__IsToken("{"):
2507 raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
2508
2509 CompressSectionObj = CommonDataClass.FdfClass.CompressSectionClassObject()
2510 CompressSectionObj.Alignment = AlignValue
2511 CompressSectionObj.CompType = type
2512 # Recursive sections...
2513 while True:
2514 IsLeafSection = self.__GetLeafSection(CompressSectionObj)
2515 IsEncapSection = self.__GetEncapsulationSec(CompressSectionObj)
2516 if not IsLeafSection and not IsEncapSection:
2517 break
2518
2519
2520 if not self.__IsToken( "}"):
2521 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
2522 Obj.SectionList.append(CompressSectionObj)
2523
2524 # else:
2525 # raise Warning("Compress type not known At Line ")
2526
2527 return True
2528
2529 elif self.__IsKeyword( "GUIDED"):
2530 GuidValue = None
2531 if self.__GetNextGuid():
2532 GuidValue = self.__Token
2533
2534 AttribDict = self.__GetGuidAttrib()
2535 if not self.__IsToken("{"):
2536 raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
2537 GuidSectionObj = CommonDataClass.FdfClass.GuidSectionClassObject()
2538 GuidSectionObj.Alignment = AlignValue
2539 GuidSectionObj.NameGuid = GuidValue
2540 GuidSectionObj.SectionType = "GUIDED"
2541 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
2542 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
2543 # Recursive sections...
2544 while True:
2545 IsLeafSection = self.__GetLeafSection(GuidSectionObj)
2546 IsEncapSection = self.__GetEncapsulationSec(GuidSectionObj)
2547 if not IsLeafSection and not IsEncapSection:
2548 break
2549
2550 if not self.__IsToken( "}"):
2551 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
2552 Obj.SectionList.append(GuidSectionObj)
2553
2554 return True
2555
2556 return False
2557
2558 ## __GetGuidAttri() method
2559 #
2560 # Get attributes for GUID section
2561 #
2562 # @param self The object pointer
2563 # @retval AttribDict Dictionary of key-value pair of section attributes
2564 #
2565 def __GetGuidAttrib(self):
2566
2567 AttribDict = {}
2568 AttribDict["PROCESSING_REQUIRED"] = False
2569 AttribDict["AUTH_STATUS_VALID"] = False
2570 if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"):
2571 AttribKey = self.__Token
2572
2573 if not self.__IsToken("="):
2574 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2575
2576 if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
2577 raise Warning("expected TRUE/FALSE (1/0) At Line ", self.FileName, self.CurrentLineNumber)
2578 AttribDict[AttribKey] = self.__Token
2579
2580 if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"):
2581 AttribKey = self.__Token
2582
2583 if not self.__IsToken("="):
2584 raise Warning("expected '=' At Line ")
2585
2586 if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
2587 raise Warning("expected TRUE/FALSE (1/0) At Line ", self.FileName, self.CurrentLineNumber)
2588 AttribDict[AttribKey] = self.__Token
2589
2590 return AttribDict
2591
2592 ## __GetEncapsulationSec() method
2593 #
2594 # Get encapsulation section for FILE
2595 #
2596 # @param self The object pointer
2597 # @param FfsFile for whom section is got
2598 # @retval True Successfully find section statement
2599 # @retval False Not able to find section statement
2600 #
2601 def __GetEncapsulationSec(self, FfsFileObj):
2602
2603 OldPos = self.GetFileBufferPos()
2604 if not self.__IsKeyword( "SECTION"):
2605 if len(FfsFileObj.SectionList) == 0:
2606 raise Warning("expected SECTION At Line ", self.FileName, self.CurrentLineNumber)
2607 else:
2608 return False
2609
2610 AlignValue = None
2611 if self.__GetAlignment():
2612 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
2613 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
2614 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2615 AlignValue = self.__Token
2616
2617 if not self.__GetCglSection(FfsFileObj, AlignValue):
2618 self.SetFileBufferPos(OldPos)
2619 return False
2620 else:
2621 return True
2622
2623 ## __GetCapsule() method
2624 #
2625 # Get capsule section contents and store its data into capsule list of self.Profile
2626 #
2627 # @param self The object pointer
2628 # @retval True Successfully find a capsule
2629 # @retval False Not able to find a capsule
2630 #
2631 def __GetCapsule(self):
2632
2633 if not self.__GetNextToken():
2634 return False
2635
2636 S = self.__Token.upper()
2637 if S.startswith("[") and not S.startswith("[CAPSULE."):
2638 if not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
2639 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
2640 self.__UndoToken()
2641 return False
2642
2643 self.__UndoToken()
2644 if not self.__IsToken("[CAPSULE.", True):
2645 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
2646 print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2647 % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2648 raise Warning("expected [Capsule.] At Line ", self.FileName, self.CurrentLineNumber)
2649
2650 CapsuleObj = CommonDataClass.FdfClass.CapsuleClassObject()
2651
2652 CapsuleName = self.__GetUiName()
2653 if not CapsuleName:
2654 raise Warning("expected capsule name At line ", self.FileName, self.CurrentLineNumber)
2655
2656 CapsuleObj.UiCapsuleName = CapsuleName.upper()
2657
2658 if not self.__IsToken( "]"):
2659 raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber)
2660
2661 if self.__IsKeyword("CREATE_FILE"):
2662 if not self.__IsToken( "="):
2663 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2664
2665 if not self.__GetNextToken():
2666 raise Warning("expected file name At Line ", self.FileName, self.CurrentLineNumber)
2667
2668 CapsuleObj.CreateFile = self.__Token
2669
2670 self.__GetCapsuleStatements(CapsuleObj)
2671 self.Profile.CapsuleList.append(CapsuleObj)
2672 return True
2673
2674 ## __GetCapsuleStatements() method
2675 #
2676 # Get statements for capsule
2677 #
2678 # @param self The object pointer
2679 # @param Obj for whom statements are got
2680 #
2681 def __GetCapsuleStatements(self, Obj):
2682 self.__GetCapsuleTokens(Obj)
2683 self.__GetDefineStatements(Obj)
2684 self.__GetSetStatements(Obj)
2685
2686 self.__GetCapsuleData(Obj)
2687
2688 ## __GetCapsuleStatements() method
2689 #
2690 # Get token statements for capsule
2691 #
2692 # @param self The object pointer
2693 # @param Obj for whom token statements are got
2694 #
2695 def __GetCapsuleTokens(self, Obj):
2696
2697 if not self.__IsKeyword("CAPSULE_GUID"):
2698 raise Warning("expected 'CAPSULE_GUID' At Line ", self.FileName, self.CurrentLineNumber)
2699
2700 while self.__CurrentLine().find("=") != -1:
2701 NameValue = self.__CurrentLine().split("=")
2702 Obj.TokensDict[NameValue[0].strip()] = NameValue[1].strip()
2703 self.CurrentLineNumber += 1
2704 self.CurrentOffsetWithinLine = 0
2705
2706 ## __GetCapsuleData() method
2707 #
2708 # Get capsule data for capsule
2709 #
2710 # @param self The object pointer
2711 # @param Obj for whom capsule data are got
2712 #
2713 def __GetCapsuleData(self, Obj):
2714
2715 while True:
2716 IsInf = self.__GetInfStatement(Obj, True)
2717 IsFile = self.__GetFileStatement(Obj, True)
2718 IsFv = self.__GetFvStatement(Obj)
2719 if not IsInf and not IsFile and not IsFv:
2720 break
2721
2722 ## __GetFvStatement() method
2723 #
2724 # Get FV for capsule
2725 #
2726 # @param self The object pointer
2727 # @param CapsuleObj for whom FV is got
2728 # @retval True Successfully find a FV statement
2729 # @retval False Not able to find a FV statement
2730 #
2731 def __GetFvStatement(self, CapsuleObj):
2732
2733 if not self.__IsKeyword("FV"):
2734 return False
2735
2736 if not self.__IsToken("="):
2737 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2738
2739 if not self.__GetNextToken():
2740 raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber)
2741
2742 # CapsuleFv = CapsuleData.CapsuleFv()
2743 # CapsuleFv.FvName = self.__Token
2744 # CapsuleObj.CapsuleDataList.append(CapsuleFv)
2745 return True
2746
2747 ## __GetRule() method
2748 #
2749 # Get Rule section contents and store its data into rule list of self.Profile
2750 #
2751 # @param self The object pointer
2752 # @retval True Successfully find a Rule
2753 # @retval False Not able to find a Rule
2754 #
2755 def __GetRule(self):
2756
2757 if not self.__GetNextToken():
2758 return False
2759
2760 S = self.__Token.upper()
2761 if S.startswith("[") and not S.startswith("[RULE."):
2762 if not S.startswith("[OPTIONROM."):
2763 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
2764 self.__UndoToken()
2765 return False
2766 self.__UndoToken()
2767 if not self.__IsToken("[Rule.", True):
2768 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
2769 print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2770 % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2771 raise Warning("expected [Rule.] At Line ", self.FileName, self.CurrentLineNumber)
2772
2773 if not self.__SkipToToken("."):
2774 raise Warning("expected '.' At Line ", self.FileName, self.CurrentLineNumber)
2775
2776 Arch = self.__SkippedChars.rstrip(".")
2777 if Arch.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "AARCH64", "COMMON"):
2778 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)
2779
2780 ModuleType = self.__GetModuleType()
2781
2782 TemplateName = ""
2783 if self.__IsToken("."):
2784 if not self.__GetNextWord():
2785 raise Warning("expected template name At Line ", self.FileName, self.CurrentLineNumber)
2786 TemplateName = self.__Token
2787
2788 if not self.__IsToken( "]"):
2789 raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber)
2790
2791 RuleObj = self.__GetRuleFileStatements()
2792 RuleObj.Arch = Arch.upper()
2793 RuleObj.ModuleType = ModuleType
2794 RuleObj.TemplateName = TemplateName
2795 if TemplateName == '' :
2796 self.Profile.RuleDict['RULE' + \
2797 '.' + \
2798 Arch.upper() + \
2799 '.' + \
2800 ModuleType.upper() ] = RuleObj
2801 else :
2802 self.Profile.RuleDict['RULE' + \
2803 '.' + \
2804 Arch.upper() + \
2805 '.' + \
2806 ModuleType.upper() + \
2807 '.' + \
2808 TemplateName.upper() ] = RuleObj
2809 # self.Profile.RuleList.append(rule)
2810 return True
2811
2812 ## __GetModuleType() method
2813 #
2814 # Return the module type
2815 #
2816 # @param self The object pointer
2817 # @retval string module type
2818 #
2819 def __GetModuleType(self):
2820
2821 if not self.__GetNextWord():
2822 raise Warning("expected Module type At Line ", self.FileName, self.CurrentLineNumber)
2823 if self.__Token.upper() not in ("SEC", "PEI_CORE", "PEIM", "DXE_CORE", \
2824 "DXE_DRIVER", "DXE_SAL_DRIVER", \
2825 "DXE_SMM_DRIVER", "DXE_RUNTIME_DRIVER", \
2826 "UEFI_DRIVER", "UEFI_APPLICATION", "USER_DEFINED", "DEFAULT", "BASE", \
2827 "SECURITY_CORE", "COMBINED_PEIM_DRIVER", "PIC_PEIM", "RELOCATABLE_PEIM", \
2828 "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION", "ACPITABLE", "SMM_CORE", "MM_STANDALONE", "MM_CORE_STANDALONE"):
2829 raise Warning("Unknown Module type At line ", self.FileName, self.CurrentLineNumber)
2830 return self.__Token
2831
2832 ## __GetFileExtension() method
2833 #
2834 # Return the file extension
2835 #
2836 # @param self The object pointer
2837 # @retval string file name extension
2838 #
2839 def __GetFileExtension(self):
2840 if not self.__IsToken("."):
2841 raise Warning("expected '.' At Line ", self.FileName, self.CurrentLineNumber)
2842
2843 Ext = ""
2844 if self.__GetNextToken():
2845 Pattern = re.compile(r'([a-zA-Z][a-zA-Z0-9]*)')
2846 if Pattern.match(self.__Token):
2847 Ext = self.__Token
2848 return '.' + Ext
2849 else:
2850 raise Warning("Unknown file extension At Line ", self.FileName, self.CurrentLineNumber)
2851
2852 else:
2853 raise Warning("expected file extension At Line ", self.FileName, self.CurrentLineNumber)
2854
2855 ## __GetRuleFileStatement() method
2856 #
2857 # Get rule contents
2858 #
2859 # @param self The object pointer
2860 # @retval Rule Rule object
2861 #
2862 def __GetRuleFileStatements(self):
2863
2864 if not self.__IsKeyword("FILE"):
2865 raise Warning("expected FILE At Line ", self.FileName, self.CurrentLineNumber)
2866
2867 if not self.__GetNextWord():
2868 raise Warning("expected FFS type At Line ", self.FileName, self.CurrentLineNumber)
2869
2870 Type = self.__Token.strip().upper()
2871 if Type not in ("RAW", "FREEFORM", "SEC", "PEI_CORE", "PEIM",\
2872 "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE", "SMM", "SMM_CORE", "MM_STANDALONE"):
2873 raise Warning("Unknown FV type At line ", self.FileName, self.CurrentLineNumber)
2874
2875 if not self.__IsToken("="):
2876 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
2877
2878 if not self.__IsKeyword("$(NAMED_GUID)"):
2879 if not self.__GetNextWord():
2880 raise Warning("expected $(NAMED_GUID)", self.FileName, self.CurrentLineNumber)
2881 if self.__Token == 'PCD':
2882 if not self.__IsToken( "("):
2883 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
2884 PcdPair = self.__GetNextPcdName()
2885 if not self.__IsToken( ")"):
2886 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
2887 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
2888
2889 NameGuid = self.__Token
2890
2891 KeepReloc = None
2892 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
2893 if self.__FileCouldHaveRelocFlag(Type):
2894 if self.__Token == 'RELOCS_STRIPPED':
2895 KeepReloc = False
2896 else:
2897 KeepReloc = True
2898 else:
2899 raise Warning("File type %s could not have reloc strip flag At Line %d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
2900
2901 KeyStringList = []
2902 if self.__GetNextToken():
2903 Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
2904 if Pattern.match(self.__Token):
2905 KeyStringList.append(self.__Token)
2906 if self.__IsToken(","):
2907 while self.__GetNextToken():
2908 if not Pattern.match(self.__Token):
2909 raise Warning("expected KeyString \"Target_Tag_Arch\" At Line ", self.FileName, self.CurrentLineNumber)
2910 KeyStringList.append(self.__Token)
2911
2912 if not self.__IsToken(","):
2913 break
2914
2915 else:
2916 self.__UndoToken()
2917
2918
2919 Fixed = False
2920 if self.__IsKeyword("Fixed", True):
2921 Fixed = True
2922
2923 CheckSum = False
2924 if self.__IsKeyword("CheckSum", True):
2925 CheckSum = True
2926
2927 AlignValue = ""
2928 if self.__GetAlignment():
2929 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
2930 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
2931 raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber)
2932 AlignValue = self.__Token
2933
2934 if self.__IsToken("{"):
2935 # Complex file rule expected
2936 Rule = RuleComplexFile.RuleComplexFile()
2937 Rule.FvFileType = Type
2938 Rule.NameGuid = NameGuid
2939 Rule.Alignment = AlignValue
2940 Rule.CheckSum = CheckSum
2941 Rule.Fixed = Fixed
2942 Rule.KeyStringList = KeyStringList
2943 if KeepReloc != None:
2944 Rule.KeepReloc = KeepReloc
2945
2946 while True:
2947 IsEncapsulate = self.__GetRuleEncapsulationSection(Rule)
2948 IsLeaf = self.__GetEfiSection(Rule)
2949 if not IsEncapsulate and not IsLeaf:
2950 break
2951
2952 if not self.__IsToken("}"):
2953 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
2954
2955 return Rule
2956
2957 elif self.__IsToken("|"):
2958 # Ext rule expected
2959 Ext = self.__GetFileExtension()
2960
2961 Rule = RuleSimpleFile.RuleSimpleFile()
2962
2963 Rule.FvFileType = Type
2964 Rule.NameGuid = NameGuid
2965 Rule.Alignment = AlignValue
2966 Rule.CheckSum = CheckSum
2967 Rule.Fixed = Fixed
2968 Rule.FileExtension = Ext
2969 Rule.KeyStringList = KeyStringList
2970 if KeepReloc != None:
2971 Rule.KeepReloc = KeepReloc
2972
2973 return Rule
2974
2975 else:
2976 # Simple file rule expected
2977 if not self.__GetNextWord():
2978 raise Warning("expected leaf section type At Line ", self.FileName, self.CurrentLineNumber)
2979
2980 SectionName = self.__Token
2981
2982 if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
2983 "UI", "PEI_DEPEX", "VERSION", "SUBTYPE_GUID", "SMM_DEPEX"):
2984 raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber)
2985
2986
2987 if self.__IsKeyword("Fixed", True):
2988 Fixed = True
2989
2990 if self.__IsKeyword("CheckSum", True):
2991 CheckSum = True
2992
2993 if self.__GetAlignment():
2994 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
2995 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
2996 raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber)
2997 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
2998 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2999 AlignValue = self.__Token
3000
3001 if not self.__GetNextToken():
3002 raise Warning("expected File name At Line ", self.FileName, self.CurrentLineNumber)
3003
3004 Rule = RuleSimpleFile.RuleSimpleFile()
3005 Rule.SectionType = SectionName
3006 Rule.FvFileType = Type
3007 Rule.NameGuid = NameGuid
3008 Rule.Alignment = AlignValue
3009 Rule.CheckSum = CheckSum
3010 Rule.Fixed = Fixed
3011 Rule.FileName = self.__Token
3012 Rule.KeyStringList = KeyStringList
3013 if KeepReloc != None:
3014 Rule.KeepReloc = KeepReloc
3015 return Rule
3016
3017 ## __GetEfiSection() method
3018 #
3019 # Get section list for Rule
3020 #
3021 # @param self The object pointer
3022 # @param Obj for whom section is got
3023 # @retval True Successfully find section statement
3024 # @retval False Not able to find section statement
3025 #
3026 def __GetEfiSection(self, Obj):
3027
3028 OldPos = self.GetFileBufferPos()
3029 if not self.__GetNextWord():
3030 return False
3031 SectionName = self.__Token
3032
3033 if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3034 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3035 self.__UndoToken()
3036 return False
3037
3038 if SectionName == "FV_IMAGE":
3039 FvImageSectionObj = FvImageSection.FvImageSection()
3040 if self.__IsKeyword("FV_IMAGE"):
3041 pass
3042 if self.__IsToken( "{"):
3043 FvObj = Fv.FV()
3044 self.__GetDefineStatements(FvObj)
3045 self.__GetBlockStatement(FvObj)
3046 self.__GetSetStatements(FvObj)
3047 self.__GetFvAlignment(FvObj)
3048 self.__GetFvAttributes(FvObj)
3049 self.__GetAprioriSection(FvObj)
3050 self.__GetAprioriSection(FvObj)
3051
3052 while True:
3053 IsInf = self.__GetInfStatement(FvObj)
3054 IsFile = self.__GetFileStatement(FvObj)
3055 if not IsInf and not IsFile:
3056 break
3057
3058 if not self.__IsToken( "}"):
3059 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
3060 FvImageSectionObj.Fv = FvObj
3061 FvImageSectionObj.FvName = None
3062
3063 else:
3064 if not self.__IsKeyword("FV"):
3065 raise Warning("expected 'FV' At Line ", self.FileName, self.CurrentLineNumber)
3066 FvImageSectionObj.FvFileType = self.__Token
3067
3068 if self.__GetAlignment():
3069 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
3070 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
3071 raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber)
3072 FvImageSectionObj.Alignment = self.__Token
3073
3074 if self.__IsToken('|'):
3075 FvImageSectionObj.FvFileExtension = self.__GetFileExtension()
3076 elif self.__GetNextToken():
3077 if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3078 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3079 FvImageSectionObj.FvFileName = self.__Token
3080 else:
3081 self.__UndoToken()
3082 else:
3083 raise Warning("expected FV file name At Line ", self.FileName, self.CurrentLineNumber)
3084
3085 Obj.SectionList.append(FvImageSectionObj)
3086 return True
3087
3088 EfiSectionObj = EfiSection.EfiSection()
3089 EfiSectionObj.SectionType = SectionName
3090
3091 if not self.__GetNextToken():
3092 raise Warning("expected file type At Line ", self.FileName, self.CurrentLineNumber)
3093
3094 if self.__Token == "STRING":
3095 if not self.__RuleSectionCouldHaveString(EfiSectionObj.SectionType):
3096 raise Warning("%s section could NOT have string data At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3097
3098 if not self.__IsToken('='):
3099 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3100
3101 if not self.__GetNextToken():
3102 raise Warning("expected Quoted String At Line ", self.FileName, self.CurrentLineNumber)
3103
3104 if self.__GetStringData():
3105 EfiSectionObj.StringData = self.__Token
3106
3107 if self.__IsKeyword("BUILD_NUM"):
3108 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
3109 raise Warning("%s section could NOT have BUILD_NUM At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3110
3111 if not self.__IsToken("="):
3112 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3113 if not self.__GetNextToken():
3114 raise Warning("expected Build number At Line ", self.FileName, self.CurrentLineNumber)
3115 EfiSectionObj.BuildNum = self.__Token
3116
3117 else:
3118 EfiSectionObj.FileType = self.__Token
3119 self.__CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType)
3120
3121 if self.__IsKeyword("Optional"):
3122 if not self.__RuleSectionCouldBeOptional(EfiSectionObj.SectionType):
3123 raise Warning("%s section could NOT be optional At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3124 EfiSectionObj.Optional = True
3125
3126 if self.__IsKeyword("BUILD_NUM"):
3127 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
3128 raise Warning("%s section could NOT have BUILD_NUM At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3129
3130 if not self.__IsToken("="):
3131 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3132 if not self.__GetNextToken():
3133 raise Warning("expected Build number At Line ", self.FileName, self.CurrentLineNumber)
3134 EfiSectionObj.BuildNum = self.__Token
3135
3136 if self.__GetAlignment():
3137 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
3138 "256K", "512K", "1M", "2M", "4M", "8M", "16M"):
3139 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3140 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
3141 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
3142 EfiSectionObj.Alignment = self.__Token
3143
3144 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
3145 if self.__SectionCouldHaveRelocFlag(EfiSectionObj.SectionType):
3146 if self.__Token == 'RELOCS_STRIPPED':
3147 EfiSectionObj.KeepReloc = False
3148 else:
3149 EfiSectionObj.KeepReloc = True
3150 if Obj.KeepReloc != None and Obj.KeepReloc != EfiSectionObj.KeepReloc:
3151 raise Warning("Section type %s has reloc strip flag conflict with Rule At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3152 else:
3153 raise Warning("Section type %s could not have reloc strip flag At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3154
3155
3156 if self.__IsToken('|'):
3157 EfiSectionObj.FileExtension = self.__GetFileExtension()
3158 elif self.__GetNextToken():
3159 if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3160 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3161
3162 if self.__Token.startswith('PCD'):
3163 self.__UndoToken()
3164 self.__GetNextWord()
3165
3166 if self.__Token == 'PCD':
3167 if not self.__IsToken( "("):
3168 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
3169 PcdPair = self.__GetNextPcdName()
3170 if not self.__IsToken( ")"):
3171 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
3172 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
3173
3174 EfiSectionObj.FileName = self.__Token
3175
3176 else:
3177 self.__UndoToken()
3178 else:
3179 raise Warning("expected section file name At Line ", self.FileName, self.CurrentLineNumber)
3180
3181 Obj.SectionList.append(EfiSectionObj)
3182 return True
3183
3184 ## __RuleSectionCouldBeOptional() method
3185 #
3186 # Get whether a section could be optional
3187 #
3188 # @param self The object pointer
3189 # @param SectionType The section type to check
3190 # @retval True section could be optional
3191 # @retval False section never optional
3192 #
3193 def __RuleSectionCouldBeOptional(self, SectionType):
3194 if SectionType in ("DXE_DEPEX", "UI", "VERSION", "PEI_DEPEX", "RAW", "SMM_DEPEX"):
3195 return True
3196 else:
3197 return False
3198
3199 ## __RuleSectionCouldHaveBuildNum() method
3200 #
3201 # Get whether a section could have build number information
3202 #
3203 # @param self The object pointer
3204 # @param SectionType The section type to check
3205 # @retval True section could have build number information
3206 # @retval False section never have build number information
3207 #
3208 def __RuleSectionCouldHaveBuildNum(self, SectionType):
3209 if SectionType in ("VERSION"):
3210 return True
3211 else:
3212 return False
3213
3214 ## __RuleSectionCouldHaveString() method
3215 #
3216 # Get whether a section could have string
3217 #
3218 # @param self The object pointer
3219 # @param SectionType The section type to check
3220 # @retval True section could have string
3221 # @retval False section never have string
3222 #
3223 def __RuleSectionCouldHaveString(self, SectionType):
3224 if SectionType in ("UI", "VERSION"):
3225 return True
3226 else:
3227 return False
3228
3229 ## __CheckRuleSectionFileType() method
3230 #
3231 # Get whether a section matches a file type
3232 #
3233 # @param self The object pointer
3234 # @param SectionType The section type to check
3235 # @param FileType The file type to check
3236 #
3237 def __CheckRuleSectionFileType(self, SectionType, FileType):
3238 if SectionType == "COMPAT16":
3239 if FileType not in ("COMPAT16", "SEC_COMPAT16"):
3240 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3241 elif SectionType == "PE32":
3242 if FileType not in ("PE32", "SEC_PE32"):
3243 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3244 elif SectionType == "PIC":
3245 if FileType not in ("PIC", "PIC"):
3246 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3247 elif SectionType == "TE":
3248 if FileType not in ("TE", "SEC_TE"):
3249 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3250 elif SectionType == "RAW":
3251 if FileType not in ("BIN", "SEC_BIN", "RAW", "ASL", "ACPI"):
3252 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3253 elif SectionType == "DXE_DEPEX" or SectionType == "SMM_DEPEX":
3254 if FileType not in ("DXE_DEPEX", "SEC_DXE_DEPEX", "SMM_DEPEX"):
3255 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3256 elif SectionType == "UI":
3257 if FileType not in ("UI", "SEC_UI"):
3258 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3259 elif SectionType == "VERSION":
3260 if FileType not in ("VERSION", "SEC_VERSION"):
3261 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3262 elif SectionType == "PEI_DEPEX":
3263 if FileType not in ("PEI_DEPEX", "SEC_PEI_DEPEX"):
3264 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3265 elif SectionType == "GUID":
3266 if FileType not in ("PE32", "SEC_GUID"):
3267 raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber)
3268
3269 ## __GetRuleEncapsulationSection() method
3270 #
3271 # Get encapsulation section for Rule
3272 #
3273 # @param self The object pointer
3274 # @param Rule for whom section is got
3275 # @retval True Successfully find section statement
3276 # @retval False Not able to find section statement
3277 #
3278 def __GetRuleEncapsulationSection(self, Rule):
3279
3280 if self.__IsKeyword( "COMPRESS"):
3281 Type = "PI_STD"
3282 if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):
3283 Type = self.__Token
3284
3285 if not self.__IsToken("{"):
3286 raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
3287
3288 CompressSectionObj = CompressSection.CompressSection()
3289
3290 CompressSectionObj.CompType = Type
3291 # Recursive sections...
3292 while True:
3293 IsEncapsulate = self.__GetRuleEncapsulationSection(CompressSectionObj)
3294 IsLeaf = self.__GetEfiSection(CompressSectionObj)
3295 if not IsEncapsulate and not IsLeaf:
3296 break
3297
3298 if not self.__IsToken( "}"):
3299 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
3300 Rule.SectionList.append(CompressSectionObj)
3301
3302 return True
3303
3304 elif self.__IsKeyword( "GUIDED"):
3305 GuidValue = None
3306 if self.__GetNextGuid():
3307 GuidValue = self.__Token
3308
3309 if self.__IsKeyword( "$(NAMED_GUID)"):
3310 GuidValue = self.__Token
3311
3312 AttribDict = self.__GetGuidAttrib()
3313
3314 if not self.__IsToken("{"):
3315 raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber)
3316 GuidSectionObj = GuidSection.GuidSection()
3317 GuidSectionObj.NameGuid = GuidValue
3318 GuidSectionObj.SectionType = "GUIDED"
3319 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
3320 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
3321
3322 # Efi sections...
3323 while True:
3324 IsEncapsulate = self.__GetRuleEncapsulationSection(GuidSectionObj)
3325 IsLeaf = self.__GetEfiSection(GuidSectionObj)
3326 if not IsEncapsulate and not IsLeaf:
3327 break
3328
3329 if not self.__IsToken( "}"):
3330 raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber)
3331 Rule.SectionList.append(GuidSectionObj)
3332
3333 return True
3334
3335 return False
3336
3337 ## __GetVtf() method
3338 #
3339 # Get VTF section contents and store its data into VTF list of self.Profile
3340 #
3341 # @param self The object pointer
3342 # @retval True Successfully find a VTF
3343 # @retval False Not able to find a VTF
3344 #
3345 def __GetVtf(self):
3346
3347 if not self.__GetNextToken():
3348 return False
3349
3350 S = self.__Token.upper()
3351 if S.startswith("[") and not S.startswith("[VTF."):
3352 if not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
3353 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
3354 self.__UndoToken()
3355 return False
3356
3357 self.__UndoToken()
3358 if not self.__IsToken("[VTF.", True):
3359 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
3360 print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3361 % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3362 raise Warning("expected [VTF.] At Line ", self.FileName, self.CurrentLineNumber)
3363
3364 if not self.__SkipToToken("."):
3365 raise Warning("expected '.' At Line ", self.FileName, self.CurrentLineNumber)
3366
3367 Arch = self.__SkippedChars.rstrip(".").upper()
3368 if Arch not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
3369 raise Warning("Unknown Arch At line ", self.FileName, self.CurrentLineNumber)
3370
3371 if not self.__GetNextWord():
3372 raise Warning("expected VTF name At Line ", self.FileName, self.CurrentLineNumber)
3373 Name = self.__Token.upper()
3374
3375 VtfObj = Vtf.Vtf()
3376 VtfObj.UiName = Name
3377 VtfObj.KeyArch = Arch
3378
3379 if self.__IsToken(","):
3380 if not self.__GetNextWord():
3381 raise Warning("expected Arch list At Line ", self.FileName, self.CurrentLineNumber)
3382 if self.__Token.upper() not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
3383 raise Warning("Unknown Arch At line ", self.FileName, self.CurrentLineNumber)
3384 VtfObj.ArchList = self.__Token.upper()
3385
3386 if not self.__IsToken( "]"):
3387 raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber)
3388
3389 if self.__IsKeyword("IA32_RST_BIN"):
3390 if not self.__IsToken("="):
3391 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3392
3393 if not self.__GetNextToken():
3394 raise Warning("expected Reset file At Line ", self.FileName, self.CurrentLineNumber)
3395
3396 VtfObj.ResetBin = self.__Token
3397
3398 while self.__GetComponentStatement(VtfObj):
3399 pass
3400
3401 self.Profile.VtfList.append(VtfObj)
3402 return True
3403
3404 ## __GetComponentStatement() method
3405 #
3406 # Get components in VTF
3407 #
3408 # @param self The object pointer
3409 # @param VtfObj for whom component is got
3410 # @retval True Successfully find a component
3411 # @retval False Not able to find a component
3412 #
3413 def __GetComponentStatement(self, VtfObj):
3414
3415 if not self.__IsKeyword("COMP_NAME"):
3416 return False
3417
3418 if not self.__IsToken("="):
3419 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3420
3421 if not self.__GetNextWord():
3422 raise Warning("expected Component Name At Line ", self.FileName, self.CurrentLineNumber)
3423
3424 CompStatementObj = ComponentStatement.ComponentStatement()
3425 CompStatementObj.CompName = self.__Token
3426
3427 if not self.__IsKeyword("COMP_LOC"):
3428 raise Warning("expected COMP_LOC At Line ", self.FileName, self.CurrentLineNumber)
3429
3430 if not self.__IsToken("="):
3431 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3432
3433 CompStatementObj.CompLoc = ""
3434 if self.__GetNextWord():
3435 CompStatementObj.CompLoc = self.__Token
3436 if self.__IsToken('|'):
3437 if not self.__GetNextWord():
3438 raise Warning("Expected Region Name At Line ", self.FileName, self.CurrentLineNumber)
3439
3440 if self.__Token not in ("F", "N", "S"): #, "H", "L", "PH", "PL"): not support
3441 raise Warning("Unknown location type At line ", self.FileName, self.CurrentLineNumber)
3442
3443 CompStatementObj.FilePos = self.__Token
3444 else:
3445 self.CurrentLineNumber += 1
3446 self.CurrentOffsetWithinLine = 0
3447
3448 if not self.__IsKeyword("COMP_TYPE"):
3449 raise Warning("expected COMP_TYPE At Line ", self.FileName, self.CurrentLineNumber)
3450
3451 if not self.__IsToken("="):
3452 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3453
3454 if not self.__GetNextToken():
3455 raise Warning("expected Component type At Line ", self.FileName, self.CurrentLineNumber)
3456 if self.__Token not in ("FIT", "PAL_B", "PAL_A", "OEM"):
3457 if not self.__Token.startswith("0x") or len(self.__Token) < 3 or len(self.__Token) > 4 or \
3458 not self.__HexDigit(self.__Token[2]) or not self.__HexDigit(self.__Token[-1]):
3459 raise Warning("Unknown location type At line ", self.FileName, self.CurrentLineNumber)
3460 CompStatementObj.CompType = self.__Token
3461
3462 if not self.__IsKeyword("COMP_VER"):
3463 raise Warning("expected COMP_VER At Line ", self.FileName, self.CurrentLineNumber)
3464
3465 if not self.__IsToken("="):
3466 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3467
3468 if not self.__GetNextToken():
3469 raise Warning("expected Component version At Line ", self.FileName, self.CurrentLineNumber)
3470
3471 Pattern = re.compile('-$|[0-9]{0,1}[0-9]{1}\.[0-9]{0,1}[0-9]{1}')
3472 if Pattern.match(self.__Token) == None:
3473 raise Warning("Unknown version format At line ", self.FileName, self.CurrentLineNumber)
3474 CompStatementObj.CompVer = self.__Token
3475
3476 if not self.__IsKeyword("COMP_CS"):
3477 raise Warning("expected COMP_CS At Line ", self.FileName, self.CurrentLineNumber)
3478
3479 if not self.__IsToken("="):
3480 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3481
3482 if not self.__GetNextToken():
3483 raise Warning("expected Component CS At Line ", self.FileName, self.CurrentLineNumber)
3484 if self.__Token not in ("1", "0"):
3485 raise Warning("Unknown Component CS At line ", self.FileName, self.CurrentLineNumber)
3486 CompStatementObj.CompCs = self.__Token
3487
3488
3489 if not self.__IsKeyword("COMP_BIN"):
3490 raise Warning("expected COMP_BIN At Line ", self.FileName, self.CurrentLineNumber)
3491
3492 if not self.__IsToken("="):
3493 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3494
3495 if not self.__GetNextToken():
3496 raise Warning("expected Component file At Line ", self.FileName, self.CurrentLineNumber)
3497
3498 CompStatementObj.CompBin = self.__Token
3499
3500 if not self.__IsKeyword("COMP_SYM"):
3501 raise Warning("expected COMP_SYM At Line ", self.FileName, self.CurrentLineNumber)
3502
3503 if not self.__IsToken("="):
3504 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3505
3506 if not self.__GetNextToken():
3507 raise Warning("expected Component symbol file At Line ", self.FileName, self.CurrentLineNumber)
3508
3509 CompStatementObj.CompSym = self.__Token
3510
3511 if not self.__IsKeyword("COMP_SIZE"):
3512 raise Warning("expected COMP_SIZE At Line ", self.FileName, self.CurrentLineNumber)
3513
3514 if not self.__IsToken("="):
3515 raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber)
3516
3517 if self.__IsToken("-"):
3518 CompStatementObj.CompSize = self.__Token
3519 elif self.__GetNextDecimalNumber():
3520 CompStatementObj.CompSize = self.__Token
3521 elif self.__GetNextHexNumber():
3522 CompStatementObj.CompSize = self.__Token
3523 else:
3524 raise Warning("Unknown size At line ", self.FileName, self.CurrentLineNumber)
3525
3526 VtfObj.ComponentStatementList.append(CompStatementObj)
3527 return True
3528
3529 ## __GetFvInFd() method
3530 #
3531 # Get FV list contained in FD
3532 #
3533 # @param self The object pointer
3534 # @param FdName FD name
3535 # @retval FvList list of FV in FD
3536 #
3537 def __GetFvInFd (self, FdName):
3538
3539 FvList = []
3540 if FdName.upper() in self.Profile.FdDict.keys():
3541 FdObj = self.Profile.FdDict[FdName.upper()]
3542 for elementRegion in FdObj.RegionList:
3543 if elementRegion.RegionType == 'FV':
3544 for elementRegionData in elementRegion.RegionDataList:
3545 if elementRegionData != None and elementRegionData.upper() not in FvList:
3546 FvList.append(elementRegionData.upper())
3547 return FvList
3548
3549 ## __GetReferencedFdFvTuple() method
3550 #
3551 # Get FD and FV list referenced by a FFS file
3552 #
3553 # @param self The object pointer
3554 # @param FfsFile contains sections to be searched
3555 # @param RefFdList referenced FD by section
3556 # @param RefFvList referenced FV by section
3557 #
3558 def __GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []):
3559
3560 for FfsObj in FvObj.FfsList:
3561 if isinstance(FfsObj, FfsFileStatement.FileStatement):
3562 if FfsObj.FvName != None and FfsObj.FvName.upper() not in RefFvList:
3563 RefFvList.append(FfsObj.FvName.upper())
3564 elif FfsObj.FdName != None and FfsObj.FdName.upper() not in RefFdList:
3565 RefFdList.append(FfsObj.FdName.upper())
3566 else:
3567 self.__GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList)
3568
3569 ## __GetReferencedFdFvTupleFromSection() method
3570 #
3571 # Get FD and FV list referenced by a FFS section
3572 #
3573 # @param self The object pointer
3574 # @param FfsFile contains sections to be searched
3575 # @param FdList referenced FD by section
3576 # @param FvList referenced FV by section
3577 #
3578 def __GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []):
3579
3580 SectionStack = []
3581 SectionStack.extend(FfsFile.SectionList)
3582 while SectionStack != []:
3583 SectionObj = SectionStack.pop()
3584 if isinstance(SectionObj, FvImageSection.FvImageSection):
3585 if SectionObj.FvName != None and SectionObj.FvName.upper() not in FvList:
3586 FvList.append(SectionObj.FvName.upper())
3587 if SectionObj.Fv != None and SectionObj.Fv.UiFvName != None and SectionObj.Fv.UiFvName.upper() not in FvList:
3588 FvList.append(SectionObj.Fv.UiFvName.upper())
3589 self.__GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList)
3590
3591 if isinstance(SectionObj, CompressSection.CompressSection) or isinstance(SectionObj, GuidSection.GuidSection):
3592 SectionStack.extend(SectionObj.SectionList)
3593
3594 ## CycleReferenceCheck() method
3595 #
3596 # Check whether cycle reference exists in FDF
3597 #
3598 # @param self The object pointer
3599 # @retval True cycle reference exists
3600 # @retval False Not exists cycle reference
3601 #
3602 def CycleReferenceCheck(self):
3603
3604 CycleRefExists = False
3605
3606 try:
3607 for FvName in self.Profile.FvDict.keys():
3608 LogStr = "Cycle Reference Checking for FV: %s\n" % FvName
3609 RefFvStack = []
3610 RefFvStack.append(FvName)
3611 FdAnalyzedList = []
3612
3613 while RefFvStack != []:
3614 FvNameFromStack = RefFvStack.pop()
3615 if FvNameFromStack.upper() in self.Profile.FvDict.keys():
3616 FvObj = self.Profile.FvDict[FvNameFromStack.upper()]
3617 else:
3618 continue
3619
3620 RefFdList = []
3621 RefFvList = []
3622 self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
3623
3624 for RefFdName in RefFdList:
3625 if RefFdName in FdAnalyzedList:
3626 continue
3627
3628 LogStr += "FD %s is referenced by FV %s\n" % (RefFdName, FvNameFromStack)
3629 FvInFdList = self.__GetFvInFd(RefFdName)
3630 if FvInFdList != []:
3631 LogStr += "FD %s contains FV: " % RefFdName
3632 for FvObj in FvInFdList:
3633 LogStr += FvObj
3634 LogStr += ' \n'
3635 if FvObj not in RefFvStack:
3636 RefFvStack.append(FvObj)
3637
3638 if FvName in RefFvStack:
3639 CycleRefExists = True
3640 raise Warning(LogStr)
3641 FdAnalyzedList.append(RefFdName)
3642
3643 for RefFvName in RefFvList:
3644 LogStr += "FV %s is referenced by FV %s\n" % (RefFvName, FvNameFromStack)
3645 if RefFvName not in RefFvStack:
3646 RefFvStack.append(RefFvName)
3647
3648 if FvName in RefFvStack:
3649 CycleRefExists = True
3650 raise Warning(LogStr)
3651
3652 except Warning:
3653 print LogStr
3654
3655 finally:
3656 return CycleRefExists
3657
3658 if __name__ == "__main__":
3659 import sys
3660 try:
3661 test_file = sys.argv[1]
3662 except IndexError, v:
3663 print "Usage: %s filename" % sys.argv[0]
3664 sys.exit(1)
3665
3666 parser = FdfParser(test_file)
3667 try:
3668 parser.ParseFile()
3669 parser.CycleReferenceCheck()
3670 except Warning, X:
3671 print X.message
3672 else:
3673 print "Success!"
3674