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