]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/UPT/Library/Misc.py
BaseTools/UPT: UPT to Support UTF-8
[mirror_edk2.git] / BaseTools / Source / Python / UPT / Library / Misc.py
index 750805e32814a978b7b3fbb62436b44fdb312782..0d92cb3767c65482335b13a140890d3e13874167 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # Common routines used by all tools\r
 #\r
-# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2011 - 2014, 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
@@ -41,11 +41,16 @@ from Library import GlobalData
 from Library.DataType import SUP_MODULE_LIST\r
 from Library.DataType import END_OF_LINE\r
 from Library.DataType import TAB_SPLIT\r
-from Library.DataType import LANGUAGE_EN_US\r
+from Library.DataType import TAB_LANGUAGE_EN_US\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.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
 # structure style\r
@@ -160,14 +165,14 @@ def SaveFileOnChange(File, Content, IsBinaryFile=True):
 \r
     if os.path.exists(File):\r
         try:\r
-            if Content == open(File, "rb").read():\r
+            if Content == __FileHookOpen__(File, "rb").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 = open(File, "wb")\r
+        FileFd = __FileHookOpen__(File, "wb")\r
         FileFd.write(Content)\r
         FileFd.close()\r
     except BaseException:\r
@@ -188,6 +193,8 @@ def GetFiles(Root, SkipList=None, FullPath=True):
             for Item in SkipList:\r
                 if Item in Dirs:\r
                     Dirs.remove(Item)\r
+                if Item in Files:\r
+                    Files.remove(Item)\r
         for Dir in Dirs:\r
             if Dir.startswith('.'):\r
                 Dirs.remove(Dir)\r
@@ -566,39 +573,50 @@ class PathClass(object):
 \r
     Key = property(_GetFileKey)\r
 \r
-## Check environment variables\r
+## Get current workspace\r
 #\r
-#  Check environment variables that must be set for build. Currently they are\r
+#  get WORKSPACE from environment variable if present,if not use current working directory as WORKSPACE\r
 #\r
-#   WORKSPACE           The directory all packages/platforms start from\r
-#   EDK_TOOLS_PATH      The directory contains all tools needed by the build\r
-#   PATH                $(EDK_TOOLS_PATH)/Bin/<sys> must be set in PATH\r
-#\r
-#   If any of above environment variable is not set or has error, the build\r
-#   will be broken.\r
-#\r
-def CheckEnvVariable():\r
+def GetWorkspace():\r
     #\r
     # check WORKSPACE\r
     #\r
-    if "WORKSPACE" not in environ:\r
-        Logger.Error("UPT",\r
-                     ToolError.UPT_ENVIRON_MISSING_ERROR,\r
-                     ST.ERR_NOT_FOUND_ENVIRONMENT,\r
-                     ExtraData="WORKSPACE")\r
-\r
-    WorkspaceDir = os.path.normpath(environ["WORKSPACE"])\r
-    if not os.path.exists(WorkspaceDir):\r
-        Logger.Error("UPT",\r
-                     ToolError.UPT_ENVIRON_MISSING_ERROR,\r
-                     ST.ERR_WORKSPACE_NOTEXIST,\r
-                     ExtraData="%s" % WorkspaceDir)\r
-    elif ' ' in WorkspaceDir:\r
-        Logger.Error("UPT",\r
-                     ToolError.FORMAT_NOT_SUPPORTED,\r
-                     ST.ERR_SPACE_NOTALLOWED,\r
-                     ExtraData=WorkspaceDir)\r
+    if "WORKSPACE" in environ:\r
+        WorkspaceDir = os.path.normpath(environ["WORKSPACE"])\r
+        if not os.path.exists(WorkspaceDir):\r
+            Logger.Error("UPT",\r
+                         ToolError.UPT_ENVIRON_MISSING_ERROR,\r
+                         ST.ERR_WORKSPACE_NOTEXIST,\r
+                         ExtraData="%s" % WorkspaceDir)\r
+    else:\r
+        WorkspaceDir = os.getcwd()\r
+\r
+    if WorkspaceDir[-1] == ':':\r
+        WorkspaceDir += os.sep\r
+\r
+    PackagesPath = os.environ.get("PACKAGES_PATH")\r
+    mws.setWs(WorkspaceDir, PackagesPath)\r
+\r
+    return WorkspaceDir, mws.PACKAGES_PATH\r
 \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
