]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Common/Misc.py
BaseTools: Remove un-needed list comprehension
[mirror_edk2.git] / BaseTools / Source / Python / Common / Misc.py
index 3ae2ec5b59b2204a505e7f06e115d9235ff2eb33..5ffd8cd0223dbeb12f8f0428153de5509da0ea00 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # Common routines used by all tools\r
 #\r
 ## @file\r
 # Common routines used by all tools\r
 #\r
-# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2018, 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
 # 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
@@ -37,7 +37,8 @@ from Parsing import GetSplitValueList
 from Common.LongFilePathSupport import OpenLongFilePath as open\r
 from Common.MultipleWorkspace import MultipleWorkspace as mws\r
 import uuid\r
 from Common.LongFilePathSupport import OpenLongFilePath as open\r
 from Common.MultipleWorkspace import MultipleWorkspace as mws\r
 import uuid\r
-\r
+from CommonDataClass.Exceptions import BadExpression\r
+import subprocess\r
 ## Regular expression used to find out place holders in string template\r
 gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE | re.UNICODE)\r
 \r
 ## Regular expression used to find out place holders in string template\r
 gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE | re.UNICODE)\r
 \r
@@ -75,7 +76,7 @@ def GetVariableOffset(mapfilepath, efifilepath, varnames):
 def _parseForXcode(lines, efifilepath, varnames):\r
     status = 0\r
     ret = []\r
 def _parseForXcode(lines, efifilepath, varnames):\r
     status = 0\r
     ret = []\r
-    for index, line in enumerate(lines):\r
+    for line in lines:\r
         line = line.strip()\r
         if status == 0 and line == "# Symbols:":\r
             status = 1\r
         line = line.strip()\r
         if status == 0 and line == "# Symbols:":\r
             status = 1\r
@@ -84,7 +85,7 @@ def _parseForXcode(lines, efifilepath, varnames):
             for varname in varnames:\r
                 if varname in line:\r
                     m = re.match('^([\da-fA-FxX]+)([\s\S]*)([_]*%s)$' % varname, line)\r
             for varname in varnames:\r
                 if varname in line:\r
                     m = re.match('^([\da-fA-FxX]+)([\s\S]*)([_]*%s)$' % varname, line)\r
-                    if m != None:\r
+                    if m is not None:\r
                         ret.append((varname, m.group(1)))\r
     return ret\r
 \r
                         ret.append((varname, m.group(1)))\r
     return ret\r
 \r
@@ -109,27 +110,27 @@ def _parseForGCC(lines, efifilepath, varnames):
         # status handler\r
         if status == 3:\r
             m = re.match('^([\w_\.]+) +([\da-fA-Fx]+) +([\da-fA-Fx]+)$', line)\r
         # status handler\r
         if status == 3:\r
             m = re.match('^([\w_\.]+) +([\da-fA-Fx]+) +([\da-fA-Fx]+)$', line)\r
-            if m != None:\r
+            if m is not None:\r
                 sections.append(m.groups(0))\r
             for varname in varnames:\r
                 Str = ''\r
                 m = re.match("^.data.(%s)" % varname, line)\r
                 sections.append(m.groups(0))\r
             for varname in varnames:\r
                 Str = ''\r
                 m = re.match("^.data.(%s)" % varname, line)\r
-                if m != None:\r
+                if m is not None:\r
                     m = re.match(".data.(%s)$" % varname, line)\r
                     m = re.match(".data.(%s)$" % varname, line)\r
-                    if m != None:\r
+                    if m is not None:\r
                         Str = lines[index + 1]\r
                     else:\r
                         Str = line[len(".data.%s" % varname):]\r
                     if Str:\r
                         m = re.match('^([\da-fA-Fx]+) +([\da-fA-Fx]+)', Str.strip())\r
                         Str = lines[index + 1]\r
                     else:\r
                         Str = line[len(".data.%s" % varname):]\r
                     if Str:\r
                         m = re.match('^([\da-fA-Fx]+) +([\da-fA-Fx]+)', Str.strip())\r
-                        if m != None:\r
+                        if m is not None:\r
                             varoffset.append((varname, int(m.groups(0)[0], 16) , int(sections[-1][1], 16), sections[-1][0]))\r
 \r
     if not varoffset:\r
         return []\r
     # get section information from efi file\r
     efisecs = PeImageClass(efifilepath).SectionHeaderList\r
                             varoffset.append((varname, int(m.groups(0)[0], 16) , int(sections[-1][1], 16), sections[-1][0]))\r
 \r
     if not varoffset:\r
         return []\r
     # get section information from efi file\r
     efisecs = PeImageClass(efifilepath).SectionHeaderList\r
-    if efisecs == None or len(efisecs) == 0:\r
+    if efisecs is None or len(efisecs) == 0:\r
         return []\r
     #redirection\r
     redirection = 0\r
         return []\r
     #redirection\r
     redirection = 0\r
@@ -165,19 +166,19 @@ def _parseGeneral(lines, efifilepath, varnames):
             continue        \r
         if status == 1 and len(line) != 0:\r
             m =  secRe.match(line)\r
             continue        \r
         if status == 1 and len(line) != 0:\r
             m =  secRe.match(line)\r
-            assert m != None, "Fail to parse the section in map file , line is %s" % line\r
+            assert m is not None, "Fail to parse the section in map file , line is %s" % line\r
             sec_no, sec_start, sec_length, sec_name, sec_class = m.groups(0)\r
             secs.append([int(sec_no, 16), int(sec_start, 16), int(sec_length, 16), sec_name, sec_class])\r
         if status == 2 and len(line) != 0:\r
             for varname in varnames:\r
                 m = symRe.match(line)\r
             sec_no, sec_start, sec_length, sec_name, sec_class = m.groups(0)\r
             secs.append([int(sec_no, 16), int(sec_start, 16), int(sec_length, 16), sec_name, sec_class])\r
         if status == 2 and len(line) != 0:\r
             for varname in varnames:\r
                 m = symRe.match(line)\r
-                assert m != None, "Fail to parse the symbol in map file, line is %s" % line\r
+                assert m is not None, "Fail to parse the symbol in map file, line is %s" % line\r
                 sec_no, sym_offset, sym_name, vir_addr = m.groups(0)\r
                 sec_no     = int(sec_no,     16)\r
                 sym_offset = int(sym_offset, 16)\r
                 vir_addr   = int(vir_addr,   16)\r
                 m2 = re.match('^[_]*(%s)' % varname, sym_name)\r
                 sec_no, sym_offset, sym_name, vir_addr = m.groups(0)\r
                 sec_no     = int(sec_no,     16)\r
                 sym_offset = int(sym_offset, 16)\r
                 vir_addr   = int(vir_addr,   16)\r
                 m2 = re.match('^[_]*(%s)' % varname, sym_name)\r
-                if m2 != None:\r
+                if m2 is not None:\r
                     # fond a binary pcd entry in map file\r
                     for sec in secs:\r
                         if sec[0] == sec_no and (sym_offset >= sec[1] and sym_offset < sec[1] + sec[2]):\r
                     # fond a binary pcd entry in map file\r
                     for sec in secs:\r
                         if sec[0] == sec_no and (sym_offset >= sec[1] and sym_offset < sec[1] + sec[2]):\r
@@ -187,7 +188,7 @@ def _parseGeneral(lines, efifilepath, varnames):
 \r
     # get section information from efi file\r
     efisecs = PeImageClass(efifilepath).SectionHeaderList\r
 \r
     # get section information from efi file\r
     efisecs = PeImageClass(efifilepath).SectionHeaderList\r
-    if efisecs == None or len(efisecs) == 0:\r
+    if efisecs is None or len(efisecs) == 0:\r
         return []\r
 \r
     ret = []\r
         return []\r
 \r
     ret = []\r
@@ -286,32 +287,6 @@ def ClearDuplicatedInf():
         if os.path.exists(File):\r
             os.remove(File)\r
 \r
         if os.path.exists(File):\r
             os.remove(File)\r
 \r
