1## @file DecPomAlignment.py 2# This file contained the adapter for convert INF parser object to POM Object 3# 4# Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR> 5# 6# This program and the accompanying materials are licensed and made available 7# under the terms and conditions of the BSD License which accompanies this 8# 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''' 16DecPomAlignment 17''' 18 19## 20# Import Modules 21# 22import os.path 23from os import sep 24import platform 25 26import re 27import Logger.Log as Logger 28from Logger import StringTable as ST 29from Logger.ToolError import UPT_MUL_DEC_ERROR 30from Logger.ToolError import FORMAT_INVALID 31 32from Library.Parsing import NormPath 33from Library.DataType import ARCH_LIST 34from Library.DataType import TAB_GUIDS 35from Library.DataType import TAB_PROTOCOLS 36from Library.DataType import TAB_PPIS 37from Library.DataType import TAB_DEC_DEFINES_PACKAGE_NAME 38from Library.DataType import TAB_DEC_DEFINES_PACKAGE_GUID 39from Library.DataType import TAB_DEC_DEFINES_PACKAGE_VERSION 40from Library.DataType import TAB_DEC_DEFINES_DEC_SPECIFICATION 41from Library.DataType import TAB_DEC_DEFINES_PKG_UNI_FILE 42from Library.DataType import TAB_ARCH_COMMON 43from Library.DataType import TAB_INCLUDES 44from Library.DataType import TAB_LIBRARY_CLASSES 45from Library.DataType import TAB_PCDS 46from Library.DataType import TAB_PCDS_FIXED_AT_BUILD_NULL 47from Library.DataType import TAB_PCDS_PATCHABLE_IN_MODULE_NULL 48from Library.DataType import TAB_PCDS_FEATURE_FLAG_NULL 49from Library.DataType import TAB_PCDS_DYNAMIC_EX_NULL 50from Library.DataType import TAB_PCDS_DYNAMIC_NULL 51from Library.DataType import TAB_PTR_TYPE_PCD 52from Library.DataType import ITEM_UNDEFINED 53from Library.DataType import TAB_DEC_BINARY_ABSTRACT 54from Library.DataType import TAB_DEC_BINARY_DESCRIPTION 55from Library.DataType import TAB_LANGUAGE_EN_US 56from Library.DataType import TAB_BINARY_HEADER_IDENTIFIER 57from Library.DataType import TAB_BINARY_HEADER_USERID 58from Library.DataType import TAB_LANGUAGE_EN_X 59from Library.DataType import TAB_LANGUAGE_EN 60from Library.DataType import TAB_STR_TOKENCNAME 61from Library.DataType import TAB_STR_TOKENPROMPT 62from Library.DataType import TAB_STR_TOKENHELP 63from Library.DataType import TAB_STR_TOKENERR 64from Library.DataType import TAB_HEX_START 65from Library.DataType import TAB_SPLIT 66from Library.CommentParsing import ParseHeaderCommentSection 67from Library.CommentParsing import ParseGenericComment 68from Library.CommentParsing import ParseDecPcdGenericComment 69from Library.CommentParsing import ParseDecPcdTailComment 70from Library.Misc import GetFiles 71from Library.Misc import Sdict 72from Library.Misc import GetRelativePath 73from Library.Misc import PathClass 74from Library.Misc import ValidateUNIFilePath 75from Library.UniClassObject import UniFileClassObject 76from Library.UniClassObject import ConvertSpecialUnicodes 77from Library.UniClassObject import GetLanguageCode1766 78from Library.ParserValidate import IsValidPath 79from Parser.DecParser import Dec 80from Object.POM.PackageObject import PackageObject 81from Object.POM.CommonObject import UserExtensionObject 82from Object.POM.CommonObject import IncludeObject 83from Object.POM.CommonObject import GuidObject 84from Object.POM.CommonObject import ProtocolObject 85from Object.POM.CommonObject import PpiObject 86from Object.POM.CommonObject import LibraryClassObject 87from Object.POM.CommonObject import PcdObject 88from Object.POM.CommonObject import TextObject 89from Object.POM.CommonObject import MiscFileObject 90from Object.POM.CommonObject import FileObject 91 92 93## DecPomAlignment 94# 95# Inherited from PackageObject 96# 97class DecPomAlignment(PackageObject): 98 def __init__(self, Filename, WorkspaceDir = None, CheckMulDec = False): 99 PackageObject.__init__(self) 100 self.UserExtensions = '' 101 self.WorkspaceDir = WorkspaceDir 102 self.SupArchList = ARCH_LIST 103 self.CheckMulDec = CheckMulDec 104 self.DecParser = None 105 self.UniFileClassObject = None 106 self.PcdDefaultValueDict = {} 107 108 # 109 # Load Dec file 110 # 111 self.LoadDecFile(Filename) 112 113 # 114 # Transfer to Package Object if IsToPackage is True 115 # 116 self.DecToPackage() 117 118 ## Load Dec file 119 # 120 # Load the file if it exists 121 # 122 # @param Filename: Input value for filename of Dec file 123 # 124 def LoadDecFile(self, Filename): 125 # 126 # Insert a record for file 127 # 128 Filename = NormPath(Filename) 129 (Path, Name) = os.path.split(Filename) 130 self.SetFullPath(Filename) 131 self.SetRelaPath(Path) 132 self.SetFileName(Name) 133 self.SetPackagePath(GetRelativePath(Path, self.WorkspaceDir)) 134 self.SetCombinePath(GetRelativePath(Filename, self.WorkspaceDir)) 135 136 self.DecParser = Dec(Filename) 137 138 ## Transfer to Package Object 139 # 140 # Transfer all contents of a Dec file to a standard Package Object 141 # 142 def DecToPackage(self): 143 # 144 # Init global information for the file 145 # 146 ContainerFile = self.GetFullPath() 147 148 # 149 # Generate Package Header 150 # 151 self.GenPackageHeader(ContainerFile) 152 153 # 154 # Generate Includes 155 # 156 self.GenIncludes(ContainerFile) 157 158 # 159 # Generate Guids 160 # 161 self.GenGuidProtocolPpis(TAB_GUIDS, ContainerFile) 162 163 # 164 # Generate Protocols 165 # 166 self.GenGuidProtocolPpis(TAB_PROTOCOLS, ContainerFile) 167 168 # 169 # Generate Ppis 170 # 171 self.GenGuidProtocolPpis(TAB_PPIS, ContainerFile) 172 173 # 174 # Generate LibraryClasses 175 # 176 self.GenLibraryClasses(ContainerFile) 177 178 # 179 # Generate Pcds 180 # 181 self.GenPcds(ContainerFile) 182 183 # 184 # Generate Module File list, will be used later on to generate 185 # distribution 186 # 187 self.GenModuleFileList(ContainerFile) 188 189 # 190 # Generate user extensions 191 # 192 self.GenUserExtensions() 193 194 ## Generate user extension 195 # 196 # 197 def GenUserExtensions(self): 198 UEObj = self.DecParser.GetUserExtensionSectionObject() 199 UEList = UEObj.GetAllUserExtensions() 200 for Item in UEList: 201 if not Item.UserString: 202 continue 203 UserExtension = UserExtensionObject() 204 UserId = Item.UserId 205 if UserId.startswith('"') and UserId.endswith('"'): 206 UserId = UserId[1:-1] 207 UserExtension.SetUserID(UserId) 208 Identifier = Item.IdString 209 if Identifier.startswith('"') and Identifier.endswith('"'): 210 Identifier = Identifier[1:-1] 211 # 212 # Generate miscellaneous files of DEC file 213 # 214 if UserId == 'TianoCore' and Identifier == 'ExtraFiles': 215 self.GenMiscFiles(Item.UserString) 216 UserExtension.SetIdentifier(Identifier) 217 UserExtension.SetStatement(Item.UserString) 218 UserExtension.SetSupArchList( 219 Item.ArchAndModuleType 220 ) 221 self.SetUserExtensionList( 222 self.GetUserExtensionList() + [UserExtension] 223 ) 224 225 ## Generate miscellaneous files on DEC file 226 # 227 # 228 def GenMiscFiles(self, Content): 229 MiscFileObj = MiscFileObject() 230 for Line in Content.splitlines(): 231 FileName = '' 232 if '#' in Line: 233 FileName = Line[:Line.find('#')] 234 else: 235 FileName = Line 236 if FileName: 237 if IsValidPath(FileName, self.GetRelaPath()): 238 FileObj = FileObject() 239 FileObj.SetURI(FileName) 240 MiscFileObj.SetFileList(MiscFileObj.GetFileList()+[FileObj]) 241 else: 242 Logger.Error("InfParser", 243 FORMAT_INVALID, 244 ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(Line), 245 File=self.GetFileName(), 246 ExtraData=Line) 247 self.SetMiscFileList(self.GetMiscFileList()+[MiscFileObj]) 248 249 ## Generate Package Header 250 # 251 # Gen Package Header of Dec as <Key> = <Value> 252 # 253 # @param ContainerFile: The Dec file full path 254 # 255 def GenPackageHeader(self, ContainerFile): 256 Logger.Debug(2, "Generate PackageHeader ...") 257 DefinesDict = {} 258 259 # 260 # Update all defines item in database 261 # 262 DefObj = self.DecParser.GetDefineSectionObject() 263 for Item in DefObj.GetDefines(): 264 # 265 # put items into Dict except for PackageName, Guid, Version, DEC_SPECIFICATION 266 # 267 SkipItemList = [TAB_DEC_DEFINES_PACKAGE_NAME, \ 268 TAB_DEC_DEFINES_PACKAGE_GUID, TAB_DEC_DEFINES_PACKAGE_VERSION, \ 269 TAB_DEC_DEFINES_DEC_SPECIFICATION, TAB_DEC_DEFINES_PKG_UNI_FILE] 270 if Item.Key in SkipItemList: 271 continue 272 DefinesDict['%s = %s' % (Item.Key, Item.Value)] = TAB_ARCH_COMMON 273 274 self.SetBaseName(DefObj.GetPackageName()) 275 self.SetVersion(DefObj.GetPackageVersion()) 276# self.SetName(DefObj.GetPackageName() + ' Version ' + \ 277# DefObj.GetPackageVersion()) 278 self.SetName(os.path.splitext(self.GetFileName())[0]) 279 self.SetGuid(DefObj.GetPackageGuid()) 280 if DefObj.GetPackageUniFile(): 281 ValidateUNIFilePath(DefObj.GetPackageUniFile()) 282 self.UniFileClassObject = \ 283 UniFileClassObject([PathClass(os.path.join(DefObj.GetPackagePath(), DefObj.GetPackageUniFile()))]) 284 else: 285 self.UniFileClassObject = None 286 287 if DefinesDict: 288 UserExtension = UserExtensionObject() 289 UserExtension.SetDefinesDict(DefinesDict) 290 UserExtension.SetIdentifier('DefineModifiers') 291 UserExtension.SetUserID('EDK2') 292 self.SetUserExtensionList( 293 self.GetUserExtensionList() + [UserExtension] 294 ) 295 296 # 297 # Get File header information 298 # 299 if self.UniFileClassObject: 300 Lang = TAB_LANGUAGE_EN_X 301 else: 302 Lang = TAB_LANGUAGE_EN_US 303 Abstract, Description, Copyright, License = \ 304 ParseHeaderCommentSection(self.DecParser.GetHeadComment(), 305 ContainerFile) 306 if Abstract: 307 self.SetAbstract((Lang, Abstract)) 308 if Description: 309 self.SetDescription((Lang, Description)) 310 if Copyright: 311 self.SetCopyright(('', Copyright)) 312 if License: 313 self.SetLicense(('', License)) 314 315 # 316 # Get Binary header information 317 # 318 if self.DecParser.BinaryHeadComment: 319 Abstract, Description, Copyright, License = \ 320 ParseHeaderCommentSection(self.DecParser.BinaryHeadComment, 321 ContainerFile, True) 322 323 if not Abstract or not Description or not Copyright or not License: 324 Logger.Error('MkPkg', 325 FORMAT_INVALID, 326 ST.ERR_INVALID_BINARYHEADER_FORMAT, 327 ContainerFile) 328 else: 329 self.SetBinaryHeaderAbstract((Lang, Abstract)) 330 self.SetBinaryHeaderDescription((Lang, Description)) 331 self.SetBinaryHeaderCopyright(('', Copyright)) 332 self.SetBinaryHeaderLicense(('', License)) 333 334 BinaryAbstractList = [] 335 BinaryDescriptionList = [] 336 337 #Get Binary header from UNI file 338 # Initialize the UniStrDict dictionary, top keys are language codes 339 UniStrDict = {} 340 if self.UniFileClassObject: 341 UniStrDict = self.UniFileClassObject.OrderedStringList 342 for Lang in UniStrDict: 343 for StringDefClassObject in UniStrDict[Lang]: 344 Lang = GetLanguageCode1766(Lang) 345 if StringDefClassObject.StringName == TAB_DEC_BINARY_ABSTRACT: 346 if (Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue)) \ 347 not in self.GetBinaryHeaderAbstract(): 348 BinaryAbstractList.append((Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue))) 349 if StringDefClassObject.StringName == TAB_DEC_BINARY_DESCRIPTION: 350 if (Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue)) \ 351 not in self.GetBinaryHeaderDescription(): 352 BinaryDescriptionList.append((Lang, 353 ConvertSpecialUnicodes(StringDefClassObject.StringValue))) 354 #Combine Binary header from DEC file and UNI file 355 BinaryAbstractList = self.GetBinaryHeaderAbstract() + BinaryAbstractList 356 BinaryDescriptionList = self.GetBinaryHeaderDescription() + BinaryDescriptionList 357 BinaryCopyrightList = self.GetBinaryHeaderCopyright() 358 BinaryLicenseList = self.GetBinaryHeaderLicense() 359 #Generate the UserExtensionObject for TianoCore."BinaryHeader" 360 if BinaryAbstractList or BinaryDescriptionList or BinaryCopyrightList or BinaryLicenseList: 361 BinaryUserExtension = UserExtensionObject() 362 BinaryUserExtension.SetBinaryAbstract(BinaryAbstractList) 363 BinaryUserExtension.SetBinaryDescription(BinaryDescriptionList) 364 BinaryUserExtension.SetBinaryCopyright(BinaryCopyrightList) 365 BinaryUserExtension.SetBinaryLicense(BinaryLicenseList) 366 BinaryUserExtension.SetIdentifier(TAB_BINARY_HEADER_IDENTIFIER) 367 BinaryUserExtension.SetUserID(TAB_BINARY_HEADER_USERID) 368 self.SetUserExtensionList(self.GetUserExtensionList() + [BinaryUserExtension]) 369 370 371 ## GenIncludes 372 # 373 # Gen Includes of Dec 374 # 375 # @param ContainerFile: The Dec file full path 376 # 377 def GenIncludes(self, ContainerFile): 378 if ContainerFile: 379 pass 380 Logger.Debug(2, "Generate %s ..." % TAB_INCLUDES) 381 IncludesDict = Sdict() 382 383 IncObj = self.DecParser.GetIncludeSectionObject() 384 for Item in IncObj.GetAllIncludes(): 385 IncludePath = os.path.normpath(Item.File) 386 if platform.system() != 'Windows' and platform.system() != 'Microsoft': 387 IncludePath = IncludePath.replace('\\', '/') 388 if IncludePath in IncludesDict: 389 if Item.GetArchList() == [TAB_ARCH_COMMON] or IncludesDict[IncludePath] == [TAB_ARCH_COMMON]: 390 IncludesDict[IncludePath] = [TAB_ARCH_COMMON] 391 else: 392 IncludesDict[IncludePath] = IncludesDict[IncludePath] + Item.GetArchList() 393 else: 394 IncludesDict[IncludePath] = Item.GetArchList() 395 396 # 397 # get the standardIncludeFileList(industry), packageIncludeFileList 398 # (others) for PackageObject 399 # 400 PackagePath = os.path.split(self.GetFullPath())[0] 401 IncludePathList = \ 402 [os.path.normpath(Path) + sep for Path in IncludesDict.keys()] 403 IncludePathList.sort() 404 405 # 406 # get a non-overlap set of include path, IncludePathList should be 407 # sorted, and path should be end with path seperator '\' 408 # 409 NonOverLapList = [] 410 for Path1 in IncludePathList: 411 for Path2 in NonOverLapList: 412 if Path1.startswith(Path2): 413 break 414 else: 415 NonOverLapList.append(Path1) 416 # 417 # revert the list so the longest path shown first in list, also need 418 # to remove the extra path seperator '\' 419 # as this list is used to search the supported Arch info 420 # 421 for IndexN in range (0, len(IncludePathList)): 422 IncludePathList[IndexN] = os.path.normpath(IncludePathList[IndexN]) 423 IncludePathList.sort() 424 IncludePathList.reverse() 425 # 426 # save the include path list for later usage 427 # 428 self.SetIncludePathList(IncludePathList) 429 StandardIncludeFileList = [] 430 PackageIncludeFileList = [] 431 432 IncludeFileList = [] 433 for Path in NonOverLapList: 434 FileList = GetFiles(os.path.join(PackagePath, Path), ['CVS', '.svn'], False) 435 IncludeFileList += [os.path.normpath(os.path.join(Path, File)) for File in FileList] 436 for Includefile in IncludeFileList: 437 ExtName = os.path.splitext(Includefile)[1] 438 if ExtName.upper() == '.DEC' and self.CheckMulDec: 439 Logger.Error('MkPkg', 440 UPT_MUL_DEC_ERROR, 441 ST.ERR_MUL_DEC_ERROR%(os.path.dirname(ContainerFile), 442 os.path.basename(ContainerFile), 443 Includefile)) 444 445 FileCombinePath = os.path.dirname(Includefile) 446 Include = IncludeObject() 447 for Path in IncludePathList: 448 if FileCombinePath.startswith(Path): 449 SupArchList = IncludesDict[Path] 450 break 451 Include.SetFilePath(Includefile) 452 Include.SetSupArchList(SupArchList) 453 if Includefile.find('IndustryStandard') != -1: 454 StandardIncludeFileList.append(Include) 455 else: 456 PackageIncludeFileList.append(Include) 457 458 self.SetStandardIncludeFileList(StandardIncludeFileList) 459 460 # 461 # put include path into the PackageIncludeFileList 462 # 463 PackagePathList = [] 464 IncObj = self.DecParser.GetIncludeSectionObject() 465 for Item in IncObj.GetAllIncludes(): 466 IncludePath = Item.File 467 Include = IncludeObject() 468 Include.SetFilePath(IncludePath) 469 Include.SetSupArchList(Item.GetArchList()) 470 PackagePathList.append(Include) 471 self.SetPackageIncludeFileList(PackagePathList + PackageIncludeFileList) 472 473 ## GenPpis 474 # 475 # Gen Ppis of Dec 476 # <CName>=<GuidValue> 477 # 478 # @param ContainerFile: The Dec file full path 479 # 480 def GenGuidProtocolPpis(self, Type, ContainerFile): 481 if ContainerFile: 482 pass 483 Logger.Debug(2, "Generate %s ..." % Type) 484 485 Obj = None 486 Factory = None 487 if Type == TAB_GUIDS: 488 Obj = self.DecParser.GetGuidSectionObject() 489 def CreateGuidObject(): 490 Object = GuidObject() 491 Object.SetGuidTypeList([]) 492 Object.SetUsage(None) 493 Object.SetName(None) 494 return Object 495 Factory = CreateGuidObject 496 elif Type == TAB_PROTOCOLS: 497 Obj = self.DecParser.GetProtocolSectionObject() 498 499 def CreateProtocolObject(): 500 return ProtocolObject() 501 Factory = CreateProtocolObject 502 elif Type == TAB_PPIS: 503 Obj = self.DecParser.GetPpiSectionObject() 504 505 def CreatePpiObject(): 506 return PpiObject() 507 Factory = CreatePpiObject 508 else: 509 # 510 # Should not be here 511 # 512 return 513 514 DeclarationsList = [] 515 516 # 517 # Go through each arch 518 # 519 for Item in Obj.GetGuidStyleAllItems(): 520 Name = Item.GuidCName 521 Value = Item.GuidString 522 HelpTxt = ParseGenericComment(Item.GetHeadComment() + \ 523 Item.GetTailComment()) 524 525 ListObject = Factory() 526 ListObject.SetCName(Name) 527 ListObject.SetGuid(Value) 528 ListObject.SetSupArchList(Item.GetArchList()) 529 if HelpTxt: 530 if self.UniFileClassObject: 531 HelpTxt.SetLang(TAB_LANGUAGE_EN_X) 532 ListObject.SetHelpTextList([HelpTxt]) 533 534 DeclarationsList.append(ListObject) 535 536 # 537 #GuidTypeList is abstracted from help 538 # 539 if Type == TAB_GUIDS: 540 self.SetGuidList(self.GetGuidList() + DeclarationsList) 541 elif Type == TAB_PROTOCOLS: 542 self.SetProtocolList(self.GetProtocolList() + DeclarationsList) 543 elif Type == TAB_PPIS: 544 self.SetPpiList(self.GetPpiList() + DeclarationsList) 545 546 ## GenLibraryClasses 547 # 548 # Gen LibraryClasses of Dec 549 # <CName>=<GuidValue> 550 # 551 # @param ContainerFile: The Dec file full path 552 # 553 def GenLibraryClasses(self, ContainerFile): 554 if ContainerFile: 555 pass 556 Logger.Debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES) 557 LibraryClassDeclarations = [] 558 559 LibObj = self.DecParser.GetLibraryClassSectionObject() 560 for Item in LibObj.GetAllLibraryclasses(): 561 LibraryClass = LibraryClassObject() 562 LibraryClass.SetLibraryClass(Item.Libraryclass) 563 LibraryClass.SetSupArchList(Item.GetArchList()) 564 LibraryClass.SetIncludeHeader(Item.File) 565 HelpTxt = ParseGenericComment(Item.GetHeadComment() + \ 566 Item.GetTailComment(), None, '@libraryclass') 567 if HelpTxt: 568 if self.UniFileClassObject: 569 HelpTxt.SetLang(TAB_LANGUAGE_EN_X) 570 LibraryClass.SetHelpTextList([HelpTxt]) 571 LibraryClassDeclarations.append(LibraryClass) 572 573 self.SetLibraryClassList(self.GetLibraryClassList() + \ 574 LibraryClassDeclarations) 575 576 ## GenPcds 577 # 578 # Gen Pcds of Dec 579 # <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token> 580 # 581 # @param ContainerFile: The Dec file full path 582 # 583 def GenPcds(self, ContainerFile): 584 Logger.Debug(2, "Generate %s ..." % TAB_PCDS) 585 PcdObj = self.DecParser.GetPcdSectionObject() 586 # 587 # Get all Pcds 588 # 589 PcdDeclarations = [] 590 IterList = [ 591 (TAB_PCDS_FIXED_AT_BUILD_NULL, 'FixedPcd'), 592 (TAB_PCDS_PATCHABLE_IN_MODULE_NULL, 'PatchPcd'), 593 (TAB_PCDS_FEATURE_FLAG_NULL, 'FeaturePcd'), 594 (TAB_PCDS_DYNAMIC_EX_NULL, 'PcdEx'), 595 (TAB_PCDS_DYNAMIC_NULL, 'Pcd')] 596 597 PromptStrList = [] 598 HelpStrList = [] 599 PcdErrStrList = [] 600 # Initialize UniStrDict dictionary, top keys are language codes 601 UniStrDict = {} 602 StrList = [] 603 604 Language = '' 605 if self.UniFileClassObject: 606 Language = TAB_LANGUAGE_EN_X 607 else: 608 Language = TAB_LANGUAGE_EN_US 609 610 if self.UniFileClassObject: 611 UniStrDict = self.UniFileClassObject.OrderedStringList 612 for Lang in UniStrDict: 613 for StringDefClassObject in UniStrDict[Lang]: 614 StrList = StringDefClassObject.StringName.split('_') 615 # StringName format is STR_<TOKENSPACECNAME>_<PCDCNAME>_PROMPT 616 if len(StrList) == 4 and StrList[0] == TAB_STR_TOKENCNAME and StrList[3] == TAB_STR_TOKENPROMPT: 617 PromptStrList.append((GetLanguageCode1766(Lang), StringDefClassObject.StringName, \ 618 StringDefClassObject.StringValue)) 619 # StringName format is STR_<TOKENSPACECNAME>_<PCDCNAME>_HELP 620 if len(StrList) == 4 and StrList[0] == TAB_STR_TOKENCNAME and StrList[3] == TAB_STR_TOKENHELP: 621 HelpStrList.append((GetLanguageCode1766(Lang), StringDefClassObject.StringName, \ 622 StringDefClassObject.StringValue)) 623 # StringName format is STR_<TOKENSPACECNAME>_ERR_## 624 if len(StrList) == 4 and StrList[0] == TAB_STR_TOKENCNAME and StrList[2] == TAB_STR_TOKENERR: 625 PcdErrStrList.append((GetLanguageCode1766(Lang), StringDefClassObject.StringName, \ 626 StringDefClassObject.StringValue)) 627 # 628 # For each PCD type 629 # 630 for PcdType, Type in IterList: 631 # 632 # Go through all archs 633 # 634 # for Arch in self.SupArchList + [TAB_ARCH_COMMON]: 635 # 636 for Item in PcdObj.GetPcdsByType(PcdType.upper()): 637 PcdDeclaration = GenPcdDeclaration( 638 ContainerFile, 639 (Item.TokenSpaceGuidCName, Item.TokenCName, 640 Item.DefaultValue, Item.DatumType, Item.TokenValue, 641 Type, Item.GetHeadComment(), Item.GetTailComment(),''), 642 Language, 643 self.DecParser.GetDefineSectionMacro() 644 ) 645 PcdDeclaration.SetSupArchList(Item.GetArchListOfType(PcdType)) 646 647 # 648 # Get PCD error message from PCD error comment section in DEC file 649 # 650 for PcdErr in PcdDeclaration.GetPcdErrorsList(): 651 if (PcdDeclaration.GetTokenSpaceGuidCName(), PcdErr.GetErrorNumber()) \ 652 in self.DecParser.PcdErrorCommentDict: 653 Key = (PcdDeclaration.GetTokenSpaceGuidCName(), PcdErr.GetErrorNumber()) 654 PcdErr.SetErrorMessageList(PcdErr.GetErrorMessageList() + \ 655 [(Language, self.DecParser.PcdErrorCommentDict[Key])]) 656 657 for Index in range(0, len(PromptStrList)): 658 StrNameList = PromptStrList[Index][1].split('_') 659 if StrNameList[1].lower() == Item.TokenSpaceGuidCName.lower() and \ 660 StrNameList[2].lower() == Item.TokenCName.lower(): 661 TxtObj = TextObject() 662 TxtObj.SetLang(PromptStrList[Index][0]) 663 TxtObj.SetString(PromptStrList[Index][2]) 664 for Prompt in PcdDeclaration.GetPromptList(): 665 if Prompt.GetLang() == TxtObj.GetLang() and \ 666 Prompt.GetString() == TxtObj.GetString(): 667 break 668 else: 669 PcdDeclaration.SetPromptList(PcdDeclaration.GetPromptList() + [TxtObj]) 670 671 for Index in range(0, len(HelpStrList)): 672 StrNameList = HelpStrList[Index][1].split('_') 673 if StrNameList[1].lower() == Item.TokenSpaceGuidCName.lower() and \ 674 StrNameList[2].lower() == Item.TokenCName.lower(): 675 TxtObj = TextObject() 676 TxtObj.SetLang(HelpStrList[Index][0]) 677 TxtObj.SetString(HelpStrList[Index][2]) 678 for HelpStrObj in PcdDeclaration.GetHelpTextList(): 679 if HelpStrObj.GetLang() == TxtObj.GetLang() and \ 680 HelpStrObj.GetString() == TxtObj.GetString(): 681 break 682 else: 683 PcdDeclaration.SetHelpTextList(PcdDeclaration.GetHelpTextList() + [TxtObj]) 684 685 # 686 # Get PCD error message from UNI file 687 # 688 for Index in range(0, len(PcdErrStrList)): 689 StrNameList = PcdErrStrList[Index][1].split('_') 690 if StrNameList[1].lower() == Item.TokenSpaceGuidCName.lower() and \ 691 StrNameList[2].lower() == TAB_STR_TOKENERR.lower(): 692 for PcdErr in PcdDeclaration.GetPcdErrorsList(): 693 if PcdErr.GetErrorNumber().lower() == (TAB_HEX_START + StrNameList[3]).lower() and \ 694 (PcdErrStrList[Index][0], PcdErrStrList[Index][2]) not in PcdErr.GetErrorMessageList(): 695 PcdErr.SetErrorMessageList(PcdErr.GetErrorMessageList() + \ 696 [(PcdErrStrList[Index][0], PcdErrStrList[Index][2])]) 697 698 # 699 # Check to prevent missing error message if a Pcd has the error code. 700 # 701 for PcdErr in PcdDeclaration.GetPcdErrorsList(): 702 if PcdErr.GetErrorNumber().strip(): 703 if not PcdErr.GetErrorMessageList(): 704 Logger.Error('UPT', 705 FORMAT_INVALID, 706 ST.ERR_DECPARSE_PCD_UNMATCHED_ERRORCODE % PcdErr.GetErrorNumber(), 707 ContainerFile, 708 PcdErr.GetLineNum(), 709 PcdErr.GetFileLine()) 710 711 PcdDeclarations.append(PcdDeclaration) 712 self.SetPcdList(self.GetPcdList() + PcdDeclarations) 713 self.CheckPcdValue() 714 715 ## 716 # Get error message via language 717 # @param ErrorMessageList: Error message tuple list the language and its message 718 # @param Lang: the language of setting 719 # @return: the error message described in the related UNI file 720 def GetEnErrorMessage(self, ErrorMessageList): 721 if self.FullPath: 722 pass 723 Lang = TAB_LANGUAGE_EN_US 724 for (Language, Message) in ErrorMessageList: 725 if Language == Lang: 726 return Message 727 for (Language, Message) in ErrorMessageList: 728 if Language.find(TAB_LANGUAGE_EN) >= 0: 729 return Message 730 else: 731 try: 732 return ErrorMessageList[0][1] 733 except IndexError: 734 return '' 735 return '' 736 737 ## 738 # Replace the strings for Python eval function. 739 # @param ReplaceValue: The string that needs to be replaced. 740 # @return: The string was replaced, then eval function is always making out it. 741 def ReplaceForEval(self, ReplaceValue, IsRange=False, IsExpr=False): 742 if self.FullPath: 743 pass 744 # 745 # deal with "NOT EQ", "NOT LT", "NOT GT", "NOT LE", "NOT GE", "NOT NOT" 746 # 747 NOTNOT_Pattern = '[\t\s]*NOT[\t\s]+NOT[\t\s]*' 748 NOTGE_Pattern = '[\t\s]*NOT[\t\s]+GE[\t\s]*' 749 NOTLE_Pattern = '[\t\s]*NOT[\t\s]+LE[\t\s]*' 750 NOTGT_Pattern = '[\t\s]*NOT[\t\s]+GT[\t\s]*' 751 NOTLT_Pattern = '[\t\s]*NOT[\t\s]+LT[\t\s]*' 752 NOTEQ_Pattern = '[\t\s]*NOT[\t\s]+EQ[\t\s]*' 753 ReplaceValue = re.compile(NOTNOT_Pattern).sub('', ReplaceValue) 754 ReplaceValue = re.compile(NOTLT_Pattern).sub('x >= ', ReplaceValue) 755 ReplaceValue = re.compile(NOTGT_Pattern).sub('x <= ', ReplaceValue) 756 ReplaceValue = re.compile(NOTLE_Pattern).sub('x > ', ReplaceValue) 757 ReplaceValue = re.compile(NOTGE_Pattern).sub('x < ', ReplaceValue) 758 ReplaceValue = re.compile(NOTEQ_Pattern).sub('x != ', ReplaceValue) 759 760 if IsRange: 761 ReplaceValue = ReplaceValue.replace('EQ', 'x ==') 762 ReplaceValue = ReplaceValue.replace('LT', 'x <') 763 ReplaceValue = ReplaceValue.replace('LE', 'x <=') 764 ReplaceValue = ReplaceValue.replace('GT', 'x >') 765 ReplaceValue = ReplaceValue.replace('GE', 'x >=') 766 ReplaceValue = ReplaceValue.replace('XOR', 'x ^') 767 elif IsExpr: 768 ReplaceValue = ReplaceValue.replace('EQ', '==') 769 ReplaceValue = ReplaceValue.replace('NE', '!=') 770 ReplaceValue = ReplaceValue.replace('LT', '<') 771 ReplaceValue = ReplaceValue.replace('LE', '<=') 772 ReplaceValue = ReplaceValue.replace('GT', '>') 773 ReplaceValue = ReplaceValue.replace('GE', '>=') 774 ReplaceValue = ReplaceValue.replace('XOR', '^') 775 776 ReplaceValue = ReplaceValue.replace('AND', 'and') 777 ReplaceValue = ReplaceValue.replace('&&', ' and ') 778 ReplaceValue = ReplaceValue.replace('xor', '^') 779 ReplaceValue = ReplaceValue.replace('OR', 'or') 780 ReplaceValue = ReplaceValue.replace('||', ' or ') 781 ReplaceValue = ReplaceValue.replace('NOT', 'not') 782 if ReplaceValue.find('!') >= 0 and ReplaceValue[ReplaceValue.index('!') + 1] != '=': 783 ReplaceValue = ReplaceValue.replace('!', ' not ') 784 if '.' in ReplaceValue: 785 Pattern = '[a-zA-Z0-9]{1,}\.[a-zA-Z0-9]{1,}' 786 MatchedList = re.findall(Pattern, ReplaceValue) 787 for MatchedItem in MatchedList: 788 if MatchedItem not in self.PcdDefaultValueDict: 789 Logger.Error("Dec File Parser", FORMAT_INVALID, Message=ST.ERR_DECPARSE_PCD_NODEFINED % MatchedItem, 790 File=self.FullPath) 791 792 ReplaceValue = ReplaceValue.replace(MatchedItem, self.PcdDefaultValueDict[MatchedItem]) 793 794 return ReplaceValue 795 796 ## 797 # Check pcd's default value according to the pcd's description 798 # 799 def CheckPcdValue(self): 800 for Pcd in self.GetPcdList(): 801 self.PcdDefaultValueDict[TAB_SPLIT.join((Pcd.GetTokenSpaceGuidCName(), Pcd.GetCName())).strip()] = \ 802 Pcd.GetDefaultValue() 803 804 for Pcd in self.GetPcdList(): 805 ValidationExpressions = [] 806 PcdGuidName = TAB_SPLIT.join((Pcd.GetTokenSpaceGuidCName(), Pcd.GetCName())) 807 Valids = Pcd.GetPcdErrorsList() 808 for Valid in Valids: 809 Expression = Valid.GetExpression() 810 if Expression: 811 # 812 # Delete the 'L' prefix of a quoted string, this operation is for eval() 813 # 814 QUOTED_PATTERN = '[\t\s]*L?"[^"]*"' 815 QuotedMatchedObj = re.search(QUOTED_PATTERN, Expression) 816 if QuotedMatchedObj: 817 MatchedStr = QuotedMatchedObj.group().strip() 818 if MatchedStr.startswith('L'): 819 Expression = Expression.replace(MatchedStr, MatchedStr[1:].strip()) 820 821 Expression = self.ReplaceForEval(Expression, IsExpr=True) 822 Expression = Expression.replace(PcdGuidName, 'x') 823 Message = self.GetEnErrorMessage(Valid.GetErrorMessageList()) 824 ValidationExpressions.append((Expression, Message)) 825 826 ValidList = Valid.GetValidValue() 827 if ValidList: 828 ValidValue = 'x in %s' % [eval(v) for v in ValidList.split(' ') if v] 829 Message = self.GetEnErrorMessage(Valid.GetErrorMessageList()) 830 ValidationExpressions.append((ValidValue, Message)) 831 832 ValidValueRange = Valid.GetValidValueRange() 833 if ValidValueRange: 834 ValidValueRange = self.ReplaceForEval(ValidValueRange, IsRange=True) 835 if ValidValueRange.find('-') >= 0: 836 ValidValueRange = ValidValueRange.replace('-', '<= x <=') 837 elif not ValidValueRange.startswith('x ') and not ValidValueRange.startswith('not ') \ 838 and not ValidValueRange.startswith('not(') and not ValidValueRange.startswith('('): 839 ValidValueRange = 'x %s' % ValidValueRange 840 Message = self.GetEnErrorMessage(Valid.GetErrorMessageList()) 841 ValidationExpressions.append((ValidValueRange, Message)) 842 843 DefaultValue = self.PcdDefaultValueDict[PcdGuidName.strip()] 844 # 845 # Delete the 'L' prefix of a quoted string, this operation is for eval() 846 # 847 QUOTED_PATTERN = '[\t\s]*L?"[^"]*"' 848 QuotedMatchedObj = re.search(QUOTED_PATTERN, DefaultValue) 849 if QuotedMatchedObj: 850 MatchedStr = QuotedMatchedObj.group().strip() 851 if MatchedStr.startswith('L'): 852 DefaultValue = DefaultValue.replace(MatchedStr, MatchedStr[1:].strip()) 853 854 try: 855 DefaultValue = eval(DefaultValue.replace('TRUE', 'True').replace('true', 'True') 856 .replace('FALSE', 'False').replace('false', 'False')) 857 except BaseException: 858 pass 859 860 for (Expression, Msg) in ValidationExpressions: 861 try: 862 if not eval(Expression, {'x':DefaultValue}): 863 Logger.Error("Dec File Parser", FORMAT_INVALID, ExtraData='%s, value = %s' %\ 864 (PcdGuidName, DefaultValue), Message=Msg, File=self.FullPath) 865 except TypeError: 866 Logger.Error("Dec File Parser", FORMAT_INVALID, ExtraData=PcdGuidName, \ 867 Message=Msg, File=self.FullPath) 868 869 ## GenModuleFileList 870 # 871 def GenModuleFileList(self, ContainerFile): 872 ModuleFileList = [] 873 ContainerFileName = os.path.basename(ContainerFile) 874 ContainerFilePath = os.path.dirname(ContainerFile) 875 for Item in GetFiles(ContainerFilePath, 876 ['CVS', '.svn'] + self.GetIncludePathList(), False): 877 ExtName = os.path.splitext(Item)[1] 878 if ExtName.lower() == '.inf': 879 ModuleFileList.append(Item) 880 elif ExtName.upper() == '.DEC' and self.CheckMulDec: 881 if Item == ContainerFileName: 882 continue 883 Logger.Error('MkPkg', 884 UPT_MUL_DEC_ERROR, 885 ST.ERR_MUL_DEC_ERROR%(ContainerFilePath, 886 ContainerFileName, 887 Item)) 888 889 self.SetModuleFileList(ModuleFileList) 890 891 ## Show detailed information of Package 892 # 893 # Print all members and their values of Package class 894 # 895 def ShowPackage(self): 896 print '\nName =', self.GetName() 897 print '\nBaseName =', self.GetBaseName() 898 print '\nVersion =', self.GetVersion() 899 print '\nGuid =', self.GetGuid() 900 901 print '\nStandardIncludes = %d ' \ 902 % len(self.GetStandardIncludeFileList()), 903 for Item in self.GetStandardIncludeFileList(): 904 print Item.GetFilePath(), ' ', Item.GetSupArchList() 905 print '\nPackageIncludes = %d \n' \ 906 % len(self.GetPackageIncludeFileList()), 907 for Item in self.GetPackageIncludeFileList(): 908 print Item.GetFilePath(), ' ', Item.GetSupArchList() 909 910 print '\nGuids =', self.GetGuidList() 911 for Item in self.GetGuidList(): 912 print Item.GetCName(), Item.GetGuid(), Item.GetSupArchList() 913 print '\nProtocols =', self.GetProtocolList() 914 for Item in self.GetProtocolList(): 915 print Item.GetCName(), Item.GetGuid(), Item.GetSupArchList() 916 print '\nPpis =', self.GetPpiList() 917 for Item in self.GetPpiList(): 918 print Item.GetCName(), Item.GetGuid(), Item.GetSupArchList() 919 print '\nLibraryClasses =', self.GetLibraryClassList() 920 for Item in self.GetLibraryClassList(): 921 print Item.GetLibraryClass(), Item.GetRecommendedInstance(), \ 922 Item.GetSupArchList() 923 print '\nPcds =', self.GetPcdList() 924 for Item in self.GetPcdList(): 925 print 'CName=', Item.GetCName(), 'TokenSpaceGuidCName=', \ 926 Item.GetTokenSpaceGuidCName(), \ 927 'DefaultValue=', Item.GetDefaultValue(), \ 928 'ValidUsage=', Item.GetValidUsage(), \ 929 'SupArchList', Item.GetSupArchList(), \ 930 'Token=', Item.GetToken(), 'DatumType=', Item.GetDatumType() 931 932 for Item in self.GetMiscFileList(): 933 print Item.GetName() 934 for FileObjectItem in Item.GetFileList(): 935 print FileObjectItem.GetURI() 936 print '****************\n' 937 938## GenPcdDeclaration 939# 940# @param ContainerFile: File name of the DEC file 941# @param PcdInfo: Pcd information, of format (TokenGuidCName, 942# TokenName, Value, DatumType, Token, Type, 943# GenericComment, TailComment, Arch) 944# @param Language: The language of HelpText, Prompt 945# 946def GenPcdDeclaration(ContainerFile, PcdInfo, Language, MacroReplaceDict): 947 HelpStr = '' 948 PromptStr = '' 949 TailHelpStr = '' 950 TokenGuidCName, TokenName, Value, DatumType, Token, Type, \ 951 GenericComment, TailComment, Arch = PcdInfo 952 Pcd = PcdObject() 953 Pcd.SetCName(TokenName) 954 Pcd.SetToken(Token) 955 Pcd.SetTokenSpaceGuidCName(TokenGuidCName) 956 Pcd.SetDatumType(DatumType) 957 Pcd.SetDefaultValue(Value) 958 Pcd.SetValidUsage(Type) 959 # 960 # MaxDatumSize is required field for 'VOID*' PCD 961 # 962 if DatumType == TAB_PTR_TYPE_PCD: 963 Pcd.SetMaxDatumSize(ITEM_UNDEFINED) 964 965 SupArchList = [Arch] 966 Pcd.SetSupArchList(SupArchList) 967 968 if GenericComment: 969 HelpStr, PcdErrList, PromptStr = ParseDecPcdGenericComment(GenericComment, 970 ContainerFile, 971 TokenGuidCName, 972 TokenName, 973 MacroReplaceDict) 974 if PcdErrList: 975 Pcd.SetPcdErrorsList(PcdErrList) 976 977 if TailComment: 978 SupModuleList, TailHelpStr = ParseDecPcdTailComment(TailComment, 979 ContainerFile) 980 if SupModuleList: 981 Pcd.SetSupModuleList(SupModuleList) 982 983 if HelpStr and (not HelpStr.endswith('\n')) and TailHelpStr: 984 HelpStr += '\n' 985 HelpStr += TailHelpStr 986 if HelpStr: 987 HelpTxtObj = TextObject() 988 HelpTxtObj.SetLang(Language) 989 HelpTxtObj.SetString(HelpStr) 990 Pcd.SetHelpTextList([HelpTxtObj]) 991 if PromptStr: 992 TxtObj = TextObject() 993 TxtObj.SetLang(Language) 994 TxtObj.SetString(PromptStr) 995 Pcd.SetPromptList([TxtObj]) 996 997 return Pcd 998