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