-## callback routine for processing variable option\r
-#\r
-# This function can be used to process variable number of option values. The\r
-# typical usage of it is specify architecure list on command line.\r
-# (e.g. <tool> -a IA32 X64 IPF)\r
-#\r
-# @param  Option        Standard callback function parameter\r
-# @param  OptionString  Standard callback function parameter\r
-# @param  Value         Standard callback function parameter\r
-# @param  Parser        Standard callback function parameter\r
-#\r
-# @retval\r
-#\r
-def ProcessVariableArgument(Option, OptionString, Value, Parser):\r
-    assert Value is None\r
-    Value = []\r
-    RawArgs = Parser.rargs\r
-    while RawArgs:\r
-        Arg = RawArgs[0]\r
-        if (Arg[:2] == "--" and len(Arg) > 2) or \\r
-           (Arg[:1] == "-" and len(Arg) > 1 and Arg[1] != "-"):\r
-            break\r
-        Value.append(Arg)\r
-        del RawArgs[0]\r
-    setattr(Parser.values, Option.dest, Value)\r
-\r
 ## Convert GUID string in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx style to C structure style\r
 #\r
 #   @param      Guid    The GUID string\r
 ## Convert GUID string in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx style to C structure style\r
 #\r
 #   @param      Guid    The GUID string\r
@@ -422,7 +397,7 @@ def GuidStructureStringToGuidValueName(GuidValue):
 #   @param      Directory   The directory name\r
 #\r
 def CreateDirectory(Directory):\r
 #   @param      Directory   The directory name\r
 #\r
 def CreateDirectory(Directory):\r
-    if Directory == None or Directory.strip() == "":\r
+    if Directory is None or Directory.strip() == "":\r
         return True\r
     try:\r
         if not os.access(Directory, os.F_OK):\r
         return True\r
     try:\r
         if not os.access(Directory, os.F_OK):\r
@@ -436,7 +411,7 @@ def CreateDirectory(Directory):
 #   @param      Directory   The directory name\r
 #\r
 def RemoveDirectory(Directory, Recursively=False):\r
 #   @param      Directory   The directory name\r
 #\r
 def RemoveDirectory(Directory, Recursively=False):\r
-    if Directory == None or Directory.strip() == "" or not os.path.exists(Directory):\r
+    if Directory is None or Directory.strip() == "" or not os.path.exists(Directory):\r
         return\r
     if Recursively:\r
         CurrentDirectory = os.getcwd()\r
         return\r
     if Recursively:\r
         CurrentDirectory = os.getcwd()\r
@@ -449,32 +424,6 @@ def RemoveDirectory(Directory, Recursively=False):
         os.chdir(CurrentDirectory)\r
     os.rmdir(Directory)\r
 \r
         os.chdir(CurrentDirectory)\r
     os.rmdir(Directory)\r
 \r
-## Check if given file is changed or not\r
-#\r
-#  This method is used to check if a file is changed or not between two build\r
-#  actions. It makes use a cache to store files timestamp.\r
-#\r
-#   @param      File    The path of file\r
-#\r
-#   @retval     True    If the given file is changed, doesn't exist, or can't be\r
-#                       found in timestamp cache\r
-#   @retval     False   If the given file is changed\r
-#\r
-def IsChanged(File):\r
-    if not os.path.exists(File):\r
-        return True\r
-\r
-    FileState = os.stat(File)\r
-    TimeStamp = FileState[-2]\r
-\r
-    if File in gFileTimeStampCache and TimeStamp == gFileTimeStampCache[File]:\r
-        FileChanged = False\r
-    else:\r
-        FileChanged = True\r
-        gFileTimeStampCache[File] = TimeStamp\r
-\r
-    return FileChanged\r
-\r
 ## Store content in file\r
 #\r
 #  This method is used to save file only when its content is changed. This is\r
 ## Store content in file\r
 #\r
 #  This method is used to save file only when its content is changed. This is\r
@@ -539,7 +488,7 @@ def DataDump(Data, File):
     except:\r
         EdkLogger.error("", FILE_OPEN_FAILURE, ExtraData=File, RaiseError=False)\r
     finally:\r
     except:\r
         EdkLogger.error("", FILE_OPEN_FAILURE, ExtraData=File, RaiseError=False)\r
     finally:\r
-        if Fd != None:\r
+        if Fd is not None:\r
             Fd.close()\r
 \r
 ## Restore a Python object from a file\r
             Fd.close()\r
 \r
 ## Restore a Python object from a file\r
@@ -559,7 +508,7 @@ def DataRestore(File):
         EdkLogger.verbose("Failed to load [%s]\n\t%s" % (File, str(e)))\r
         Data = None\r
     finally:\r
         EdkLogger.verbose("Failed to load [%s]\n\t%s" % (File, str(e)))\r
         Data = None\r
     finally:\r
-        if Fd != None:\r
+        if Fd is not None:\r
             Fd.close()\r
     return Data\r
 \r
             Fd.close()\r
     return Data\r
 \r
@@ -634,47 +583,6 @@ class DirCache:
             return os.path.join(self._Root, self._UPPER_CACHE_[UpperPath])\r
         return None\r
 \r
             return os.path.join(self._Root, self._UPPER_CACHE_[UpperPath])\r
         return None\r
 \r
-## Get all files of a directory\r
-#\r
-# @param Root:       Root dir\r
-# @param SkipList :  The files need be skipped\r
-#\r
-# @retval  A list of all files\r
-#\r
-def GetFiles(Root, SkipList=None, FullPath=True):\r
-    OriPath = Root\r
-    FileList = []\r
-    for Root, Dirs, Files in os.walk(Root):\r
-        if SkipList:\r
-            for Item in SkipList:\r
-                if Item in Dirs:\r
-                    Dirs.remove(Item)\r
-\r
-        for File in Files:\r
-            File = os.path.normpath(os.path.join(Root, File))\r
-            if not FullPath:\r
-                File = File[len(OriPath) + 1:]\r
-            FileList.append(File)\r
-\r
-    return FileList\r
-\r
-## Check if gvien file exists or not\r
-#\r
-#   @param      File    File name or path to be checked\r
-#   @param      Dir     The directory the file is relative to\r
-#\r
-#   @retval     True    if file exists\r
-#   @retval     False   if file doesn't exists\r
-#\r
-def ValidFile(File, Ext=None):\r
-    if Ext != None:\r
-        Dummy, FileExt = os.path.splitext(File)\r
-        if FileExt.lower() != Ext.lower():\r
-            return False\r
-    if not os.path.exists(File):\r
-        return False\r
-    return True\r
-\r
 def RealPath(File, Dir='', OverrideDir=''):\r
     NewFile = os.path.normpath(os.path.join(Dir, File))\r
     NewFile = GlobalData.gAllFiles[NewFile]\r
 def RealPath(File, Dir='', OverrideDir=''):\r
     NewFile = os.path.normpath(os.path.join(Dir, File))\r
     NewFile = GlobalData.gAllFiles[NewFile]\r
@@ -709,115 +617,6 @@ def RealPath2(File, Dir='', OverrideDir=''):
 \r
     return None, None\r
 \r
 \r
     return None, None\r
 \r
