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''' 16InfPpiObject 17''' 18 19from Library.ParserValidate import IsValidCVariableName 20from Library.CommentParsing import ParseComment 21from Library.ExpressionValidate import IsValidFeatureFlagExp 22 23from Library.Misc import Sdict 24from Library import DataType as DT 25import Logger.Log as Logger 26from Logger import ToolError 27from Logger import StringTable as ST 28 29def 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 143class 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 172class 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# 202class 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