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