]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Ecc/Ecc.py
BaseTools: Rename String to StringUtils.
[mirror_edk2.git] / BaseTools / Source / Python / Ecc / Ecc.py
index e2e92ef6723ceeb3f2fe680c40da98dbfcf0a811..e78d70372e36ce354be7b49f45de69d3410a5e8a 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # This file is used to be the main entrance of ECC tool\r
 #\r
-# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2009 - 2016, 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
@@ -14,7 +14,7 @@
 ##\r
 # Import Modules\r
 #\r
-import os, time, glob, sys\r
+import Common.LongFilePathOs as os, time, glob, sys\r
 import Common.EdkLogger as EdkLogger\r
 import Database\r
 import EccGlobalData\r
@@ -24,10 +24,11 @@ from Configuration import Configuration
 from Check import Check\r
 import Common.GlobalData as GlobalData\r
 \r
-from Common.String import NormPath\r
+from Common.StringUtils import NormPath\r
 from Common.BuildVersion import gBUILD_VERSION\r
 from Common import BuildToolError\r
 from Common.Misc import PathClass\r
+from Common.Misc import DirCache\r
 from MetaFileWorkspace.MetaFileParser import DscParser\r
 from MetaFileWorkspace.MetaFileParser import DecParser\r
 from MetaFileWorkspace.MetaFileParser import InfParser\r
@@ -36,6 +37,8 @@ from MetaFileWorkspace.MetaFileTable import MetaFileStorage
 import c\r
 import re, string\r
 from Exception import *\r
+from Common.LongFilePathSupport import OpenLongFilePath as open\r
+from Common.MultipleWorkspace import MultipleWorkspace as mws\r
 \r
 ## Ecc\r
 #\r
@@ -46,9 +49,9 @@ from Exception import *
 class Ecc(object):\r
     def __init__(self):\r
         # Version and Copyright\r
-        self.VersionNumber = ("0.01" + " " + gBUILD_VERSION)\r
+        self.VersionNumber = ("1.0" + " Build " + gBUILD_VERSION)\r
         self.Version = "%prog Version " + self.VersionNumber\r
-        self.Copyright = "Copyright (c) 2009 - 2010, Intel Corporation  All rights reserved."\r
+        self.Copyright = "Copyright (c) 2009 - 2016, Intel Corporation  All rights reserved."\r
 \r
         self.InitDefaultConfigIni()\r
         self.OutputFile = 'output.txt'\r
@@ -58,17 +61,24 @@ class Ecc(object):
         self.ScanSourceCode = True\r
         self.ScanMetaData = True\r
         self.MetaFile = ''\r
+        self.OnlyScan = None\r
 \r
         # Parse the options and args\r
         self.ParseOption()\r
+        EdkLogger.info(time.strftime("%H:%M:%S, %b.%d %Y ", time.localtime()) + "[00:00]" + "\n")\r
         \r
         #\r
         # Check EFI_SOURCE (Edk build convention). EDK_SOURCE will always point to ECP\r
         #\r
         WorkspaceDir = os.path.normcase(os.path.normpath(os.environ["WORKSPACE"]))\r
         os.environ["WORKSPACE"] = WorkspaceDir\r
+        \r
+        # set multiple workspace\r
+        PackagesPath = os.getenv("PACKAGES_PATH")\r
+        mws.setWs(WorkspaceDir, PackagesPath)\r
+        \r
         if "ECP_SOURCE" not in os.environ:\r
-            os.environ["ECP_SOURCE"] = os.path.join(WorkspaceDir, GlobalData.gEdkCompatibilityPkg)\r
+            os.environ["ECP_SOURCE"] = mws.join(WorkspaceDir, GlobalData.gEdkCompatibilityPkg)\r
         if "EFI_SOURCE" not in os.environ:\r
             os.environ["EFI_SOURCE"] = os.environ["ECP_SOURCE"]\r
         if "EDK_SOURCE" not in os.environ:\r
