| ## @file | |
| # This file is used to provide method for process AsBuilt INF file. It will consumed by InfParser | |
| # | |
| # Copyright (c) 2011 - 2014, 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. | |
| ''' | |
| 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.String 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 = "" | |
| OrignalString = 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, OrignalString) | |
| 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 != None: | |
| DefineSectionMacros[Name] = Value | |
| continue | |
| if PackageHederFlag: | |
| # | |
| # Find Macro | |
| # | |
| Name, Value = MacroParser((Line, LineNo), | |
| FileNameString, | |
| DT.MODEL_META_DATA_PACKAGE, | |
| DefineSectionMacros) | |
| if Name != 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, "rb", 0) | |
| 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, "rb", 0) | |
| 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 '', '' | |