1. Add a recovery mode for UPT failure 2. Add UNI file support 3. Add binary file header support 4. Add support for PCD error message 5. Add support for replace 6. Format generated INF/DEC files 7. Update dependency check 8. Other minor fixes Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Hess Chen <hesheng.chen@intel.com> Reviewed-by: Gao, Liming <liming.gao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15896 6f19259b-4bc3-4df7-8a09-765794883524
290 lines
9.2 KiB
Python
290 lines
9.2 KiB
Python
## @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 '', ''
|
|
|
|
|