@@ -95,7 +105,7 @@ class Ecc(object):
         GlobalData.gGlobalDefines["EDK_SOURCE"] = EdkSourceDir\r
         GlobalData.gGlobalDefines["ECP_SOURCE"] = EcpSourceDir\r
         \r
-        \r
+        EdkLogger.info("Loading ECC configuration ... done")\r
         # Generate checkpoints list\r
         EccGlobalData.gConfig = Configuration(self.ConfigFile)\r
 \r
@@ -106,9 +116,15 @@ class Ecc(object):
         EccGlobalData.gDb = Database.Database(Database.DATABASE_PATH)\r
         EccGlobalData.gDb.InitDatabase(self.IsInit)\r
 \r
+        #\r
+        # Get files real name in workspace dir\r
+        #\r
+        GlobalData.gAllFiles = DirCache(GlobalData.gWorkspace)\r
+         \r
         # Build ECC database\r
-        self.BuildDatabase()\r
-\r
+#         self.BuildDatabase()\r
+        self.DetectOnlyScanDirs()\r
+        \r
         # Start to check\r
         self.Check()\r
 \r
@@ -127,85 +143,125 @@ class Ecc(object):
                 return\r
         self.ConfigFile = 'config.ini'\r
 \r
+\r
+    ## DetectOnlyScan\r
+    #\r
+    # Detect whether only scanned folders have been enabled\r
+    #\r
+    def DetectOnlyScanDirs(self):\r
+        if self.OnlyScan == True:\r
+            OnlyScanDirs = []\r
+            # Use regex here if multiple spaces or TAB exists in ScanOnlyDirList in config.ini file\r
+            for folder in re.finditer(r'\S+', EccGlobalData.gConfig.ScanOnlyDirList):\r
+                OnlyScanDirs.append(folder.group())\r
+            if len(OnlyScanDirs) != 0:\r
+                self.BuildDatabase(OnlyScanDirs)\r
+            else:\r
+                EdkLogger.error("ECC", BuildToolError.OPTION_VALUE_INVALID, ExtraData="Use -f option need to fill specific folders in config.ini file")\r
+        else:\r
+            self.BuildDatabase()\r
+            \r
+    \r
     ## BuildDatabase\r
     #\r
     # Build the database for target\r
     #\r
-    def BuildDatabase(self):\r
+    def BuildDatabase(self, SpeciDirs = None):\r
         # Clean report table\r
         EccGlobalData.gDb.TblReport.Drop()\r
         EccGlobalData.gDb.TblReport.Create()\r
 \r
         # Build database\r
-        if self.IsInit:\r
-            if self.ScanSourceCode:\r
-                EdkLogger.quiet("Building database for source code ...")\r
-                c.CollectSourceCodeDataIntoDB(EccGlobalData.gTarget)\r
+        if self.IsInit:            \r
             if self.ScanMetaData:\r
-                EdkLogger.quiet("Building database for source code done!")\r
-                self.BuildMetaDataFileDatabase()\r
+                EdkLogger.quiet("Building database for Meta Data File ...")\r
+                self.BuildMetaDataFileDatabase(SpeciDirs)\r
+            if self.ScanSourceCode:\r
+                EdkLogger.quiet("Building database for Meta Data File Done!")\r
+                if SpeciDirs is None:\r
+                    c.CollectSourceCodeDataIntoDB(EccGlobalData.gTarget)\r
+                else:\r
+                    for specificDir in SpeciDirs:\r
+                        c.CollectSourceCodeDataIntoDB(os.path.join(EccGlobalData.gTarget, specificDir))\r
 \r
         EccGlobalData.gIdentifierTableList = GetTableList((MODEL_FILE_C, MODEL_FILE_H), 'Identifier', EccGlobalData.gDb)\r
         EccGlobalData.gCFileList = GetFileList(MODEL_FILE_C, EccGlobalData.gDb)\r
         EccGlobalData.gHFileList = GetFileList(MODEL_FILE_H, EccGlobalData.gDb)\r