-## Check if gvien file exists or not\r
-#\r
-#\r
-def ValidFile2(AllFiles, File, Ext=None, Workspace='', EfiSource='', EdkSource='', Dir='.', OverrideDir=''):\r
-    NewFile = File\r
-    if Ext != None:\r
-        Dummy, FileExt = os.path.splitext(File)\r
-        if FileExt.lower() != Ext.lower():\r
-            return False, File\r
-\r
-    # Replace the Edk macros\r
-    if OverrideDir != '' and OverrideDir != None:\r
-        if OverrideDir.find('$(EFI_SOURCE)') > -1:\r
-            OverrideDir = OverrideDir.replace('$(EFI_SOURCE)', EfiSource)\r
-        if OverrideDir.find('$(EDK_SOURCE)') > -1:\r
-            OverrideDir = OverrideDir.replace('$(EDK_SOURCE)', EdkSource)\r
-\r
-    # Replace the default dir to current dir\r
-    if Dir == '.':\r
-        Dir = os.getcwd()\r
-        Dir = Dir[len(Workspace) + 1:]\r
-\r
-    # First check if File has Edk definition itself\r
-    if File.find('$(EFI_SOURCE)') > -1 or File.find('$(EDK_SOURCE)') > -1:\r
-        NewFile = File.replace('$(EFI_SOURCE)', EfiSource)\r
-        NewFile = NewFile.replace('$(EDK_SOURCE)', EdkSource)\r
-        NewFile = AllFiles[os.path.normpath(NewFile)]\r
-        if NewFile != None:\r
-            return True, NewFile\r
-\r
-    # Second check the path with override value\r
-    if OverrideDir != '' and OverrideDir != None:\r
-        NewFile = AllFiles[os.path.normpath(os.path.join(OverrideDir, File))]\r
-        if NewFile != None:\r
-            return True, NewFile\r
-\r
-    # Last check the path with normal definitions\r
-    File = os.path.join(Dir, File)\r
-    NewFile = AllFiles[os.path.normpath(File)]\r
-    if NewFile != None:\r
-        return True, NewFile\r
-\r
-    return False, File\r
-\r
-## Check if gvien file exists or not\r
-#\r
-#\r
-def ValidFile3(AllFiles, File, Workspace='', EfiSource='', EdkSource='', Dir='.', OverrideDir=''):\r
-    # Replace the Edk macros\r
-    if OverrideDir != '' and OverrideDir != None:\r
-        if OverrideDir.find('$(EFI_SOURCE)') > -1:\r
-            OverrideDir = OverrideDir.replace('$(EFI_SOURCE)', EfiSource)\r
-        if OverrideDir.find('$(EDK_SOURCE)') > -1:\r
-            OverrideDir = OverrideDir.replace('$(EDK_SOURCE)', EdkSource)\r
-\r
-    # Replace the default dir to current dir\r
-    # Dir is current module dir related to workspace\r
-    if Dir == '.':\r
-        Dir = os.getcwd()\r
-        Dir = Dir[len(Workspace) + 1:]\r
-\r
-    NewFile = File\r
-    RelaPath = AllFiles[os.path.normpath(Dir)]\r
-    NewRelaPath = RelaPath\r
-\r
-    while(True):\r
-        # First check if File has Edk definition itself\r
-        if File.find('$(EFI_SOURCE)') > -1 or File.find('$(EDK_SOURCE)') > -1:\r
-            File = File.replace('$(EFI_SOURCE)', EfiSource)\r
-            File = File.replace('$(EDK_SOURCE)', EdkSource)\r
-            NewFile = AllFiles[os.path.normpath(File)]\r
-            if NewFile != None:\r
-                NewRelaPath = os.path.dirname(NewFile)\r
-                File = os.path.basename(NewFile)\r
-                #NewRelaPath = NewFile[:len(NewFile) - len(File.replace("..\\", '').replace("../", '')) - 1]\r
-                break\r
-\r
-        # Second check the path with override value\r
-        if OverrideDir != '' and OverrideDir != None:\r
-            NewFile = AllFiles[os.path.normpath(os.path.join(OverrideDir, File))]\r
-            if NewFile != None:\r
-                #NewRelaPath = os.path.dirname(NewFile)\r
-                NewRelaPath = NewFile[:len(NewFile) - len(File.replace("..\\", '').replace("../", '')) - 1]\r
-                break\r
-\r
-        # Last check the path with normal definitions\r
-        NewFile = AllFiles[os.path.normpath(os.path.join(Dir, File))]\r
-        if NewFile != None:\r
-            break\r
-\r
-        # No file found\r
-        break\r
-\r
-    return NewRelaPath, RelaPath, File\r
-\r
-\r
-def GetRelPath(Path1, Path2):\r
-    FileName = os.path.basename(Path2)\r
-    L1 = os.path.normpath(Path1).split(os.path.normpath('/'))\r
-    L2 = os.path.normpath(Path2).split(os.path.normpath('/'))\r
-    for Index in range(0, len(L1)):\r
-        if L1[Index] != L2[Index]:\r
-            FileName = '../' * (len(L1) - Index)\r
-            for Index2 in range(Index, len(L2)):\r
-                FileName = os.path.join(FileName, L2[Index2])\r
-            break\r
-    return os.path.normpath(FileName)\r
-\r
-\r
 ## Get GUID value from given packages\r
 #\r
 #   @param      CName           The CName of the GUID\r
 ## Get GUID value from given packages\r
 #\r
 #   @param      CName           The CName of the GUID\r
@@ -832,7 +631,7 @@ def GuidValue(CName, PackageList, Inffile = None):
         GuidKeys = P.Guids.keys()\r
         if Inffile and P._PrivateGuids:\r
             if not Inffile.startswith(P.MetaFile.Dir):\r
         GuidKeys = P.Guids.keys()\r
         if Inffile and P._PrivateGuids:\r
             if not Inffile.startswith(P.MetaFile.Dir):\r
-                GuidKeys = (dict.fromkeys(x for x in P.Guids if x not in P._PrivateGuids)).keys()\r
+                GuidKeys = [x for x in P.Guids if x not in P._PrivateGuids]\r
         if CName in GuidKeys:\r
             return P.Guids[CName]\r
     return None\r
         if CName in GuidKeys:\r
             return P.Guids[CName]\r
     return None\r
@@ -851,7 +650,7 @@ def ProtocolValue(CName, PackageList, Inffile = None):
         ProtocolKeys = P.Protocols.keys()\r
         if Inffile and P._PrivateProtocols:\r
             if not Inffile.startswith(P.MetaFile.Dir):\r
         ProtocolKeys = P.Protocols.keys()\r
         if Inffile and P._PrivateProtocols:\r
             if not Inffile.startswith(P.MetaFile.Dir):\r
-                ProtocolKeys = (dict.fromkeys(x for x in P.Protocols if x not in P._PrivateProtocols)).keys()\r
+                ProtocolKeys = [x for x in P.Protocols if x not in P._PrivateProtocols]\r
         if CName in ProtocolKeys:\r
             return P.Protocols[CName]\r
     return None\r
         if CName in ProtocolKeys:\r
             return P.Protocols[CName]\r
     return None\r
@@ -870,7 +669,7 @@ def PpiValue(CName, PackageList, Inffile = None):
         PpiKeys = P.Ppis.keys()\r
         if Inffile and P._PrivatePpis:\r
             if not Inffile.startswith(P.MetaFile.Dir):\r
         PpiKeys = P.Ppis.keys()\r
         if Inffile and P._PrivatePpis:\r
             if not Inffile.startswith(P.MetaFile.Dir):\r
-                PpiKeys = (dict.fromkeys(x for x in P.Ppis if x not in P._PrivatePpis)).keys()\r
+                PpiKeys = [x for x in P.Ppis if x not in P._PrivatePpis]\r
         if CName in PpiKeys:\r
             return P.Ppis[CName]\r
     return None\r
         if CName in PpiKeys:\r
             return P.Ppis[CName]\r
     return None\r
@@ -1061,7 +860,7 @@ class Progressor:
         self.CodaMessage = CloseMessage\r
         self.ProgressChar = ProgressChar\r
         self.Interval = Interval\r
         self.CodaMessage = CloseMessage\r
         self.ProgressChar = ProgressChar\r
         self.Interval = Interval\r
-        if Progressor._StopFlag == None:\r
+        if Progressor._StopFlag is None:\r
             Progressor._StopFlag = threading.Event()\r
 \r
     ## Start to print progress charater\r
             Progressor._StopFlag = threading.Event()\r
 \r
     ## Start to print progress charater\r
@@ -1069,10 +868,10 @@ class Progressor:
     #   @param      OpenMessage     The string printed before progress charaters\r
     #\r
     def Start(self, OpenMessage=None):\r
     #   @param      OpenMessage     The string printed before progress charaters\r
     #\r
     def Start(self, OpenMessage=None):\r
-        if OpenMessage != None:\r
+        if OpenMessage is not None:\r
             self.PromptMessage = OpenMessage\r
         Progressor._StopFlag.clear()\r
             self.PromptMessage = OpenMessage\r
         Progressor._StopFlag.clear()\r
