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