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