-        if Progressor._ProgressThread == None:\r
+        if Progressor._ProgressThread is None:\r
             Progressor._ProgressThread = threading.Thread(target=self._ProgressThreadEntry)\r
             Progressor._ProgressThread.setDaemon(False)\r
             Progressor._ProgressThread.start()\r
             Progressor._ProgressThread = threading.Thread(target=self._ProgressThreadEntry)\r
             Progressor._ProgressThread.setDaemon(False)\r
             Progressor._ProgressThread.start()\r
@@ -1083,7 +882,7 @@ class Progressor:
     #\r
     def Stop(self, CloseMessage=None):\r
         OriginalCodaMessage = self.CodaMessage\r
     #\r
     def Stop(self, CloseMessage=None):\r
         OriginalCodaMessage = self.CodaMessage\r
-        if CloseMessage != None:\r
+        if CloseMessage is not None:\r
             self.CodaMessage = CloseMessage\r
         self.Abort()\r
         self.CodaMessage = OriginalCodaMessage\r
             self.CodaMessage = CloseMessage\r
         self.Abort()\r
         self.CodaMessage = OriginalCodaMessage\r
@@ -1106,9 +905,9 @@ class Progressor:
     ## Abort the progress display\r
     @staticmethod\r
     def Abort():\r
     ## Abort the progress display\r
     @staticmethod\r
     def Abort():\r
-        if Progressor._StopFlag != None:\r
+        if Progressor._StopFlag is not None:\r
             Progressor._StopFlag.set()\r
             Progressor._StopFlag.set()\r
-        if Progressor._ProgressThread != None:\r
+        if Progressor._ProgressThread is not None:\r
             Progressor._ProgressThread.join()\r
             Progressor._ProgressThread = None\r
 \r
             Progressor._ProgressThread.join()\r
             Progressor._ProgressThread = None\r
 \r
@@ -1227,7 +1026,7 @@ class sdict(IterableUserDict):
         return key, value\r
 \r
     def update(self, dict=None, **kwargs):\r
         return key, value\r
 \r
     def update(self, dict=None, **kwargs):\r
-        if dict != None:\r
+        if dict is not None:\r
             for k, v in dict.items():\r
                 self[k] = v\r
         if len(kwargs):\r
             for k, v in dict.items():\r
                 self[k] = v\r
         if len(kwargs):\r
@@ -1300,7 +1099,7 @@ class tdict:
             if self._Level_ > 1:\r
                 RestKeys = [self._Wildcard for i in range(0, self._Level_ - 1)]\r
 \r
             if self._Level_ > 1:\r
                 RestKeys = [self._Wildcard for i in range(0, self._Level_ - 1)]\r
 \r
-        if FirstKey == None or str(FirstKey).upper() in self._ValidWildcardList:\r
+        if FirstKey is None or str(FirstKey).upper() in self._ValidWildcardList:\r
             FirstKey = self._Wildcard\r
 \r
         if self._Single_:\r
             FirstKey = self._Wildcard\r
 \r
         if self._Single_:\r
@@ -1315,24 +1114,24 @@ class tdict:
             if FirstKey == self._Wildcard:\r
                 if FirstKey in self.data:\r
                     Value = self.data[FirstKey][RestKeys]\r
             if FirstKey == self._Wildcard:\r
                 if FirstKey in self.data:\r
                     Value = self.data[FirstKey][RestKeys]\r
-                if Value == None:\r
+                if Value is None:\r
                     for Key in self.data:\r
                         Value = self.data[Key][RestKeys]\r
                     for Key in self.data:\r
                         Value = self.data[Key][RestKeys]\r
-                        if Value != None: break\r
+                        if Value is not None: break\r
             else:\r
                 if FirstKey in self.data:\r
                     Value = self.data[FirstKey][RestKeys]\r
             else:\r
                 if FirstKey in self.data:\r
                     Value = self.data[FirstKey][RestKeys]\r
-                if Value == None and self._Wildcard in self.data:\r
+                if Value is None and self._Wildcard in self.data:\r
                     #print "Value=None"\r
                     Value = self.data[self._Wildcard][RestKeys]\r
         else:\r
             if FirstKey == self._Wildcard:\r
                 if FirstKey in self.data:\r
                     Value = self.data[FirstKey]\r
                     #print "Value=None"\r
                     Value = self.data[self._Wildcard][RestKeys]\r
         else:\r
             if FirstKey == self._Wildcard:\r
                 if FirstKey in self.data:\r
                     Value = self.data[FirstKey]\r
-                if Value == None:\r
+                if Value is None:\r
                     for Key in self.data:\r
                         Value = self.data[Key]\r
                     for Key in self.data:\r
                         Value = self.data[Key]\r
-                        if Value != None: break\r
+                        if Value is not None: break\r
             else:\r
                 if FirstKey in self.data:\r
                     Value = self.data[FirstKey]\r
             else:\r
                 if FirstKey in self.data:\r
                     Value = self.data[FirstKey]\r
@@ -1410,53 +1209,44 @@ class tdict:
                 keys |= self.data[Key].GetKeys(KeyIndex - 1)\r
             return keys\r
 \r
                 keys |= self.data[Key].GetKeys(KeyIndex - 1)\r
             return keys\r
 \r
-## Boolean chain list\r
-#\r
-class Blist(UserList):\r
-    def __init__(self, initlist=None):\r
-        UserList.__init__(self, initlist)\r
-    def __setitem__(self, i, item):\r
-        if item not in [True, False]:\r
-            if item == 0:\r
-                item = False\r
-            else:\r
-                item = True\r
-        self.data[i] = item\r
-    def _GetResult(self):\r
-        Value = True\r
-        for item in self.data:\r
-            Value &= item\r
-        return Value\r
-    Result = property(_GetResult)\r
-\r
-def ParseConsoleLog(Filename):\r
-    Opr = open(os.path.normpath(Filename), 'r')\r
-    Opw = open(os.path.normpath(Filename + '.New'), 'w+')\r
-    for Line in Opr.readlines():\r
-        if Line.find('.efi') > -1:\r
-            Line = Line[Line.rfind(' ') : Line.rfind('.efi')].strip()\r
-            Opw.write('%s\n' % Line)\r
-\r
-    Opr.close()\r
-    Opw.close()\r
+def IsFieldValueAnArray (Value):\r
+    Value = Value.strip()\r
+    if Value.startswith('GUID') and Value.endswith(')'):\r
+        return True\r
+    if Value.startswith('L"') and Value.endswith('"')  and len(list(Value[2:-1])) > 1:\r
+        return True\r
+    if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1:\r
+        return True\r
+    if Value[0] == '{' and Value[-1] == '}':\r
+        return True\r
+    if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:\r
+        return True\r
+    if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:\r
+        return True\r
+    return False\r
 \r
 def AnalyzePcdExpression(Setting):\r
     Setting = Setting.strip()\r
 \r
 def AnalyzePcdExpression(Setting):\r
     Setting = Setting.strip()\r
-    # There might be escaped quote in a string: \", \\\"\r
-    Data = Setting.replace('\\\\', '//').replace('\\\"', '\\\'')\r
+    # There might be escaped quote in a string: \", \\\" , \', \\\'\r
+    Data = Setting\r
     # There might be '|' in string and in ( ... | ... ), replace it with '-'\r
     NewStr = ''\r
     # There might be '|' in string and in ( ... | ... ), replace it with '-'\r
     NewStr = ''\r
-    InStr = False\r
+    InSingleQuoteStr = False\r
+    InDoubleQuoteStr = False\r
     Pair = 0\r
     Pair = 0\r
-    for ch in Data:\r
-        if ch == '"':\r
-            InStr = not InStr\r
-        elif ch == '(' and not InStr:\r
+    for Index, ch in enumerate(Data):\r
+        if ch == '"' and not InSingleQuoteStr:\r
+            if Data[Index - 1] != '\\':\r
+                InDoubleQuoteStr = not InDoubleQuoteStr\r
+        elif ch == "'" and not InDoubleQuoteStr:\r
+            if Data[Index - 1] != '\\':\r
+                InSingleQuoteStr = not InSingleQuoteStr\r
+        elif ch == '(' and not (InSingleQuoteStr or InDoubleQuoteStr):\r
             Pair += 1\r
             Pair += 1\r
