## @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 '', '' | |