1## @file 2# This file is used to define class objects of INF file [Protocols] 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''' 16InfProtocolObject 17''' 18 19from Library.ParserValidate import IsValidCVariableName 20from Library.CommentParsing import ParseComment 21from Library.ExpressionValidate import IsValidFeatureFlagExp 22 23from Library.Misc import Sdict 24 25from Object.Parser.InfMisc import ErrorInInf 26 27from Library import DataType as DT 28from Logger import StringTable as ST 29 30def ParseProtocolComment(CommentsList, InfProtocolItemObj): 31 CommentInsList = [] 32 PreUsage = None 33 PreNotify = None 34 PreHelpText = '' 35 BlockFlag = -1 36 Count = 0 37 for CommentItem in CommentsList: 38 Count = Count + 1 39 CommentItemUsage, \ 40 CommentItemNotify, \ 41 CommentItemString, \ 42 CommentItemHelpText = \ 43 ParseComment(CommentItem, 44 DT.PROTOCOL_USAGE_TOKENS, 45 DT.PROTOCOL_NOTIFY_TOKENS, 46 ['PROTOCOL'], 47 False) 48 49 if CommentItemString: 50 pass 51 52 if CommentItemHelpText == None: 53 CommentItemHelpText = '' 54 if Count == len(CommentsList) and CommentItemUsage == CommentItemNotify == DT.ITEM_UNDEFINED: 55 CommentItemHelpText = DT.END_OF_LINE 56 57 if Count == len(CommentsList): 58 if BlockFlag == 1 or BlockFlag == 2: 59 if CommentItemUsage == CommentItemNotify == DT.ITEM_UNDEFINED: 60 BlockFlag = 4 61 else: 62 BlockFlag = 3 63 elif BlockFlag == -1: 64 BlockFlag = 4 65 66 if BlockFlag == -1 or BlockFlag == 1 or BlockFlag == 2: 67 if CommentItemUsage == CommentItemNotify == DT.ITEM_UNDEFINED: 68 if BlockFlag == -1: 69 BlockFlag = 1 70 elif BlockFlag == 1: 71 BlockFlag = 2 72 else: 73 if BlockFlag == 1 or BlockFlag == 2: 74 BlockFlag = 3 75 elif BlockFlag == -1: 76 BlockFlag = 4 77 78 # 79 # Combine two comment line if they are generic comment 80 # 81 if CommentItemUsage == CommentItemNotify == PreUsage == PreNotify == DT.ITEM_UNDEFINED: 82 CommentItemHelpText = PreHelpText + DT.END_OF_LINE + CommentItemHelpText 83 84 PreHelpText = CommentItemHelpText 85 86 if BlockFlag == 4: 87 CommentItemIns = InfProtocolItemCommentContent() 88 CommentItemIns.SetUsageItem(CommentItemUsage) 89 CommentItemIns.SetNotify(CommentItemNotify) 90 CommentItemIns.SetHelpStringItem(CommentItemHelpText) 91 CommentInsList.append(CommentItemIns) 92 93 BlockFlag = -1 94 PreUsage = None 95 PreNotify = None 96 PreHelpText = '' 97 98 elif BlockFlag == 3: 99 # 100 # Add previous help string 101 # 102 CommentItemIns = InfProtocolItemCommentContent() 103 CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED) 104 CommentItemIns.SetNotify(DT.ITEM_UNDEFINED) 105 if PreHelpText == '' or PreHelpText.endswith(DT.END_OF_LINE): 106 PreHelpText += DT.END_OF_LINE 107 CommentItemIns.SetHelpStringItem(PreHelpText) 108 CommentInsList.append(CommentItemIns) 109 # 110 # Add Current help string 111 # 112 CommentItemIns = InfProtocolItemCommentContent() 113 CommentItemIns.SetUsageItem(CommentItemUsage) 114 CommentItemIns.SetNotify(CommentItemNotify) 115 CommentItemIns.SetHelpStringItem(CommentItemHelpText) 116 CommentInsList.append(CommentItemIns) 117 118 BlockFlag = -1 119 PreUsage = None 120 PreNotify = None 121 PreHelpText = '' 122 123 else: 124 PreUsage = CommentItemUsage 125 PreNotify = CommentItemNotify 126 PreHelpText = CommentItemHelpText 127 128 InfProtocolItemObj.SetCommentList(CommentInsList) 129 130 return InfProtocolItemObj 131 132class InfProtocolItemCommentContent(): 133 def __init__(self): 134 # 135 # ## SOMETIMES_CONSUMES ## HelpString 136 # 137 self.UsageItem = '' 138 # 139 # Help String 140 # 141 self.HelpStringItem = '' 142 self.Notify = '' 143 self.CommentList = [] 144 145 def SetUsageItem(self, UsageItem): 146 self.UsageItem = UsageItem 147 def GetUsageItem(self): 148 return self.UsageItem 149 150 def SetNotify(self, Notify): 151 if Notify != DT.ITEM_UNDEFINED: 152 self.Notify = 'true' 153 def GetNotify(self): 154 return self.Notify 155 156 def SetHelpStringItem(self, HelpStringItem): 157 self.HelpStringItem = HelpStringItem 158 def GetHelpStringItem(self): 159 return self.HelpStringItem 160 161class InfProtocolItem(): 162 def __init__(self): 163 self.Name = '' 164 self.FeatureFlagExp = '' 165 self.SupArchList = [] 166 self.CommentList = [] 167 168 def SetName(self, Name): 169 self.Name = Name 170 def GetName(self): 171 return self.Name 172 173 def SetFeatureFlagExp(self, FeatureFlagExp): 174 self.FeatureFlagExp = FeatureFlagExp 175 def GetFeatureFlagExp(self): 176 return self.FeatureFlagExp 177 178 def SetSupArchList(self, SupArchList): 179 self.SupArchList = SupArchList 180 def GetSupArchList(self): 181 return self.SupArchList 182 183 def SetCommentList(self, CommentList): 184 self.CommentList = CommentList 185 def GetCommentList(self): 186 return self.CommentList 187 188## 189# 190# 191# 192class InfProtocolObject(): 193 def __init__(self): 194 self.Protocols = Sdict() 195 # 196 # Macro defined in this section should be only used in this section. 197 # 198 self.Macros = {} 199 200 def SetProtocol(self, ProtocolContent, Arch = None,): 201 __SupArchList = [] 202 for ArchItem in Arch: 203 # 204 # Validate Arch 205 # 206 if (ArchItem == '' or ArchItem == None): 207 ArchItem = 'COMMON' 208 __SupArchList.append(ArchItem) 209 210 for Item in ProtocolContent: 211 # 212 # Get Comment content of this protocol 213 # 214 CommentsList = None 215 if len(Item) == 3: 216 CommentsList = Item[1] 217 CurrentLineOfItem = Item[2] 218 LineInfo = (CurrentLineOfItem[2], CurrentLineOfItem[1], CurrentLineOfItem[0]) 219 Item = Item[0] 220 InfProtocolItemObj = InfProtocolItem() 221 if len(Item) >= 1 and len(Item) <= 2: 222 # 223 # Only CName contained 224 # 225 if not IsValidCVariableName(Item[0]): 226 ErrorInInf(ST.ERR_INF_PARSER_INVALID_CNAME%(Item[0]), 227 LineInfo=LineInfo) 228 if (Item[0] != ''): 229 InfProtocolItemObj.SetName(Item[0]) 230 else: 231 ErrorInInf(ST.ERR_INF_PARSER_CNAME_MISSING, 232 LineInfo=LineInfo) 233 if len(Item) == 2: 234 # 235 # Contained CName and Feature Flag Express 236 # <statements> ::= <CName> ["|" 237 # <FeatureFlagExpress>] 238 # For Protocol Object 239 # 240 if Item[1].strip() == '': 241 ErrorInInf(ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING, 242 LineInfo=LineInfo) 243 # 244 # Validate Feature Flag Express for Item[1] 245 # 246 FeatureFlagRtv = IsValidFeatureFlagExp(Item[1].strip()) 247 if not FeatureFlagRtv[0]: 248 ErrorInInf(ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]), 249 LineInfo=LineInfo) 250 InfProtocolItemObj.SetFeatureFlagExp(Item[1]) 251 252 if len(Item) < 1 or len(Item) > 2: 253 # 254 # Invalid format of Protocols statement 255 # 256 ErrorInInf(ST.ERR_INF_PARSER_GUID_PPI_PROTOCOL_SECTION_CONTENT_ERROR, 257 LineInfo=LineInfo) 258 259 # 260 # Get/Set Usage and HelpString for Protocol entry 261 # 262 if CommentsList != None and len(CommentsList) != 0: 263 InfProtocolItemObj = ParseProtocolComment(CommentsList, InfProtocolItemObj) 264 else: 265 CommentItemIns = InfProtocolItemCommentContent() 266 CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED) 267 CommentItemIns.SetNotify(DT.ITEM_UNDEFINED) 268 InfProtocolItemObj.SetCommentList([CommentItemIns]) 269 270 InfProtocolItemObj.SetSupArchList(__SupArchList) 271 272 # 273 # Determine protocol name duplicate. Follow below rule: 274 # 275 # A protocol must not be duplicated within a [Protocols] section. 276 # A protocol may appear in multiple architectural [Protocols] 277 # sections. A protocol listed in an architectural [Protocols] 278 # section must not be listed in the common architectural 279 # [Protocols] section. 280 # 281 # NOTE: This check will not report error now. 282 # 283 for Item in self.Protocols: 284 if Item.GetName() == InfProtocolItemObj.GetName(): 285 ItemSupArchList = Item.GetSupArchList() 286 for ItemArch in ItemSupArchList: 287 for ProtocolItemObjArch in __SupArchList: 288 if ItemArch == ProtocolItemObjArch: 289 # 290 # ST.ERR_INF_PARSER_ITEM_DUPLICATE 291 # 292 pass 293 if ItemArch.upper() == 'COMMON' or ProtocolItemObjArch.upper() == 'COMMON': 294 # 295 # ST.ERR_INF_PARSER_ITEM_DUPLICATE_COMMON 296 # 297 pass 298 299 if self.Protocols.has_key((InfProtocolItemObj)): 300 ProcotolList = self.Protocols[InfProtocolItemObj] 301 ProcotolList.append(InfProtocolItemObj) 302 self.Protocols[InfProtocolItemObj] = ProcotolList 303 else: 304 ProcotolList = [] 305 ProcotolList.append(InfProtocolItemObj) 306 self.Protocols[InfProtocolItemObj] = ProcotolList 307 308 return True 309 310 def GetProtocol(self): 311 return self.Protocols 312