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