+        EccGlobalData.gUFileList = GetFileList(MODEL_FILE_UNI, EccGlobalData.gDb)\r
 \r
     ## BuildMetaDataFileDatabase\r
     #\r
     # Build the database for meta data files\r
     #\r
-    def BuildMetaDataFileDatabase(self):\r
+    def BuildMetaDataFileDatabase(self, SpecificDirs = None):\r
+        ScanFolders = []\r
+        if SpecificDirs is None:\r
+            ScanFolders.append(EccGlobalData.gTarget)\r
+        else:\r
+            for specificDir in SpecificDirs:    \r
+                ScanFolders.append(os.path.join(EccGlobalData.gTarget, specificDir))\r
         EdkLogger.quiet("Building database for meta data files ...")\r
         Op = open(EccGlobalData.gConfig.MetaDataFileCheckPathOfGenerateFileList, 'w+')\r
         #SkipDirs = Read from config file\r
         SkipDirs = EccGlobalData.gConfig.SkipDirList\r
         SkipDirString = string.join(SkipDirs, '|')\r
-        p = re.compile(r'.*[\\/](?:%s)[\\/]?.*' % SkipDirString)\r
-        for Root, Dirs, Files in os.walk(EccGlobalData.gTarget):\r
-            if p.match(Root.upper()):\r
-                continue\r
-            for Dir in Dirs:\r
-                Dirname = os.path.join(Root, Dir)\r
-                if os.path.islink(Dirname):\r
-                    Dirname = os.path.realpath(Dirname)\r
-                    if os.path.isdir(Dirname):\r
-                        # symlinks to directories are treated as directories\r
-                        Dirs.remove(Dir)\r
-                        Dirs.append(Dirname)\r
-\r
-            for File in Files:\r
-                if len(File) > 4 and File[-4:].upper() == ".DEC":\r
-                    Filename = os.path.normpath(os.path.join(Root, File))\r
-                    EdkLogger.quiet("Parsing %s" % Filename)\r
-                    Op.write("%s\r" % Filename)\r
-                    #Dec(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)\r
-                    self.MetaFile = DecParser(Filename, MODEL_FILE_DEC, EccGlobalData.gDb.TblDec)\r
-                    self.MetaFile.Start()\r
-                    continue\r
-                if len(File) > 4 and File[-4:].upper() == ".DSC":\r
-                    Filename = os.path.normpath(os.path.join(Root, File))\r
-                    EdkLogger.quiet("Parsing %s" % Filename)\r
-                    Op.write("%s\r" % Filename)\r
-                    #Dsc(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)\r
-                    self.MetaFile = DscParser(PathClass(Filename, Root), MODEL_FILE_DSC, MetaFileStorage(EccGlobalData.gDb.TblDsc.Cur, Filename, MODEL_FILE_DSC, True))\r
-                    # alwasy do post-process, in case of macros change\r
-                    self.MetaFile.DoPostProcess()\r
-                    self.MetaFile.Start()\r
-                    self.MetaFile._PostProcess()\r
-                    continue\r
-                if len(File) > 4 and File[-4:].upper() == ".INF":\r
-                    Filename = os.path.normpath(os.path.join(Root, File))\r
-                    EdkLogger.quiet("Parsing %s" % Filename)\r
-                    Op.write("%s\r" % Filename)\r
-                    #Inf(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)\r
-                    self.MetaFile = InfParser(Filename, MODEL_FILE_INF, EccGlobalData.gDb.TblInf)\r
-                    self.MetaFile.Start()\r
-                    continue\r
-                if len(File) > 4 and File[-4:].upper() == ".FDF":\r
-                    Filename = os.path.normpath(os.path.join(Root, File))\r
-                    EdkLogger.quiet("Parsing %s" % Filename)\r
-                    Op.write("%s\r" % Filename)\r
-                    Fdf(Filename, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)\r
+#         p = re.compile(r'.*[\\/](?:%s)[\\/]?.*' % SkipDirString)\r
+        p = re.compile(r'.*[\\/](?:%s^\S)[\\/]?.*' % SkipDirString)\r
+        for scanFolder in ScanFolders:\r
+            for Root, Dirs, Files in os.walk(scanFolder):\r
+                if p.match(Root.upper()):\r
                     continue\r
