CloverBootloader/BaseTools/Source/Python/UPT/Parser/InfGuidPpiProtocolSectionParser.py
2019-09-03 12:58:42 +03:00

369 lines
13 KiB
Python

## @file
# This file contained the parser for [Guids], [Ppis], [Protocols] sections in INF file
#
# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
'''
InfGuidPpiProtocolSectionParser
'''
##
# Import Modules
#
import Logger.Log as Logger
from Logger import StringTable as ST
from Logger.ToolError import FORMAT_INVALID
from Parser.InfParserMisc import InfExpandMacro
from Library import DataType as DT
from Library import GlobalData
from Library.Parsing import MacroParser
from Library.Misc import GetSplitValueList
from Library.ParserValidate import IsValidIdString
from Library.ParserValidate import IsValidUserId
from Library.ParserValidate import IsValidArch
from Parser.InfParserMisc import InfParserSectionRoot
class InfGuidPpiProtocolSectionParser(InfParserSectionRoot):
## InfGuidParser
#
#
def InfGuidParser(self, SectionString, InfSectionObject, FileName):
#
# Macro defined in this section
#
SectionMacros = {}
ValueList = []
GuidList = []
CommentsList = []
CurrentLineVar = None
#
# Parse section content
#
for Line in SectionString:
LineContent = Line[0]
LineNo = Line[1]
if LineContent.strip() == '':
CommentsList = []
continue
if LineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
CommentsList.append(Line)
continue
else:
#
# Encounter a GUID entry
#
if LineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
CommentsList.append((
LineContent[LineContent.find(DT.TAB_COMMENT_SPLIT):],
LineNo))
LineContent = \
LineContent[:LineContent.find(DT.TAB_COMMENT_SPLIT)]
if LineContent != '':
#
# Find Macro
#
Name, Value = MacroParser((LineContent, LineNo),
FileName,
DT.MODEL_EFI_GUID,
self.FileLocalMacros)
if Name is not None:
SectionMacros[Name] = Value
CommentsList = []
ValueList = []
continue
TokenList = GetSplitValueList(LineContent, DT.TAB_VALUE_SPLIT, 1)
ValueList[0:len(TokenList)] = TokenList
#
# Replace with Local section Macro and [Defines] section Macro.
#
ValueList = [InfExpandMacro(Value, (FileName, LineContent, LineNo),
self.FileLocalMacros, SectionMacros, True)
for Value in ValueList]
CurrentLineVar = (LineContent, LineNo, FileName)
if len(ValueList) >= 1:
GuidList.append((ValueList, CommentsList, CurrentLineVar))
CommentsList = []
ValueList = []
continue
#
# Current section archs
#
ArchList = []
LineIndex = -1
for Item in self.LastSectionHeaderContent:
LineIndex = Item[3]
if Item[1] not in ArchList:
ArchList.append(Item[1])
if not InfSectionObject.SetGuid(GuidList, Arch=ArchList):
Logger.Error('InfParser',
FORMAT_INVALID,
ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[Guid]"),
File=FileName,
Line=LineIndex)
## InfPpiParser
#
#
def InfPpiParser(self, SectionString, InfSectionObject, FileName):
#
# Macro defined in this section
#
SectionMacros = {}
ValueList = []
PpiList = []
CommentsList = []
CurrentLineVar = None
#
# Parse section content
#
for Line in SectionString:
LineContent = Line[0]
LineNo = Line[1]
if LineContent.strip() == '':
CommentsList = []
continue
if LineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
CommentsList.append(Line)
continue
else:
#
# Encounter a PPI entry
#
if LineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
CommentsList.append((
LineContent[LineContent.find(DT.TAB_COMMENT_SPLIT):],
LineNo))
LineContent = \
LineContent[:LineContent.find(DT.TAB_COMMENT_SPLIT)]
if LineContent != '':
#
# Find Macro
#
Name, Value = MacroParser((LineContent, LineNo),
FileName,
DT.MODEL_EFI_PPI,
self.FileLocalMacros)
if Name is not None:
SectionMacros[Name] = Value
ValueList = []
CommentsList = []
continue
TokenList = GetSplitValueList(LineContent, DT.TAB_VALUE_SPLIT, 1)
ValueList[0:len(TokenList)] = TokenList
#
# Replace with Local section Macro and [Defines] section Macro.
#
ValueList = [InfExpandMacro(Value, (FileName, LineContent, LineNo), self.FileLocalMacros, SectionMacros)
for Value in ValueList]
CurrentLineVar = (LineContent, LineNo, FileName)
if len(ValueList) >= 1:
PpiList.append((ValueList, CommentsList, CurrentLineVar))
ValueList = []
CommentsList = []
continue
#
# Current section archs
#
ArchList = []
LineIndex = -1
for Item in self.LastSectionHeaderContent:
LineIndex = Item[3]
if Item[1] not in ArchList:
ArchList.append(Item[1])
if not InfSectionObject.SetPpi(PpiList, Arch=ArchList):
Logger.Error('InfParser',
FORMAT_INVALID,
ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[Ppis]"),
File=FileName,
Line=LineIndex)
## InfUserExtensionParser
#
#
def InfUserExtensionParser(self, SectionString, InfSectionObject, FileName):
UserExtensionContent = ''
#
# Parse section content
#
for Line in SectionString:
LineContent = Line[0]
# Comment the code to support user extension without any statement just the section header in []
# if LineContent.strip() == '':
# continue
UserExtensionContent += LineContent + DT.END_OF_LINE
continue
#
# Current section UserId, IdString
#
IdContentList = []
LastItem = ''
SectionLineNo = None
for Item in self.LastSectionHeaderContent:
UserId = Item[1]
IdString = Item[2]
Arch = Item[3]
SectionLineNo = Item[4]
if not IsValidArch(Arch):
Logger.Error(
'InfParser',
FORMAT_INVALID,
ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID % (Arch),
File=GlobalData.gINF_MODULE_NAME,
Line=SectionLineNo,
ExtraData=None)
if (UserId, IdString, Arch) not in IdContentList:
#
# To check the UserId and IdString valid or not.
#
if not IsValidUserId(UserId):
Logger.Error('InfParser',
FORMAT_INVALID,
ST.ERR_INF_PARSER_UE_SECTION_USER_ID_ERROR % (Item[1]),
File=GlobalData.gINF_MODULE_NAME,
Line=SectionLineNo,
ExtraData=None)
if not IsValidIdString(IdString):
Logger.Error('InfParser',
FORMAT_INVALID,
ST.ERR_INF_PARSER_UE_SECTION_ID_STRING_ERROR % (IdString),
File=GlobalData.gINF_MODULE_NAME, Line=SectionLineNo,
ExtraData=None)
IdContentList.append((UserId, IdString, Arch))
else:
#
# Each UserExtensions section header must have a unique set
# of UserId, IdString and Arch values.
# This means that the same UserId can be used in more than one
# section header, provided the IdString or Arch values are
# different. The same IdString values can be used in more than
# one section header if the UserId or Arch values are
# different. The same UserId and the same IdString can be used
# in a section header if the Arch values are different in each
# of the section headers.
#
Logger.Error('InfParser',
FORMAT_INVALID,
ST.ERR_INF_PARSER_UE_SECTION_DUPLICATE_ERROR % (
IdString),
File=GlobalData.gINF_MODULE_NAME,
Line=SectionLineNo,
ExtraData=None)
LastItem = Item
if not InfSectionObject.SetUserExtension(UserExtensionContent,
IdContent=IdContentList,
LineNo=SectionLineNo):
Logger.Error\
('InfParser', FORMAT_INVALID, \
ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[UserExtension]"), \
File=FileName, Line=LastItem[4])
def InfProtocolParser(self, SectionString, InfSectionObject, FileName):
#
# Macro defined in this section
#
SectionMacros = {}
ValueList = []
ProtocolList = []
CommentsList = []
CurrentLineVar = None
#
# Parse section content
#
for Line in SectionString:
LineContent = Line[0]
LineNo = Line[1]
if LineContent.strip() == '':
CommentsList = []
continue
if LineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
CommentsList.append(Line)
continue
else:
#
# Encounter a Protocol entry
#
if LineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
CommentsList.append((
LineContent[LineContent.find(DT.TAB_COMMENT_SPLIT):],
LineNo))
LineContent = \
LineContent[:LineContent.find(DT.TAB_COMMENT_SPLIT)]
if LineContent != '':
#
# Find Macro
#
Name, Value = MacroParser((LineContent, LineNo),
FileName,
DT.MODEL_EFI_PROTOCOL,
self.FileLocalMacros)
if Name is not None:
SectionMacros[Name] = Value
ValueList = []
CommentsList = []
continue
TokenList = GetSplitValueList(LineContent, DT.TAB_VALUE_SPLIT, 1)
ValueList[0:len(TokenList)] = TokenList
#
# Replace with Local section Macro and [Defines] section Macro.
#
ValueList = [InfExpandMacro(Value, (FileName, LineContent, LineNo), self.FileLocalMacros, SectionMacros)
for Value in ValueList]
CurrentLineVar = (LineContent, LineNo, FileName)
if len(ValueList) >= 1:
ProtocolList.append((ValueList, CommentsList, CurrentLineVar))
ValueList = []
CommentsList = []
continue
#
# Current section archs
#
ArchList = []
LineIndex = -1
for Item in self.LastSectionHeaderContent:
LineIndex = Item[3]
if Item[1] not in ArchList:
ArchList.append(Item[1])
if not InfSectionObject.SetProtocol(ProtocolList, Arch=ArchList):
Logger.Error\
('InfParser', FORMAT_INVALID, \
ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[Protocol]"), \
File=FileName, Line=LineIndex)