-        elif ch == ')' and not InStr:\r
+        elif ch == ')' and not (InSingleQuoteStr or InDoubleQuoteStr):\r
             Pair -= 1\r
 \r
             Pair -= 1\r
 \r
-        if (Pair > 0 or InStr) and ch == TAB_VALUE_SPLIT:\r
+        if (Pair > 0 or InSingleQuoteStr or InDoubleQuoteStr) and ch == TAB_VALUE_SPLIT:\r
             NewStr += '-'\r
         else:\r
             NewStr += ch\r
             NewStr += '-'\r
         else:\r
             NewStr += ch\r
@@ -1472,104 +1262,162 @@ def AnalyzePcdExpression(Setting):
 \r
     return FieldList\r
 \r
 \r
     return FieldList\r
 \r
+def ParseDevPathValue (Value):\r
+    if '\\' in Value:\r
+        Value.replace('\\', '/').replace(' ', '')\r
+\r
+    Cmd = 'DevicePath ' + '"' + Value + '"'\r
+    try:\r
+        p = subprocess.Popen(Cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\r
+        out, err = p.communicate()\r
+    except Exception, X:\r
+        raise BadExpression("DevicePath: %s" % (str(X)) )\r
+    finally:\r
+        subprocess._cleanup()\r
+        p.stdout.close()\r
+        p.stderr.close()\r
+    if err:\r
+        raise BadExpression("DevicePath: %s" % str(err))\r
+    Size = len(out.split())\r
+    out = ','.join(out.split())\r
+    return '{' + out + '}', Size\r
+\r
 def ParseFieldValue (Value):\r
 def ParseFieldValue (Value):\r
-  if type(Value) == type(0):\r
-    return Value, (Value.bit_length() + 7) / 8\r
-  if type(Value) <> type(''):\r
-    raise ValueError\r
-  Value = Value.strip()\r
-  if Value.startswith('UINT8') and Value.endswith(')'):\r
-    Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])\r
-    if Size > 1:\r
-      raise ValueError\r
+    if type(Value) == type(0):\r
+        return Value, (Value.bit_length() + 7) / 8\r
+    if type(Value) <> type(''):\r
+        raise BadExpression('Type %s is %s' %(Value, type(Value)))\r
+    Value = Value.strip()\r
+    if Value.startswith('UINT8') and Value.endswith(')'):\r
+        Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])\r
+        if Size > 1:\r
+            raise BadExpression('Value (%s) Size larger than %d' %(Value, Size))\r
+        return Value, 1\r
+    if Value.startswith('UINT16') and Value.endswith(')'):\r
+        Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])\r
+        if Size > 2:\r
+            raise BadExpression('Value (%s) Size larger than %d' %(Value, Size))\r
+        return Value, 2\r
+    if Value.startswith('UINT32') and Value.endswith(')'):\r
+        Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])\r
+        if Size > 4:\r
+            raise BadExpression('Value (%s) Size larger than %d' %(Value, Size))\r
+        return Value, 4\r
+    if Value.startswith('UINT64') and Value.endswith(')'):\r
+        Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])\r
+        if Size > 8:\r
+            raise BadExpression('Value (%s) Size larger than %d' % (Value, Size))\r
+        return Value, 8\r
+    if Value.startswith('GUID') and Value.endswith(')'):\r
+        Value = Value.split('(', 1)[1][:-1].strip()\r
+        if Value[0] == '{' and Value[-1] == '}':\r
+            TmpValue = GuidStructureStringToGuidString(Value)\r
+            if len(TmpValue) == 0:\r
+                raise BadExpression("Invalid GUID value string %s" % Value)\r
+            Value = TmpValue\r
+        if Value[0] == '"' and Value[-1] == '"':\r
+            Value = Value[1:-1]\r
+        try:\r
+            Value = "'" + uuid.UUID(Value).get_bytes_le() + "'"\r
+        except ValueError, Message:\r
+            raise BadExpression('%s' % Message)\r
+        Value, Size = ParseFieldValue(Value)\r
+        return Value, 16\r
+    if Value.startswith('L"') and Value.endswith('"'):\r
+        # Unicode String\r
+        # translate escape character\r
+        Value = Value[1:]\r
+        try:\r
+            Value = eval(Value)\r
+        except:\r
+            Value = Value[1:-1]\r
+        List = list(Value)\r
+        List.reverse()\r
+        Value = 0\r
+        for Char in List:\r
+            Value = (Value << 16) | ord(Char)\r
+        return Value, (len(List) + 1) * 2\r
+    if Value.startswith('"') and Value.endswith('"'):\r
+        # ASCII String\r
+        # translate escape character\r
+        try:\r
+            Value = eval(Value)\r
+        except:\r
+            Value = Value[1:-1]\r
+        List = list(Value)\r
+        List.reverse()\r
+        Value = 0\r
+        for Char in List:\r
+            Value = (Value << 8) | ord(Char)\r
+        return Value, len(List) + 1\r
+    if Value.startswith("L'") and Value.endswith("'"):\r
+        # Unicode Character Constant\r
+        # translate escape character\r
+        Value = Value[1:]\r
+        try:\r
+            Value = eval(Value)\r
+        except:\r
+            Value = Value[1:-1]\r
+        List = list(Value)\r
+        if len(List) == 0:\r
+            raise BadExpression('Length %s is %s' % (Value, len(List)))\r
+        List.reverse()\r
+        Value = 0\r
+        for Char in List:\r
+            Value = (Value << 16) | ord(Char)\r
+        return Value, len(List) * 2\r
+    if Value.startswith("'") and Value.endswith("'"):\r
+        # Character constant\r
+        # translate escape character\r
+        try:\r
+            Value = eval(Value)\r
+        except:\r
+            Value = Value[1:-1]\r
+        List = list(Value)\r
+        if len(List) == 0:\r
+            raise BadExpression('Length %s is %s' % (Value, len(List)))\r
+        List.reverse()\r
+        Value = 0\r
+        for Char in List:\r
+            Value = (Value << 8) | ord(Char)\r
+        return Value, len(List)\r
+    if Value.startswith('{') and Value.endswith('}'):\r
+        # Byte array\r
+        Value = Value[1:-1]\r
+        List = [Item.strip() for Item in Value.split(',')]\r
+        List.reverse()\r
+        Value = 0\r
+        RetSize = 0\r
+        for Item in List:\r
+            ItemValue, Size = ParseFieldValue(Item)\r
+            RetSize += Size\r
+            for I in range(Size):\r
+                Value = (Value << 8) | ((ItemValue >> 8 * I) & 0xff)\r
+        return Value, RetSize\r
+    if Value.startswith('DEVICE_PATH(') and Value.endswith(')'):\r
+        Value = Value.replace("DEVICE_PATH(", '').rstrip(')')\r
+        Value = Value.strip().strip('"')\r
+        return ParseDevPathValue(Value)\r
+    if Value.lower().startswith('0x'):\r
+        Value = int(Value, 16)\r
+        if Value == 0:\r
+            return 0, 1\r
+        return Value, (Value.bit_length() + 7) / 8\r
+    if Value[0].isdigit():\r
+        Value = int(Value, 10)\r
+        if Value == 0:\r
+            return 0, 1\r
+        return Value, (Value.bit_length() + 7) / 8\r
+    if Value.lower() == 'true':\r
+        return 1, 1\r
+    if Value.lower() == 'false':\r
+        return 0, 1\r
     return Value, 1\r
     return Value, 1\r
