## @file # This file is used to provide method for process AsBuilt INF file. It will consumed by InfParser # # Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent ''' InfAsBuiltProcess ''' ## Import modules # import os import re from Library import GlobalData import Logger.Log as Logger from Logger import StringTable as ST from Logger import ToolError from Library.StringUtils import GetSplitValueList from Library.Misc import GetHelpStringByRemoveHashKey from Library.Misc import ValidFile from Library.Misc import ProcessLineExtender from Library.ParserValidate import IsValidPath from Library.Parsing import MacroParser from Parser.InfParserMisc import InfExpandMacro from Library import DataType as DT ## GetLibInstanceInfo # # Get the information from Library Instance INF file. # # @param string. A string start with # and followed by INF file path # @param WorkSpace. The WorkSpace directory used to combined with INF file path. # # @return GUID, Version def GetLibInstanceInfo(String, WorkSpace, LineNo, CurrentInfFileName): FileGuidString = "" VerString = "" OriginalString = String String = String.strip() if not String: return None, None # # Remove "#" characters at the beginning # String = GetHelpStringByRemoveHashKey(String) String = String.strip() # # To deal with library instance specified by GUID and version # RegFormatGuidPattern = re.compile("\s*([0-9a-fA-F]){8}-" "([0-9a-fA-F]){4}-" "([0-9a-fA-F]){4}-" "([0-9a-fA-F]){4}-" "([0-9a-fA-F]){12}\s*") VersionPattern = re.compile('[\t\s]*\d+(\.\d+)?[\t\s]*') GuidMatchedObj = RegFormatGuidPattern.search(String) if String.upper().startswith('GUID') and GuidMatchedObj and 'Version' in String: VersionStr = String[String.upper().find('VERSION') + 8:] VersionMatchedObj = VersionPattern.search(VersionStr) if VersionMatchedObj: Guid = GuidMatchedObj.group().strip() Version = VersionMatchedObj.group().strip() return Guid, Version # # To deal with library instance specified by file name # FileLinesList = GetFileLineContent(String, WorkSpace, LineNo, OriginalString) ReFindFileGuidPattern = re.compile("^\s*FILE_GUID\s*=.*$") ReFindVerStringPattern = re.compile("^\s*VERSION_STRING\s*=.*$") for Line in FileLinesList: if ReFindFileGuidPattern.match(Line): FileGuidString = Line if ReFindVerStringPattern.match(Line): VerString = Line if FileGuidString: FileGuidString = GetSplitValueList(FileGuidString, '=', 1)[1] if VerString: VerString = GetSplitValueList(VerString, '=', 1)[1] return FileGuidString, VerString ## GetPackageListInfo # # Get the package information from INF file. # # @param string. A string start with # and followed by INF file path # @param WorkSpace. The WorkSpace directory used to combined with INF file path. # # @return GUID, Version def GetPackageListInfo(FileNameString, WorkSpace, LineNo): PackageInfoList = [] DefineSectionMacros = {} PackageSectionMacros = {} FileLinesList = GetFileLineContent(FileNameString, WorkSpace, LineNo, '') RePackageHeader = re.compile('^\s*\[Packages.*\].*$') ReDefineHeader = re.compile('^\s*\[Defines].*$') PackageHederFlag = False DefineHeaderFlag = False LineNo = -1 for Line in FileLinesList: LineNo += 1 Line = Line.strip() if Line.startswith('['): PackageHederFlag = False DefineHeaderFlag = False if Line.startswith("#"): continue if not Line: continue # # Found [Packages] section # if RePackageHeader.match(Line): PackageHederFlag = True continue # # Found [Define] section # if ReDefineHeader.match(Line): DefineHeaderFlag = True continue if DefineHeaderFlag: # # Find Macro # Name, Value = MacroParser((Line, LineNo), FileNameString, DT.MODEL_META_DATA_HEADER, DefineSectionMacros) if Name is not None: DefineSectionMacros[Name] = Value continue if PackageHederFlag: # # Find Macro # Name, Value = MacroParser((Line, LineNo), FileNameString, DT.MODEL_META_DATA_PACKAGE, DefineSectionMacros) if Name is not None: PackageSectionMacros[Name] = Value continue # # Replace with Local section Macro and [Defines] section Macro. # Line = InfExpandMacro(Line, (FileNameString, Line, LineNo), DefineSectionMacros, PackageSectionMacros, True) Line = GetSplitValueList(Line, "#", 1)[0] Line = GetSplitValueList(Line, "|", 1)[0] PackageInfoList.append(Line) return PackageInfoList def GetFileLineContent(FileName, WorkSpace, LineNo, OriginalString): if not LineNo: LineNo = -1 # # Validate file name exist. # FullFileName = os.path.normpath(os.path.realpath(os.path.join(WorkSpace, FileName))) if not (ValidFile(FullFileName)): return [] # # Validate file exist/format. # if not IsValidPath(FileName, WorkSpace): return [] FileLinesList = [] try: FullFileName = FullFileName.replace('\\', '/') Inputfile = open(FullFileName, "r") try: FileLinesList = Inputfile.readlines() except BaseException: Logger.Error("InfParser", ToolError.FILE_READ_FAILURE, ST.ERR_FILE_OPEN_FAILURE, File=FullFileName) finally: Inputfile.close() except BaseException: Logger.Error("InfParser", ToolError.FILE_READ_FAILURE, ST.ERR_FILE_OPEN_FAILURE, File=FullFileName) FileLinesList = ProcessLineExtender(FileLinesList) return FileLinesList ## # Get all INF files from current workspace # # def GetInfsFromWorkSpace(WorkSpace): InfFiles = [] for top, dirs, files in os.walk(WorkSpace): dirs = dirs # just for pylint for File in files: if File.upper().endswith(".INF"): InfFiles.append(os.path.join(top, File)) return InfFiles ## # Get GUID and version from library instance file # # def GetGuidVerFormLibInstance(Guid, Version, WorkSpace, CurrentInfFileName): for InfFile in GetInfsFromWorkSpace(WorkSpace): try: if InfFile.strip().upper() == CurrentInfFileName.strip().upper(): continue InfFile = InfFile.replace('\\', '/') if InfFile not in GlobalData.gLIBINSTANCEDICT: InfFileObj = open(InfFile, "r") GlobalData.gLIBINSTANCEDICT[InfFile] = InfFileObj else: InfFileObj = GlobalData.gLIBINSTANCEDICT[InfFile] except BaseException: Logger.Error("InfParser", ToolError.FILE_READ_FAILURE, ST.ERR_FILE_OPEN_FAILURE, File=InfFile) try: FileLinesList = InfFileObj.readlines() FileLinesList = ProcessLineExtender(FileLinesList) ReFindFileGuidPattern = re.compile("^\s*FILE_GUID\s*=.*$") ReFindVerStringPattern = re.compile("^\s*VERSION_STRING\s*=.*$") for Line in FileLinesList: if ReFindFileGuidPattern.match(Line): FileGuidString = Line if ReFindVerStringPattern.match(Line): VerString = Line if FileGuidString: FileGuidString = GetSplitValueList(FileGuidString, '=', 1)[1] if VerString: VerString = GetSplitValueList(VerString, '=', 1)[1] if FileGuidString.strip().upper() == Guid.upper() and \ VerString.strip().upper() == Version.upper(): return Guid, Version except BaseException: Logger.Error("InfParser", ToolError.FILE_READ_FAILURE, ST.ERR_FILE_OPEN_FAILURE, File=InfFile) finally: InfFileObj.close() return '', ''