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