X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FUPT%2FLibrary%2FMisc.py;h=77ba3584e00054b56aa94535e59f676db44a0fee;hb=HEAD;hp=bc9e0e172bf748f56de2424f501859252013461f;hpb=421ccda3079077dd613308526e02d797f5cc356a;p=mirror_edk2.git diff --git a/BaseTools/Source/Python/UPT/Library/Misc.py b/BaseTools/Source/Python/UPT/Library/Misc.py index bc9e0e172b..77ba3584e0 100644 --- a/BaseTools/Source/Python/UPT/Library/Misc.py +++ b/BaseTools/Source/Python/UPT/Library/Misc.py @@ -1,15 +1,9 @@ ## @file # Common routines used by all tools # -# Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.
# -# 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. +# SPDX-License-Identifier: BSD-2-Clause-Patent # ''' @@ -32,7 +26,7 @@ from os import linesep from os import walk from os import environ import re -from UserDict import IterableUserDict +from collections import OrderedDict as Sdict import Logger.Log as Logger from Logger import StringTable as ST @@ -45,13 +39,14 @@ from Library.DataType import TAB_LANGUAGE_EN_US from Library.DataType import TAB_LANGUAGE_EN from Library.DataType import TAB_LANGUAGE_EN_X from Library.DataType import TAB_UNI_FILE_SUFFIXS -from Library.String import GetSplitValueList +from Library.StringUtils import GetSplitValueList from Library.ParserValidate import IsValidHexVersion from Library.ParserValidate import IsValidPath from Object.POM.CommonObject import TextObject from Core.FileHook import __FileHookOpen__ +from Common.MultipleWorkspace import MultipleWorkspace as mws -## Convert GUID string in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx style to C +## Convert GUID string in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx style to C # structure style # # @param Guid: The GUID string @@ -86,7 +81,7 @@ def CheckGuidRegFormat(GuidValue): return False -## Convert GUID string in C structure style to +## Convert GUID string in C structure style to # xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx # # @param GuidValue: The GUID value in C structure format @@ -119,7 +114,7 @@ def GuidStructureStringToGuidString(GuidValue): # @param Directory: The directory name # def CreateDirectory(Directory): - if Directory == None or Directory.strip() == "": + if Directory is None or Directory.strip() == "": return True try: if not access(Directory, F_OK): @@ -133,7 +128,7 @@ def CreateDirectory(Directory): # @param Directory: The directory name # def RemoveDirectory(Directory, Recursively=False): - if Directory == None or Directory.strip() == "" or not \ + if Directory is None or Directory.strip() == "" or not \ os.path.exists(Directory): return if Recursively: @@ -150,32 +145,44 @@ def RemoveDirectory(Directory, Recursively=False): ## 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 +# 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 +# @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 == __FileHookOpen__(File, "rb").read(): - return False - except BaseException: - Logger.Error(None, ToolError.FILE_OPEN_FAILURE, ExtraData=File) + if IsBinaryFile: + try: + if Content == __FileHookOpen__(File, "rb").read(): + return False + except BaseException: + Logger.Error(None, ToolError.FILE_OPEN_FAILURE, ExtraData=File) + else: + try: + if Content == __FileHookOpen__(File, "r").read(): + return False + except BaseException: + Logger.Error(None, ToolError.FILE_OPEN_FAILURE, ExtraData=File) CreateDirectory(os.path.dirname(File)) - try: - FileFd = __FileHookOpen__(File, "wb") - FileFd.write(Content) - FileFd.close() - except BaseException: - Logger.Error(None, ToolError.FILE_CREATE_FAILURE, ExtraData=File) + if IsBinaryFile: + try: + FileFd = __FileHookOpen__(File, "wb") + FileFd.write(Content) + FileFd.close() + except BaseException: + Logger.Error(None, ToolError.FILE_CREATE_FAILURE, ExtraData=File) + else: + try: + FileFd = __FileHookOpen__(File, "w") + FileFd.write(Content) + FileFd.close() + except BaseException: + Logger.Error(None, ToolError.FILE_CREATE_FAILURE, ExtraData=File) return True @@ -215,7 +222,7 @@ def GetFiles(Root, SkipList=None, FullPath=True): # @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 = [] @@ -236,7 +243,7 @@ def GetNonMetaDataFiles(Root, SkipList, FullPath, PrefixPath): # def ValidFile(File, Ext=None): File = File.replace('\\', '/') - if Ext != None: + if Ext is not None: FileExt = os.path.splitext(File)[1] if FileExt.lower() != Ext.lower(): return False @@ -287,148 +294,6 @@ def RealPath2(File, Dir='', OverrideDir=''): 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 @@ -436,7 +301,7 @@ class Sdict(IterableUserDict): 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))): + for Index in range(min(len(Path1), len(Path2))): if Path1[Index] != Path2[Index]: return os.path.sep.join(Path1[:Index]) return os.path.sep.join(Path1) @@ -513,7 +378,7 @@ class PathClass(object): # Check whether PathClass are the same # def __eq__(self, Other): - if type(Other) == type(self): + if isinstance(Other, type(self)): return self.Path == Other.Path else: return self.Path == str(Other) @@ -528,7 +393,7 @@ class PathClass(object): ## _GetFileKey # def _GetFileKey(self): - if self._Key == None: + if self._Key is None: self._Key = self.Path.upper() return self._Key ## Validate @@ -592,30 +457,34 @@ def GetWorkspace(): if WorkspaceDir[-1] == ':': WorkspaceDir += os.sep - return WorkspaceDir + + PackagesPath = os.environ.get("PACKAGES_PATH") + mws.setWs(WorkspaceDir, PackagesPath) + + return WorkspaceDir, mws.PACKAGES_PATH ## Get relative path # # use full path and workspace to get relative path -# the destination of this function is mainly to resolve the root path issue(like c: or c:\) +# the destination of this function is mainly to resolve the root path issue(like c: or c:\) # # @param Fullpath: a string of fullpath # @param Workspace: a string of workspace # def GetRelativePath(Fullpath, Workspace): - + RelativePath = '' if Workspace.endswith(os.sep): RelativePath = Fullpath[Fullpath.upper().find(Workspace.upper())+len(Workspace):] else: RelativePath = Fullpath[Fullpath.upper().find(Workspace.upper())+len(Workspace)+1:] - + return RelativePath - + ## 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): @@ -627,9 +496,9 @@ def IsAllModuleList(ModuleList): return True ## Dictionary that use comment(GenericComment, TailComment) as value, -# if a new comment which key already in the dic is inserted, then the +# 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 +# Key is (Statement, SupArch), when TailComment is added, it will ident # according to Statement # class MergeCommentDict(dict): @@ -666,7 +535,7 @@ def GenDummyHelpTextObj(): # ::= (a-fA-F0-9){4} # ::= (a-fA-F0-9){4} # ::= (0-65535) ["." (0-99)] -# +# # @param StringIn: The string contains version defined in INF file. # It can be Decimal or Hex # @@ -759,7 +628,7 @@ def ConvertPath(Path): ## ConvertSpec # -# during install, convert the Spec string extract from UPD into INF allowable definition, +# 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 # @@ -782,7 +651,7 @@ def ConvertSpec(SpecStr): # 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 # @@ -803,10 +672,10 @@ def IsEqualList(ListA, ListB): ## 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])* +# 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): @@ -814,11 +683,11 @@ def ConvertArchList(ArchList): if not ArchList: return NewArchList - if type(ArchList) == list: + if isinstance(ArchList, list): for Arch in ArchList: Arch = Arch.upper() NewArchList.append(Arch) - elif type(ArchList) == str: + elif isinstance(ArchList, str): ArchList = ArchList.upper() NewArchList.append(ArchList) @@ -830,7 +699,7 @@ def ConvertArchList(ArchList): # 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): @@ -849,11 +718,11 @@ def ProcessLineExtender(LineList): ## ProcessEdkComment # -# Process EDK style comment in LineList: c style /* */ comment or cpp style // comment +# 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 # @@ -863,7 +732,7 @@ def ProcessEdkComment(LineList): StartPos = -1 EndPos = -1 FirstPos = -1 - + while(Count < len(LineList)): Line = LineList[Count].strip() if Line.startswith("/*"): @@ -881,11 +750,11 @@ def ProcessEdkComment(LineList): FindEdkBlockComment = True break Count = Count + 1 - + if FindEdkBlockComment: if FirstPos == -1: FirstPos = StartPos - for Index in xrange(StartPos, EndPos+1): + for Index in range(StartPos, EndPos+1): LineList[Index] = '' FindEdkBlockComment = False elif Line.find("//") != -1 and not Line.startswith("#"): @@ -895,9 +764,9 @@ def ProcessEdkComment(LineList): LineList[Count] = Line.replace("//", '#') if FirstPos == -1: FirstPos = Count - + Count = Count + 1 - + return LineList, FirstPos ## GetLibInstanceInfo @@ -913,7 +782,7 @@ def GetLibInstanceInfo(String, WorkSpace, LineNo): FileGuidString = "" VerString = "" - OrignalString = String + OriginalString = String String = String.strip() if not String: return None, None @@ -933,7 +802,7 @@ def GetLibInstanceInfo(String, WorkSpace, LineNo): ST.ERR_FILELIST_EXIST % (String), File=GlobalData.gINF_MODULE_NAME, Line=LineNo, - ExtraData=OrignalString) + ExtraData=OriginalString) # # Validate file exist/format. @@ -946,13 +815,13 @@ def GetLibInstanceInfo(String, WorkSpace, LineNo): ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID % (String), File=GlobalData.gINF_MODULE_NAME, Line=LineNo, - ExtraData=OrignalString) + ExtraData=OriginalString) return False if IsValidFileFlag: FileLinesList = [] try: - FInputfile = open(FullFileName, "rb", 0) + FInputfile = open(FullFileName, "r") try: FileLinesList = FInputfile.readlines() except BaseException: @@ -989,13 +858,13 @@ def GetLibInstanceInfo(String, WorkSpace, LineNo): ## GetLocalValue # # Generate the local value for INF and DEC file. If Lang attribute not present, then use this value. -# If present, and there is no element without the Lang attribute, and one of the elements has the rfc1766 code is -# "en-x-tianocore", or "en-US" if "en-x-tianocore" was not found, or "en" if "en-US" was not found, or startswith 'en' +# If present, and there is no element without the Lang attribute, and one of the elements has the rfc1766 code is +# "en-x-tianocore", or "en-US" if "en-x-tianocore" was not found, or "en" if "en-US" was not found, or startswith 'en' # if 'en' was not found, then use this value. # If multiple entries of a tag exist which have the same language code, use the last entry. # # @param ValueList A list need to be processed. -# @param UseFirstValue: True to use the first value, False to use the last value +# @param UseFirstValue: True to use the first value, False to use the last value # # @return LocalValue def GetLocalValue(ValueList, UseFirstValue=False): @@ -1035,7 +904,7 @@ def GetLocalValue(ValueList, UseFirstValue=False): Value5 = Value else: Value5 = Value - + if Value1: return Value1 if Value2: @@ -1046,7 +915,7 @@ def GetLocalValue(ValueList, UseFirstValue=False): return Value4 if Value5: return Value5 - + return '' @@ -1083,29 +952,29 @@ def GetCharIndexOutStr(CommentCharacter, Line): # # Check the UNI file path # -# @param FilePath: The UNI file path +# @param FilePath: The UNI file path # def ValidateUNIFilePath(Path): Suffix = Path[Path.rfind(TAB_SPLIT):] - + # - # Check if the suffix is one of the '.uni', '.UNI', '.Uni' + # Check if the suffix is one of the '.uni', '.UNI', '.Uni' # if Suffix not in TAB_UNI_FILE_SUFFIXS: - Logger.Error("Unicode File Parser", - ToolError.FORMAT_INVALID, - Message=ST.ERR_UNI_FILE_SUFFIX_WRONG, - ExtraData=Path) - + Logger.Error("Unicode File Parser", + ToolError.FORMAT_INVALID, + Message=ST.ERR_UNI_FILE_SUFFIX_WRONG, + ExtraData=Path) + # - # Check if '..' in the file name(without suffixe) + # Check if '..' in the file name(without suffix) # if (TAB_SPLIT + TAB_SPLIT) in Path: - Logger.Error("Unicode File Parser", - ToolError.FORMAT_INVALID, - Message=ST.ERR_UNI_FILE_NAME_INVALID, - ExtraData=Path) - + Logger.Error("Unicode File Parser", + ToolError.FORMAT_INVALID, + Message=ST.ERR_UNI_FILE_NAME_INVALID, + ExtraData=Path) + # # Check if the file name is valid according to the DEC and INF specification # @@ -1113,8 +982,8 @@ def ValidateUNIFilePath(Path): FileName = Path.replace(Suffix, '') InvalidCh = re.sub(Pattern, '', FileName) if InvalidCh: - Logger.Error("Unicode File Parser", - ToolError.FORMAT_INVALID, - Message=ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID, - ExtraData=Path) + Logger.Error("Unicode File Parser", + ToolError.FORMAT_INVALID, + Message=ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID, + ExtraData=Path)