audk/BaseTools/Source/Python/UPT/Parser/InfParserMisc.py

223 lines
7.0 KiB
Python

## @file
# This file contained the miscellaneous functions for INF parser
#
# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials are licensed and made available
# under the terms and conditions of the BSD License which accompanies this
# distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
'''
InfParserMisc
'''
##
# Import Modules
#
import re
from Library import DataType as DT
from Library.StringUtils import gMACRO_PATTERN
from Library.StringUtils import ReplaceMacro
from Object.Parser.InfMisc import ErrorInInf
from Logger.StringTable import ERR_MARCO_DEFINITION_MISS_ERROR
#
# Global variable
#
#
# Sections can exist in INF file
#
gINF_SECTION_DEF = {
DT.TAB_UNKNOWN.upper() : DT.MODEL_UNKNOWN,
DT.TAB_HEADER.upper() : DT.MODEL_META_DATA_FILE_HEADER,
DT.TAB_INF_DEFINES.upper() : DT.MODEL_META_DATA_DEFINE,
DT.TAB_BUILD_OPTIONS.upper() : DT.MODEL_META_DATA_BUILD_OPTION,
DT.TAB_LIBRARY_CLASSES.upper() : DT.MODEL_EFI_LIBRARY_CLASS,
DT.TAB_PACKAGES.upper() : DT.MODEL_META_DATA_PACKAGE,
DT.TAB_INF_FIXED_PCD.upper() : DT.MODEL_PCD_FIXED_AT_BUILD,
DT.TAB_INF_PATCH_PCD.upper() : DT.MODEL_PCD_PATCHABLE_IN_MODULE,
DT.TAB_INF_FEATURE_PCD.upper() : DT.MODEL_PCD_FEATURE_FLAG,
DT.TAB_INF_PCD_EX.upper() : DT.MODEL_PCD_DYNAMIC_EX,
DT.TAB_INF_PCD.upper() : DT.MODEL_PCD_DYNAMIC,
DT.TAB_SOURCES.upper() : DT.MODEL_EFI_SOURCE_FILE,
DT.TAB_GUIDS.upper() : DT.MODEL_EFI_GUID,
DT.TAB_PROTOCOLS.upper() : DT.MODEL_EFI_PROTOCOL,
DT.TAB_PPIS.upper() : DT.MODEL_EFI_PPI,
DT.TAB_DEPEX.upper() : DT.MODEL_EFI_DEPEX,
DT.TAB_BINARIES.upper() : DT.MODEL_EFI_BINARY_FILE,
DT.TAB_USER_EXTENSIONS.upper() : DT.MODEL_META_DATA_USER_EXTENSION
#
# EDK1 section
# TAB_NMAKE.upper() : MODEL_META_DATA_NMAKE
#
}
## InfExpandMacro
#
# Expand MACRO definition with MACROs defined in [Defines] section and specific section.
# The MACROs defined in specific section has high priority and will be expanded firstly.
#
# @param LineInfo Contain information of FileName, LineContent, LineNo
# @param GlobalMacros MACROs defined in INF [Defines] section
# @param SectionMacros MACROs defined in INF specific section
# @param Flag If the flag set to True, need to skip macros in a quoted string
#
def InfExpandMacro(Content, LineInfo, GlobalMacros=None, SectionMacros=None, Flag=False):
if GlobalMacros is None:
GlobalMacros = {}
if SectionMacros is None:
SectionMacros = {}
FileName = LineInfo[0]
LineContent = LineInfo[1]
LineNo = LineInfo[2]
# Don't expand macros in comments
if LineContent.strip().startswith("#"):
return Content
NewLineInfo = (FileName, LineNo, LineContent)
#
# First, replace MARCOs with value defined in specific section
#
Content = ReplaceMacro (Content,
SectionMacros,
False,
(LineContent, LineNo),
FileName,
Flag)
#
# Then replace MARCOs with value defined in [Defines] section
#
Content = ReplaceMacro (Content,
GlobalMacros,
False,
(LineContent, LineNo),
FileName,
Flag)
MacroUsed = gMACRO_PATTERN.findall(Content)
#
# no macro found in String, stop replacing
#
if len(MacroUsed) == 0:
return Content
else:
for Macro in MacroUsed:
gQuotedMacro = re.compile(".*\".*\$\(%s\).*\".*"%(Macro))
if not gQuotedMacro.match(Content):
#
# Still have MACROs can't be expanded.
#
ErrorInInf (ERR_MARCO_DEFINITION_MISS_ERROR,
LineInfo=NewLineInfo)
return Content
## IsBinaryInf
#
# Judge whether the INF file is Binary INF or Common INF
#
# @param FileLineList A list contain all INF file content.
#
def IsBinaryInf(FileLineList):
if not FileLineList:
return False
ReIsSourcesSection = re.compile("^\s*\[Sources.*\]\s.*$", re.IGNORECASE)
ReIsBinarySection = re.compile("^\s*\[Binaries.*\]\s.*$", re.IGNORECASE)
BinarySectionFoundFlag = False
for Line in FileLineList:
if ReIsSourcesSection.match(Line):
return False
if ReIsBinarySection.match(Line):
BinarySectionFoundFlag = True
if BinarySectionFoundFlag:
return True
return False
## IsLibInstanceInfo
#
# Judge whether the string contain the information of ## @LIB_INSTANCES.
#
# @param String
#
# @return Flag
#
def IsLibInstanceInfo(String):
ReIsLibInstance = re.compile("^\s*##\s*@LIB_INSTANCES\s*$")
if ReIsLibInstance.match(String):
return True
else:
return False
## IsAsBuildOptionInfo
#
# Judge whether the string contain the information of ## @ASBUILD.
#
# @param String
#
# @return Flag
#
def IsAsBuildOptionInfo(String):
ReIsAsBuildInstance = re.compile("^\s*##\s*@AsBuilt\s*$")
if ReIsAsBuildInstance.match(String):
return True
else:
return False
class InfParserSectionRoot(object):
def __init__(self):
#
# Macros defined in [Define] section are file scope global
#
self.FileLocalMacros = {}
#
# Current Section Header content.
#
self.SectionHeaderContent = []
#
# Last time Section Header content.
#
self.LastSectionHeaderContent = []
self.FullPath = ''
self.InfDefSection = None
self.InfBuildOptionSection = None
self.InfLibraryClassSection = None
self.InfPackageSection = None
self.InfPcdSection = None
self.InfSourcesSection = None
self.InfUserExtensionSection = None
self.InfProtocolSection = None
self.InfPpiSection = None
self.InfGuidSection = None
self.InfDepexSection = None
self.InfPeiDepexSection = None
self.InfDxeDepexSection = None
self.InfSmmDepexSection = None
self.InfBinariesSection = None
self.InfHeader = None
self.InfSpecialCommentSection = None