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