+                for Dir in Dirs:\r
+                    Dirname = os.path.join(Root, Dir)\r
+                    if os.path.islink(Dirname):\r
+                        Dirname = os.path.realpath(Dirname)\r
+                        if os.path.isdir(Dirname):\r
+                            # symlinks to directories are treated as directories\r
+                            Dirs.remove(Dir)\r
+                            Dirs.append(Dirname)\r
+    \r
+                for File in Files:\r
+                    if len(File) > 4 and File[-4:].upper() == ".DEC":\r
+                        Filename = os.path.normpath(os.path.join(Root, File))\r
+                        EdkLogger.quiet("Parsing %s" % Filename)\r
+                        Op.write("%s\r" % Filename)\r
+                        #Dec(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)\r
+                        self.MetaFile = DecParser(Filename, MODEL_FILE_DEC, EccGlobalData.gDb.TblDec)\r
+                        self.MetaFile.Start()\r
+                        continue\r
+                    if len(File) > 4 and File[-4:].upper() == ".DSC":\r
+                        Filename = os.path.normpath(os.path.join(Root, File))\r
+                        EdkLogger.quiet("Parsing %s" % Filename)\r
+                        Op.write("%s\r" % Filename)\r
+                        #Dsc(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)\r
+                        self.MetaFile = DscParser(PathClass(Filename, Root), MODEL_FILE_DSC, MetaFileStorage(EccGlobalData.gDb.TblDsc.Cur, Filename, MODEL_FILE_DSC, True))\r
+                        # alwasy do post-process, in case of macros change\r
+                        self.MetaFile.DoPostProcess()\r
+                        self.MetaFile.Start()\r
+                        self.MetaFile._PostProcess()\r
+                        continue\r
+                    if len(File) > 4 and File[-4:].upper() == ".INF":\r
+                        Filename = os.path.normpath(os.path.join(Root, File))\r
+                        EdkLogger.quiet("Parsing %s" % Filename)\r
+                        Op.write("%s\r" % Filename)\r
+                        #Inf(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)\r
+                        self.MetaFile = InfParser(Filename, MODEL_FILE_INF, EccGlobalData.gDb.TblInf)\r
+                        self.MetaFile.Start()\r
+                        continue\r
+                    if len(File) > 4 and File[-4:].upper() == ".FDF":\r
+                        Filename = os.path.normpath(os.path.join(Root, File))\r
+                        EdkLogger.quiet("Parsing %s" % Filename)\r
+                        Op.write("%s\r" % Filename)\r
+                        Fdf(Filename, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)\r
+                        continue\r
+                    if len(File) > 4 and File[-4:].upper() == ".UNI":\r
+                        Filename = os.path.normpath(os.path.join(Root, File))\r
+                        EdkLogger.quiet("Parsing %s" % Filename)\r
+                        Op.write("%s\r" % Filename)\r
+                        FileID = EccGlobalData.gDb.TblFile.InsertFile(Filename, MODEL_FILE_UNI)\r
+                        EccGlobalData.gDb.TblReport.UpdateBelongsToItemByFile(FileID, File)\r
+                        continue\r
+\r
         Op.close()\r
 \r
         # Commit to database\r
@@ -272,7 +328,6 @@ class Ecc(object):
     # Parse options\r
     #\r
     def ParseOption(self):\r
