1## @file 2# This file contained the parser for [Guids], [Ppis], [Protocols] sections in INF file 3# 4# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR> 5# 6# SPDX-License-Identifier: BSD-2-Clause-Patent 7# 8''' 9InfGuidPpiProtocolSectionParser 10''' 11## 12# Import Modules 13# 14 15import Logger.Log as Logger 16from Logger import StringTable as ST 17from Logger.ToolError import FORMAT_INVALID 18from Parser.InfParserMisc import InfExpandMacro 19from Library import DataType as DT 20from Library import GlobalData 21from Library.Parsing import MacroParser 22from Library.Misc import GetSplitValueList 23from Library.ParserValidate import IsValidIdString 24from Library.ParserValidate import IsValidUserId 25from Library.ParserValidate import IsValidArch 26from Parser.InfParserMisc import InfParserSectionRoot 27 28class InfGuidPpiProtocolSectionParser(InfParserSectionRoot): 29 ## InfGuidParser 30 # 31 # 32 def InfGuidParser(self, SectionString, InfSectionObject, FileName): 33 # 34 # Macro defined in this section 35 # 36 SectionMacros = {} 37 ValueList = [] 38 GuidList = [] 39 CommentsList = [] 40 CurrentLineVar = None 41 # 42 # Parse section content 43 # 44 for Line in SectionString: 45 LineContent = Line[0] 46 LineNo = Line[1] 47 48 if LineContent.strip() == '': 49 CommentsList = [] 50 continue 51 52 if LineContent.strip().startswith(DT.TAB_COMMENT_SPLIT): 53 CommentsList.append(Line) 54 continue 55 else: 56 # 57 # Encounter a GUID entry 58 # 59 if LineContent.find(DT.TAB_COMMENT_SPLIT) > -1: 60 CommentsList.append(( 61 LineContent[LineContent.find(DT.TAB_COMMENT_SPLIT):], 62 LineNo)) 63 LineContent = \ 64 LineContent[:LineContent.find(DT.TAB_COMMENT_SPLIT)] 65 66 if LineContent != '': 67 # 68 # Find Macro 69 # 70 Name, Value = MacroParser((LineContent, LineNo), 71 FileName, 72 DT.MODEL_EFI_GUID, 73 self.FileLocalMacros) 74 if Name is not None: 75 SectionMacros[Name] = Value 76 CommentsList = [] 77 ValueList = [] 78 continue 79 80 TokenList = GetSplitValueList(LineContent, DT.TAB_VALUE_SPLIT, 1) 81 ValueList[0:len(TokenList)] = TokenList 82 83 # 84 # Replace with Local section Macro and [Defines] section Macro. 85 # 86 ValueList = [InfExpandMacro(Value, (FileName, LineContent, LineNo), 87 self.FileLocalMacros, SectionMacros, True) 88 for Value in ValueList] 89 90 CurrentLineVar = (LineContent, LineNo, FileName) 91 92 93 if len(ValueList) >= 1: 94 GuidList.append((ValueList, CommentsList, CurrentLineVar)) 95 CommentsList = [] 96 ValueList = [] 97 continue 98 99 # 100 # Current section archs 101 # 102 ArchList = [] 103 LineIndex = -1 104 for Item in self.LastSectionHeaderContent: 105 LineIndex = Item[3] 106 if Item[1] not in ArchList: 107 ArchList.append(Item[1]) 108 109 if not InfSectionObject.SetGuid(GuidList, Arch=ArchList): 110 Logger.Error('InfParser', 111 FORMAT_INVALID, 112 ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[Guid]"), 113 File=FileName, 114 Line=LineIndex) 115 116 ## InfPpiParser 117 # 118 # 119 def InfPpiParser(self, SectionString, InfSectionObject, FileName): 120 # 121 # Macro defined in this section 122 # 123 SectionMacros = {} 124 ValueList = [] 125 PpiList = [] 126 CommentsList = [] 127 CurrentLineVar = None 128 # 129 # Parse section content 130 # 131 for Line in SectionString: 132 LineContent = Line[0] 133 LineNo = Line[1] 134 135 if LineContent.strip() == '': 136 CommentsList = [] 137 continue 138 139 if LineContent.strip().startswith(DT.TAB_COMMENT_SPLIT): 140 CommentsList.append(Line) 141 continue 142 else: 143 # 144 # Encounter a PPI entry 145 # 146 if LineContent.find(DT.TAB_COMMENT_SPLIT) > -1: 147 CommentsList.append(( 148 LineContent[LineContent.find(DT.TAB_COMMENT_SPLIT):], 149 LineNo)) 150 LineContent = \ 151 LineContent[:LineContent.find(DT.TAB_COMMENT_SPLIT)] 152 153 if LineContent != '': 154 # 155 # Find Macro 156 # 157 Name, Value = MacroParser((LineContent, LineNo), 158 FileName, 159 DT.MODEL_EFI_PPI, 160 self.FileLocalMacros) 161 if Name is not None: 162 SectionMacros[Name] = Value 163 ValueList = [] 164 CommentsList = [] 165 continue 166 167 TokenList = GetSplitValueList(LineContent, DT.TAB_VALUE_SPLIT, 1) 168 ValueList[0:len(TokenList)] = TokenList 169 170 # 171 # Replace with Local section Macro and [Defines] section Macro. 172 # 173 ValueList = [InfExpandMacro(Value, (FileName, LineContent, LineNo), self.FileLocalMacros, SectionMacros) 174 for Value in ValueList] 175 176 CurrentLineVar = (LineContent, LineNo, FileName) 177 178 if len(ValueList) >= 1: 179 PpiList.append((ValueList, CommentsList, CurrentLineVar)) 180 ValueList = [] 181 CommentsList = [] 182 continue 183 184 # 185 # Current section archs 186 # 187 ArchList = [] 188 LineIndex = -1 189 for Item in self.LastSectionHeaderContent: 190 LineIndex = Item[3] 191 if Item[1] not in ArchList: 192 ArchList.append(Item[1]) 193 194 if not InfSectionObject.SetPpi(PpiList, Arch=ArchList): 195 Logger.Error('InfParser', 196 FORMAT_INVALID, 197 ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[Ppis]"), 198 File=FileName, 199 Line=LineIndex) 200 201 ## InfUserExtensionParser 202 # 203 # 204 def InfUserExtensionParser(self, SectionString, InfSectionObject, FileName): 205 206 UserExtensionContent = '' 207 208 # 209 # Parse section content 210 # 211 for Line in SectionString: 212 LineContent = Line[0] 213 214# Comment the code to support user extension without any statement just the section header in [] 215# if LineContent.strip() == '': 216# continue 217 218 UserExtensionContent += LineContent + DT.END_OF_LINE 219 continue 220 221 # 222 # Current section UserId, IdString 223 # 224 IdContentList = [] 225 LastItem = '' 226 SectionLineNo = None 227 for Item in self.LastSectionHeaderContent: 228 UserId = Item[1] 229 IdString = Item[2] 230 Arch = Item[3] 231 SectionLineNo = Item[4] 232 if not IsValidArch(Arch): 233 Logger.Error( 234 'InfParser', 235 FORMAT_INVALID, 236 ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID % (Arch), 237 File=GlobalData.gINF_MODULE_NAME, 238 Line=SectionLineNo, 239 ExtraData=None) 240 241 if (UserId, IdString, Arch) not in IdContentList: 242 # 243 # To check the UserId and IdString valid or not. 244 # 245 if not IsValidUserId(UserId): 246 Logger.Error('InfParser', 247 FORMAT_INVALID, 248 ST.ERR_INF_PARSER_UE_SECTION_USER_ID_ERROR % (Item[1]), 249 File=GlobalData.gINF_MODULE_NAME, 250 Line=SectionLineNo, 251 ExtraData=None) 252 253 if not IsValidIdString(IdString): 254 Logger.Error('InfParser', 255 FORMAT_INVALID, 256 ST.ERR_INF_PARSER_UE_SECTION_ID_STRING_ERROR % (IdString), 257 File=GlobalData.gINF_MODULE_NAME, Line=SectionLineNo, 258 ExtraData=None) 259 IdContentList.append((UserId, IdString, Arch)) 260 else: 261 # 262 # Each UserExtensions section header must have a unique set 263 # of UserId, IdString and Arch values. 264 # This means that the same UserId can be used in more than one 265 # section header, provided the IdString or Arch values are 266 # different. The same IdString values can be used in more than 267 # one section header if the UserId or Arch values are 268 # different. The same UserId and the same IdString can be used 269 # in a section header if the Arch values are different in each 270 # of the section headers. 271 # 272 Logger.Error('InfParser', 273 FORMAT_INVALID, 274 ST.ERR_INF_PARSER_UE_SECTION_DUPLICATE_ERROR % ( 275 IdString), 276 File=GlobalData.gINF_MODULE_NAME, 277 Line=SectionLineNo, 278 ExtraData=None) 279 LastItem = Item 280 281 if not InfSectionObject.SetUserExtension(UserExtensionContent, 282 IdContent=IdContentList, 283 LineNo=SectionLineNo): 284 Logger.Error\ 285 ('InfParser', FORMAT_INVALID, \ 286 ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[UserExtension]"), \ 287 File=FileName, Line=LastItem[4]) 288 289 def InfProtocolParser(self, SectionString, InfSectionObject, FileName): 290 # 291 # Macro defined in this section 292 # 293 SectionMacros = {} 294 ValueList = [] 295 ProtocolList = [] 296 CommentsList = [] 297 CurrentLineVar = None 298 # 299 # Parse section content 300 # 301 for Line in SectionString: 302 LineContent = Line[0] 303 LineNo = Line[1] 304 305 if LineContent.strip() == '': 306 CommentsList = [] 307 continue 308 309 if LineContent.strip().startswith(DT.TAB_COMMENT_SPLIT): 310 CommentsList.append(Line) 311 continue 312 else: 313 # 314 # Encounter a Protocol entry 315 # 316 if LineContent.find(DT.TAB_COMMENT_SPLIT) > -1: 317 CommentsList.append(( 318 LineContent[LineContent.find(DT.TAB_COMMENT_SPLIT):], 319 LineNo)) 320 LineContent = \ 321 LineContent[:LineContent.find(DT.TAB_COMMENT_SPLIT)] 322 323 if LineContent != '': 324 # 325 # Find Macro 326 # 327 Name, Value = MacroParser((LineContent, LineNo), 328 FileName, 329 DT.MODEL_EFI_PROTOCOL, 330 self.FileLocalMacros) 331 if Name is not None: 332 SectionMacros[Name] = Value 333 ValueList = [] 334 CommentsList = [] 335 continue 336 337 TokenList = GetSplitValueList(LineContent, DT.TAB_VALUE_SPLIT, 1) 338 ValueList[0:len(TokenList)] = TokenList 339 340 # 341 # Replace with Local section Macro and [Defines] section Macro. 342 # 343 ValueList = [InfExpandMacro(Value, (FileName, LineContent, LineNo), self.FileLocalMacros, SectionMacros) 344 for Value in ValueList] 345 346 CurrentLineVar = (LineContent, LineNo, FileName) 347 348 if len(ValueList) >= 1: 349 ProtocolList.append((ValueList, CommentsList, CurrentLineVar)) 350 ValueList = [] 351 CommentsList = [] 352 continue 353 354 # 355 # Current section archs 356 # 357 ArchList = [] 358 LineIndex = -1 359 for Item in self.LastSectionHeaderContent: 360 LineIndex = Item[3] 361 if Item[1] not in ArchList: 362 ArchList.append(Item[1]) 363 364 if not InfSectionObject.SetProtocol(ProtocolList, Arch=ArchList): 365 Logger.Error\ 366 ('InfParser', FORMAT_INVALID, \ 367 ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[Protocol]"), \ 368 File=FileName, Line=LineIndex) 369