+#\r
+#  @param Fullpath: a string of fullpath\r
+#  @param Workspace: a string of workspace\r
+#\r
+def GetRelativePath(Fullpath, Workspace):\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
+    return RelativePath\r
+    \r
 ## Check whether all module types are in list\r
 #\r
 # check whether all module types (SUP_MODULE_LIST) are in list\r
@@ -644,7 +662,7 @@ class MergeCommentDict(dict):
 #\r
 def GenDummyHelpTextObj():\r
     HelpTxt = TextObject()\r
-    HelpTxt.SetLang(LANGUAGE_EN_US)\r
+    HelpTxt.SetLang(TAB_LANGUAGE_EN_US)\r
     HelpTxt.SetString(' ')\r
     return HelpTxt\r
 \r
@@ -972,3 +990,136 @@ def GetLibInstanceInfo(String, WorkSpace, LineNo):
             VerString = GetSplitValueList(VerString, '=', 1)[1]\r
 \r
         return FileGuidString, VerString\r
+\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 '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
+#\r
+# @return LocalValue\r
+def GetLocalValue(ValueList, UseFirstValue=False):\r
+    Value1 = ''\r
+    Value2 = ''\r
+    Value3 = ''\r
+    Value4 = ''\r
+    Value5 = ''\r
+    for (Key, Value) in ValueList:\r
+        if Key == TAB_LANGUAGE_EN_X:\r
+            if UseFirstValue:\r
+                if not Value1:\r
+                    Value1 = Value\r
+            else:\r
+                Value1 = Value\r
+        if Key == TAB_LANGUAGE_EN_US:\r
+            if UseFirstValue:\r
+                if not Value2:\r
+                    Value2 = Value\r
+            else:\r
+                Value2 = Value\r
+        if Key == TAB_LANGUAGE_EN:\r
+            if UseFirstValue:\r
+                if not Value3:\r
+                    Value3 = Value\r
+            else:\r
+                Value3 = Value\r
+        if Key.startswith(TAB_LANGUAGE_EN):\r
+            if UseFirstValue:\r
+                if not Value4:\r
+                    Value4 = Value\r
+            else:\r
+                Value4 = Value\r
+        if Key == '':\r
+            if UseFirstValue:\r
+                if not Value5:\r
+                    Value5 = Value\r
+            else:\r
+                Value5 = Value\r
+            \r
+    if Value1:\r
+        return Value1\r
+    if Value2:\r
+        return Value2\r
+    if Value3:\r
+        return Value3\r
+    if Value4:\r
+        return Value4\r
+    if Value5:\r
+        return Value5\r
+    \r
+    return ''\r
+\r
+\r
+## GetCharIndexOutStr\r
+#\r
+# Get comment character index outside a string\r
+#\r
+# @param Line:              The string to be checked\r
+# @param CommentCharacter:  Comment char, used to ignore comment content\r
+#\r
+# @retval Index\r
+#\r
+def GetCharIndexOutStr(CommentCharacter, Line):\r
+    #\r
+    # remove whitespace\r
+    #\r
+    Line = Line.strip()\r
+\r
+    #\r
+    # Check whether comment character is in a string\r
+    #\r
+    InString = False\r
+    for Index in range(0, len(Line)):\r
+        if Line[Index] == '"':\r
+            InString = not InString\r
+        elif Line[Index] == CommentCharacter and InString :\r
+            pass\r
+        elif Line[Index] == CommentCharacter and (Index +1) < len(Line) and Line[Index+1] == CommentCharacter \\r
+            and not InString :\r
+            return Index\r
+    return -1\r
+\r
+## ValidateUNIFilePath\r
+#\r
+# Check the UNI file path\r
+#\r
+# @param FilePath: The UNI file path \r
+#\r
+def ValidateUNIFilePath(Path):\r
+    Suffix = Path[Path.rfind(TAB_SPLIT):]\r
+    \r
+    #\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
+    #\r
+    # Check if '..' in the file name(without suffixe)\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
+    #\r
+    # Check if the file name is valid according to the DEC and INF specification\r
+    #\r
+    Pattern = '[a-zA-Z0-9_][a-zA-Z0-9_\-\.]*'\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
+\r