]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Common/String.py
BaseTools: Fix flexible PCD single quote and double quote bugs
[mirror_edk2.git] / BaseTools / Source / Python / Common / String.py
index c282326677f6f49d6b58fc5fb0adc424d8dc6901..5e50beff5cc39539a0eab1684d0281b0533b9918 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # This file is used to define common string related functions used in parsing process\r
 #\r
-# Copyright (c) 2007 - 2008, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
 #\r
 import re\r
 import DataType\r
-import os.path\r
+import Common.LongFilePathOs as os\r
 import string\r
 import EdkLogger as EdkLogger\r
 \r
 import GlobalData\r
 from BuildToolError import *\r
 from CommonDataClass.Exceptions import *\r
+from Common.LongFilePathSupport import OpenLongFilePath as open\r
+from Common.MultipleWorkspace import MultipleWorkspace as mws\r
 \r
 gHexVerPatt = re.compile('0x[a-f0-9]{4}[a-f0-9]{4}$', re.IGNORECASE)\r
 gHumanReadableVerPatt = re.compile(r'([1-9][0-9]*|0)\.[0-9]{1,2}$')\r
@@ -43,25 +45,36 @@ def GetSplitValueList(String, SplitTag=DataType.TAB_VALUE_SPLIT, MaxSplit= -1):
     ValueList = []\r
     Last = 0\r
     Escaped = False\r
-    InString = False\r
+    InSingleQuoteString = False\r
+    InDoubleQuoteString = False\r
+    InParenthesis = 0\r
     for Index in range(0, len(String)):\r
         Char = String[Index]\r
 \r
         if not Escaped:\r
             # Found a splitter not in a string, split it\r
-            if not InString and Char == SplitTag:\r
+            if (not InSingleQuoteString or not InDoubleQuoteString) and InParenthesis == 0 and Char == SplitTag:\r
                 ValueList.append(String[Last:Index].strip())\r
                 Last = Index + 1\r
                 if MaxSplit > 0 and len(ValueList) >= MaxSplit:\r
                     break\r
 \r
-            if Char == '\\' and InString:\r
+            if Char == '\\' and (InSingleQuoteString or InDoubleQuoteString):\r
                 Escaped = True\r
-            elif Char == '"':\r
-                if not InString:\r
-                    InString = True\r
+            elif Char == '"' and not InSingleQuoteString:\r
+                if not InDoubleQuoteString:\r
+                    InDoubleQuoteString = True\r
                 else:\r
-                    InString = False\r
+                    InDoubleQuoteString = False\r
+            elif Char == "'" and not InDoubleQuoteString:\r
+                if not InSingleQuoteString:\r
+                    InSingleQuoteString = True\r
+                else:\r
+                    InSingleQuoteString = False\r
+            elif Char == '(':\r
+                InParenthesis = InParenthesis + 1\r
+            elif Char == ')':\r
+                InParenthesis = InParenthesis - 1\r
         else:\r
             Escaped = False\r
 \r