-        EdkLogger.quiet("Loading ECC configuration ... done")\r
         (Options, Target) = self.EccOptionParser()\r
 \r
         if Options.Workspace:\r
@@ -291,15 +346,15 @@ class Ecc(object):
         self.SetLogLevel(Options)\r
 \r
         # Set other options\r
-        if Options.ConfigFile != None:\r
+        if Options.ConfigFile is not None:\r
             self.ConfigFile = Options.ConfigFile\r
-        if Options.OutputFile != None:\r
+        if Options.OutputFile is not None:\r
             self.OutputFile = Options.OutputFile\r
-        if Options.ReportFile != None:\r
+        if Options.ReportFile is not None:\r
             self.ReportFile = Options.ReportFile\r
-        if Options.ExceptionFile != None:\r
+        if Options.ExceptionFile is not None:\r
             self.ExceptionFile = Options.ExceptionFile\r
-        if Options.Target != None:\r
+        if Options.Target is not None:\r
             if not os.path.isdir(Options.Target):\r
                 EdkLogger.error("ECC", BuildToolError.OPTION_VALUE_INVALID, ExtraData="Target [%s] does NOT exist" % Options.Target)\r
             else:\r
@@ -307,14 +362,16 @@ class Ecc(object):
         else:\r
             EdkLogger.warn("Ecc", EdkLogger.ECC_ERROR, "The target source tree was not specified, using current WORKSPACE instead!")\r
             EccGlobalData.gTarget = os.path.normpath(os.getenv("WORKSPACE"))\r
-        if Options.keepdatabase != None:\r
+        if Options.keepdatabase is not None:\r
             self.IsInit = False\r
-        if Options.metadata != None and Options.sourcecode != None:\r
+        if Options.metadata is not None and Options.sourcecode is not None:\r
             EdkLogger.error("ECC", BuildToolError.OPTION_CONFLICT, ExtraData="-m and -s can't be specified at one time")\r
-        if Options.metadata != None:\r
+        if Options.metadata is not None:\r
             self.ScanSourceCode = False\r
-        if Options.sourcecode != None:\r
+        if Options.sourcecode is not None:\r
             self.ScanMetaData = False\r
+        if Options.folders is not None:\r
+            self.OnlyScan = True\r
 \r
     ## SetLogLevel\r
     #\r
@@ -323,11 +380,11 @@ class Ecc(object):
     # @param Option:  The option list including log level setting\r
     #\r
     def SetLogLevel(self, Option):\r
-        if Option.verbose != None:\r
+        if Option.verbose is not None:\r
             EdkLogger.SetLevel(EdkLogger.VERBOSE)\r
-        elif Option.quiet != None:\r
+        elif Option.quiet is not None:\r
             EdkLogger.SetLevel(EdkLogger.QUIET)\r
-        elif Option.debug != None:\r
+        elif Option.debug is not None:\r
             EdkLogger.SetLevel(Option.debug + 1)\r
         else:\r
             EdkLogger.SetLevel(EdkLogger.INFO)\r
@@ -365,6 +422,7 @@ class Ecc(object):
                                                                                    "and warning messages, etc.")\r
         Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
         Parser.add_option("-w", "--workspace", action="store", type="string", dest='Workspace', help="Specify workspace.")\r
+        Parser.add_option("-f", "--folders", action="store_true", type=None, help="Only scanning specified folders which are recorded in config.ini file.")\r
 \r
         (Opt, Args)=Parser.parse_args()\r
 \r
@@ -379,7 +437,6 @@ if __name__ == '__main__':
     # Initialize log system\r
     EdkLogger.Initialize()\r
     EdkLogger.IsRaiseError = False\r
-    EdkLogger.quiet(time.strftime("%H:%M:%S, %b.%d %Y ", time.localtime()) + "[00:00]" + "\n")\r
 \r
     StartTime = time.clock()\r
     Ecc = Ecc()\r