Home | History | Annotate | Download | only in Parser
      1 ## @file

      2 # This file is used to define class objects of [Defines] section for INF file. 

      3 # It will consumed by InfParser

      4 #

      5 # Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>

      6 #

      7 # This program and the accompanying materials are licensed and made available 

      8 # under the terms and conditions of the BSD License which accompanies this 

      9 # distribution. The full text of the license may be found at 

     10 # http://opensource.org/licenses/bsd-license.php

     11 #

     12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

     13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

     14 
     15 '''
     16 InfDefineObject
     17 '''
     18 
     19 import os
     20 import re
     21 
     22 from Logger import StringTable as ST
     23 from Logger import ToolError
     24 from Library import GlobalData 
     25 from Library import DataType as DT
     26 from Library.String import GetSplitValueList
     27 from Library.Misc import CheckGuidRegFormat
     28 from Library.Misc import Sdict
     29 from Library.Misc import ConvPathFromAbsToRel
     30 from Library.Misc import ValidateUNIFilePath
     31 from Library.ExpressionValidate import IsValidFeatureFlagExp 
     32 from Library.ParserValidate import IsValidWord
     33 from Library.ParserValidate import IsValidInfMoudleType  
     34 from Library.ParserValidate import IsValidHex  
     35 from Library.ParserValidate import IsValidHexVersion  
     36 from Library.ParserValidate import IsValidDecVersion  
     37 from Library.ParserValidate import IsValidCVariableName 
     38 from Library.ParserValidate import IsValidBoolType 
     39 from Library.ParserValidate import IsValidPath
     40 from Library.ParserValidate import IsValidFamily
     41 from Library.ParserValidate import IsValidIdentifier
     42 from Library.ParserValidate import IsValidDecVersionVal
     43 from Object.Parser.InfCommonObject import InfLineCommentObject
     44 from Object.Parser.InfCommonObject import CurrentLine
     45 from Object.Parser.InfCommonObject import InfSectionCommonDef
     46 from Object.Parser.InfMisc import ErrorInInf
     47 from Object.Parser.InfDefineCommonObject import InfDefineLibraryItem
     48 from Object.Parser.InfDefineCommonObject import InfDefineEntryPointItem
     49 from Object.Parser.InfDefineCommonObject import InfDefineUnloadImageItem
     50 from Object.Parser.InfDefineCommonObject import InfDefineConstructorItem 
     51 from Object.Parser.InfDefineCommonObject import InfDefineDestructorItem
     52 
     53 class InfDefSectionOptionRomInfo():
     54     def __init__(self):
     55         self.PciVendorId                = None
     56         self.PciDeviceId                = None
     57         self.PciClassCode               = None
     58         self.PciRevision                = None
     59         self.PciCompress                = None
     60         self.CurrentLine                = ['', -1, '']
     61     def SetPciVendorId(self, PciVendorId, Comments):
     62         #

     63         # Value has been set before.

     64         #

     65         if self.PciVendorId != None:
     66             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_PCI_VENDOR_ID),
     67                        LineInfo=self.CurrentLine)
     68             return False           
     69         #

     70         # The PciVendorId should be hex string.  

     71         #

     72         if (IsValidHex(PciVendorId)):
     73             self.PciVendorId = InfDefMember()
     74             self.PciVendorId.SetValue(PciVendorId)
     75             self.PciVendorId.Comments = Comments
     76             return True
     77         else:
     78             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(PciVendorId),
     79                        LineInfo=self.CurrentLine)
     80             return False
     81         
     82     def GetPciVendorId(self):
     83         return self.PciVendorId
     84     
     85     def SetPciDeviceId(self, PciDeviceId, Comments):
     86         #

     87         # Value has been set before.

     88         #

     89         if self.PciDeviceId != None:
     90             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_PCI_DEVICE_ID),
     91                        LineInfo=self.CurrentLine)
     92             return False         
     93         #

     94         # The PciDeviceId should be hex string.  

     95         #

     96         if (IsValidHex(PciDeviceId)):
     97             self.PciDeviceId = InfDefMember()
     98             self.PciDeviceId.SetValue(PciDeviceId)
     99             self.PciDeviceId.Comments = Comments            
    100             return True
    101         else:
    102             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(PciDeviceId),
    103                        LineInfo=self.CurrentLine)
    104             return False
    105         
    106     def GetPciDeviceId(self):
    107         return self.PciDeviceId
    108    
    109     def SetPciClassCode(self, PciClassCode, Comments):
    110         #

    111         # Value has been set before.

    112         #

    113         if self.PciClassCode != None:
    114             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_PCI_CLASS_CODE),
    115                        LineInfo=self.CurrentLine)
    116             return False        
    117         #

    118         # The PciClassCode should be 4 bytes hex string.  

    119         #

    120         if (IsValidHex(PciClassCode)):
    121             self.PciClassCode = InfDefMember()
    122             self.PciClassCode.SetValue(PciClassCode)
    123             self.PciClassCode.Comments = Comments
    124             return True
    125         else:
    126             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%\
    127                        (PciClassCode),
    128                        LineInfo=self.CurrentLine)
    129             return False
    130         
    131     def GetPciClassCode(self):
    132         return self.PciClassCode
    133     
    134     def SetPciRevision(self, PciRevision, Comments):
    135         #

    136         # Value has been set before.

    137         #

    138         if self.PciRevision != None:
    139             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_PCI_REVISION),
    140                        LineInfo=self.CurrentLine)
    141             return False          
    142         #

    143         # The PciRevision should be 4 bytes hex string.  

    144         #

    145         if (IsValidHex(PciRevision)):
    146             self.PciRevision = InfDefMember()
    147             self.PciRevision.SetValue(PciRevision)
    148             self.PciRevision.Comments = Comments
    149             return True
    150         else:
    151             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(PciRevision),
    152                        LineInfo=self.CurrentLine)
    153             return False
    154         
    155     def GetPciRevision(self):
    156         return self.PciRevision
    157     
    158     def SetPciCompress(self, PciCompress, Comments):
    159         #

    160         # Value has been set before.

    161         #

    162         if self.PciCompress != None:
    163             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_PCI_COMPRESS),
    164                        LineInfo=self.CurrentLine)
    165             return False
    166         
    167         #

    168         # The PciCompress should be 'TRUE' or 'FALSE'.  

    169         #

    170         if (PciCompress == 'TRUE' or PciCompress == 'FALSE'):
    171             self.PciCompress = InfDefMember()
    172             self.PciCompress.SetValue(PciCompress)
    173             self.PciCompress.Comments = Comments
    174             return True
    175         else:
    176             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(PciCompress),
    177                        LineInfo=self.CurrentLine)
    178             return False        
    179     def GetPciCompress(self):
    180         return self.PciCompress        
    181 ##

    182 # INF [Define] section Object

    183 #

    184 class InfDefSection(InfDefSectionOptionRomInfo):
    185     def __init__(self):
    186         self.BaseName                   = None
    187         self.FileGuid                   = None
    188         self.ModuleType                 = None
    189         self.ModuleUniFileName          = None
    190         self.InfVersion                 = None
    191         self.EdkReleaseVersion          = None
    192         self.UefiSpecificationVersion   = None
    193         self.PiSpecificationVersion     = None
    194         self.LibraryClass               = []
    195         self.Package                    = None
    196         self.VersionString              = None
    197         self.PcdIsDriver                = None
    198         self.EntryPoint                 = []
    199         self.UnloadImages               = []
    200         self.Constructor                = []
    201         self.Destructor                 = []
    202         self.Shadow                     = None
    203         self.CustomMakefile             = []
    204         self.Specification              = []
    205         self.UefiHiiResourceSection     = None
    206         self.DpxSource                  = []
    207         self.CurrentLine                = ['', -1, '']
    208         InfDefSectionOptionRomInfo.__init__(self)
    209 
    210     ## SetHeadComment

    211     #

    212     # @param BaseName: BaseName

    213     #    

    214     def SetBaseName(self, BaseName, Comments):
    215         #

    216         # Value has been set before.

    217         #

    218         if self.BaseName != None:    
    219             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_BASE_NAME),
    220                        LineInfo=self.CurrentLine)
    221             return False     
    222         if not (BaseName == '' or BaseName == None):
    223             if IsValidWord(BaseName) and not BaseName.startswith("_"):
    224                 self.BaseName = InfDefMember()
    225                 self.BaseName.SetValue(BaseName)
    226                 self.BaseName.Comments = Comments
    227                 return True
    228             else:
    229                 ErrorInInf(ST.ERR_INF_PARSER_DEFINE_NAME_INVALID%(BaseName),
    230                            LineInfo=self.CurrentLine)
    231                 return False
    232 
    233     ## GetBaseName

    234     #          

    235     def GetBaseName(self):
    236         return self.BaseName
    237 
    238     ## SetFileGuid

    239     #

    240     # @param FileGuid: FileGuid

    241     #        

    242     def SetFileGuid(self, FileGuid, Comments):
    243         #

    244         # Value has been set before.

    245         #

    246         if self.FileGuid != None:    
    247             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
    248                        %(DT.TAB_INF_DEFINES_FILE_GUID),
    249                        LineInfo=self.CurrentLine)
    250             return False                        
    251         #

    252         # Do verification of GUID content/format

    253         #          

    254         if (CheckGuidRegFormat(FileGuid)):
    255             self.FileGuid = InfDefMember()
    256             self.FileGuid.SetValue(FileGuid)
    257             self.FileGuid.Comments = Comments
    258             return True
    259         else:
    260             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_GUID_INVALID%(FileGuid),
    261                        LineInfo=self.CurrentLine)
    262             return False
    263 
    264     ## GetFileGuid

    265     #            

    266     def GetFileGuid(self):
    267         return self.FileGuid
    268 
    269     ## SetModuleType

    270     #

    271     # @param ModuleType: ModuleType

    272     #     

    273     def SetModuleType(self, ModuleType, Comments):
    274         #

    275         # Value has been set before.

    276         #

    277         if self.ModuleType != None:    
    278             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
    279                        %(DT.TAB_INF_DEFINES_MODULE_TYPE),
    280                        LineInfo=self.CurrentLine)
    281             return False           
    282         #

    283         # Valid Module Type or not

    284         #

    285         if (IsValidInfMoudleType(ModuleType)):
    286             self.ModuleType = InfDefMember()
    287             self.ModuleType.SetValue(ModuleType)
    288             self.ModuleType.CurrentLine = CurrentLine()
    289             self.ModuleType.CurrentLine.SetLineNo(self.CurrentLine[1])
    290             self.ModuleType.CurrentLine.SetLineString(self.CurrentLine[2])
    291             self.ModuleType.CurrentLine.SetFileName(self.CurrentLine[0])
    292             self.ModuleType.Comments = Comments            
    293             return True
    294         else:
    295             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_MODULETYPE_INVALID%\
    296                        (ModuleType),
    297                        LineInfo=self.CurrentLine)
    298             return False
    299 
    300     ## GetModuleType

    301     #                       

    302     def GetModuleType(self):
    303         return self.ModuleType
    304     
    305     ## SetModuleUniFileName

    306     #

    307     # @param ModuleUniFileName: ModuleUniFileName

    308     #     

    309     def SetModuleUniFileName(self, ModuleUniFileName, Comments):
    310         if Comments:
    311             pass
    312         if self.ModuleUniFileName != None:
    313             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_MODULE_UNI_FILE),
    314                        LineInfo=self.CurrentLine)
    315         self.ModuleUniFileName = ModuleUniFileName
    316 
    317     ## GetModuleType

    318     #                       

    319     def GetModuleUniFileName(self):
    320         return self.ModuleUniFileName
    321     
    322     ## SetInfVersion

    323     #

    324     # @param InfVersion: InfVersion

    325     #            

    326     def SetInfVersion(self, InfVersion, Comments):
    327         #

    328         # Value has been set before.

    329         #

    330         if self.InfVersion != None:    
    331             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
    332                        %(DT.TAB_INF_DEFINES_INF_VERSION),
    333                        LineInfo=self.CurrentLine)
    334             return False        
    335         #

    336         # The InfVersion should be 4 bytes hex string. 

    337         #

    338         if (IsValidHex(InfVersion)):
    339             if (InfVersion < '0x00010005'):
    340                 ErrorInInf(ST.ERR_INF_PARSER_NOT_SUPPORT_EDKI_INF,
    341                            ErrorCode=ToolError.EDK1_INF_ERROR,
    342                            LineInfo=self.CurrentLine)
    343         elif IsValidDecVersionVal(InfVersion):
    344             if (InfVersion < 65541):
    345                 ErrorInInf(ST.ERR_INF_PARSER_NOT_SUPPORT_EDKI_INF,
    346                            ErrorCode=ToolError.EDK1_INF_ERROR,
    347                            LineInfo=self.CurrentLine)
    348         else:
    349             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(InfVersion),
    350                        LineInfo=self.CurrentLine)
    351             return False
    352 
    353         self.InfVersion = InfDefMember()
    354         self.InfVersion.SetValue(InfVersion)
    355         self.InfVersion.Comments = Comments
    356         return True
    357 
    358     ## GetInfVersion

    359     #                     

    360     def GetInfVersion(self):
    361         return self.InfVersion
    362 
    363     ## SetEdkReleaseVersion

    364     #

    365     # @param EdkReleaseVersion: EdkReleaseVersion

    366     #      

    367     def SetEdkReleaseVersion(self, EdkReleaseVersion, Comments):
    368         #

    369         # Value has been set before.

    370         #

    371         if self.EdkReleaseVersion != None:    
    372             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
    373                        %(DT.TAB_INF_DEFINES_EDK_RELEASE_VERSION),
    374                        LineInfo=self.CurrentLine)
    375             return False          
    376         #

    377         # The EdkReleaseVersion should be 4 bytes hex string.  

    378         #

    379         if IsValidHexVersion(EdkReleaseVersion) or \
    380            IsValidDecVersionVal(EdkReleaseVersion):
    381             self.EdkReleaseVersion = InfDefMember()
    382             self.EdkReleaseVersion.SetValue(EdkReleaseVersion)
    383             self.EdkReleaseVersion.Comments = Comments
    384             return True
    385         else:
    386             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID\
    387                        %(EdkReleaseVersion),
    388                        LineInfo=self.CurrentLine)
    389             return False
    390 
    391     ## GetEdkReleaseVersion

    392     #        

    393     def GetEdkReleaseVersion(self):
    394         return self.EdkReleaseVersion 
    395 
    396     ## SetUefiSpecificationVersion

    397     #

    398     # @param UefiSpecificationVersion: UefiSpecificationVersion

    399     #         

    400     def SetUefiSpecificationVersion(self, UefiSpecificationVersion, Comments):
    401         #

    402         # Value has been set before.

    403         #

    404         if self.UefiSpecificationVersion != None:    
    405             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
    406                        %(DT.TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION),
    407                        LineInfo=self.CurrentLine)
    408             return False            
    409         #

    410         # The EdkReleaseVersion should be 4 bytes hex string.  

    411         #

    412         if IsValidHexVersion(UefiSpecificationVersion) or \
    413            IsValidDecVersionVal(UefiSpecificationVersion):
    414             self.UefiSpecificationVersion = InfDefMember()
    415             self.UefiSpecificationVersion.SetValue(UefiSpecificationVersion)
    416             self.UefiSpecificationVersion.Comments = Comments
    417             return True
    418         else:
    419             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID\
    420                        %(UefiSpecificationVersion),
    421                        LineInfo=self.CurrentLine)
    422             return False
    423 
    424     ## GetUefiSpecificationVersion

    425     #           

    426     def GetUefiSpecificationVersion(self):
    427         return self.UefiSpecificationVersion            
    428 
    429     ## SetPiSpecificationVersion

    430     #

    431     # @param PiSpecificationVersion: PiSpecificationVersion

    432     #         

    433     def SetPiSpecificationVersion(self, PiSpecificationVersion, Comments):
    434         #

    435         # Value has been set before.

    436         #

    437         if self.PiSpecificationVersion != None:    
    438             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
    439                        %(DT.TAB_INF_DEFINES_PI_SPECIFICATION_VERSION),
    440                        LineInfo=self.CurrentLine)
    441             return False         
    442         #

    443         # The EdkReleaseVersion should be 4 bytes hex string.  

    444         #

    445         if IsValidHexVersion(PiSpecificationVersion) or \
    446            IsValidDecVersionVal(PiSpecificationVersion):
    447             self.PiSpecificationVersion = InfDefMember()
    448             self.PiSpecificationVersion.SetValue(PiSpecificationVersion)
    449             self.PiSpecificationVersion.Comments = Comments
    450             return True
    451         else:
    452             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID\
    453                        %(PiSpecificationVersion),
    454                        LineInfo=self.CurrentLine)            
    455             return False
    456 
    457     ## GetPiSpecificationVersion

    458     #      

    459     def GetPiSpecificationVersion(self):
    460         return self.PiSpecificationVersion
    461 
    462     ## SetLibraryClass

    463     #

    464     # @param LibraryClass: LibraryClass

    465     #            

    466     def SetLibraryClass(self, LibraryClass, Comments):
    467         ValueList = GetSplitValueList(LibraryClass)
    468         Name = ValueList[0]         
    469         if IsValidWord(Name):
    470             InfDefineLibraryItemObj = InfDefineLibraryItem()
    471             InfDefineLibraryItemObj.SetLibraryName(Name)            
    472             InfDefineLibraryItemObj.Comments = Comments
    473             if len(ValueList) == 2:
    474                 Type = ValueList[1]
    475                 TypeList = GetSplitValueList(Type, ' ')
    476                 TypeList = [Type for Type in TypeList if Type != '']
    477                 for Item in TypeList:
    478                     if Item not in DT.MODULE_LIST:
    479                         ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Item),
    480                                    LineInfo=self.CurrentLine)
    481                         return False
    482                 InfDefineLibraryItemObj.SetTypes(TypeList)                    
    483             self.LibraryClass.append(InfDefineLibraryItemObj)               
    484         else:
    485             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Name),
    486                        LineInfo=self.CurrentLine)
    487             return False
    488         
    489         return True
    490     
    491     def GetLibraryClass(self):
    492         return self.LibraryClass
    493   
    494     def SetVersionString(self, VersionString, Comments):
    495         #

    496         # Value has been set before.

    497         #

    498         if self.VersionString != None:    
    499             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
    500                        %(DT.TAB_INF_DEFINES_VERSION_STRING),
    501                        LineInfo=self.CurrentLine)
    502             return False
    503         if not IsValidDecVersion(VersionString):
    504             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID\
    505                        %(VersionString),
    506                        LineInfo=self.CurrentLine) 
    507         self.VersionString = InfDefMember()
    508         self.VersionString.SetValue(VersionString)
    509         self.VersionString.Comments = Comments
    510         return True
    511 
    512         
    513     def GetVersionString(self):
    514         return self.VersionString
    515     
    516     def SetPcdIsDriver(self, PcdIsDriver, Comments):
    517         #

    518         # Value has been set before.

    519         #

    520         if self.PcdIsDriver != None:    
    521             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
    522                        %(DT.TAB_INF_DEFINES_PCD_IS_DRIVER),
    523                        LineInfo=self.CurrentLine)
    524             return False         
    525         if PcdIsDriver == 'PEI_PCD_DRIVER' or PcdIsDriver == 'DXE_PCD_DRIVER':
    526             self.PcdIsDriver = InfDefMember()
    527             self.PcdIsDriver.SetValue(PcdIsDriver)
    528             self.PcdIsDriver.Comments = Comments
    529             return True
    530         else:
    531             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(PcdIsDriver),
    532                        LineInfo=self.CurrentLine)
    533             return False
    534     
    535     def GetPcdIsDriver(self):
    536         return self.PcdIsDriver
    537     
    538     #

    539     # SetEntryPoint

    540     #    

    541     def SetEntryPoint(self, EntryPoint, Comments):
    542         #

    543         # It can be a list

    544         #

    545         ValueList = []
    546         TokenList = GetSplitValueList(EntryPoint, DT.TAB_VALUE_SPLIT)
    547         ValueList[0:len(TokenList)] = TokenList        
    548         InfDefineEntryPointItemObj = InfDefineEntryPointItem()
    549         if not IsValidCVariableName(ValueList[0]):
    550             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%\
    551                        (ValueList[0]),
    552                        LineInfo=self.CurrentLine)
    553         InfDefineEntryPointItemObj.SetCName(ValueList[0])
    554         if len(ValueList) == 2:
    555             if ValueList[1].strip() == '':
    556                 ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%\
    557                            (ValueList[1]),
    558                            LineInfo=self.CurrentLine)
    559             #

    560             # Validate FFE    

    561             #

    562             FeatureFlagRtv = IsValidFeatureFlagExp(ValueList[1].strip())
    563             if not FeatureFlagRtv[0]:
    564                 ErrorInInf(ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%\
    565                            (FeatureFlagRtv[1]),
    566                            LineInfo=self.CurrentLine)       
    567             InfDefineEntryPointItemObj.SetFeatureFlagExp(ValueList[1])     
    568         if len(ValueList) > 2:
    569             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(EntryPoint),
    570                        LineInfo=self.CurrentLine)
    571         InfDefineEntryPointItemObj.Comments = Comments             
    572         self.EntryPoint.append(InfDefineEntryPointItemObj)       
    573         
    574     def GetEntryPoint(self):
    575         return self.EntryPoint
    576 
    577     #

    578     # SetUnloadImages

    579     #      

    580     def SetUnloadImages(self, UnloadImages, Comments):
    581         #

    582         # It can be a list

    583         #

    584         ValueList = []
    585         TokenList = GetSplitValueList(UnloadImages, DT.TAB_VALUE_SPLIT)
    586         ValueList[0:len(TokenList)] = TokenList        
    587         InfDefineUnloadImageItemObj = InfDefineUnloadImageItem()
    588         if not IsValidCVariableName(ValueList[0]):
    589             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[0]),
    590                        LineInfo=self.CurrentLine)
    591         InfDefineUnloadImageItemObj.SetCName(ValueList[0])
    592         if len(ValueList) == 2:
    593             if ValueList[1].strip() == '':
    594                 ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[1]),
    595                            LineInfo=self.CurrentLine)
    596             #

    597             # Validate FFE    

    598             #

    599             FeatureFlagRtv = IsValidFeatureFlagExp(ValueList[1].strip())
    600             if not FeatureFlagRtv[0]:
    601                 ErrorInInf(ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]),
    602                            LineInfo=self.CurrentLine)
    603             InfDefineUnloadImageItemObj.SetFeatureFlagExp(ValueList[1])
    604                 
    605         if len(ValueList) > 2:
    606             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(UnloadImages),
    607                        LineInfo=self.CurrentLine)
    608         InfDefineUnloadImageItemObj.Comments = Comments
    609         self.UnloadImages.append(InfDefineUnloadImageItemObj)
    610         
    611     def GetUnloadImages(self):
    612         return self.UnloadImages
    613 
    614     #

    615     # SetConstructor

    616     #          

    617     def SetConstructor(self, Constructor, Comments):
    618         #

    619         # It can be a list

    620         #

    621         ValueList = []
    622         TokenList = GetSplitValueList(Constructor, DT.TAB_VALUE_SPLIT)
    623         ValueList[0:len(TokenList)] = TokenList        
    624         InfDefineConstructorItemObj = InfDefineConstructorItem()
    625         if not IsValidCVariableName(ValueList[0]):
    626             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[0]),
    627                        LineInfo=self.CurrentLine)
    628         InfDefineConstructorItemObj.SetCName(ValueList[0])
    629         if len(ValueList) >= 2:
    630             ModList = GetSplitValueList(ValueList[1], ' ')
    631             if ValueList[1].strip() == '':
    632                 ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[1]),
    633                            LineInfo=self.CurrentLine)
    634             for ModItem in ModList:
    635                 if ModItem not in DT.MODULE_LIST:
    636                     ErrorInInf(ST.ERR_INF_PARSER_DEFINE_MODULETYPE_INVALID%(ModItem),
    637                                LineInfo=self.CurrentLine)
    638             InfDefineConstructorItemObj.SetSupModList(ModList)             
    639         if len(ValueList) == 3:
    640             if ValueList[2].strip() == '':
    641                 ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[2]),
    642                            LineInfo=self.CurrentLine)
    643             #

    644             # Validate FFE    

    645             #

    646             FeatureFlagRtv = IsValidFeatureFlagExp(ValueList[2].strip())
    647             if not FeatureFlagRtv[0]:
    648                 ErrorInInf(ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[2]),
    649                            LineInfo=self.CurrentLine)
    650             InfDefineConstructorItemObj.SetFeatureFlagExp(ValueList[2])
    651                     
    652         if len(ValueList) > 3:
    653             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Constructor),
    654                        LineInfo=self.CurrentLine)
    655         InfDefineConstructorItemObj.Comments = Comments    
    656         self.Constructor.append(InfDefineConstructorItemObj)     
    657            
    658     def GetConstructor(self):
    659         return self.Constructor
    660 
    661     #

    662     # SetDestructor

    663     #      

    664     def SetDestructor(self, Destructor, Comments):
    665         #

    666         # It can be a list and only 1 set to TRUE

    667         #        

    668         ValueList = []
    669         TokenList = GetSplitValueList(Destructor, DT.TAB_VALUE_SPLIT)
    670         ValueList[0:len(TokenList)] = TokenList        
    671         InfDefineDestructorItemObj = InfDefineDestructorItem()
    672         if not IsValidCVariableName(ValueList[0]):
    673             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[0]),
    674                        LineInfo=self.CurrentLine)
    675         InfDefineDestructorItemObj.SetCName(ValueList[0])
    676         if len(ValueList) >= 2:
    677             ModList = GetSplitValueList(ValueList[1].strip(), ' ')
    678             if ValueList[1].strip() == '':
    679                 ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[1]),
    680                            LineInfo=self.CurrentLine)
    681             for ModItem in ModList:
    682                 if ModItem not in DT.MODULE_LIST:
    683                     ErrorInInf(ST.ERR_INF_PARSER_DEFINE_MODULETYPE_INVALID%(ModItem),
    684                                LineInfo=self.CurrentLine)
    685             InfDefineDestructorItemObj.SetSupModList(ModList)          
    686         if len(ValueList) == 3:
    687             if ValueList[2].strip() == '':
    688                 ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[2]),
    689                            LineInfo=self.CurrentLine)
    690             #

    691             # Validate FFE    

    692             #

    693             FeatureFlagRtv = IsValidFeatureFlagExp(ValueList[2].strip())
    694             if not FeatureFlagRtv[0]:
    695                 ErrorInInf(ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]),
    696                            LineInfo=self.CurrentLine)
    697             InfDefineDestructorItemObj.SetFeatureFlagExp(ValueList[2])
    698         
    699         if len(ValueList) > 3:
    700             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Destructor),
    701                        LineInfo=self.CurrentLine)
    702             
    703         InfDefineDestructorItemObj.Comments = Comments 
    704         self.Destructor.append(InfDefineDestructorItemObj) 
    705         
    706     def GetDestructor(self):
    707         return self.Destructor
    708     
    709     def SetShadow(self, Shadow, Comments):
    710         #

    711         # Value has been set before.

    712         #

    713         if self.Shadow != None:
    714             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_SHADOW),
    715                        LineInfo=self.CurrentLine)
    716             return False          
    717         if (IsValidBoolType(Shadow)):
    718             self.Shadow = InfDefMember()
    719             self.Shadow.SetValue(Shadow)
    720             self.Shadow.Comments = Comments
    721             return True
    722         else:
    723             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Shadow),
    724                        LineInfo=self.CurrentLine)
    725             return False
    726     def GetShadow(self):
    727         return self.Shadow
    728 
    729     #

    730     # <Family>               ::=  {"MSFT"} {"GCC"}

    731     # <CustomMake>           ::=  [<Family> "|"] <Filename>

    732     #

    733     def SetCustomMakefile(self, CustomMakefile, Comments):
    734         if not (CustomMakefile == '' or CustomMakefile == None):
    735             ValueList = GetSplitValueList(CustomMakefile)
    736             if len(ValueList) == 1:
    737                 FileName = ValueList[0]
    738                 Family = ''
    739             else:
    740                 Family = ValueList[0]
    741                 FileName = ValueList[1]
    742             Family = Family.strip()
    743             if Family != '':
    744                 if not IsValidFamily(Family):
    745                     ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Family),
    746                                LineInfo=self.CurrentLine)
    747                     return False
    748             #

    749             # The MakefileName specified file should exist

    750             #

    751             IsValidFileFlag = False
    752             ModulePath = os.path.split(self.CurrentLine[0])[0]
    753             if IsValidPath(FileName, ModulePath):
    754                 IsValidFileFlag = True           
    755             else:
    756                 ErrorInInf(ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(FileName),
    757                            LineInfo=self.CurrentLine)
    758                 return False
    759             if IsValidFileFlag:
    760                 FileName = ConvPathFromAbsToRel(FileName, GlobalData.gINF_MODULE_DIR)                     
    761                 self.CustomMakefile.append((Family, FileName, Comments))
    762                 IsValidFileFlag = False
    763             return True
    764         else:
    765             return False
    766         
    767     def GetCustomMakefile(self):
    768         return self.CustomMakefile
    769     
    770     #

    771     # ["SPEC" <Spec> <EOL>]*{0,}

    772     # <Spec>                 ::=  <Word> "=" <VersionVal>

    773     # <VersionVal>           ::=  {<HexVersion>] {<DecVersion>}

    774     # <HexNumber>            ::=  "0x" [<HexDigit>]{1,}

    775     # <DecVersion>           ::=  (0-9){1,} ["." (0-9){1,2}]

    776     #

    777     def SetSpecification(self, Specification, Comments):
    778         #

    779         # Valid the value of Specification

    780         #

    781         __ValueList = []
    782         TokenList = GetSplitValueList(Specification, DT.TAB_EQUAL_SPLIT, 1)
    783         __ValueList[0:len(TokenList)] = TokenList
    784         if len(__ValueList) != 2:
    785             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_NO_NAME + ' Or ' + ST.ERR_INF_PARSER_DEFINE_ITEM_NO_VALUE,
    786                        LineInfo=self.CurrentLine)
    787         Name = __ValueList[0].strip()
    788         Version = __ValueList[1].strip()   
    789         if IsValidIdentifier(Name):
    790             if IsValidDecVersion(Version):
    791                 self.Specification.append((Name, Version, Comments))
    792                 return True
    793             else:
    794                 ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Version),
    795                            LineInfo=self.CurrentLine)
    796                 return False
    797         else:                  
    798             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Name),
    799                        LineInfo=self.CurrentLine)
    800             return False    
    801         return True
    802 
    803     def GetSpecification(self):
    804         return self.Specification
    805     
    806     #

    807     # [<UefiHiiResource> <EOL>]{0,1}

    808     # <UefiHiiResource>      ::=  "UEFI_HII_RESOURCE_SECTION" "=" <BoolType>

    809     #

    810     def SetUefiHiiResourceSection(self, UefiHiiResourceSection, Comments):
    811         #

    812         # Value has been set before.

    813         #

    814         if self.UefiHiiResourceSection != None:
    815             ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND
    816                        %(DT.TAB_INF_DEFINES_UEFI_HII_RESOURCE_SECTION),
    817                        LineInfo=self.CurrentLine)
    818             return False           
    819         if not (UefiHiiResourceSection == '' or UefiHiiResourceSection == None):
    820             if (IsValidBoolType(UefiHiiResourceSection)):
    821                 self.UefiHiiResourceSection = InfDefMember()
    822                 self.UefiHiiResourceSection.SetValue(UefiHiiResourceSection)
    823                 self.UefiHiiResourceSection.Comments = Comments                
    824                 return True
    825             else:
    826                 ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(UefiHiiResourceSection),
    827                            LineInfo=self.CurrentLine)
    828                 return False
    829         else:
    830             return False
    831             
    832     def GetUefiHiiResourceSection(self):
    833         return self.UefiHiiResourceSection
    834     
    835     def SetDpxSource(self, DpxSource, Comments):    
    836         #

    837         # The MakefileName specified file should exist

    838         #

    839         IsValidFileFlag = False
    840         ModulePath = os.path.split(self.CurrentLine[0])[0]
    841         if IsValidPath(DpxSource, ModulePath):
    842             IsValidFileFlag = True           
    843         else:
    844             ErrorInInf(ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(DpxSource),
    845                        LineInfo=self.CurrentLine)
    846             return False
    847         if IsValidFileFlag:
    848             DpxSource = ConvPathFromAbsToRel(DpxSource, 
    849                             GlobalData.gINF_MODULE_DIR)     
    850             self.DpxSource.append((DpxSource, Comments))
    851             IsValidFileFlag = False
    852         return True               
    853 
    854     def GetDpxSource(self):
    855         return self.DpxSource
    856 
    857 gFUNCTION_MAPPING_FOR_DEFINE_SECTION = {
    858     #

    859     # Required Fields

    860     #

    861     DT.TAB_INF_DEFINES_BASE_NAME                   : InfDefSection.SetBaseName,
    862     DT.TAB_INF_DEFINES_FILE_GUID                   : InfDefSection.SetFileGuid,
    863     DT.TAB_INF_DEFINES_MODULE_TYPE                 : InfDefSection.SetModuleType,
    864     #

    865     # Required by EDKII style INF file

    866     #

    867     DT.TAB_INF_DEFINES_INF_VERSION                 : InfDefSection.SetInfVersion,
    868     #

    869     # Optional Fields

    870     #        

    871     DT.TAB_INF_DEFINES_MODULE_UNI_FILE             : InfDefSection.SetModuleUniFileName,
    872     DT.TAB_INF_DEFINES_EDK_RELEASE_VERSION         : InfDefSection.SetEdkReleaseVersion,
    873     DT.TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION  : InfDefSection.SetUefiSpecificationVersion,
    874     DT.TAB_INF_DEFINES_PI_SPECIFICATION_VERSION    : InfDefSection.SetPiSpecificationVersion,
    875     DT.TAB_INF_DEFINES_LIBRARY_CLASS               : InfDefSection.SetLibraryClass,
    876     DT.TAB_INF_DEFINES_VERSION_STRING              : InfDefSection.SetVersionString,
    877     DT.TAB_INF_DEFINES_PCD_IS_DRIVER               : InfDefSection.SetPcdIsDriver,
    878     DT.TAB_INF_DEFINES_ENTRY_POINT                 : InfDefSection.SetEntryPoint,
    879     DT.TAB_INF_DEFINES_UNLOAD_IMAGE                : InfDefSection.SetUnloadImages,
    880     DT.TAB_INF_DEFINES_CONSTRUCTOR                 : InfDefSection.SetConstructor,
    881     DT.TAB_INF_DEFINES_DESTRUCTOR                  : InfDefSection.SetDestructor,
    882     DT.TAB_INF_DEFINES_SHADOW                      : InfDefSection.SetShadow,
    883     DT.TAB_INF_DEFINES_PCI_VENDOR_ID               : InfDefSection.SetPciVendorId,
    884     DT.TAB_INF_DEFINES_PCI_DEVICE_ID               : InfDefSection.SetPciDeviceId,
    885     DT.TAB_INF_DEFINES_PCI_CLASS_CODE              : InfDefSection.SetPciClassCode,   
    886     DT.TAB_INF_DEFINES_PCI_REVISION                : InfDefSection.SetPciRevision,
    887     DT.TAB_INF_DEFINES_PCI_COMPRESS                : InfDefSection.SetPciCompress,
    888     DT.TAB_INF_DEFINES_CUSTOM_MAKEFILE             : InfDefSection.SetCustomMakefile,  
    889     DT.TAB_INF_DEFINES_SPEC                        : InfDefSection.SetSpecification,
    890     DT.TAB_INF_DEFINES_UEFI_HII_RESOURCE_SECTION   : InfDefSection.SetUefiHiiResourceSection,
    891     DT.TAB_INF_DEFINES_DPX_SOURCE                  : InfDefSection.SetDpxSource
    892 }
    893 
    894 ## InfDefMember

    895 #

    896 #

    897 class InfDefMember():
    898     def __init__(self, Name='', Value=''):
    899         self.Comments = InfLineCommentObject()
    900         self.Name  = Name
    901         self.Value = Value
    902         self.CurrentLine = CurrentLine()
    903     def GetName(self):
    904         return self.Name
    905     def SetName(self, Name):
    906         self.Name = Name
    907     def GetValue(self):
    908         return self.Value
    909     def SetValue(self, Value):
    910         self.Value = Value
    911     
    912 ## InfDefObject

    913 #

    914 #

    915 class InfDefObject(InfSectionCommonDef):
    916     def __init__(self):
    917         self.Defines = Sdict()
    918         InfSectionCommonDef.__init__(self)
    919     def SetDefines(self, DefineContent, Arch = None):
    920         #

    921         # Validate Arch

    922         #

    923         HasFoundInfVersionFalg = False
    924         LineInfo = ['', -1, '']
    925         ArchListString = ' '.join(Arch)  
    926         #

    927         # Parse Define items.

    928         #

    929         for InfDefMemberObj in DefineContent:
    930             ProcessFunc = None
    931             Name = InfDefMemberObj.GetName()
    932             Value = InfDefMemberObj.GetValue()
    933             if Name == DT.TAB_INF_DEFINES_MODULE_UNI_FILE:
    934                 ValidateUNIFilePath(Value)
    935                 Value = os.path.join(os.path.dirname(InfDefMemberObj.CurrentLine.FileName), Value)
    936                 if not os.path.isfile(Value) or not os.path.exists(Value):
    937                     LineInfo[0] = InfDefMemberObj.CurrentLine.GetFileName()
    938                     LineInfo[1] = InfDefMemberObj.CurrentLine.GetLineNo()
    939                     LineInfo[2] = InfDefMemberObj.CurrentLine.GetLineString()
    940                     ErrorInInf(ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(Name),
    941                                    LineInfo=LineInfo)
    942             InfLineCommentObj = InfLineCommentObject()
    943             InfLineCommentObj.SetHeaderComments(InfDefMemberObj.Comments.GetHeaderComments())
    944             InfLineCommentObj.SetTailComments(InfDefMemberObj.Comments.GetTailComments())
    945             if Name == 'COMPONENT_TYPE':
    946                 ErrorInInf(ST.ERR_INF_PARSER_NOT_SUPPORT_EDKI_INF,
    947                            ErrorCode=ToolError.EDK1_INF_ERROR,
    948                            RaiseError=True)
    949             if Name == DT.TAB_INF_DEFINES_INF_VERSION:
    950                 HasFoundInfVersionFalg = True  
    951             if not (Name == '' or Name == None):
    952                 #

    953                 # Process "SPEC" Keyword definition.

    954                 #

    955                 ReName = re.compile(r"SPEC ", re.DOTALL)
    956                 if ReName.match(Name):
    957                     SpecValue = Name[Name.find("SPEC") + len("SPEC"):].strip()
    958                     Name = "SPEC"
    959                     Value = SpecValue + " = " + Value
    960                 if self.Defines.has_key(ArchListString):
    961                     DefineList = self.Defines[ArchListString]                 
    962                     LineInfo[0] = InfDefMemberObj.CurrentLine.GetFileName()
    963                     LineInfo[1] = InfDefMemberObj.CurrentLine.GetLineNo()
    964                     LineInfo[2] = InfDefMemberObj.CurrentLine.GetLineString()
    965                     DefineList.CurrentLine = LineInfo
    966                     #

    967                     # Found the process function from mapping table.

    968                     #

    969                     if Name not in gFUNCTION_MAPPING_FOR_DEFINE_SECTION.keys():
    970                         ErrorInInf(ST.ERR_INF_PARSER_DEFINE_SECTION_KEYWORD_INVALID%(Name),
    971                                    LineInfo=LineInfo)                           
    972                     else:
    973                         ProcessFunc = gFUNCTION_MAPPING_FOR_DEFINE_SECTION[Name]
    974                     if (ProcessFunc != None):
    975                         ProcessFunc(DefineList, Value, InfLineCommentObj)
    976                     self.Defines[ArchListString] = DefineList
    977                 else:
    978                     DefineList = InfDefSection()
    979                     LineInfo[0] = InfDefMemberObj.CurrentLine.GetFileName()
    980                     LineInfo[1] = InfDefMemberObj.CurrentLine.GetLineNo()
    981                     LineInfo[2] = InfDefMemberObj.CurrentLine.GetLineString()
    982                     DefineList.CurrentLine = LineInfo
    983                     #

    984                     # Found the process function from mapping table.

    985                     #

    986                     if Name not in gFUNCTION_MAPPING_FOR_DEFINE_SECTION.keys():
    987                         ErrorInInf(ST.ERR_INF_PARSER_DEFINE_SECTION_KEYWORD_INVALID%(Name),
    988                                    LineInfo=LineInfo)
    989                     #

    990                     # Found the process function from mapping table.

    991                     #                    

    992                     else:
    993                         ProcessFunc = gFUNCTION_MAPPING_FOR_DEFINE_SECTION[Name]
    994                     if (ProcessFunc != None):
    995                         ProcessFunc(DefineList, Value, InfLineCommentObj)
    996                     self.Defines[ArchListString] = DefineList
    997         #

    998         # After set, check whether INF_VERSION defined.

    999         #

   1000         if not HasFoundInfVersionFalg:
   1001             ErrorInInf(ST.ERR_INF_PARSER_NOT_SUPPORT_EDKI_INF,
   1002                        ErrorCode=ToolError.EDK1_INF_ERROR,
   1003                        RaiseError=True) 
   1004         return True
   1005     
   1006     def GetDefines(self):
   1007         return self.Defines                      
   1008         
   1009