-  if Value.startswith('UINT16') and Value.endswith(')'):\r
-    Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])\r
-    if Size > 2:\r
-      raise ValueError\r
-    return Value, 2\r
-  if Value.startswith('UINT32') and Value.endswith(')'):\r
-    Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])\r
-    if Size > 4:\r
-      raise ValueError\r
-    return Value, 4\r
-  if Value.startswith('UINT64') and Value.endswith(')'):\r
-    Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])\r
-    if Size > 8:\r
-      raise ValueError\r
-    return Value, 8\r
-  if Value.startswith('GUID') and Value.endswith(')'):\r
-    Value = Value.split('(', 1)[1][:-1].strip()\r
-    if Value[0] == '{' and Value[-1] == '}':\r
-      Value = Value[1:-1].strip()\r
-      Value = Value.split('{', 1)\r
-      Value = [Item.strip()[2:] for Item in (Value[0] + Value[1][:-1]).split(',')]\r
-      Value = '-'.join(Value[0:3]) + '-' + ''.join(Value[3:5]) + '-' + ''.join(Value[5:11])\r
-    if Value[0] == '"' and Value[-1] == '"':\r
-      Value = Value[1:-1]\r
-    Value = "'" + uuid.UUID(Value).get_bytes_le() + "'"\r
-    Value, Size = ParseFieldValue(Value)\r
-    return Value, 16\r
-  if Value.startswith('L"') and Value.endswith('"'):\r
-    # Unicode String\r
-    List = list(Value[2:-1])\r
-    List.reverse()\r
-    Value = 0\r
-    for Char in List:\r
-      Value = (Value << 16) | ord(Char)\r
-    return Value, (len(List) + 1) * 2\r
-  if Value.startswith('"') and Value.endswith('"'):\r
-    # ASCII String\r
-    List = list(Value[1:-1])\r
-    List.reverse()\r
-    Value = 0\r
-    for Char in List:\r
-      Value = (Value << 8) | ord(Char)\r
-    return Value, len(List) + 1\r
-  if Value.startswith("L'") and Value.endswith("'"):\r
-    # Unicode Character Constant\r
-    List = list(Value[2:-1])\r
-    List.reverse()\r
-    Value = 0\r
-    for Char in List:\r
-      Value = (Value << 16) | ord(Char)\r
-    return Value, len(List) * 2\r
-  if Value.startswith("'") and Value.endswith("'"):\r
-    # Character constant\r
-    List = list(Value[1:-1])\r
-    List.reverse()\r
-    Value = 0\r
-    for Char in List:\r
-      Value = (Value << 8) | ord(Char)\r
-    return Value, len(List)\r
-  if Value.startswith('{') and Value.endswith('}'):\r
-    # Byte array\r
-    Value = Value[1:-1]\r
-    List = [Item.strip() for Item in Value.split(',')]\r
-    List.reverse()\r
-    Value = 0\r
-    for Item in List:\r
-      ItemValue, Size = ParseFieldValue(Item)\r
-      if Size > 1:\r
-        raise ValueError\r
-      Value = (Value << 8) | ItemValue\r
-    return Value, len(List)\r
-  if Value.lower().startswith('0x'):\r
-    Value = int(Value, 16)\r
-    return Value, (Value.bit_length() + 7) / 8\r
-  if Value[0].isdigit():\r
-    Value = int(Value, 10)\r
-    return Value, (Value.bit_length() + 7) / 8\r
-  if Value.lower() == 'true':\r
-    return 1, 1\r
-  if Value.lower() == 'false':\r
-    return 0, 1\r
-  return Value, 1\r
 \r
 ## AnalyzeDscPcd\r
 #\r
 #  Analyze DSC PCD value, since there is no data type info in DSC\r
 \r
 ## AnalyzeDscPcd\r
 #\r
 #  Analyze DSC PCD value, since there is no data type info in DSC\r
-#  This fuction is used to match functions (AnalyzePcdData, AnalyzeHiiPcdData, AnalyzeVpdPcdData) used for retrieving PCD value from database\r
+#  This fuction is used to match functions (AnalyzePcdData) used for retrieving PCD value from database\r
 #  1. Feature flag: TokenSpace.PcdCName|PcdValue\r
 #  2. Fix and Patch:TokenSpace.PcdCName|PcdValue[|MaxSize]\r
 #  3. Dynamic default:\r
 #  1. Feature flag: TokenSpace.PcdCName|PcdValue\r
 #  2. Fix and Patch:TokenSpace.PcdCName|PcdValue[|MaxSize]\r
 #  3. Dynamic default:\r
@@ -1611,6 +1459,12 @@ def AnalyzeDscPcd(Setting, PcdType, DataType=''):
         else:\r
             IsValid = (len(FieldList) <= 3)\r
 #         Value, Size = ParseFieldValue(Value)\r
         else:\r
             IsValid = (len(FieldList) <= 3)\r
 #         Value, Size = ParseFieldValue(Value)\r
+        if Size:\r
+            try:\r
+                int(Size,16) if Size.upper().startswith("0X") else int(Size)\r
+            except:\r
+                IsValid = False\r
+                Size = -1\r
         return [str(Value), '', str(Size)], IsValid, 0\r
     elif PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT):\r
         Value = FieldList[0]\r
         return [str(Value), '', str(Size)], IsValid, 0\r
     elif PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT):\r
         Value = FieldList[0]\r
@@ -1621,19 +1475,18 @@ def AnalyzeDscPcd(Setting, PcdType, DataType=''):
             Type = DataType\r
         if len(FieldList) > 2:\r
             Size = FieldList[2]\r
             Type = DataType\r
         if len(FieldList) > 2:\r
             Size = FieldList[2]\r
-        else:\r
-            if Type == 'VOID*':\r
-                if Value.startswith("L"):\r
-                    Size = str((len(Value)- 3 + 1) * 2)\r
-                elif Value.startswith("{"):\r
-                    Size = str(len(Value.split(",")))\r
-                else:\r
-                    Size = str(len(Value) -2 + 1 )\r
         if DataType == "":\r
             IsValid = (len(FieldList) <= 1)\r
         else:\r
             IsValid = (len(FieldList) <= 3)\r
         if DataType == "":\r
             IsValid = (len(FieldList) <= 1)\r
         else:\r
             IsValid = (len(FieldList) <= 3)\r
-        return [Value, Type, Size], IsValid, 0\r
+\r
+        if Size:\r
+            try:\r
+                int(Size,16) if Size.upper().startswith("0X") else int(Size)\r
+            except:\r
+                IsValid = False\r
+                Size = -1\r
+        return [Value, Type, str(Size)], IsValid, 0\r
     elif PcdType in (MODEL_PCD_DYNAMIC_VPD, MODEL_PCD_DYNAMIC_EX_VPD):\r
         VpdOffset = FieldList[0]\r
         Value = Size = ''\r
     elif PcdType in (MODEL_PCD_DYNAMIC_VPD, MODEL_PCD_DYNAMIC_EX_VPD):\r
         VpdOffset = FieldList[0]\r
         Value = Size = ''\r
@@ -1649,8 +1502,13 @@ def AnalyzeDscPcd(Setting, PcdType, DataType=''):
             IsValid = (len(FieldList) <= 1)\r
         else:\r
             IsValid = (len(FieldList) <= 3)\r
             IsValid = (len(FieldList) <= 1)\r
         else:\r
             IsValid = (len(FieldList) <= 3)\r
-\r
-        return [VpdOffset, Size, Value], IsValid, 2\r
+        if Size:\r
+            try:\r
+                int(Size,16) if Size.upper().startswith("0X") else int(Size)\r
+            except:\r
+                IsValid = False\r
+                Size = -1\r
+        return [VpdOffset, str(Size), Value], IsValid, 2\r
     elif PcdType in (MODEL_PCD_DYNAMIC_HII, MODEL_PCD_DYNAMIC_EX_HII):\r
         HiiString = FieldList[0]\r
         Guid = Offset = Value = Attribute = ''\r
     elif PcdType in (MODEL_PCD_DYNAMIC_HII, MODEL_PCD_DYNAMIC_EX_HII):\r
         HiiString = FieldList[0]\r
         Guid = Offset = Value = Attribute = ''\r
@@ -1695,52 +1553,6 @@ def AnalyzePcdData(Setting):
         \r
     return ValueList   \r
  \r
         \r
     return ValueList   \r
  \r