@@ -271,7 +284,8 @@ def ReplaceMacro(String, MacroDefinitions={}, SelfReplacement=False, RaiseError=
                 if SelfReplacement:\r
                     String = String.replace("$(%s)" % Macro, '')\r
                 continue\r
-            String = String.replace("$(%s)" % Macro, MacroDefinitions[Macro])\r
+            if "$(%s)" % Macro not in MacroDefinitions[Macro]:\r
+                String = String.replace("$(%s)" % Macro, MacroDefinitions[Macro])\r
         # in case there's macro not defined\r
         if String == LastString:\r
             break\r
@@ -303,6 +317,11 @@ def NormPath(Path, Defines={}):
         # To local path format\r
         #\r
         Path = os.path.normpath(Path)\r
+        if Path.startswith(GlobalData.gWorkspace) and not Path.startswith(GlobalData.gBuildDirectory) and not os.path.exists(Path):\r
+            Path = Path[len (GlobalData.gWorkspace):]\r
+            if Path[0] == os.path.sep:\r
+                Path = Path[1:]\r
+            Path = mws.join(GlobalData.gWorkspace, Path)\r
 \r
     if IsRelativePath and Path[0] != '.':\r
         Path = os.path.join('.', Path)\r
@@ -332,14 +351,17 @@ def CleanString(Line, CommentCharacter=DataType.TAB_COMMENT_SPLIT, AllowCppStyle
     #\r
     # remove comments, but we should escape comment character in string\r
     #\r
-    InString = False\r
+    InDoubleQuoteString = False\r
+    InSingleQuoteString = False\r
     CommentInString = 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
+        if Line[Index] == '"' and not InSingleQuoteString:\r
+            InDoubleQuoteString = not InDoubleQuoteString\r
+        elif Line[Index] == "'" and not InDoubleQuoteString:\r
+            InSingleQuoteString = not InSingleQuoteString\r
+        elif Line[Index] == CommentCharacter and (InSingleQuoteString or InDoubleQuoteString):\r
             CommentInString = True\r
-        elif Line[Index] == CommentCharacter and not InString :\r
+        elif Line[Index] == CommentCharacter and not (InSingleQuoteString or InDoubleQuoteString):\r
             Line = Line[0: Index]\r
             break\r
 \r
@@ -389,28 +411,21 @@ def CleanString2(Line, CommentCharacter=DataType.TAB_COMMENT_SPLIT, AllowCppStyl
     #\r
     # separate comments and statements, but we should escape comment character in string\r
     #\r
-    InString = False\r
+    InDoubleQuoteString = False\r
+    InSingleQuoteString = False\r
     CommentInString = False\r
     Comment = ''\r
     for Index in range(0, len(Line)):\r
-        if Line[Index] == '"':\r
-            InString = not InString\r
-        elif Line[Index] == CommentCharacter and InString:\r
+        if Line[Index] == '"' and not InSingleQuoteString:\r
+            InDoubleQuoteString = not InDoubleQuoteString\r
+        elif Line[Index] == "'" and not InDoubleQuoteString:\r
+            InSingleQuoteString = not InSingleQuoteString\r
+        elif Line[Index] == CommentCharacter and (InDoubleQuoteString or InSingleQuoteString):\r
             CommentInString = True\r
-        elif Line[Index] == CommentCharacter and not InString:\r
+        elif Line[Index] == CommentCharacter and not (InDoubleQuoteString or InSingleQuoteString):\r
             Comment = Line[Index:].strip()\r
             Line = Line[0:Index].strip()\r
             break\r
-    if Comment:\r
-        # Remove prefixed and trailing comment characters\r
-        Start = 0\r
-        End = len(Comment)\r
-        while Start < End and Comment.startswith(CommentCharacter, Start, End):\r
-            Start += 1\r
-        while End >= 0 and Comment.endswith(CommentCharacter, Start, End):\r
-            End -= 1\r
-        Comment = Comment[Start:End]\r
-        Comment = Comment.strip()\r
 \r
     return Line, Comment\r
 \r
@@ -710,7 +725,7 @@ def RaiseParserError(Line, Section, File, Format='', LineNo= -1):
 # @retval string A full path\r
 #\r
 def WorkspaceFile(WorkspaceDir, Filename):\r
-    return os.path.join(NormPath(WorkspaceDir), NormPath(Filename))\r
+    return mws.join(NormPath(WorkspaceDir), NormPath(Filename))\r
 \r
 ## Split string\r
 #\r
@@ -811,11 +826,25 @@ def StringToArray(String):
             return "{%s, 0x00, 0x00}" % ", ".join(["0x%02x, 0x00" % ord(C) for C in String[2:-1]])\r
     elif String.startswith('"'):\r
         if String == "\"\"":\r
-            return "{0x00}";\r
+            return "{0x00,0x00}"\r
+        else:\r
+            StringLen = len(String[1:-1])\r
+            if StringLen % 2:\r
+                return "{%s, 0x00}" % ", ".join(["0x%02x" % ord(C) for C in String[1:-1]])\r
+            else:\r
+                return "{%s, 0x00,0x00}" % ", ".join(["0x%02x" % ord(C) for C in String[1:-1]])\r
+    elif String.startswith('{'):\r
+        StringLen = len(String.split(","))\r
+        if StringLen % 2:\r
+            return "{%s, 0x00}" % ", ".join([ C for C in String[1:-1].split(',')])\r
         else:\r
-            return "{%s, 0x00}" % ", ".join(["0x%02x" % ord(C) for C in String[1:-1]])\r
+            return "{%s}" % ", ".join([ C for C in String[1:-1].split(',')])\r
+        \r
     else:\r
-        return '{%s, 0}' % ', '.join(String.split())\r
+        if len(String.split()) % 2:\r
+            return '{%s, 0}' % ', '.join(String.split())\r
+        else:\r
+            return '{%s, 0,0}' % ', '.join(String.split())\r
 \r
 def StringArrayLength(String):\r
     if isinstance(String, unicode):\r