diff options
author | vanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524> | 2012-01-20 05:31:42 +0000 |
---|---|---|
committer | vanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524> | 2012-01-20 05:31:42 +0000 |
commit | 5ec9762214756472d107674744a59f543ca01716 (patch) | |
tree | b70df9d5bf7a81f62d0687e2e245c7fd6508399a /BaseTools/Source/Python/Common/Misc.py | |
parent | 48e3547c122e524325107e4f7b73f57d2b5c3b7e (diff) | |
download | edk2-5ec9762214756472d107674744a59f543ca01716.tar.gz |
Delete old BaseTool from UDK2010 branch.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/branches/UDK2010@12945 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'BaseTools/Source/Python/Common/Misc.py')
-rw-r--r-- | BaseTools/Source/Python/Common/Misc.py | 1531 |
1 files changed, 0 insertions, 1531 deletions
diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py deleted file mode 100644 index 7498d9e1ee..0000000000 --- a/BaseTools/Source/Python/Common/Misc.py +++ /dev/null @@ -1,1531 +0,0 @@ -## @file -# Common routines used by all tools -# -# Copyright (c) 2007 - 2010, 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. -# - -## -# Import Modules -# -import os -import sys -import string -import thread -import threading -import time -import re -import cPickle -import array -from UserDict import IterableUserDict -from UserList import UserList - -from Common import EdkLogger as EdkLogger -from Common import GlobalData as GlobalData -from DataType import * -from BuildToolError import * - -## Regular expression used to find out place holders in string template -gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE|re.UNICODE) - -## Dictionary used to store file time stamp for quick re-access -gFileTimeStampCache = {} # {file path : file time stamp} - -## Dictionary used to store dependencies of files -gDependencyDatabase = {} # arch : {file path : [dependent files list]} - -## callback routine for processing variable option -# -# This function can be used to process variable number of option values. The -# typical usage of it is specify architecure list on command line. -# (e.g. <tool> -a IA32 X64 IPF) -# -# @param Option Standard callback function parameter -# @param OptionString Standard callback function parameter -# @param Value Standard callback function parameter -# @param Parser Standard callback function parameter -# -# @retval -# -def ProcessVariableArgument(Option, OptionString, Value, Parser): - assert Value is None - Value = [] - RawArgs = Parser.rargs - while RawArgs: - Arg = RawArgs[0] - if (Arg[:2] == "--" and len(Arg) > 2) or \ - (Arg[:1] == "-" and len(Arg) > 1 and Arg[1] != "-"): - break - Value.append(Arg) - del RawArgs[0] - setattr(Parser.values, Option.dest, Value) - -## Convert GUID string in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx style to C structure style -# -# @param Guid The GUID string -# -# @retval string The GUID string in C structure style -# -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 - -## Convert GUID structure in byte array to xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -# -# @param GuidValue The GUID value in byte array -# -# @retval string The GUID value in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format -# -def GuidStructureByteArrayToGuidString(GuidValue): - guidValueString = GuidValue.lower().replace("{", "").replace("}", "").replace(" ", "").replace(";", "") - guidValueList = guidValueString.split(",") - if len(guidValueList) != 16: - return '' - #EdkLogger.error(None, None, "Invalid GUID value string %s" % GuidValue) - try: - return "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" % ( - int(guidValueList[3], 16), - int(guidValueList[2], 16), - int(guidValueList[1], 16), - int(guidValueList[0], 16), - int(guidValueList[5], 16), - int(guidValueList[4], 16), - int(guidValueList[7], 16), - int(guidValueList[6], 16), - int(guidValueList[8], 16), - int(guidValueList[9], 16), - int(guidValueList[10], 16), - int(guidValueList[11], 16), - int(guidValueList[12], 16), - int(guidValueList[13], 16), - int(guidValueList[14], 16), - int(guidValueList[15], 16) - ) - except: - return '' - -## Convert GUID string in C structure style to xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -# -# @param GuidValue The GUID value in C structure format -# -# @retval string The GUID value in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format -# -def GuidStructureStringToGuidString(GuidValue): - guidValueString = GuidValue.lower().replace("{", "").replace("}", "").replace(" ", "").replace(";", "") - guidValueList = guidValueString.split(",") - if len(guidValueList) != 11: - return '' - #EdkLogger.error(None, None, "Invalid GUID value string %s" % GuidValue) - 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: - return '' - -## Convert GUID string in C structure style to xxxxxxxx_xxxx_xxxx_xxxx_xxxxxxxxxxxx -# -# @param GuidValue The GUID value in C structure format -# -# @retval string The GUID value in xxxxxxxx_xxxx_xxxx_xxxx_xxxxxxxxxxxx format -# -def GuidStructureStringToGuidValueName(GuidValue): - guidValueString = GuidValue.lower().replace("{", "").replace("}", "").replace(" ", "") - guidValueList = guidValueString.split(",") - if len(guidValueList) != 11: - EdkLogger.error(None, None, "Invalid GUID value string %s" % GuidValue) - 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) - ) - -## Create directories -# -# @param Directory The directory name -# -def CreateDirectory(Directory): - if Directory == None or Directory.strip() == "": - return True - try: - if not os.access(Directory, os.F_OK): - os.makedirs(Directory) - except: - 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 = os.getcwd() - os.chdir(Directory) - for File in os.listdir("."): - if os.path.isdir(File): - RemoveDirectory(File, Recursively) - else: - os.remove(File) - os.chdir(CurrentDirectory) - os.rmdir(Directory) - -## Check if given file is changed or not -# -# This method is used to check if a file is changed or not between two build -# actions. It makes use a cache to store files timestamp. -# -# @param File The path of file -# -# @retval True If the given file is changed, doesn't exist, or can't be -# found in timestamp cache -# @retval False If the given file is changed -# -def IsChanged(File): - if not os.path.exists(File): - return True - - FileState = os.stat(File) - TimeStamp = FileState[-2] - - if File in gFileTimeStampCache and TimeStamp == gFileTimeStampCache[File]: - FileChanged = False - else: - FileChanged = True - gFileTimeStampCache[File] = TimeStamp - - return FileChanged - -## 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 -# -# @retval True If the file content is changed and the file is renewed -# @retval False If the file content is the same -# -def SaveFileOnChange(File, Content, IsBinaryFile=True): - if not IsBinaryFile: - Content = Content.replace("\n", os.linesep) - - if os.path.exists(File): - try: - if Content == open(File, "rb").read(): - return False - except: - EdkLogger.error(None, FILE_OPEN_FAILURE, ExtraData=File) - - CreateDirectory(os.path.dirname(File)) - try: - if GlobalData.gIsWindows: - try: - from PyUtility import SaveFileToDisk - if not SaveFileToDisk(File, Content): - EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData=File) - except: - Fd = open(File, "wb") - Fd.write(Content) - Fd.close() - else: - Fd = open(File, "wb") - Fd.write(Content) - Fd.close() - except: - EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData=File) - - return True - -## Make a Python object persistent on file system -# -# @param Data The object to be stored in file -# @param File The path of file to store the object -# -def DataDump(Data, File): - Fd = None - try: - Fd = open(File, 'wb') - cPickle.dump(Data, Fd, cPickle.HIGHEST_PROTOCOL) - except: - EdkLogger.error("", FILE_OPEN_FAILURE, ExtraData=File, RaiseError=False) - finally: - if Fd != None: - Fd.close() - -## Restore a Python object from a file -# -# @param File The path of file stored the object -# -# @retval object A python object -# @retval None If failure in file operation -# -def DataRestore(File): - Data = None - Fd = None - try: - Fd = open(File, 'rb') - Data = cPickle.load(Fd) - except Exception, e: - EdkLogger.verbose("Failed to load [%s]\n\t%s" % (File, str(e))) - Data = None - finally: - if Fd != None: - Fd.close() - return Data - -## Retrieve and cache the real path name in file system -# -# @param Root The root directory of path relative to -# -# @retval str The path string if the path exists -# @retval None If path doesn't exist -# -class DirCache: - _CACHE_ = set() - _UPPER_CACHE_ = {} - - def __init__(self, Root): - self._Root = Root - for F in os.listdir(Root): - self._CACHE_.add(F) - self._UPPER_CACHE_[F.upper()] = F - - # =[] operator - def __getitem__(self, Path): - Path = Path[len(os.path.commonprefix([Path, self._Root])):] - if not Path: - return self._Root - if Path and Path[0] == os.path.sep: - Path = Path[1:] - if Path in self._CACHE_: - return os.path.join(self._Root, Path) - UpperPath = Path.upper() - if UpperPath in self._UPPER_CACHE_: - return os.path.join(self._Root, self._UPPER_CACHE_[UpperPath]) - - IndexList = [] - LastSepIndex = -1 - SepIndex = Path.find(os.path.sep) - while SepIndex > -1: - Parent = UpperPath[:SepIndex] - if Parent not in self._UPPER_CACHE_: - break - LastSepIndex = SepIndex - SepIndex = Path.find(os.path.sep, LastSepIndex + 1) - - if LastSepIndex == -1: - return None - - Cwd = os.getcwd() - os.chdir(self._Root) - SepIndex = LastSepIndex - while SepIndex > -1: - Parent = Path[:SepIndex] - ParentKey = UpperPath[:SepIndex] - if ParentKey not in self._UPPER_CACHE_: - os.chdir(Cwd) - return None - - if Parent in self._CACHE_: - ParentDir = Parent - else: - ParentDir = self._UPPER_CACHE_[ParentKey] - for F in os.listdir(ParentDir): - Dir = os.path.join(ParentDir, F) - self._CACHE_.add(Dir) - self._UPPER_CACHE_[Dir.upper()] = Dir - - SepIndex = Path.find(os.path.sep, SepIndex + 1) - - os.chdir(Cwd) - if Path in self._CACHE_: - return os.path.join(self._Root, Path) - elif UpperPath in self._UPPER_CACHE_: - return os.path.join(self._Root, self._UPPER_CACHE_[UpperPath]) - return None - -## Get all files of a directory -# -# @param Root: Root dir -# @param SkipList : The files need be skipped -# -# @retval A list of all files -# -def GetFiles(Root, SkipList=None, FullPath = True): - OriPath = Root - FileList = [] - for Root, Dirs, Files in os.walk(Root): - if SkipList: - for Item in SkipList: - if Item in Dirs: - Dirs.remove(Item) - - for File in Files: - File = os.path.normpath(os.path.join(Root, File)) - if not FullPath: - File = File[len(OriPath) + 1:] - FileList.append(File) - - return FileList - -## Check if gvien file exists or not -# -# @param File File name or path to be checked -# @param Dir The directory the file is relative to -# -# @retval True if file exists -# @retval False if file doesn't exists -# -def ValidFile(File, Ext=None): - if Ext != None: - Dummy, FileExt = os.path.splitext(File) - if FileExt.lower() != Ext.lower(): - return False - if not os.path.exists(File): - return False - return True - -def RealPath(File, Dir='', OverrideDir=''): - NewFile = os.path.normpath(os.path.join(Dir, File)) - NewFile = GlobalData.gAllFiles[NewFile] - if not NewFile and OverrideDir: - NewFile = os.path.normpath(os.path.join(OverrideDir, File)) - NewFile = GlobalData.gAllFiles[NewFile] - return NewFile - -def RealPath2(File, Dir='', OverrideDir=''): - if OverrideDir: - NewFile = GlobalData.gAllFiles[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.gAllFiles[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 - -## Check if gvien file exists or not -# -# -def ValidFile2(AllFiles, File, Ext=None, Workspace='', EfiSource='', EdkSource='', Dir='.', OverrideDir=''): - NewFile = File - if Ext != None: - Dummy, FileExt = os.path.splitext(File) - if FileExt.lower() != Ext.lower(): - return False, File - - # Replace the R8 macros - if OverrideDir != '' and OverrideDir != None: - if OverrideDir.find('$(EFI_SOURCE)') > -1: - OverrideDir = OverrideDir.replace('$(EFI_SOURCE)', EfiSource) - if OverrideDir.find('$(EDK_SOURCE)') > -1: - OverrideDir = OverrideDir.replace('$(EDK_SOURCE)', EdkSource) - - # Replace the default dir to current dir - if Dir == '.': - Dir = os.getcwd() - Dir = Dir[len(Workspace)+1:] - - # First check if File has R8 definition itself - if File.find('$(EFI_SOURCE)') > -1 or File.find('$(EDK_SOURCE)') > -1: - NewFile = File.replace('$(EFI_SOURCE)', EfiSource) - NewFile = NewFile.replace('$(EDK_SOURCE)', EdkSource) - NewFile = AllFiles[os.path.normpath(NewFile)] - if NewFile != None: - return True, NewFile - - # Second check the path with override value - if OverrideDir != '' and OverrideDir != None: - NewFile = AllFiles[os.path.normpath(os.path.join(OverrideDir, File))] - if NewFile != None: - return True, NewFile - - # Last check the path with normal definitions - File = os.path.join(Dir, File) - NewFile = AllFiles[os.path.normpath(File)] - if NewFile != None: - return True, NewFile - - return False, File - -## Check if gvien file exists or not -# -# -def ValidFile3(AllFiles, File, Workspace='', EfiSource='', EdkSource='', Dir='.', OverrideDir=''): - # Replace the R8 macros - if OverrideDir != '' and OverrideDir != None: - if OverrideDir.find('$(EFI_SOURCE)') > -1: - OverrideDir = OverrideDir.replace('$(EFI_SOURCE)', EfiSource) - if OverrideDir.find('$(EDK_SOURCE)') > -1: - OverrideDir = OverrideDir.replace('$(EDK_SOURCE)', EdkSource) - - # Replace the default dir to current dir - # Dir is current module dir related to workspace - if Dir == '.': - Dir = os.getcwd() - Dir = Dir[len(Workspace)+1:] - - NewFile = File - RelaPath = AllFiles[os.path.normpath(Dir)] - NewRelaPath = RelaPath - - while(True): - # First check if File has R8 definition itself - if File.find('$(EFI_SOURCE)') > -1 or File.find('$(EDK_SOURCE)') > -1: - File = File.replace('$(EFI_SOURCE)', EfiSource) - File = File.replace('$(EDK_SOURCE)', EdkSource) - NewFile = AllFiles[os.path.normpath(File)] - if NewFile != None: - NewRelaPath = os.path.dirname(NewFile) - File = os.path.basename(NewFile) - #NewRelaPath = NewFile[:len(NewFile) - len(File.replace("..\\", '').replace("../", '')) - 1] - break - - # Second check the path with override value - if OverrideDir != '' and OverrideDir != None: - NewFile = AllFiles[os.path.normpath(os.path.join(OverrideDir, File))] - if NewFile != None: - #NewRelaPath = os.path.dirname(NewFile) - NewRelaPath = NewFile[:len(NewFile) - len(File.replace("..\\", '').replace("../", '')) - 1] - break - - # Last check the path with normal definitions - NewFile = AllFiles[os.path.normpath(os.path.join(Dir, File))] - if NewFile != None: - break - - # No file found - break - - return NewRelaPath, RelaPath, File - - -def GetRelPath(Path1, Path2): - FileName = os.path.basename(Path2) - L1 = os.path.normpath(Path1).split(os.path.normpath('/')) - L2 = os.path.normpath(Path2).split(os.path.normpath('/')) - for Index in range(0, len(L1)): - if L1[Index] != L2[Index]: - FileName = '../' * (len(L1) - Index) - for Index2 in range(Index, len(L2)): - FileName = os.path.join(FileName, L2[Index2]) - break - return os.path.normpath(FileName) - - -## Get GUID value from given packages -# -# @param CName The CName of the GUID -# @param PackageList List of packages looking-up in -# -# @retval GuidValue if the CName is found in any given package -# @retval None if the CName is not found in all given packages -# -def GuidValue(CName, PackageList): - for P in PackageList: - if CName in P.Guids: - return P.Guids[CName] - return None - -## Get Protocol value from given packages -# -# @param CName The CName of the GUID -# @param PackageList List of packages looking-up in -# -# @retval GuidValue if the CName is found in any given package -# @retval None if the CName is not found in all given packages -# -def ProtocolValue(CName, PackageList): - for P in PackageList: - if CName in P.Protocols: - return P.Protocols[CName] - return None - -## Get PPI value from given packages -# -# @param CName The CName of the GUID -# @param PackageList List of packages looking-up in -# -# @retval GuidValue if the CName is found in any given package -# @retval None if the CName is not found in all given packages -# -def PpiValue(CName, PackageList): - for P in PackageList: - if CName in P.Ppis: - return P.Ppis[CName] - return None - -## A string template class -# -# This class implements a template for string replacement. A string template -# looks like following -# -# ${BEGIN} other_string ${placeholder_name} other_string ${END} -# -# The string between ${BEGIN} and ${END} will be repeated as many times as the -# length of "placeholder_name", which is a list passed through a dict. The -# "placeholder_name" is the key name of the dict. The ${BEGIN} and ${END} can -# be not used and, in this case, the "placeholder_name" must not a list and it -# will just be replaced once. -# -class TemplateString(object): - _REPEAT_START_FLAG = "BEGIN" - _REPEAT_END_FLAG = "END" - - class Section(object): - _LIST_TYPES = [type([]), type(set()), type((0,))] - - def __init__(self, TemplateSection, PlaceHolderList): - self._Template = TemplateSection - self._PlaceHolderList = [] - - # Split the section into sub-sections according to the position of placeholders - if PlaceHolderList: - self._SubSectionList = [] - SubSectionStart = 0 - # - # The placeholders passed in must be in the format of - # - # PlaceHolderName, PlaceHolderStartPoint, PlaceHolderEndPoint - # - for PlaceHolder,Start,End in PlaceHolderList: - self._SubSectionList.append(TemplateSection[SubSectionStart:Start]) - self._SubSectionList.append(TemplateSection[Start:End]) - self._PlaceHolderList.append(PlaceHolder) - SubSectionStart = End - if SubSectionStart < len(TemplateSection): - self._SubSectionList.append(TemplateSection[SubSectionStart:]) - else: - self._SubSectionList = [TemplateSection] - - def __str__(self): - return self._Template + " : " + str(self._PlaceHolderList) - - def Instantiate(self, PlaceHolderValues): - RepeatTime = -1 - RepeatPlaceHolders = {} - NonRepeatPlaceHolders = {} - - for PlaceHolder in self._PlaceHolderList: - if PlaceHolder not in PlaceHolderValues: - continue - Value = PlaceHolderValues[PlaceHolder] - if type(Value) in self._LIST_TYPES: - if RepeatTime < 0: - RepeatTime = len(Value) - elif RepeatTime != len(Value): - EdkLogger.error( - "TemplateString", - PARAMETER_INVALID, - "${%s} has different repeat time from others!" % PlaceHolder, - ExtraData=str(self._Template) - ) - RepeatPlaceHolders["${%s}" % PlaceHolder] = Value - else: - NonRepeatPlaceHolders["${%s}" % PlaceHolder] = Value - - if NonRepeatPlaceHolders: - StringList = [] - for S in self._SubSectionList: - if S not in NonRepeatPlaceHolders: - StringList.append(S) - else: - StringList.append(str(NonRepeatPlaceHolders[S])) - else: - StringList = self._SubSectionList - - if RepeatPlaceHolders: - TempStringList = [] - for Index in range(RepeatTime): - for S in StringList: - if S not in RepeatPlaceHolders: - TempStringList.append(S) - else: - TempStringList.append(str(RepeatPlaceHolders[S][Index])) - StringList = TempStringList - - return "".join(StringList) - - ## Constructor - def __init__(self, Template=None): - self.String = '' - self.IsBinary = False - self._Template = Template - self._TemplateSectionList = self._Parse(Template) - - ## str() operator - # - # @retval string The string replaced - # - def __str__(self): - return self.String - - ## Split the template string into fragments per the ${BEGIN} and ${END} flags - # - # @retval list A list of TemplateString.Section objects - # - def _Parse(self, Template): - SectionStart = 0 - SearchFrom = 0 - MatchEnd = 0 - PlaceHolderList = [] - TemplateSectionList = [] - while Template: - MatchObj = gPlaceholderPattern.search(Template, SearchFrom) - if not MatchObj: - if MatchEnd <= len(Template): - TemplateSection = TemplateString.Section(Template[SectionStart:], PlaceHolderList) - TemplateSectionList.append(TemplateSection) - break - - MatchString = MatchObj.group(1) - MatchStart = MatchObj.start() - MatchEnd = MatchObj.end() - - if MatchString == self._REPEAT_START_FLAG: - if MatchStart > SectionStart: - TemplateSection = TemplateString.Section(Template[SectionStart:MatchStart], PlaceHolderList) - TemplateSectionList.append(TemplateSection) - SectionStart = MatchEnd - PlaceHolderList = [] - elif MatchString == self._REPEAT_END_FLAG: - TemplateSection = TemplateString.Section(Template[SectionStart:MatchStart], PlaceHolderList) - TemplateSectionList.append(TemplateSection) - SectionStart = MatchEnd - PlaceHolderList = [] - else: - PlaceHolderList.append((MatchString, MatchStart - SectionStart, MatchEnd - SectionStart)) - SearchFrom = MatchEnd - return TemplateSectionList - - ## Replace the string template with dictionary of placeholders and append it to previous one - # - # @param AppendString The string template to append - # @param Dictionary The placeholder dictionaries - # - def Append(self, AppendString, Dictionary=None): - if Dictionary: - SectionList = self._Parse(AppendString) - self.String += "".join([S.Instantiate(Dictionary) for S in SectionList]) - else: - self.String += AppendString - - ## Replace the string template with dictionary of placeholders - # - # @param Dictionary The placeholder dictionaries - # - # @retval str The string replaced with placeholder values - # - def Replace(self, Dictionary=None): - return "".join([S.Instantiate(Dictionary) for S in self._TemplateSectionList]) - -## Progress indicator class -# -# This class makes use of thread to print progress on console. -# -class Progressor: - # for avoiding deadloop - _StopFlag = None - _ProgressThread = None - _CheckInterval = 0.25 - - ## Constructor - # - # @param OpenMessage The string printed before progress charaters - # @param CloseMessage The string printed after progress charaters - # @param ProgressChar The charater used to indicate the progress - # @param Interval The interval in seconds between two progress charaters - # - def __init__(self, OpenMessage="", CloseMessage="", ProgressChar='.', Interval=1.0): - self.PromptMessage = OpenMessage - self.CodaMessage = CloseMessage - self.ProgressChar = ProgressChar - self.Interval = Interval - if Progressor._StopFlag == None: - Progressor._StopFlag = threading.Event() - - ## Start to print progress charater - # - # @param OpenMessage The string printed before progress charaters - # - def Start(self, OpenMessage=None): - if OpenMessage != None: - self.PromptMessage = OpenMessage - Progressor._StopFlag.clear() - if Progressor._ProgressThread == None: - Progressor._ProgressThread = threading.Thread(target=self._ProgressThreadEntry) - Progressor._ProgressThread.setDaemon(False) - Progressor._ProgressThread.start() - - ## Stop printing progress charater - # - # @param CloseMessage The string printed after progress charaters - # - def Stop(self, CloseMessage=None): - OriginalCodaMessage = self.CodaMessage - if CloseMessage != None: - self.CodaMessage = CloseMessage - self.Abort() - self.CodaMessage = OriginalCodaMessage - - ## Thread entry method - def _ProgressThreadEntry(self): - sys.stdout.write(self.PromptMessage + " ") - sys.stdout.flush() - TimeUp = 0.0 - while not Progressor._StopFlag.isSet(): - if TimeUp <= 0.0: - sys.stdout.write(self.ProgressChar) - sys.stdout.flush() - TimeUp = self.Interval - time.sleep(self._CheckInterval) - TimeUp -= self._CheckInterval - sys.stdout.write(" " + self.CodaMessage + "\n") - sys.stdout.flush() - - ## Abort the progress display - @staticmethod - def Abort(): - if Progressor._StopFlag != None: - Progressor._StopFlag.set() - if Progressor._ProgressThread != None: - Progressor._ProgressThread.join() - Progressor._ProgressThread = 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, sdict): - for key in sdict: - if key not in self._key_list: - self._key_list.append(key) - IterableUserDict.__setitem__(self, key, sdict[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 = kv[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 - - def update(self, dict=None, **kwargs): - if dict != None: - for k, v in dict.items(): - self[k] = v - if len(kwargs): - for k, v in kwargs.items(): - self[k] = v - -## Dictionary with restricted keys -# -class rdict(dict): - ## Constructor - def __init__(self, KeyList): - for Key in KeyList: - dict.__setitem__(self, Key, "") - - ## []= operator - def __setitem__(self, key, value): - if key not in self: - EdkLogger.error("RestrictedDict", ATTRIBUTE_SET_FAILURE, "Key [%s] is not allowed" % key, - ExtraData=", ".join(dict.keys(self))) - dict.__setitem__(self, key, value) - - ## =[] operator - def __getitem__(self, key): - if key not in self: - return "" - return dict.__getitem__(self, key) - - ## del operator - def __delitem__(self, key): - EdkLogger.error("RestrictedDict", ATTRIBUTE_ACCESS_DENIED, ExtraData="del") - - ## Empty the dict - def clear(self): - for Key in self: - self.__setitem__(Key, "") - - ## Return value related to a key, and remove the (key, value) from the dict - def pop(self, key, *dv): - EdkLogger.error("RestrictedDict", ATTRIBUTE_ACCESS_DENIED, ExtraData="pop") - - ## Return (key, value) pair, and remove the (key, value) from the dict - def popitem(self): - EdkLogger.error("RestrictedDict", ATTRIBUTE_ACCESS_DENIED, ExtraData="popitem") - -## Dictionary using prioritized list as key -# -class tdict: - _ListType = type([]) - _TupleType = type(()) - _Wildcard = 'COMMON' - _ValidWildcardList = ['COMMON', 'DEFAULT', 'ALL', '*', 'PLATFORM'] - - def __init__(self, _Single_=False, _Level_=2): - self._Level_ = _Level_ - self.data = {} - self._Single_ = _Single_ - - # =[] operator - def __getitem__(self, key): - KeyType = type(key) - RestKeys = None - if KeyType == self._ListType or KeyType == self._TupleType: - FirstKey = key[0] - if len(key) > 1: - RestKeys = key[1:] - elif self._Level_ > 1: - RestKeys = [self._Wildcard for i in range(0, self._Level_-1)] - else: - FirstKey = key - if self._Level_ > 1: - RestKeys = [self._Wildcard for i in range(0, self._Level_-1)] - - if FirstKey == None or str(FirstKey).upper() in self._ValidWildcardList: - FirstKey = self._Wildcard - - if self._Single_: - return self._GetSingleValue(FirstKey, RestKeys) - else: - return self._GetAllValues(FirstKey, RestKeys) - - def _GetSingleValue(self, FirstKey, RestKeys): - Value = None - #print "%s-%s" % (FirstKey, self._Level_) , - if self._Level_ > 1: - if FirstKey == self._Wildcard: - if FirstKey in self.data: - Value = self.data[FirstKey][RestKeys] - if Value == None: - for Key in self.data: - Value = self.data[Key][RestKeys] - if Value != None: break - else: - if FirstKey in self.data: - Value = self.data[FirstKey][RestKeys] - if Value == None and self._Wildcard in self.data: - #print "Value=None" - Value = self.data[self._Wildcard][RestKeys] - else: - if FirstKey == self._Wildcard: - if FirstKey in self.data: - Value = self.data[FirstKey] - if Value == None: - for Key in self.data: - Value = self.data[Key] - if Value != None: break - else: - if FirstKey in self.data: - Value = self.data[FirstKey] - elif self._Wildcard in self.data: - Value = self.data[self._Wildcard] - return Value - - def _GetAllValues(self, FirstKey, RestKeys): - Value = [] - if self._Level_ > 1: - if FirstKey == self._Wildcard: - for Key in self.data: - Value += self.data[Key][RestKeys] - else: - if FirstKey in self.data: - Value += self.data[FirstKey][RestKeys] - if self._Wildcard in self.data: - Value += self.data[self._Wildcard][RestKeys] - else: - if FirstKey == self._Wildcard: - for Key in self.data: - Value.append(self.data[Key]) - else: - if FirstKey in self.data: - Value.append(self.data[FirstKey]) - if self._Wildcard in self.data: - Value.append(self.data[self._Wildcard]) - return Value - - ## []= operator - def __setitem__(self, key, value): - KeyType = type(key) - RestKeys = None - if KeyType == self._ListType or KeyType == self._TupleType: - FirstKey = key[0] - if len(key) > 1: - RestKeys = key[1:] - else: - RestKeys = [self._Wildcard for i in range(0, self._Level_-1)] - else: - FirstKey = key - if self._Level_ > 1: - RestKeys = [self._Wildcard for i in range(0, self._Level_-1)] - - if FirstKey in self._ValidWildcardList: - FirstKey = self._Wildcard - - if FirstKey not in self.data and self._Level_ > 0: - self.data[FirstKey] = tdict(self._Single_, self._Level_ - 1) - - if self._Level_ > 1: - self.data[FirstKey][RestKeys] = value - else: - self.data[FirstKey] = value - - def SetGreedyMode(self): - self._Single_ = False - if self._Level_ > 1: - for Key in self.data: - self.data[Key].SetGreedyMode() - - def SetSingleMode(self): - self._Single_ = True - if self._Level_ > 1: - for Key in self.data: - self.data[Key].SetSingleMode() - - def GetKeys(self, KeyIndex=0): - assert KeyIndex >= 0 - if KeyIndex == 0: - return set(self.data.keys()) - else: - keys = set() - for Key in self.data: - keys |= self.data[Key].GetKeys(KeyIndex - 1) - return keys - -## Boolean chain list -# -class Blist(UserList): - def __init__(self, initlist=None): - UserList.__init__(self, initlist) - def __setitem__(self, i, item): - if item not in [True, False]: - if item == 0: - item = False - else: - item = True - self.data[i] = item - def _GetResult(self): - Value = True - for item in self.data: - Value &= item - return Value - Result = property(_GetResult) - -def ParseConsoleLog(Filename): - Opr = open(os.path.normpath(Filename), 'r') - Opw = open(os.path.normpath(Filename + '.New'), 'w+') - for Line in Opr.readlines(): - if Line.find('.efi') > -1: - Line = Line[Line.rfind(' ') : Line.rfind('.efi')].strip() - Opw.write('%s\n' % Line) - - Opr.close() - Opw.close() - -## AnalyzePcdData -# -# Analyze the pcd Value, Datum type and TokenNumber. -# Used to avoid split issue while the value string contain "|" character -# -# @param[in] Setting: A String contain value/datum type/token number information; -# -# @retval ValueList: A List contain value, datum type and toke number. -# -def AnalyzePcdData(Setting): - ValueList = ['', '', ''] - - ValueRe = re.compile(r'^\s*L?\".*\|.*\"') - PtrValue = ValueRe.findall(Setting) - - ValueUpdateFlag = False - - if len(PtrValue) >= 1: - Setting = re.sub(ValueRe, '', Setting) - ValueUpdateFlag = True - - TokenList = Setting.split(TAB_VALUE_SPLIT) - ValueList[0:len(TokenList)] = TokenList - - if ValueUpdateFlag: - ValueList[0] = PtrValue[0] - - return ValueList - -## AnalyzeHiiPcdData -# -# Analyze the pcd Value, variable name, variable Guid and variable offset. -# Used to avoid split issue while the value string contain "|" character -# -# @param[in] Setting: A String contain VariableName, VariableGuid, VariableOffset, DefaultValue information; -# -# @retval ValueList: A List contaian VariableName, VariableGuid, VariableOffset, DefaultValue. -# -def AnalyzeHiiPcdData(Setting): - ValueList = ['', '', '', ''] - - ValueRe = re.compile(r'^\s*L?\".*\|.*\"') - PtrValue = ValueRe.findall(Setting) - - ValueUpdateFlag = False - - if len(PtrValue) >= 1: - Setting = re.sub(ValueRe, '', Setting) - ValueUpdateFlag = True - - TokenList = Setting.split(TAB_VALUE_SPLIT) - ValueList[0:len(TokenList)] = TokenList - - if ValueUpdateFlag: - ValueList[0] = PtrValue[0] - - return ValueList - -## AnalyzeVpdPcdData -# -# Analyze the vpd pcd Value, Datum type and TokenNumber. -# Used to avoid split issue while the value string contain "|" character -# -# @param[in] Setting: A String contain value/datum type/token number information; -# -# @retval ValueList: A List contain value, datum type and toke number. -# -def AnalyzeVpdPcdData(Setting): - ValueList = ['', '', ''] - - ValueRe = re.compile(r'\s*L?\".*\|.*\"\s*$') - PtrValue = ValueRe.findall(Setting) - - ValueUpdateFlag = False - - if len(PtrValue) >= 1: - Setting = re.sub(ValueRe, '', Setting) - ValueUpdateFlag = True - - TokenList = Setting.split(TAB_VALUE_SPLIT) - ValueList[0:len(TokenList)] = TokenList - - if ValueUpdateFlag: - ValueList[2] = PtrValue[0] - - return ValueList - -## check format of PCD value against its the datum type -# -# For PCD value setting -# -def CheckPcdDatum(Type, Value): - if Type == "VOID*": - if not (((Value.startswith('L"') or Value.startswith('"')) and Value.endswith('"')) - or (Value.startswith('{') and Value.endswith('}')) - ): - return False, "Invalid value [%s] of type [%s]; must be in the form of {...} for array"\ - ", or \"...\" for string, or L\"...\" for unicode string" % (Value, Type) - elif Type == 'BOOLEAN': - if Value not in ['TRUE', 'True', 'true', '0x1', '0x01', '1', 'FALSE', 'False', 'false', '0x0', '0x00', '0']: - return False, "Invalid value [%s] of type [%s]; must be one of TRUE, True, true, 0x1, 0x01, 1"\ - ", FALSE, False, false, 0x0, 0x00, 0" % (Value, Type) - elif type(Value) == type(""): - try: - Value = long(Value, 0) - except: - return False, "Invalid value [%s] of type [%s];"\ - " must be a hexadecimal, decimal or octal in C language format."\ - % (Value, Type) - - return True, "" - -## Split command line option string to list -# -# subprocess.Popen needs the args to be a sequence. Otherwise there's problem -# in non-windows platform to launch command -# -def SplitOption(OptionString): - OptionList = [] - LastChar = " " - OptionStart = 0 - QuotationMark = "" - for Index in range(0, len(OptionString)): - CurrentChar = OptionString[Index] - if CurrentChar in ['"', "'"]: - if QuotationMark == CurrentChar: - QuotationMark = "" - elif QuotationMark == "": - QuotationMark = CurrentChar - continue - elif QuotationMark: - continue - - if CurrentChar in ["/", "-"] and LastChar in [" ", "\t", "\r", "\n"]: - if Index > OptionStart: - OptionList.append(OptionString[OptionStart:Index-1]) - OptionStart = Index - LastChar = CurrentChar - OptionList.append(OptionString[OptionStart:]) - return OptionList - -def CommonPath(PathList): - P1 = min(PathList).split(os.path.sep) - P2 = max(PathList).split(os.path.sep) - for Index in xrange(min(len(P1), len(P2))): - if P1[Index] != P2[Index]: - return os.path.sep.join(P1[:Index]) - return os.path.sep.join(P1) - -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 - # - # @retval string Formatted String - # - def __str__(self): - return self.Path - - ## Override __eq__ function - # - # Check whether PathClass are the same - # - # @retval False The two PathClass are different - # @retval True The two 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 - # - # @retval string Key for hash table - # - def __hash__(self): - return hash(self.Path) - - def _GetFileKey(self): - if self._Key == None: - self._Key = self.Path.upper() # + self.ToolChainFamily + self.TagName + self.ToolCode + self.Target - return self._Key - - def Validate(self, Type='', CaseSensitive=True): - if GlobalData.gCaseInsensitive: - CaseSensitive = False - if Type and Type.lower() != self.Type: - return 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 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 = 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) - -## Parse PE image to get the required PE informaion. -# -class PeImageClass(): - ## Constructor - # - # @param File FilePath of PeImage - # - def __init__(self, PeFile): - self.FileName = PeFile - self.IsValid = False - self.Size = 0 - self.EntryPoint = 0 - self.SectionAlignment = 0 - self.SectionHeaderList = [] - self.ErrorInfo = '' - try: - PeObject = open(PeFile, 'rb') - except: - self.ErrorInfo = self.FileName + ' can not be found\n' - return - # Read DOS header - ByteArray = array.array('B') - ByteArray.fromfile(PeObject, 0x3E) - ByteList = ByteArray.tolist() - # DOS signature should be 'MZ' - if self._ByteListToStr (ByteList[0x0:0x2]) != 'MZ': - self.ErrorInfo = self.FileName + ' has no valid DOS signature MZ' - return - - # Read 4 byte PE Signature - PeOffset = self._ByteListToInt(ByteList[0x3C:0x3E]) - PeObject.seek(PeOffset) - ByteArray = array.array('B') - ByteArray.fromfile(PeObject, 4) - # PE signature should be 'PE\0\0' - if ByteArray.tostring() != 'PE\0\0': - self.ErrorInfo = self.FileName + ' has no valid PE signature PE00' - return - - # Read PE file header - ByteArray = array.array('B') - ByteArray.fromfile(PeObject, 0x14) - ByteList = ByteArray.tolist() - SecNumber = self._ByteListToInt(ByteList[0x2:0x4]) - if SecNumber == 0: - self.ErrorInfo = self.FileName + ' has no section header' - return - - # Read PE optional header - OptionalHeaderSize = self._ByteListToInt(ByteArray[0x10:0x12]) - ByteArray = array.array('B') - ByteArray.fromfile(PeObject, OptionalHeaderSize) - ByteList = ByteArray.tolist() - self.EntryPoint = self._ByteListToInt(ByteList[0x10:0x14]) - self.SectionAlignment = self._ByteListToInt(ByteList[0x20:0x24]) - self.Size = self._ByteListToInt(ByteList[0x38:0x3C]) - - # Read each Section Header - for Index in range(SecNumber): - ByteArray = array.array('B') - ByteArray.fromfile(PeObject, 0x28) - ByteList = ByteArray.tolist() - SecName = self._ByteListToStr(ByteList[0:8]) - SecVirtualSize = self._ByteListToInt(ByteList[8:12]) - SecRawAddress = self._ByteListToInt(ByteList[20:24]) - SecVirtualAddress = self._ByteListToInt(ByteList[12:16]) - self.SectionHeaderList.append((SecName, SecVirtualAddress, SecRawAddress, SecVirtualSize)) - self.IsValid = True - PeObject.close() - - def _ByteListToStr(self, ByteList): - String = '' - for index in range(len(ByteList)): - if ByteList[index] == 0: - break - String += chr(ByteList[index]) - return String - - def _ByteListToInt(self, ByteList): - Value = 0 - for index in range(len(ByteList) - 1, -1, -1): - Value = (Value << 8) | int(ByteList[index]) - return Value - -## -# -# This acts like the main() function for the script, unless it is 'import'ed into another -# script. -# -if __name__ == '__main__': - pass - |