## @file\r
# Common routines used by all tools\r
#\r
-# Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.<BR>\r
#\r
-# This program and the accompanying materials are licensed and made available \r
-# under the terms and conditions of the BSD License which accompanies this \r
-# distribution. The full text of the license may be found at \r
+# This program and the accompanying materials are licensed and made available\r
+# under the terms and conditions of the BSD License which accompanies this\r
+# distribution. The full text of the license may be found at\r
# http://opensource.org/licenses/bsd-license.php\r
#\r
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
from os import walk\r
from os import environ\r
import re\r
-from UserDict import IterableUserDict\r
+from collections import OrderedDict as Sdict\r
\r
import Logger.Log as Logger\r
from Logger import StringTable as ST\r
from Library.DataType import TAB_LANGUAGE_EN\r
from Library.DataType import TAB_LANGUAGE_EN_X\r
from Library.DataType import TAB_UNI_FILE_SUFFIXS\r
-from Library.String import GetSplitValueList\r
+from Library.StringUtils import GetSplitValueList\r
from Library.ParserValidate import IsValidHexVersion\r
from Library.ParserValidate import IsValidPath\r
from Object.POM.CommonObject import TextObject\r
from Core.FileHook import __FileHookOpen__\r
from Common.MultipleWorkspace import MultipleWorkspace as mws\r
\r
-## Convert GUID string in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx style to C \r
+## Convert GUID string in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx style to C\r
# structure style\r
#\r
# @param Guid: The GUID string\r
return False\r
\r
\r
-## Convert GUID string in C structure style to \r
+## Convert GUID string in C structure style to\r
# xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\r
#\r
# @param GuidValue: The GUID value in C structure format\r
## Store content in file\r
#\r
# This method is used to save file only when its content is changed. This is\r
-# quite useful for "make" system to decide what will be re-built and what \r
+# quite useful for "make" system to decide what will be re-built and what\r
# won't.\r
#\r
# @param File: The path of file\r
# @param Content: The new content of the file\r
-# @param IsBinaryFile: The flag indicating if the file is binary file \r
+# @param IsBinaryFile: The flag indicating if the file is binary file\r
# or not\r
#\r
def SaveFileOnChange(File, Content, IsBinaryFile=True):\r
- if not IsBinaryFile:\r
- Content = Content.replace("\n", linesep)\r
-\r
if os.path.exists(File):\r
- try:\r
- if Content == __FileHookOpen__(File, "rb").read():\r
- return False\r
- except BaseException:\r
- Logger.Error(None, ToolError.FILE_OPEN_FAILURE, ExtraData=File)\r
+ if IsBinaryFile:\r
+ try:\r
+ if Content == __FileHookOpen__(File, "rb").read():\r
+ return False\r
+ except BaseException:\r
+ Logger.Error(None, ToolError.FILE_OPEN_FAILURE, ExtraData=File)\r
+ else:\r
+ try:\r
+ if Content == __FileHookOpen__(File, "r").read():\r
+ return False\r
+ except BaseException:\r
+ Logger.Error(None, ToolError.FILE_OPEN_FAILURE, ExtraData=File)\r
\r
CreateDirectory(os.path.dirname(File))\r
- try:\r
- FileFd = __FileHookOpen__(File, "wb")\r
- FileFd.write(Content)\r
- FileFd.close()\r
- except BaseException:\r
- Logger.Error(None, ToolError.FILE_CREATE_FAILURE, ExtraData=File)\r
+ if IsBinaryFile:\r
+ try:\r
+ FileFd = __FileHookOpen__(File, "wb")\r
+ FileFd.write(Content)\r
+ FileFd.close()\r
+ except BaseException:\r
+ Logger.Error(None, ToolError.FILE_CREATE_FAILURE, ExtraData=File)\r
+ else:\r
+ try:\r
+ FileFd = __FileHookOpen__(File, "w")\r
+ FileFd.write(Content)\r
+ FileFd.close()\r
+ except BaseException:\r
+ Logger.Error(None, ToolError.FILE_CREATE_FAILURE, ExtraData=File)\r
\r
return True\r
\r
# @param FullPath: True if the returned file should be full path\r
# @param PrefixPath: the path that need to be added to the files found\r
# @return: the list of files found\r
-# \r
+#\r
def GetNonMetaDataFiles(Root, SkipList, FullPath, PrefixPath):\r
FileList = GetFiles(Root, SkipList, FullPath)\r
NewFileList = []\r
\r
return None, None\r
\r
-## A dict which can access its keys and/or values orderly\r
-#\r
-# The class implements a new kind of dict which its keys or values can be\r
-# accessed in the order they are added into the dict. It guarantees the order\r
-# by making use of an internal list to keep a copy of keys.\r
-#\r
-class Sdict(IterableUserDict):\r
- ## Constructor\r
- #\r
- def __init__(self):\r
- IterableUserDict.__init__(self)\r
- self._key_list = []\r
-\r
- ## [] operator\r
- #\r
- def __setitem__(self, Key, Value):\r
- if Key not in self._key_list:\r
- self._key_list.append(Key)\r
- IterableUserDict.__setitem__(self, Key, Value)\r
-\r
- ## del operator\r
- #\r
- def __delitem__(self, Key):\r
- self._key_list.remove(Key)\r
- IterableUserDict.__delitem__(self, Key)\r
-\r
- ## used in "for k in dict" loop to ensure the correct order\r
- #\r
- def __iter__(self):\r
- return self.iterkeys()\r
-\r
- ## len() support\r
- #\r
- def __len__(self):\r
- return len(self._key_list)\r
-\r
- ## "in" test support\r
- #\r
- def __contains__(self, Key):\r
- return Key in self._key_list\r
-\r
- ## indexof support\r
- #\r
- def index(self, Key):\r
- return self._key_list.index(Key)\r
-\r
- ## insert support\r
- #\r
- def insert(self, Key, Newkey, Newvalue, Order):\r
- Index = self._key_list.index(Key)\r
- if Order == 'BEFORE':\r
- self._key_list.insert(Index, Newkey)\r
- IterableUserDict.__setitem__(self, Newkey, Newvalue)\r
- elif Order == 'AFTER':\r
- self._key_list.insert(Index + 1, Newkey)\r
- IterableUserDict.__setitem__(self, Newkey, Newvalue)\r
-\r
- ## append support\r
- #\r
- def append(self, Sdict2):\r
- for Key in Sdict2:\r
- if Key not in self._key_list:\r
- self._key_list.append(Key)\r
- IterableUserDict.__setitem__(self, Key, Sdict2[Key])\r
- ## hash key\r
- #\r
- def has_key(self, Key):\r
- return Key in self._key_list\r
-\r
- ## Empty the dict\r
- #\r
- def clear(self):\r
- self._key_list = []\r
- IterableUserDict.clear(self)\r
-\r
- ## Return a copy of keys\r
- #\r
- def keys(self):\r
- Keys = []\r
- for Key in self._key_list:\r
- Keys.append(Key)\r
- return Keys\r
-\r
- ## Return a copy of values\r
- #\r
- def values(self):\r
- Values = []\r
- for Key in self._key_list:\r
- Values.append(self[Key])\r
- return Values\r
-\r
- ## Return a copy of (key, value) list\r
- #\r
- def items(self):\r
- Items = []\r
- for Key in self._key_list:\r
- Items.append((Key, self[Key]))\r
- return Items\r
-\r
- ## Iteration support\r
- #\r
- def iteritems(self):\r
- return iter(self.items())\r
-\r
- ## Keys interation support\r
- #\r
- def iterkeys(self):\r
- return iter(self.keys())\r
-\r
- ## Values interation support\r
- #\r
- def itervalues(self):\r
- return iter(self.values())\r
-\r
- ## Return value related to a key, and remove the (key, value) from the dict\r
- #\r
- def pop(self, Key, *Dv):\r
- Value = None\r
- if Key in self._key_list:\r
- Value = self[Key]\r
- self.__delitem__(Key)\r
- elif len(Dv) != 0 :\r
- Value = Dv[0]\r
- return Value\r
-\r
- ## Return (key, value) pair, and remove the (key, value) from the dict\r
- #\r
- def popitem(self):\r
- Key = self._key_list[-1]\r
- Value = self[Key]\r
- self.__delitem__(Key)\r
- return Key, Value\r
- ## update method\r
- #\r
- def update(self, Dict=None, **Kwargs):\r
- if Dict is not None:\r
- for Key1, Val1 in Dict.items():\r
- self[Key1] = Val1\r
- if len(Kwargs):\r
- for Key1, Val1 in Kwargs.items():\r
- self[Key1] = Val1\r
-\r
## CommonPath\r
#\r
# @param PathList: PathList\r
def CommonPath(PathList):\r
Path1 = min(PathList).split(os.path.sep)\r
Path2 = max(PathList).split(os.path.sep)\r
- for Index in xrange(min(len(Path1), len(Path2))):\r
+ for Index in range(min(len(Path1), len(Path2))):\r
if Path1[Index] != Path2[Index]:\r
return os.path.sep.join(Path1[:Index])\r
return os.path.sep.join(Path1)\r
# Check whether PathClass are the same\r
#\r
def __eq__(self, Other):\r
- if type(Other) == type(self):\r
+ if isinstance(Other, type(self)):\r
return self.Path == Other.Path\r
else:\r
return self.Path == str(Other)\r
## Get relative path\r
#\r
# use full path and workspace to get relative path\r
-# the destination of this function is mainly to resolve the root path issue(like c: or c:\) \r
+# the destination of this function is mainly to resolve the root path issue(like c: or c:\)\r
#\r
# @param Fullpath: a string of fullpath\r
# @param Workspace: a string of workspace\r
#\r
def GetRelativePath(Fullpath, Workspace):\r
- \r
+\r
RelativePath = ''\r
if Workspace.endswith(os.sep):\r
RelativePath = Fullpath[Fullpath.upper().find(Workspace.upper())+len(Workspace):]\r
else:\r
RelativePath = Fullpath[Fullpath.upper().find(Workspace.upper())+len(Workspace)+1:]\r
- \r
+\r
return RelativePath\r
- \r
+\r
## Check whether all module types are in list\r
#\r
# check whether all module types (SUP_MODULE_LIST) are in list\r
-# \r
+#\r
# @param ModuleList: a list of ModuleType\r
#\r
def IsAllModuleList(ModuleList):\r
return True\r
\r
## Dictionary that use comment(GenericComment, TailComment) as value,\r
-# if a new comment which key already in the dic is inserted, then the \r
+# if a new comment which key already in the dic is inserted, then the\r
# comment will be merged.\r
-# Key is (Statement, SupArch), when TailComment is added, it will ident \r
+# Key is (Statement, SupArch), when TailComment is added, it will ident\r
# according to Statement\r
#\r
class MergeCommentDict(dict):\r
# <Major> ::= (a-fA-F0-9){4}\r
# <Minor> ::= (a-fA-F0-9){4}\r
# <DecVersion> ::= (0-65535) ["." (0-99)]\r
-# \r
+#\r
# @param StringIn: The string contains version defined in INF file.\r
# It can be Decimal or Hex\r
#\r
\r
## ConvertSpec\r
#\r
-# during install, convert the Spec string extract from UPD into INF allowable definition, \r
+# during install, convert the Spec string extract from UPD into INF allowable definition,\r
# the difference is period is allowed in the former (not the first letter) but not in the latter.\r
# return converted Spec string\r
#\r
# The rule is elements in List A are in List B and elements in List B are in List A.\r
#\r
# @param ListA, ListB Lists need to be judged.\r
-# \r
+#\r
# @return True ListA and ListB are identical\r
# @return False ListA and ListB are different with each other\r
#\r
## ConvertArchList\r
#\r
# Convert item in ArchList if the start character is lower case.\r
-# In UDP spec, Arch is only allowed as: [A-Z]([a-zA-Z0-9])* \r
+# In UDP spec, Arch is only allowed as: [A-Z]([a-zA-Z0-9])*\r
#\r
# @param ArchList The ArchList need to be converted.\r
-# \r
+#\r
# @return NewList The ArchList been converted.\r
#\r
def ConvertArchList(ArchList):\r
if not ArchList:\r
return NewArchList\r
\r
- if type(ArchList) == list:\r
+ if isinstance(ArchList, list):\r
for Arch in ArchList:\r
Arch = Arch.upper()\r
NewArchList.append(Arch)\r
- elif type(ArchList) == str:\r
+ elif isinstance(ArchList, str):\r
ArchList = ArchList.upper()\r
NewArchList.append(ArchList)\r
\r
# If one line ends with a line extender, then it will be combined together with next line.\r
#\r
# @param LineList The LineList need to be processed.\r
-# \r
+#\r
# @return NewList The ArchList been processed.\r
#\r
def ProcessLineExtender(LineList):\r
\r
## ProcessEdkComment\r
#\r
-# Process EDK style comment in LineList: c style /* */ comment or cpp style // comment \r
+# Process EDK style comment in LineList: c style /* */ comment or cpp style // comment\r
#\r
#\r
# @param LineList The LineList need to be processed.\r
-# \r
+#\r
# @return LineList The LineList been processed.\r
# @return FirstPos Where Edk comment is first found, -1 if not found\r
#\r
StartPos = -1\r
EndPos = -1\r
FirstPos = -1\r
- \r
+\r
while(Count < len(LineList)):\r
Line = LineList[Count].strip()\r
if Line.startswith("/*"):\r
FindEdkBlockComment = True\r
break\r
Count = Count + 1\r
- \r
+\r
if FindEdkBlockComment:\r
if FirstPos == -1:\r
FirstPos = StartPos\r
- for Index in xrange(StartPos, EndPos+1):\r
+ for Index in range(StartPos, EndPos+1):\r
LineList[Index] = ''\r
FindEdkBlockComment = False\r
elif Line.find("//") != -1 and not Line.startswith("#"):\r
LineList[Count] = Line.replace("//", '#')\r
if FirstPos == -1:\r
FirstPos = Count\r
- \r
+\r
Count = Count + 1\r
- \r
+\r
return LineList, FirstPos\r
\r
## GetLibInstanceInfo\r
FileGuidString = ""\r
VerString = ""\r
\r
- OrignalString = String\r
+ OriginalString = String\r
String = String.strip()\r
if not String:\r
return None, None\r
ST.ERR_FILELIST_EXIST % (String),\r
File=GlobalData.gINF_MODULE_NAME,\r
Line=LineNo,\r
- ExtraData=OrignalString)\r
+ ExtraData=OriginalString)\r
\r
#\r
# Validate file exist/format.\r
ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID % (String),\r
File=GlobalData.gINF_MODULE_NAME,\r
Line=LineNo,\r
- ExtraData=OrignalString)\r
+ ExtraData=OriginalString)\r
return False\r
if IsValidFileFlag:\r
FileLinesList = []\r
\r
try:\r
- FInputfile = open(FullFileName, "rb", 0)\r
+ FInputfile = open(FullFileName, "r")\r
try:\r
FileLinesList = FInputfile.readlines()\r
except BaseException:\r
## GetLocalValue\r
#\r
# Generate the local value for INF and DEC file. If Lang attribute not present, then use this value.\r
-# If present, and there is no element without the Lang attribute, and one of the elements has the rfc1766 code is \r
-# "en-x-tianocore", or "en-US" if "en-x-tianocore" was not found, or "en" if "en-US" was not found, or startswith 'en' \r
+# If present, and there is no element without the Lang attribute, and one of the elements has the rfc1766 code is\r
+# "en-x-tianocore", or "en-US" if "en-x-tianocore" was not found, or "en" if "en-US" was not found, or startswith 'en'\r
# if 'en' was not found, then use this value.\r
# If multiple entries of a tag exist which have the same language code, use the last entry.\r
#\r
# @param ValueList A list need to be processed.\r
-# @param UseFirstValue: True to use the first value, False to use the last value \r
+# @param UseFirstValue: True to use the first value, False to use the last value\r
#\r
# @return LocalValue\r
def GetLocalValue(ValueList, UseFirstValue=False):\r
Value5 = Value\r
else:\r
Value5 = Value\r
- \r
+\r
if Value1:\r
return Value1\r
if Value2:\r
return Value4\r
if Value5:\r
return Value5\r
- \r
+\r
return ''\r
\r
\r
#\r
# Check the UNI file path\r
#\r
-# @param FilePath: The UNI file path \r
+# @param FilePath: The UNI file path\r
#\r
def ValidateUNIFilePath(Path):\r
Suffix = Path[Path.rfind(TAB_SPLIT):]\r
- \r
+\r
#\r
- # Check if the suffix is one of the '.uni', '.UNI', '.Uni' \r
+ # Check if the suffix is one of the '.uni', '.UNI', '.Uni'\r
#\r
if Suffix not in TAB_UNI_FILE_SUFFIXS:\r
- Logger.Error("Unicode File Parser", \r
- ToolError.FORMAT_INVALID, \r
- Message=ST.ERR_UNI_FILE_SUFFIX_WRONG, \r
- ExtraData=Path) \r
- \r
+ Logger.Error("Unicode File Parser",\r
+ ToolError.FORMAT_INVALID,\r
+ Message=ST.ERR_UNI_FILE_SUFFIX_WRONG,\r
+ ExtraData=Path)\r
+\r
#\r
- # Check if '..' in the file name(without suffixe)\r
+ # Check if '..' in the file name(without suffix)\r
#\r
if (TAB_SPLIT + TAB_SPLIT) in Path:\r
- Logger.Error("Unicode File Parser", \r
- ToolError.FORMAT_INVALID, \r
- Message=ST.ERR_UNI_FILE_NAME_INVALID, \r
- ExtraData=Path) \r
- \r
+ Logger.Error("Unicode File Parser",\r
+ ToolError.FORMAT_INVALID,\r
+ Message=ST.ERR_UNI_FILE_NAME_INVALID,\r
+ ExtraData=Path)\r
+\r
#\r
# Check if the file name is valid according to the DEC and INF specification\r
#\r
FileName = Path.replace(Suffix, '')\r
InvalidCh = re.sub(Pattern, '', FileName)\r
if InvalidCh:\r
- Logger.Error("Unicode File Parser", \r
- ToolError.FORMAT_INVALID, \r
- Message=ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID, \r
- ExtraData=Path) \r
+ Logger.Error("Unicode File Parser",\r
+ ToolError.FORMAT_INVALID,\r
+ Message=ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID,\r
+ ExtraData=Path)\r
\r