Home | History | Annotate | Download | only in PomAdapter
      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 '''
     16 DecPomAlignment
     17 '''
     18 
     19 ##

     20 # Import Modules

     21 #

     22 import os.path
     23 from os import sep
     24 import platform
     25 
     26 import re
     27 import Logger.Log as Logger
     28 from Logger import StringTable as ST
     29 from Logger.ToolError import UPT_MUL_DEC_ERROR
     30 from Logger.ToolError import FORMAT_INVALID
     31 
     32 from Library.Parsing import NormPath
     33 from Library.DataType import ARCH_LIST
     34 from Library.DataType import TAB_GUIDS
     35 from Library.DataType import TAB_PROTOCOLS
     36 from Library.DataType import TAB_PPIS
     37 from Library.DataType import TAB_DEC_DEFINES_PACKAGE_NAME
     38 from Library.DataType import TAB_DEC_DEFINES_PACKAGE_GUID
     39 from Library.DataType import TAB_DEC_DEFINES_PACKAGE_VERSION
     40 from Library.DataType import TAB_DEC_DEFINES_DEC_SPECIFICATION
     41 from Library.DataType import TAB_DEC_DEFINES_PKG_UNI_FILE
     42 from Library.DataType import TAB_ARCH_COMMON
     43 from Library.DataType import TAB_INCLUDES
     44 from Library.DataType import TAB_LIBRARY_CLASSES
     45 from Library.DataType import TAB_PCDS
     46 from Library.DataType import TAB_PCDS_FIXED_AT_BUILD_NULL
     47 from Library.DataType import TAB_PCDS_PATCHABLE_IN_MODULE_NULL
     48 from Library.DataType import TAB_PCDS_FEATURE_FLAG_NULL
     49 from Library.DataType import TAB_PCDS_DYNAMIC_EX_NULL
     50 from Library.DataType import TAB_PCDS_DYNAMIC_NULL
     51 from Library.DataType import TAB_PTR_TYPE_PCD
     52 from Library.DataType import ITEM_UNDEFINED
     53 from Library.DataType import TAB_DEC_BINARY_ABSTRACT
     54 from Library.DataType import TAB_DEC_BINARY_DESCRIPTION
     55 from Library.DataType import TAB_LANGUAGE_EN_US
     56 from Library.DataType import TAB_BINARY_HEADER_IDENTIFIER
     57 from Library.DataType import TAB_BINARY_HEADER_USERID
     58 from Library.DataType import TAB_LANGUAGE_EN_X
     59 from Library.DataType import TAB_LANGUAGE_EN
     60 from Library.DataType import TAB_STR_TOKENCNAME
     61 from Library.DataType import TAB_STR_TOKENPROMPT
     62 from Library.DataType import TAB_STR_TOKENHELP
     63 from Library.DataType import TAB_STR_TOKENERR
     64 from Library.DataType import TAB_HEX_START
     65 from Library.DataType import TAB_SPLIT
     66 from Library.CommentParsing import ParseHeaderCommentSection
     67 from Library.CommentParsing import ParseGenericComment
     68 from Library.CommentParsing import ParseDecPcdGenericComment
     69 from Library.CommentParsing import ParseDecPcdTailComment
     70 from Library.Misc import GetFiles
     71 from Library.Misc import Sdict
     72 from Library.Misc import GetRelativePath
     73 from Library.Misc import PathClass
     74 from Library.Misc import ValidateUNIFilePath
     75 from Library.UniClassObject import UniFileClassObject
     76 from Library.UniClassObject import ConvertSpecialUnicodes
     77 from Library.UniClassObject import GetLanguageCode1766
     78 from Library.ParserValidate import IsValidPath
     79 from Parser.DecParser import Dec
     80 from Object.POM.PackageObject import PackageObject
     81 from Object.POM.CommonObject import UserExtensionObject
     82 from Object.POM.CommonObject import IncludeObject
     83 from Object.POM.CommonObject import GuidObject
     84 from Object.POM.CommonObject import ProtocolObject
     85 from Object.POM.CommonObject import PpiObject
     86 from Object.POM.CommonObject import LibraryClassObject
     87 from Object.POM.CommonObject import PcdObject
     88 from Object.POM.CommonObject import TextObject
     89 from Object.POM.CommonObject import MiscFileObject
     90 from Object.POM.CommonObject import FileObject
     91 
     92 
     93 ## DecPomAlignment

     94 #

     95 # Inherited from PackageObject

     96 #

     97 class 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 # 
    946 def 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