audk/BaseTools/Source/Python/UPT/Library/Misc.py

975 lines
29 KiB
Python

## @file
# Common routines used by all tools
#
# Copyright (c) 2011, 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.
#
'''
Misc
'''
##
# Import Modules
#
import os.path
from os import access
from os import F_OK
from os import makedirs
from os import getcwd
from os import chdir
from os import listdir
from os import remove
from os import rmdir
from os import linesep
from os import walk
from os import environ
import re
from UserDict import IterableUserDict
import Logger.Log as Logger
from Logger import StringTable as ST
from Logger import ToolError
from Library import GlobalData
from Library.DataType import SUP_MODULE_LIST
from Library.DataType import END_OF_LINE
from Library.DataType import TAB_SPLIT
from Library.DataType import LANGUAGE_EN_US
from Library.String import GetSplitValueList
from Library.ParserValidate import IsValidHexVersion
from Library.ParserValidate import IsValidPath
from Object.POM.CommonObject import TextObject
## Convert GUID string in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx style to C
# structure style
#
# @param Guid: The GUID string
#
def GuidStringToGuidStructureString(Guid):
GuidList = Guid.split('-')
Result = '{'
for Index in range(0, 3, 1):
Result = Result + '0x' + GuidList[Index] + ', '
Result = Result + '{0x' + GuidList[3][0:2] + ', 0x' + GuidList[3][2:4]
for Index in range(0, 12, 2):
Result = Result + ', 0x' + GuidList[4][Index:Index + 2]
Result += '}}'
return Result
## Check whether GUID string is of format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
#
# @param GuidValue: The GUID value
#
def CheckGuidRegFormat(GuidValue):
## Regular expression used to find out register format of GUID
#
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*$")
if RegFormatGuidPattern.match(GuidValue):
return True
else:
return False
## Convert GUID string in C structure style to
# xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
#
# @param GuidValue: The GUID value in C structure format
#
def GuidStructureStringToGuidString(GuidValue):
GuidValueString = GuidValue.lower().replace("{", "").replace("}", "").\
replace(" ", "").replace(";", "")
GuidValueList = GuidValueString.split(",")
if len(GuidValueList) != 11:
return ''
try:
return "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x" % (
int(GuidValueList[0], 16),
int(GuidValueList[1], 16),
int(GuidValueList[2], 16),
int(GuidValueList[3], 16),
int(GuidValueList[4], 16),
int(GuidValueList[5], 16),
int(GuidValueList[6], 16),
int(GuidValueList[7], 16),
int(GuidValueList[8], 16),
int(GuidValueList[9], 16),
int(GuidValueList[10], 16)
)
except BaseException:
return ''
## Create directories
#
# @param Directory: The directory name
#
def CreateDirectory(Directory):
if Directory == None or Directory.strip() == "":
return True
try:
if not access(Directory, F_OK):
makedirs(Directory)
except BaseException:
return False
return True
## Remove directories, including files and sub-directories in it
#
# @param Directory: The directory name
#
def RemoveDirectory(Directory, Recursively=False):
if Directory == None or Directory.strip() == "" or not \
os.path.exists(Directory):
return
if Recursively:
CurrentDirectory = getcwd()
chdir(Directory)
for File in listdir("."):
if os.path.isdir(File):
RemoveDirectory(File, Recursively)
else:
remove(File)
chdir(CurrentDirectory)
rmdir(Directory)
## Store content in file
#
# This method is used to save file only when its content is changed. This is
# quite useful for "make" system to decide what will be re-built and what
# won't.
#
# @param File: The path of file
# @param Content: The new content of the file
# @param IsBinaryFile: The flag indicating if the file is binary file
# or not
#
def SaveFileOnChange(File, Content, IsBinaryFile=True):
if not IsBinaryFile:
Content = Content.replace("\n", linesep)
if os.path.exists(File):
try:
if Content == open(File, "rb").read():
return False
except BaseException:
Logger.Error(None, ToolError.FILE_OPEN_FAILURE, ExtraData=File)
CreateDirectory(os.path.dirname(File))
try:
FileFd = open(File, "wb")
FileFd.write(Content)
FileFd.close()
except BaseException:
Logger.Error(None, ToolError.FILE_CREATE_FAILURE, ExtraData=File)
return True
## Get all files of a directory
#
# @param Root: Root dir
# @param SkipList : The files need be skipped
#
def GetFiles(Root, SkipList=None, FullPath=True):
OriPath = os.path.normpath(Root)
FileList = []
for Root, Dirs, Files in walk(Root):
if SkipList:
for Item in SkipList:
if Item in Dirs:
Dirs.remove(Item)
for Dir in Dirs:
if Dir.startswith('.'):
Dirs.remove(Dir)
for File in Files:
if File.startswith('.'):
continue
File = os.path.normpath(os.path.join(Root, File))
if not FullPath:
File = File[len(OriPath) + 1:]
FileList.append(File)
return FileList
## Get all non-metadata files of a directory
#
# @param Root: Root Dir
# @param SkipList : List of path need be skipped
# @param FullPath: True if the returned file should be full path
# @param PrefixPath: the path that need to be added to the files found
# @return: the list of files found
#
def GetNonMetaDataFiles(Root, SkipList, FullPath, PrefixPath):
FileList = GetFiles(Root, SkipList, FullPath)
NewFileList = []
for File in FileList:
ExtName = os.path.splitext(File)[1]
#
# skip '.dec', '.inf', '.dsc', '.fdf' files
#
if ExtName.lower() not in ['.dec', '.inf', '.dsc', '.fdf']:
NewFileList.append(os.path.normpath(os.path.join(PrefixPath, File)))
return NewFileList
## Check if given file exists or not
#
# @param File: File name or path to be checked
# @param Dir: The directory the file is relative to
#
def ValidFile(File, Ext=None):
File = File.replace('\\', '/')
if Ext != None:
FileExt = os.path.splitext(File)[1]
if FileExt.lower() != Ext.lower():
return False
if not os.path.exists(File):
return False
return True
## RealPath
#
# @param File: File name or path to be checked
# @param Dir: The directory the file is relative to
# @param OverrideDir: The override directory
#
def RealPath(File, Dir='', OverrideDir=''):
NewFile = os.path.normpath(os.path.join(Dir, File))
NewFile = GlobalData.gALL_FILES[NewFile]
if not NewFile and OverrideDir:
NewFile = os.path.normpath(os.path.join(OverrideDir, File))
NewFile = GlobalData.gALL_FILES[NewFile]
return NewFile
## RealPath2
#
# @param File: File name or path to be checked
# @param Dir: The directory the file is relative to
# @param OverrideDir: The override directory
#
def RealPath2(File, Dir='', OverrideDir=''):
if OverrideDir:
NewFile = GlobalData.gALL_FILES[os.path.normpath(os.path.join\
(OverrideDir, File))]
if NewFile:
if OverrideDir[-1] == os.path.sep:
return NewFile[len(OverrideDir):], NewFile[0:len(OverrideDir)]
else:
return NewFile[len(OverrideDir) + 1:], \
NewFile[0:len(OverrideDir)]
NewFile = GlobalData.gALL_FILES[os.path.normpath(os.path.join(Dir, File))]
if NewFile:
if Dir:
if Dir[-1] == os.path.sep:
return NewFile[len(Dir):], NewFile[0:len(Dir)]
else:
return NewFile[len(Dir) + 1:], NewFile[0:len(Dir)]
else:
return NewFile, ''
return None, None
## A dict which can access its keys and/or values orderly
#
# The class implements a new kind of dict which its keys or values can be
# accessed in the order they are added into the dict. It guarantees the order
# by making use of an internal list to keep a copy of keys.
#
class Sdict(IterableUserDict):
## Constructor
#
def __init__(self):
IterableUserDict.__init__(self)
self._key_list = []
## [] operator
#
def __setitem__(self, Key, Value):
if Key not in self._key_list:
self._key_list.append(Key)
IterableUserDict.__setitem__(self, Key, Value)
## del operator
#
def __delitem__(self, Key):
self._key_list.remove(Key)
IterableUserDict.__delitem__(self, Key)
## used in "for k in dict" loop to ensure the correct order
#
def __iter__(self):
return self.iterkeys()
## len() support
#
def __len__(self):
return len(self._key_list)
## "in" test support
#
def __contains__(self, Key):
return Key in self._key_list
## indexof support
#
def index(self, Key):
return self._key_list.index(Key)
## insert support
#
def insert(self, Key, Newkey, Newvalue, Order):
Index = self._key_list.index(Key)
if Order == 'BEFORE':
self._key_list.insert(Index, Newkey)
IterableUserDict.__setitem__(self, Newkey, Newvalue)
elif Order == 'AFTER':
self._key_list.insert(Index + 1, Newkey)
IterableUserDict.__setitem__(self, Newkey, Newvalue)
## append support
#
def append(self, Sdict2):
for Key in Sdict2:
if Key not in self._key_list:
self._key_list.append(Key)
IterableUserDict.__setitem__(self, Key, Sdict2[Key])
## hash key
#
def has_key(self, Key):
return Key in self._key_list
## Empty the dict
#
def clear(self):
self._key_list = []
IterableUserDict.clear(self)
## Return a copy of keys
#
def keys(self):
Keys = []
for Key in self._key_list:
Keys.append(Key)
return Keys
## Return a copy of values
#
def values(self):
Values = []
for Key in self._key_list:
Values.append(self[Key])
return Values
## Return a copy of (key, value) list
#
def items(self):
Items = []
for Key in self._key_list:
Items.append((Key, self[Key]))
return Items
## Iteration support
#
def iteritems(self):
return iter(self.items())
## Keys interation support
#
def iterkeys(self):
return iter(self.keys())
## Values interation support
#
def itervalues(self):
return iter(self.values())
## Return value related to a key, and remove the (key, value) from the dict
#
def pop(self, Key, *Dv):
Value = None
if Key in self._key_list:
Value = self[Key]
self.__delitem__(Key)
elif len(Dv) != 0 :
Value = Dv[0]
return Value
## Return (key, value) pair, and remove the (key, value) from the dict
#
def popitem(self):
Key = self._key_list[-1]
Value = self[Key]
self.__delitem__(Key)
return Key, Value
## update method
#
def update(self, Dict=None, **Kwargs):
if Dict != None:
for Key1, Val1 in Dict.items():
self[Key1] = Val1
if len(Kwargs):
for Key1, Val1 in Kwargs.items():
self[Key1] = Val1
## CommonPath
#
# @param PathList: PathList
#
def CommonPath(PathList):
Path1 = min(PathList).split(os.path.sep)
Path2 = max(PathList).split(os.path.sep)
for Index in xrange(min(len(Path1), len(Path2))):
if Path1[Index] != Path2[Index]:
return os.path.sep.join(Path1[:Index])
return os.path.sep.join(Path1)
## PathClass
#
class PathClass(object):
def __init__(self, File='', Root='', AlterRoot='', Type='', IsBinary=False,
Arch='COMMON', ToolChainFamily='', Target='', TagName='', \
ToolCode=''):
self.Arch = Arch
self.File = str(File)
if os.path.isabs(self.File):
self.Root = ''
self.AlterRoot = ''
else:
self.Root = str(Root)
self.AlterRoot = str(AlterRoot)
#
# Remove any '.' and '..' in path
#
if self.Root:
self.Path = os.path.normpath(os.path.join(self.Root, self.File))
self.Root = os.path.normpath(CommonPath([self.Root, self.Path]))
#
# eliminate the side-effect of 'C:'
#
if self.Root[-1] == ':':
self.Root += os.path.sep
#
# file path should not start with path separator
#
if self.Root[-1] == os.path.sep:
self.File = self.Path[len(self.Root):]
else:
self.File = self.Path[len(self.Root) + 1:]
else:
self.Path = os.path.normpath(self.File)
self.SubDir, self.Name = os.path.split(self.File)
self.BaseName, self.Ext = os.path.splitext(self.Name)
if self.Root:
if self.SubDir:
self.Dir = os.path.join(self.Root, self.SubDir)
else:
self.Dir = self.Root
else:
self.Dir = self.SubDir
if IsBinary:
self.Type = Type
else:
self.Type = self.Ext.lower()
self.IsBinary = IsBinary
self.Target = Target
self.TagName = TagName
self.ToolCode = ToolCode
self.ToolChainFamily = ToolChainFamily
self._Key = None
## Convert the object of this class to a string
#
# Convert member Path of the class to a string
#
def __str__(self):
return self.Path
## Override __eq__ function
#
# Check whether PathClass are the same
#
def __eq__(self, Other):
if type(Other) == type(self):
return self.Path == Other.Path
else:
return self.Path == str(Other)
## Override __hash__ function
#
# Use Path as key in hash table
#
def __hash__(self):
return hash(self.Path)
## _GetFileKey
#
def _GetFileKey(self):
if self._Key == None:
self._Key = self.Path.upper()
return self._Key
## Validate
#
def Validate(self, Type='', CaseSensitive=True):
if GlobalData.gCASE_INSENSITIVE:
CaseSensitive = False
if Type and Type.lower() != self.Type:
return ToolError.FILE_TYPE_MISMATCH, '%s (expect %s but got %s)' % \
(self.File, Type, self.Type)
RealFile, RealRoot = RealPath2(self.File, self.Root, self.AlterRoot)
if not RealRoot and not RealFile:
RealFile = self.File
if self.AlterRoot:
RealFile = os.path.join(self.AlterRoot, self.File)
elif self.Root:
RealFile = os.path.join(self.Root, self.File)
return ToolError.FILE_NOT_FOUND, os.path.join(self.AlterRoot, RealFile)
ErrorCode = 0
ErrorInfo = ''
if RealRoot != self.Root or RealFile != self.File:
if CaseSensitive and (RealFile != self.File or \
(RealRoot != self.Root and RealRoot != \
self.AlterRoot)):
ErrorCode = ToolError.FILE_CASE_MISMATCH
ErrorInfo = self.File + '\n\t' + RealFile + \
" [in file system]"
self.SubDir, self.Name = os.path.split(RealFile)
self.BaseName, self.Ext = os.path.splitext(self.Name)
if self.SubDir:
self.Dir = os.path.join(RealRoot, self.SubDir)
else:
self.Dir = RealRoot
self.File = RealFile
self.Root = RealRoot
self.Path = os.path.join(RealRoot, RealFile)
return ErrorCode, ErrorInfo
Key = property(_GetFileKey)
## Check environment variables
#
# Check environment variables that must be set for build. Currently they are
#
# WORKSPACE The directory all packages/platforms start from
# EDK_TOOLS_PATH The directory contains all tools needed by the build
# PATH $(EDK_TOOLS_PATH)/Bin/<sys> must be set in PATH
#
# If any of above environment variable is not set or has error, the build
# will be broken.
#
def CheckEnvVariable():
#
# check WORKSPACE
#
if "WORKSPACE" not in environ:
Logger.Error("UPT",
ToolError.UPT_ENVIRON_MISSING_ERROR,
ST.ERR_NOT_FOUND_ENVIRONMENT,
ExtraData="WORKSPACE")
WorkspaceDir = os.path.normpath(environ["WORKSPACE"])
if not os.path.exists(WorkspaceDir):
Logger.Error("UPT",
ToolError.UPT_ENVIRON_MISSING_ERROR,
ST.ERR_WORKSPACE_NOTEXIST,
ExtraData="%s" % WorkspaceDir)
elif ' ' in WorkspaceDir:
Logger.Error("UPT",
ToolError.FORMAT_NOT_SUPPORTED,
ST.ERR_SPACE_NOTALLOWED,
ExtraData=WorkspaceDir)
## Check whether all module types are in list
#
# check whether all module types (SUP_MODULE_LIST) are in list
#
# @param ModuleList: a list of ModuleType
#
def IsAllModuleList(ModuleList):
NewModuleList = [Module.upper() for Module in ModuleList]
for Module in SUP_MODULE_LIST:
if Module not in NewModuleList:
return False
else:
return True
## Dictionary that use comment(GenericComment, TailComment) as value,
# if a new comment which key already in the dic is inserted, then the
# comment will be merged.
# Key is (Statement, SupArch), when TailComment is added, it will ident
# according to Statement
#
class MergeCommentDict(dict):
## []= operator
#
def __setitem__(self, Key, CommentVal):
GenericComment, TailComment = CommentVal
if Key in self:
OrigVal1, OrigVal2 = dict.__getitem__(self, Key)
Statement = Key[0]
dict.__setitem__(self, Key, (OrigVal1 + GenericComment, OrigVal2 \
+ len(Statement) * ' ' + TailComment))
else:
dict.__setitem__(self, Key, (GenericComment, TailComment))
## =[] operator
#
def __getitem__(self, Key):
return dict.__getitem__(self, Key)
## GenDummyHelpTextObj
#
# @retval HelpTxt: Generated dummy help text object
#
def GenDummyHelpTextObj():
HelpTxt = TextObject()
HelpTxt.SetLang(LANGUAGE_EN_US)
HelpTxt.SetString(' ')
return HelpTxt
## ConvertVersionToDecimal, the minor version should be within 0 - 99
# <HexVersion> ::= "0x" <Major> <Minor>
# <Major> ::= (a-fA-F0-9){4}
# <Minor> ::= (a-fA-F0-9){4}
# <DecVersion> ::= (0-65535) ["." (0-99)]
#
# @param StringIn: The string contains version defined in INF file.
# It can be Decimal or Hex
#
def ConvertVersionToDecimal(StringIn):
if IsValidHexVersion(StringIn):
Value = int(StringIn, 16)
Major = Value >> 16
Minor = Value & 0xFFFF
MinorStr = str(Minor)
if len(MinorStr) == 1:
MinorStr = '0' + MinorStr
return str(Major) + '.' + MinorStr
else:
if StringIn.find(TAB_SPLIT) != -1:
return StringIn
elif StringIn:
return StringIn + '.0'
else:
#
# when StringIn is '', return it directly
#
return StringIn
## GetHelpStringByRemoveHashKey
#
# Remove hash key at the header of string and return the remain.
#
# @param String: The string need to be processed.
#
def GetHelpStringByRemoveHashKey(String):
ReturnString = ''
PattenRemoveHashKey = re.compile(r"^[#+\s]+", re.DOTALL)
String = String.strip()
if String == '':
return String
LineList = GetSplitValueList(String, END_OF_LINE)
for Line in LineList:
ValueList = PattenRemoveHashKey.split(Line)
if len(ValueList) == 1:
ReturnString += ValueList[0] + END_OF_LINE
else:
ReturnString += ValueList[1] + END_OF_LINE
if ReturnString.endswith('\n') and not ReturnString.endswith('\n\n') and ReturnString != '\n':
ReturnString = ReturnString[:-1]
return ReturnString
## ConvPathFromAbsToRel
#
# Get relative file path from absolute path.
#
# @param Path: The string contain file absolute path.
# @param Root: The string contain the parent path of Path in.
#
#
def ConvPathFromAbsToRel(Path, Root):
Path = os.path.normpath(Path)
Root = os.path.normpath(Root)
FullPath = os.path.normpath(os.path.join(Root, Path))
#
# If Path is absolute path.
# It should be in Root.
#
if os.path.isabs(Path):
return FullPath[FullPath.find(Root) + len(Root) + 1:]
else:
return Path
## ConvertPath
#
# Convert special characters to '_', '\' to '/'
# return converted path: Test!1.inf -> Test_1.inf
#
# @param Path: Path to be converted
#
def ConvertPath(Path):
RetPath = ''
for Char in Path.strip():
if Char.isalnum() or Char in '.-_/':
RetPath = RetPath + Char
elif Char == '\\':
RetPath = RetPath + '/'
else:
RetPath = RetPath + '_'
return RetPath
## ConvertSpec
#
# during install, convert the Spec string extract from UPD into INF allowable definition,
# the difference is period is allowed in the former (not the first letter) but not in the latter.
# return converted Spec string
#
# @param SpecStr: SpecStr to be converted
#
def ConvertSpec(SpecStr):
RetStr = ''
for Char in SpecStr:
if Char.isalnum() or Char == '_':
RetStr = RetStr + Char
else:
RetStr = RetStr + '_'
return RetStr
## IsEqualList
#
# Judge two lists are identical(contain same item).
# The rule is elements in List A are in List B and elements in List B are in List A.
#
# @param ListA, ListB Lists need to be judged.
#
# @return True ListA and ListB are identical
# @return False ListA and ListB are different with each other
#
def IsEqualList(ListA, ListB):
if ListA == ListB:
return True
for ItemA in ListA:
if not ItemA in ListB:
return False
for ItemB in ListB:
if not ItemB in ListA:
return False
return True
## ConvertArchList
#
# Convert item in ArchList if the start character is lower case.
# In UDP spec, Arch is only allowed as: [A-Z]([a-zA-Z0-9])*
#
# @param ArchList The ArchList need to be converted.
#
# @return NewList The ArchList been converted.
#
def ConvertArchList(ArchList):
NewArchList = []
if not ArchList:
return NewArchList
if type(ArchList) == list:
for Arch in ArchList:
Arch = Arch.upper()
NewArchList.append(Arch)
elif type(ArchList) == str:
ArchList = ArchList.upper()
NewArchList.append(ArchList)
return NewArchList
## ProcessLineExtender
#
# Process the LineExtender of Line in LineList.
# If one line ends with a line extender, then it will be combined together with next line.
#
# @param LineList The LineList need to be processed.
#
# @return NewList The ArchList been processed.
#
def ProcessLineExtender(LineList):
NewList = []
Count = 0
while Count < len(LineList):
if LineList[Count].strip().endswith("\\") and Count + 1 < len(LineList):
NewList.append(LineList[Count].strip()[:-2] + LineList[Count + 1])
Count = Count + 1
else:
NewList.append(LineList[Count])
Count = Count + 1
return NewList
## ProcessEdkComment
#
# Process EDK style comment in LineList: c style /* */ comment or cpp style // comment
#
#
# @param LineList The LineList need to be processed.
#
# @return LineList The LineList been processed.
# @return FirstPos Where Edk comment is first found, -1 if not found
#
def ProcessEdkComment(LineList):
FindEdkBlockComment = False
Count = 0
StartPos = -1
EndPos = -1
FirstPos = -1
while(Count < len(LineList)):
Line = LineList[Count].strip()
if Line.startswith("/*"):
#
# handling c style comment
#
StartPos = Count
while Count < len(LineList):
Line = LineList[Count].strip()
if Line.endswith("*/"):
if (Count == StartPos) and Line.strip() == '/*/':
Count = Count + 1
continue
EndPos = Count
FindEdkBlockComment = True
break
Count = Count + 1
if FindEdkBlockComment:
if FirstPos == -1:
FirstPos = StartPos
for Index in xrange(StartPos, EndPos+1):
LineList[Index] = ''
FindEdkBlockComment = False
elif Line.find("//") != -1 and not Line.startswith("#"):
#
# handling cpp style comment
#
LineList[Count] = Line.replace("//", '#')
if FirstPos == -1:
FirstPos = Count
Count = Count + 1
return LineList, FirstPos
## 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):
FileGuidString = ""
VerString = ""
OrignalString = String
String = String.strip()
if not String:
return None, None
#
# Remove "#" characters at the beginning
#
String = GetHelpStringByRemoveHashKey(String)
String = String.strip()
#
# Validate file name exist.
#
FullFileName = os.path.normpath(os.path.realpath(os.path.join(WorkSpace, String)))
if not (ValidFile(FullFileName)):
Logger.Error("InfParser",
ToolError.FORMAT_INVALID,
ST.ERR_FILELIST_EXIST % (String),
File=GlobalData.gINF_MODULE_NAME,
Line=LineNo,
ExtraData=OrignalString)
#
# Validate file exist/format.
#
if IsValidPath(String, WorkSpace):
IsValidFileFlag = True
else:
Logger.Error("InfParser",
ToolError.FORMAT_INVALID,
ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID % (String),
File=GlobalData.gINF_MODULE_NAME,
Line=LineNo,
ExtraData=OrignalString)
return False
if IsValidFileFlag:
FileLinesList = []
try:
FInputfile = open(FullFileName, "rb", 0)
try:
FileLinesList = FInputfile.readlines()
except BaseException:
Logger.Error("InfParser",
ToolError.FILE_READ_FAILURE,
ST.ERR_FILE_OPEN_FAILURE,
File=FullFileName)
finally:
FInputfile.close()
except BaseException:
Logger.Error("InfParser",
ToolError.FILE_READ_FAILURE,
ST.ERR_FILE_OPEN_FAILURE,
File=FullFileName)
ReFileGuidPattern = re.compile("^\s*FILE_GUID\s*=.*$")
ReVerStringPattern = re.compile("^\s*VERSION_STRING\s*=.*$")
FileLinesList = ProcessLineExtender(FileLinesList)
for Line in FileLinesList:
if ReFileGuidPattern.match(Line):
FileGuidString = Line
if ReVerStringPattern.match(Line):
VerString = Line
if FileGuidString:
FileGuidString = GetSplitValueList(FileGuidString, '=', 1)[1]
if VerString:
VerString = GetSplitValueList(VerString, '=', 1)[1]
return FileGuidString, VerString