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