-## AnalyzeHiiPcdData\r
-#\r
-#  Analyze the pcd Value, variable name, variable Guid and variable offset.\r
-#  Used to avoid split issue while the value string contain "|" character\r
-#\r
-#  @param[in] Setting:  A String contain VariableName, VariableGuid, VariableOffset, DefaultValue information;\r
-#  \r
-#  @retval   ValueList: A List contaian VariableName, VariableGuid, VariableOffset, DefaultValue. \r
-#\r
-def AnalyzeHiiPcdData(Setting):\r
-    ValueList = ['', '', '', '']\r
-\r
-    TokenList = GetSplitValueList(Setting)\r
-    ValueList[0:len(TokenList)] = TokenList\r
-\r
-    return ValueList\r
-\r
-## AnalyzeVpdPcdData\r
-#\r
-#  Analyze the vpd pcd VpdOffset, MaxDatumSize and InitialValue.\r
-#  Used to avoid split issue while the value string contain "|" character\r
-#\r
-#  @param[in] Setting:  A String contain VpdOffset/MaxDatumSize/InitialValue information;\r
-#  \r
-#  @retval   ValueList: A List contain VpdOffset, MaxDatumSize and InitialValue. \r
-#\r
-def AnalyzeVpdPcdData(Setting):\r
-    ValueList = ['', '', '']\r
-\r
-    ValueRe = re.compile(r'\s*L?\".*\|.*\"\s*$')\r
-    PtrValue = ValueRe.findall(Setting)\r
-    \r
-    ValueUpdateFlag = False\r
-    \r
-    if len(PtrValue) >= 1:\r
-        Setting = re.sub(ValueRe, '', Setting)\r
-        ValueUpdateFlag = True\r
-\r
-    TokenList = Setting.split(TAB_VALUE_SPLIT)\r
-    ValueList[0:len(TokenList)] = TokenList\r
-    \r
-    if ValueUpdateFlag:\r
-        ValueList[2] = PtrValue[0]\r
-        \r
-    return ValueList     \r
-\r
 ## check format of PCD value against its the datum type\r
 #\r
 # For PCD value setting\r
 ## check format of PCD value against its the datum type\r
 #\r
 # For PCD value setting\r
@@ -1749,10 +1561,10 @@ def CheckPcdDatum(Type, Value):
     if Type == "VOID*":\r
         ValueRe = re.compile(r'\s*L?\".*\"\s*$')\r
         if not (((Value.startswith('L"') or Value.startswith('"')) and Value.endswith('"'))\r
     if Type == "VOID*":\r
         ValueRe = re.compile(r'\s*L?\".*\"\s*$')\r
         if not (((Value.startswith('L"') or Value.startswith('"')) and Value.endswith('"'))\r
-                or (Value.startswith('{') and Value.endswith('}'))\r
+                or (Value.startswith('{') and Value.endswith('}')) or (Value.startswith("L'") or Value.startswith("'") and Value.endswith("'"))\r
                ):\r
             return False, "Invalid value [%s] of type [%s]; must be in the form of {...} for array"\\r
                ):\r
             return False, "Invalid value [%s] of type [%s]; must be in the form of {...} for array"\\r
-                          ", or \"...\" for string, or L\"...\" for unicode string" % (Value, Type)\r
+                          ", \"...\" or \'...\' for string, L\"...\" or L\'...\' for unicode string" % (Value, Type)\r
         elif ValueRe.match(Value):\r
             # Check the chars in UnicodeString or CString is printable\r
             if Value.startswith("L"):\r
         elif ValueRe.match(Value):\r
             # Check the chars in UnicodeString or CString is printable\r
             if Value.startswith("L"):\r
@@ -1963,7 +1775,7 @@ class PathClass(object):
         return hash(self.Path)\r
 \r
     def _GetFileKey(self):\r
         return hash(self.Path)\r
 \r
     def _GetFileKey(self):\r
-        if self._Key == None:\r
+        if self._Key is None:\r
             self._Key = self.Path.upper()   # + self.ToolChainFamily + self.TagName + self.ToolCode + self.Target\r
         return self._Key\r
 \r
             self._Key = self.Path.upper()   # + self.ToolChainFamily + self.TagName + self.ToolCode + self.Target\r
         return self._Key\r
 \r
@@ -2093,61 +1905,167 @@ class PeImageClass():
             Value = (Value << 8) | int(ByteList[index])\r
         return Value\r
 \r
             Value = (Value << 8) | int(ByteList[index])\r
         return Value\r
 \r
+class DefaultStore():\r
+    def __init__(self,DefaultStores ):\r
 \r
 \r
+        self.DefaultStores = DefaultStores\r
+    def DefaultStoreID(self,DefaultStoreName):\r
+        for key,value in self.DefaultStores.items():\r
+            if value == DefaultStoreName:\r
+                return key\r
+        return None\r
+    def GetDefaultDefault(self):\r
+        if not self.DefaultStores or "0" in self.DefaultStores:\r
+            return "0",TAB_DEFAULT_STORES_DEFAULT\r
+        else:\r
+            minvalue = min([int(value_str) for value_str in self.DefaultStores.keys()])\r
+            return (str(minvalue), self.DefaultStores[str(minvalue)])\r
+    def GetMin(self,DefaultSIdList):\r
+        if not DefaultSIdList:\r
+            return TAB_DEFAULT_STORES_DEFAULT\r
+        storeidset = {storeid for storeid, storename in self.DefaultStores.values() if storename in DefaultSIdList}\r
+        if not storeidset:\r
+            return ""\r
+        minid = min(storeidset )\r
+        for sid,name in self.DefaultStores.values():\r
+            if sid == minid:\r
+                return name\r
 class SkuClass():\r
     \r
     DEFAULT = 0\r
     SINGLE = 1\r
     MULTIPLE =2\r
     \r
 class SkuClass():\r
     \r
     DEFAULT = 0\r
     SINGLE = 1\r
     MULTIPLE =2\r
     \r
-    def __init__(self,SkuIdentifier='', SkuIds={}):\r
+    def __init__(self,SkuIdentifier='', SkuIds=None):\r
+        if SkuIds is None:\r
+            SkuIds = {}\r
+\r
+        for SkuName in SkuIds:\r
+            SkuId = SkuIds[SkuName][0]\r
+            skuid_num = int(SkuId,16) if SkuId.upper().startswith("0X") else int(SkuId)\r
+            if skuid_num > 0xFFFFFFFFFFFFFFFF:\r
+                EdkLogger.error("build", PARAMETER_INVALID,\r
+                            ExtraData = "SKU-ID [%s] value %s exceeds the max value of UINT64"\r
+                                      % (SkuName, SkuId))\r
         \r
         self.AvailableSkuIds = sdict()\r
         self.SkuIdSet = []\r
         self.SkuIdNumberSet = []\r
         \r
         self.AvailableSkuIds = sdict()\r
         self.SkuIdSet = []\r
         self.SkuIdNumberSet = []\r
+        self.SkuData = SkuIds\r
+        self.__SkuInherit = {}\r
+        self.__SkuIdentifier = SkuIdentifier\r
         if SkuIdentifier == '' or SkuIdentifier is None:\r
             self.SkuIdSet = ['DEFAULT']\r
             self.SkuIdNumberSet = ['0U']\r
         elif SkuIdentifier == 'ALL':\r
             self.SkuIdSet = SkuIds.keys()\r
         if SkuIdentifier == '' or SkuIdentifier is None:\r
             self.SkuIdSet = ['DEFAULT']\r
             self.SkuIdNumberSet = ['0U']\r
         elif SkuIdentifier == 'ALL':\r
             self.SkuIdSet = SkuIds.keys()\r
-            self.SkuIdNumberSet = [num.strip() + 'U' for num in SkuIds.values()]\r
+            self.SkuIdNumberSet = [num[0].strip() + 'U' for num in SkuIds.values()]\r
         else:\r
             r = SkuIdentifier.split('|') \r
         else:\r
             r = SkuIdentifier.split('|') \r
-            self.SkuIdSet=[r[k].strip() for k in range(len(r))]      \r
+            self.SkuIdSet=[(r[k].strip()).upper() for k in range(len(r))]\r
             k = None\r
             try: \r
             k = None\r
             try: \r
