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