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