-                self.SkuIdNumberSet = [SkuIds[k].strip() + 'U' for k in self.SkuIdSet]   \r
+                self.SkuIdNumberSet = [SkuIds[k][0].strip() + 'U' for k in self.SkuIdSet]\r
             except Exception:\r
                 EdkLogger.error("build", PARAMETER_INVALID,\r
                             ExtraData = "SKU-ID [%s] is not supported by the platform. [Valid SKU-ID: %s]"\r
                                       % (k, " | ".join(SkuIds.keys())))\r
             except Exception:\r
                 EdkLogger.error("build", PARAMETER_INVALID,\r
                             ExtraData = "SKU-ID [%s] is not supported by the platform. [Valid SKU-ID: %s]"\r
                                       % (k, " | ".join(SkuIds.keys())))\r
-        if len(self.SkuIdSet) == 2 and 'DEFAULT' in self.SkuIdSet and SkuIdentifier != 'ALL':\r
-            self.SkuIdSet.remove('DEFAULT')\r
-            self.SkuIdNumberSet.remove('0U')\r
         for each in self.SkuIdSet:\r
             if each in SkuIds:\r
         for each in self.SkuIdSet:\r
             if each in SkuIds:\r
-                self.AvailableSkuIds[each] = SkuIds[each]\r
+                self.AvailableSkuIds[each] = SkuIds[each][0]\r
             else:\r
                 EdkLogger.error("build", PARAMETER_INVALID,\r
                             ExtraData="SKU-ID [%s] is not supported by the platform. [Valid SKU-ID: %s]"\r
                                       % (each, " | ".join(SkuIds.keys())))\r
             else:\r
                 EdkLogger.error("build", PARAMETER_INVALID,\r
                             ExtraData="SKU-ID [%s] is not supported by the platform. [Valid SKU-ID: %s]"\r
                                       % (each, " | ".join(SkuIds.keys())))\r
+        if self.SkuUsageType != self.SINGLE:\r
+            self.AvailableSkuIds.update({'DEFAULT':0, 'COMMON':0})\r
+        if self.SkuIdSet:\r
+            GlobalData.gSkuids = (self.SkuIdSet)\r
+            if 'COMMON' in GlobalData.gSkuids:\r
+                GlobalData.gSkuids.remove('COMMON')\r
+            if self.SkuUsageType == self.SINGLE:\r
+                if len(GlobalData.gSkuids) != 1:\r
+                    if 'DEFAULT' in GlobalData.gSkuids:\r
+                        GlobalData.gSkuids.remove('DEFAULT')\r
+            if GlobalData.gSkuids:\r
+                GlobalData.gSkuids.sort()\r
+\r
+    def GetNextSkuId(self, skuname):\r
+        if not self.__SkuInherit:\r
+            self.__SkuInherit = {}\r
+            for item in self.SkuData.values():\r
+                self.__SkuInherit[item[1]]=item[2] if item[2] else "DEFAULT"\r
+        return self.__SkuInherit.get(skuname,"DEFAULT")\r
+\r
+    def GetSkuChain(self,sku):\r
+        if sku == "DEFAULT":\r
+            return ["DEFAULT"]\r
+        skulist = [sku]\r
+        nextsku = sku\r
+        while 1:\r
+            nextsku = self.GetNextSkuId(nextsku)\r
+            skulist.append(nextsku)\r
+            if nextsku == "DEFAULT":\r
+                break\r
+        skulist.reverse()\r
+        return skulist\r
+    def SkuOverrideOrder(self):\r
+        skuorderset = []\r
+        for skuname in self.SkuIdSet:\r
+            skuorderset.append(self.GetSkuChain(skuname))\r
         \r
         \r
+        skuorder = []\r
+        for index in range(max([len(item) for item in skuorderset])):\r
+            for subset in skuorderset:\r
+                if index > len(subset)-1:\r
+                    continue\r
+                if subset[index] in skuorder:\r
+                    continue\r
+                skuorder.append(subset[index])\r
+\r
+        return skuorder\r
+\r
     def __SkuUsageType(self): \r
         \r
     def __SkuUsageType(self): \r
         \r
+        if self.__SkuIdentifier.upper() == "ALL":\r
+            return SkuClass.MULTIPLE\r
+\r
         if len(self.SkuIdSet) == 1:\r
             if self.SkuIdSet[0] == 'DEFAULT':\r
                 return SkuClass.DEFAULT\r
             else:\r
                 return SkuClass.SINGLE\r
         if len(self.SkuIdSet) == 1:\r
             if self.SkuIdSet[0] == 'DEFAULT':\r
                 return SkuClass.DEFAULT\r
             else:\r
                 return SkuClass.SINGLE\r
+        elif len(self.SkuIdSet) == 2:\r
+            if 'DEFAULT' in self.SkuIdSet:\r
+                return SkuClass.SINGLE\r
+            else:\r
+                return SkuClass.MULTIPLE\r
         else:\r
             return SkuClass.MULTIPLE\r
         else:\r
             return SkuClass.MULTIPLE\r
+    def DumpSkuIdArrary(self):\r
 \r
 \r
+        ArrayStrList = []\r
+        if self.SkuUsageType == SkuClass.SINGLE:\r
+            ArrayStr = "{0x0}"\r
+        else:\r
+            for skuname in self.AvailableSkuIds:\r
+                if skuname == "COMMON":\r
+                    continue\r
+                while skuname != "DEFAULT":\r
+                    ArrayStrList.append(hex(int(self.AvailableSkuIds[skuname])))\r
+                    skuname = self.GetNextSkuId(skuname)\r
+                ArrayStrList.append("0x0")\r
+            ArrayStr = "{" + ",".join(ArrayStrList) +  "}"\r
+        return ArrayStr\r
     def __GetAvailableSkuIds(self):\r
         return self.AvailableSkuIds\r
     \r
     def __GetSystemSkuID(self):\r
         if self.__SkuUsageType() == SkuClass.SINGLE:\r
     def __GetAvailableSkuIds(self):\r
         return self.AvailableSkuIds\r
     \r
     def __GetSystemSkuID(self):\r
         if self.__SkuUsageType() == SkuClass.SINGLE:\r
-            return self.SkuIdSet[0]\r
+            if len(self.SkuIdSet) == 1:\r
+                return self.SkuIdSet[0]\r
+            else:\r
+                return self.SkuIdSet[0] if self.SkuIdSet[0] != 'DEFAULT' else self.SkuIdSet[1]\r
         else:\r
             return 'DEFAULT'\r
     def __GetAvailableSkuIdNumber(self):\r
         else:\r
             return 'DEFAULT'\r
     def __GetAvailableSkuIdNumber(self):\r
@@ -2176,31 +2094,6 @@ def PackRegistryFormatGuid(Guid):
                 int(Guid[4][-2:], 16)\r
                 )\r
 \r
                 int(Guid[4][-2:], 16)\r
                 )\r
 \r
-def BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, Value):\r
-    if PcdDatumType == 'VOID*':\r
-        if Value.startswith('L'):\r
-            if not Value[1]:\r
-                EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", H"{...}"')\r
-            Value = Value[0] + '"' + Value[1:] + '"'\r
-        elif Value.startswith('H'):\r
-            if not Value[1]:\r
-                EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", H"{...}"')\r
-            Value = Value[1:]\r
-        else:\r
-            if not Value[0]:\r
-                EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", H"{...}"')\r
-            Value = '"' + Value + '"'\r
-\r
-    IsValid, Cause = CheckPcdDatum(PcdDatumType, Value)\r
-    if not IsValid:\r
-        EdkLogger.error("build", FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName))\r
-    if PcdDatumType == 'BOOLEAN':\r
-        Value = Value.upper()\r
-        if Value == 'TRUE' or Value == '1':\r
-            Value = '1'\r
-        elif Value == 'FALSE' or Value == '0':\r
-            Value = '0'\r
-    return  Value\r
 ##  Get the integer value from string like "14U" or integer like 2\r
 #\r
 #   @param      Input   The object that may be either a integer value or a string\r
 ##  Get the integer value from string like "14U" or integer like 2\r
 #\r
 #   @param      Input   The object that may be either a integer value or a string\r