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

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

      3 # It will consumed by InfParser. 

      4 #

      5 # Copyright (c) 2011, 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 InfPpiObject
     17 '''
     18 
     19 from Library.ParserValidate import IsValidCVariableName
     20 from Library.CommentParsing import ParseComment
     21 from Library.ExpressionValidate import IsValidFeatureFlagExp 
     22                                
     23 from Library.Misc import Sdict
     24 from Library import DataType as DT                
     25 import Logger.Log as Logger
     26 from Logger import ToolError
     27 from Logger import StringTable as ST
     28 
     29 def ParsePpiComment(CommentsList, InfPpiItemObj):
     30     PreNotify = None
     31     PreUsage = None              
     32     PreHelpText = ''
     33     BlockFlag = -1
     34     CommentInsList = []
     35     Count = 0
     36     for CommentItem in CommentsList:
     37         Count = Count + 1
     38         CommentItemUsage, \
     39         CommentItemNotify, \
     40         CommentItemString, \
     41         CommentItemHelpText = \
     42                 ParseComment(CommentItem, 
     43                              DT.ALL_USAGE_TOKENS, 
     44                              DT.PPI_NOTIFY_TOKENS, 
     45                              ['PPI'], 
     46                              False)
     47         
     48         #

     49         # To avoid PyLint error   

     50         #

     51         if CommentItemString:
     52             pass
     53         
     54         if CommentItemHelpText == None:
     55             CommentItemHelpText = ''
     56             if Count == len(CommentsList) and CommentItemUsage == CommentItemNotify == DT.ITEM_UNDEFINED:
     57                 CommentItemHelpText = DT.END_OF_LINE                    
     58         #

     59         # For the Last comment Item, set BlockFlag.

     60         #

     61         if Count == len(CommentsList):
     62             if BlockFlag == 1 or BlockFlag == 2:
     63                 if CommentItemUsage == CommentItemNotify == DT.ITEM_UNDEFINED:
     64                     BlockFlag = 4
     65                 else:
     66                     BlockFlag = 3
     67             elif BlockFlag == -1:
     68                 BlockFlag = 4  
     69         
     70         #

     71         # Comment USAGE and NOTIFY information are "UNDEFINED"

     72         #

     73         if BlockFlag == -1 or BlockFlag == 1 or BlockFlag == 2:                                             
     74             if CommentItemUsage == CommentItemNotify == DT.ITEM_UNDEFINED:
     75                 if BlockFlag == -1:
     76                     BlockFlag = 1
     77                 elif BlockFlag == 1:
     78                     BlockFlag = 2
     79             else:
     80                 if BlockFlag == 1 or BlockFlag == 2:
     81                     BlockFlag = 3
     82                 #

     83                 # An item have Usage or Notify information and the first time get this information

     84                 # 

     85                 elif BlockFlag == -1:
     86                     BlockFlag = 4
     87                                                                           
     88         #

     89         # Combine two comment line if they are generic comment

     90         #   

     91         if CommentItemUsage == CommentItemNotify == PreUsage == PreNotify == DT.ITEM_UNDEFINED:
     92             CommentItemHelpText = PreHelpText + DT.END_OF_LINE + CommentItemHelpText
     93             #

     94             # Store this information for next line may still need  combine operation.

     95             #

     96             PreHelpText = CommentItemHelpText
     97             
     98         if BlockFlag == 4:     
     99             CommentItemIns = InfPpiItemCommentContent()
    100             CommentItemIns.SetUsage(CommentItemUsage)
    101             CommentItemIns.SetNotify(CommentItemNotify)
    102             CommentItemIns.SetHelpStringItem(CommentItemHelpText)
    103             CommentInsList.append(CommentItemIns)
    104             
    105             BlockFlag = -1
    106             PreUsage = None
    107             PreNotify = None
    108             PreHelpText = ''
    109             
    110         elif BlockFlag == 3:
    111             #

    112             # Add previous help string

    113             # 

    114             CommentItemIns = InfPpiItemCommentContent()
    115             CommentItemIns.SetUsage(DT.ITEM_UNDEFINED)
    116             CommentItemIns.SetNotify(DT.ITEM_UNDEFINED)
    117             if PreHelpText == '' or PreHelpText.endswith(DT.END_OF_LINE):
    118                 PreHelpText += DT.END_OF_LINE            
    119             CommentItemIns.SetHelpStringItem(PreHelpText)
    120             CommentInsList.append(CommentItemIns)
    121             #

    122             # Add Current help string

    123             #

    124             CommentItemIns = InfPpiItemCommentContent()
    125             CommentItemIns.SetUsage(CommentItemUsage)
    126             CommentItemIns.SetNotify(CommentItemNotify)
    127             CommentItemIns.SetHelpStringItem(CommentItemHelpText)
    128             CommentInsList.append(CommentItemIns)
    129             
    130             BlockFlag = -1
    131             PreUsage = None
    132             PreNotify = None
    133             PreHelpText = ''
    134         else:
    135             PreUsage = CommentItemUsage
    136             PreNotify = CommentItemNotify
    137             PreHelpText = CommentItemHelpText
    138             
    139     InfPpiItemObj.SetCommentList(CommentInsList)
    140     
    141     return InfPpiItemObj
    142 
    143 class InfPpiItemCommentContent():
    144     def __init__(self):
    145         #

    146         # ## SOMETIMES_CONSUMES ## HelpString 

    147         #

    148         self.UsageItem = ''
    149         #

    150         # Help String

    151         #

    152         self.HelpStringItem = ''
    153         self.Notify = ''
    154         self.CommentList = []
    155                 
    156     def SetUsage(self, UsageItem):
    157         self.UsageItem = UsageItem
    158     def GetUsage(self):
    159         return self.UsageItem
    160     
    161     def SetNotify(self, Notify):
    162         if Notify != DT.ITEM_UNDEFINED:
    163             self.Notify = 'true'
    164     def GetNotify(self):
    165         return self.Notify
    166           
    167     def SetHelpStringItem(self, HelpStringItem):
    168         self.HelpStringItem = HelpStringItem
    169     def GetHelpStringItem(self):
    170         return self.HelpStringItem
    171     
    172 class InfPpiItem():
    173     def __init__(self):
    174         self.Name             = ''
    175         self.FeatureFlagExp   = ''    
    176         self.SupArchList      = []
    177         self.CommentList      = []
    178         
    179     def SetName(self, Name):
    180         self.Name = Name
    181     def GetName(self):
    182         return self.Name
    183 
    184     def SetSupArchList(self, SupArchList):
    185         self.SupArchList = SupArchList
    186     def GetSupArchList(self):
    187         return self.SupArchList        
    188 
    189     def SetCommentList(self, CommentList):
    190         self.CommentList = CommentList
    191     def GetCommentList(self):
    192         return self.CommentList
    193 
    194     def SetFeatureFlagExp(self, FeatureFlagExp):
    195         self.FeatureFlagExp = FeatureFlagExp
    196     def GetFeatureFlagExp(self):
    197         return self.FeatureFlagExp
    198 ##

    199 #

    200 #

    201 #

    202 class InfPpiObject():
    203     def __init__(self):
    204         self.Ppis = Sdict()
    205         #

    206         # Macro defined in this section should be only used in this section.

    207         #

    208         self.Macros = {}
    209     
    210     def SetPpi(self, PpiList, Arch = None):
    211         __SupArchList = []
    212         for ArchItem in Arch:
    213             #

    214             # Validate Arch

    215             #            

    216             if (ArchItem == '' or ArchItem == None):
    217                 ArchItem = 'COMMON'   
    218             __SupArchList.append(ArchItem)
    219             
    220         for Item in PpiList:
    221             #

    222             # Get Comment content of this protocol

    223             #

    224             CommentsList = None
    225             if len(Item) == 3:
    226                 CommentsList = Item[1]
    227             CurrentLineOfItem = Item[2]
    228             Item = Item[0]
    229             InfPpiItemObj = InfPpiItem()                  
    230             if len(Item) >= 1 and len(Item) <= 2:
    231                 #

    232                 # Only CName contained

    233                 #

    234                 if not IsValidCVariableName(Item[0]):
    235                     Logger.Error("InfParser", 
    236                                  ToolError.FORMAT_INVALID, 
    237                                  ST.ERR_INF_PARSER_INVALID_CNAME%(Item[0]),
    238                                  File=CurrentLineOfItem[2], 
    239                                  Line=CurrentLineOfItem[1], 
    240                                  ExtraData=CurrentLineOfItem[0])
    241                 if (Item[0] != ''):
    242                     InfPpiItemObj.SetName(Item[0])
    243                 else:
    244                     Logger.Error("InfParser", 
    245                                  ToolError.FORMAT_INVALID, 
    246                                  ST.ERR_INF_PARSER_CNAME_MISSING,
    247                                  File=CurrentLineOfItem[2], 
    248                                  Line=CurrentLineOfItem[1], 
    249                                  ExtraData=CurrentLineOfItem[0])
    250             #

    251             # Have FeatureFlag information

    252             #

    253             if len(Item) == 2:
    254                 #

    255                 # Contained CName and Feature Flag Express

    256                 # <statements>           ::=  <CName> ["|" <FeatureFlagExpress>]

    257                 # Item[1] should not be empty  

    258                 #

    259                 if Item[1].strip() == '':
    260                     Logger.Error("InfParser", 
    261                                  ToolError.FORMAT_INVALID, 
    262                                  ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,
    263                                  File=CurrentLineOfItem[2], 
    264                                  Line=CurrentLineOfItem[1], 
    265                                  ExtraData=CurrentLineOfItem[0])
    266                 #

    267                 # Validate Feature Flag Express for PPI entry

    268                 # Item[1] contain FFE information

    269                 #

    270                 FeatureFlagRtv = IsValidFeatureFlagExp(Item[1].strip())
    271                 if not FeatureFlagRtv[0]:
    272                     Logger.Error("InfParser", 
    273                                  ToolError.FORMAT_INVALID,
    274                                  ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]),
    275                                  File=CurrentLineOfItem[2], 
    276                                  Line=CurrentLineOfItem[1], 
    277                                  ExtraData=CurrentLineOfItem[0])
    278                 InfPpiItemObj.SetFeatureFlagExp(Item[1])
    279             if len(Item) != 1 and len(Item) != 2:
    280                 #

    281                 # Invalid format of Ppi statement 

    282                 #

    283                 Logger.Error("InfParser", 
    284                              ToolError.FORMAT_INVALID,
    285                              ST.ERR_INF_PARSER_GUID_PPI_PROTOCOL_SECTION_CONTENT_ERROR,
    286                              File=CurrentLineOfItem[2], 
    287                              Line=CurrentLineOfItem[1], 
    288                              ExtraData=CurrentLineOfItem[0])
    289             
    290             #

    291             # Get/Set Usage and HelpString for PPI entry

    292             #

    293             if CommentsList != None and len(CommentsList) != 0:
    294                 InfPpiItemObj = ParsePpiComment(CommentsList, InfPpiItemObj)
    295             else:
    296                 CommentItemIns = InfPpiItemCommentContent()
    297                 CommentItemIns.SetUsage(DT.ITEM_UNDEFINED)
    298                 CommentItemIns.SetNotify(DT.ITEM_UNDEFINED)
    299                 InfPpiItemObj.SetCommentList([CommentItemIns])
    300             
    301             InfPpiItemObj.SetSupArchList(__SupArchList)
    302 
    303             #

    304             # Determine PPI name duplicate. Follow below rule:

    305             #

    306             # A PPI must not be duplicated within a [Ppis] section. 

    307             # A PPI may appear in multiple architectural [Ppis] 

    308             # sections. A PPI listed in an architectural [Ppis] 

    309             # section must not be listed in the common architectural 

    310             # [Ppis] section.

    311             # 

    312             # NOTE: This check will not report error now.

    313             # 

    314             for Item in self.Ppis:
    315                 if Item.GetName() == InfPpiItemObj.GetName():
    316                     ItemSupArchList = Item.GetSupArchList()
    317                     for ItemArch in ItemSupArchList:
    318                         for PpiItemObjArch in __SupArchList:
    319                             if ItemArch == PpiItemObjArch:
    320                                 #

    321                                 # ST.ERR_INF_PARSER_ITEM_DUPLICATE

    322                                 #

    323                                 pass
    324                             if ItemArch.upper() == 'COMMON' or PpiItemObjArch.upper() == 'COMMON':
    325                                 #

    326                                 # ST.ERR_INF_PARSER_ITEM_DUPLICATE_COMMON

    327                                 # 

    328                                 pass
    329             
    330             if self.Ppis.has_key((InfPpiItemObj)):           
    331                 PpiList = self.Ppis[InfPpiItemObj]
    332                 PpiList.append(InfPpiItemObj)
    333                 self.Ppis[InfPpiItemObj] = PpiList
    334             else:
    335                 PpiList = []
    336                 PpiList.append(InfPpiItemObj)
    337                 self.Ppis[InfPpiItemObj] = PpiList
    338                 
    339         return True        
    340         
    341     
    342     def GetPpi(self):
    343         return self.Ppis