X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FEcc%2FEcc.py;h=94f9a427e37016038feb5456de630b8a5cf4b722;hb=b7f63a5a53a77bc48b81e7ddad511349addff421;hp=ea9d0b343c955080add93ce9789e9c4d25acc26e;hpb=fd171542e0aa89ac12a09d79608173f48019b14b;p=mirror_edk2.git diff --git a/BaseTools/Source/Python/Ecc/Ecc.py b/BaseTools/Source/Python/Ecc/Ecc.py index ea9d0b343c..94f9a427e3 100644 --- a/BaseTools/Source/Python/Ecc/Ecc.py +++ b/BaseTools/Source/Python/Ecc/Ecc.py @@ -1,8 +1,8 @@ ## @file # This file is used to be the main entrance of ECC tool # -# Copyright (c) 2009, Intel Corporation -# All rights reserved. This program and the accompanying materials +# Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
+# This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at # http://opensource.org/licenses/bsd-license.php @@ -14,7 +14,7 @@ ## # Import Modules # -import os, time, glob, sys +import Common.LongFilePathOs as os, time, glob, sys import Common.EdkLogger as EdkLogger import Database import EccGlobalData @@ -22,15 +22,23 @@ from MetaDataParser import * from optparse import OptionParser from Configuration import Configuration from Check import Check -from Common.InfClassObject import Inf -from Common.DecClassObject import Dec -from Common.DscClassObject import Dsc -from Common.FdfClassObject import Fdf +import Common.GlobalData as GlobalData + from Common.String import NormPath +from Common.BuildVersion import gBUILD_VERSION from Common import BuildToolError +from Common.Misc import PathClass +from Common.Misc import DirCache +from MetaFileWorkspace.MetaFileParser import DscParser +from MetaFileWorkspace.MetaFileParser import DecParser +from MetaFileWorkspace.MetaFileParser import InfParser +from MetaFileWorkspace.MetaFileParser import Fdf +from MetaFileWorkspace.MetaFileTable import MetaFileStorage import c import re, string from Exception import * +from Common.LongFilePathSupport import OpenLongFilePath as open +from Common.MultipleWorkspace import MultipleWorkspace as mws ## Ecc # @@ -41,9 +49,9 @@ from Exception import * class Ecc(object): def __init__(self): # Version and Copyright - self.VersionNumber = "0.01" + self.VersionNumber = ("1.0" + " Build " + gBUILD_VERSION) self.Version = "%prog Version " + self.VersionNumber - self.Copyright = "Copyright (c) 2009, Intel Corporation All rights reserved." + self.Copyright = "Copyright (c) 2009 - 2016, Intel Corporation All rights reserved." self.InitDefaultConfigIni() self.OutputFile = 'output.txt' @@ -52,10 +60,52 @@ class Ecc(object): self.IsInit = True self.ScanSourceCode = True self.ScanMetaData = True + self.MetaFile = '' + self.OnlyScan = None # Parse the options and args self.ParseOption() - + EdkLogger.info(time.strftime("%H:%M:%S, %b.%d %Y ", time.localtime()) + "[00:00]" + "\n") + + # + # Check EFI_SOURCE (Edk build convention). EDK_SOURCE will always point to ECP + # + WorkspaceDir = os.path.normcase(os.path.normpath(os.environ["WORKSPACE"])) + os.environ["WORKSPACE"] = WorkspaceDir + + # set multiple workspace + PackagesPath = os.getenv("PACKAGES_PATH") + mws.setWs(WorkspaceDir, PackagesPath) + + if "ECP_SOURCE" not in os.environ: + os.environ["ECP_SOURCE"] = mws.join(WorkspaceDir, GlobalData.gEdkCompatibilityPkg) + if "EFI_SOURCE" not in os.environ: + os.environ["EFI_SOURCE"] = os.environ["ECP_SOURCE"] + if "EDK_SOURCE" not in os.environ: + os.environ["EDK_SOURCE"] = os.environ["ECP_SOURCE"] + + # + # Unify case of characters on case-insensitive systems + # + EfiSourceDir = os.path.normcase(os.path.normpath(os.environ["EFI_SOURCE"])) + EdkSourceDir = os.path.normcase(os.path.normpath(os.environ["EDK_SOURCE"])) + EcpSourceDir = os.path.normcase(os.path.normpath(os.environ["ECP_SOURCE"])) + + os.environ["EFI_SOURCE"] = EfiSourceDir + os.environ["EDK_SOURCE"] = EdkSourceDir + os.environ["ECP_SOURCE"] = EcpSourceDir + + GlobalData.gWorkspace = WorkspaceDir + GlobalData.gEfiSource = EfiSourceDir + GlobalData.gEdkSource = EdkSourceDir + GlobalData.gEcpSource = EcpSourceDir + + GlobalData.gGlobalDefines["WORKSPACE"] = WorkspaceDir + GlobalData.gGlobalDefines["EFI_SOURCE"] = EfiSourceDir + GlobalData.gGlobalDefines["EDK_SOURCE"] = EdkSourceDir + GlobalData.gGlobalDefines["ECP_SOURCE"] = EcpSourceDir + + EdkLogger.info("Loading ECC configuration ... done") # Generate checkpoints list EccGlobalData.gConfig = Configuration(self.ConfigFile) @@ -66,9 +116,15 @@ class Ecc(object): EccGlobalData.gDb = Database.Database(Database.DATABASE_PATH) EccGlobalData.gDb.InitDatabase(self.IsInit) + # + # Get files real name in workspace dir + # + GlobalData.gAllFiles = DirCache(GlobalData.gWorkspace) + # Build ECC database - self.BuildDatabase() - +# self.BuildDatabase() + self.DetectOnlyScanDirs() + # Start to check self.Check() @@ -87,75 +143,125 @@ class Ecc(object): return self.ConfigFile = 'config.ini' + + ## DetectOnlyScan + # + # Detect whether only scanned folders have been enabled + # + def DetectOnlyScanDirs(self): + if self.OnlyScan == True: + OnlyScanDirs = [] + # Use regex here if multiple spaces or TAB exists in ScanOnlyDirList in config.ini file + for folder in re.finditer(r'\S+', EccGlobalData.gConfig.ScanOnlyDirList): + OnlyScanDirs.append(folder.group()) + if len(OnlyScanDirs) != 0: + self.BuildDatabase(OnlyScanDirs) + else: + EdkLogger.error("ECC", BuildToolError.OPTION_VALUE_INVALID, ExtraData="Use -f option need to fill specific folders in config.ini file") + else: + self.BuildDatabase() + + ## BuildDatabase # # Build the database for target # - def BuildDatabase(self): + def BuildDatabase(self, SpeciDirs = None): # Clean report table EccGlobalData.gDb.TblReport.Drop() EccGlobalData.gDb.TblReport.Create() # Build database - if self.IsInit: - if self.ScanSourceCode: - EdkLogger.quiet("Building database for source code ...") - c.CollectSourceCodeDataIntoDB(EccGlobalData.gTarget) + if self.IsInit: if self.ScanMetaData: - EdkLogger.quiet("Building database for source code done!") - self.BuildMetaDataFileDatabase() + EdkLogger.quiet("Building database for Meta Data File ...") + self.BuildMetaDataFileDatabase(SpeciDirs) + if self.ScanSourceCode: + EdkLogger.quiet("Building database for Meta Data File Done!") + if SpeciDirs == None: + c.CollectSourceCodeDataIntoDB(EccGlobalData.gTarget) + else: + for specificDir in SpeciDirs: + c.CollectSourceCodeDataIntoDB(os.path.join(EccGlobalData.gTarget, specificDir)) EccGlobalData.gIdentifierTableList = GetTableList((MODEL_FILE_C, MODEL_FILE_H), 'Identifier', EccGlobalData.gDb) + EccGlobalData.gCFileList = GetFileList(MODEL_FILE_C, EccGlobalData.gDb) + EccGlobalData.gHFileList = GetFileList(MODEL_FILE_H, EccGlobalData.gDb) + EccGlobalData.gUFileList = GetFileList(MODEL_FILE_UNI, EccGlobalData.gDb) ## BuildMetaDataFileDatabase # # Build the database for meta data files # - def BuildMetaDataFileDatabase(self): + def BuildMetaDataFileDatabase(self, SpecificDirs = None): + ScanFolders = [] + if SpecificDirs == None: + ScanFolders.append(EccGlobalData.gTarget) + else: + for specificDir in SpecificDirs: + ScanFolders.append(os.path.join(EccGlobalData.gTarget, specificDir)) EdkLogger.quiet("Building database for meta data files ...") Op = open(EccGlobalData.gConfig.MetaDataFileCheckPathOfGenerateFileList, 'w+') #SkipDirs = Read from config file SkipDirs = EccGlobalData.gConfig.SkipDirList SkipDirString = string.join(SkipDirs, '|') - p = re.compile(r'.*[\\/](?:%s)[\\/]?.*' % SkipDirString) - for Root, Dirs, Files in os.walk(EccGlobalData.gTarget): - if p.match(Root.upper()): - continue - - for Dir in Dirs: - Dirname = os.path.join(Root, Dir) - if os.path.islink(Dirname): - Dirname = os.path.realpath(Dirname) - if os.path.isdir(Dirname): - # symlinks to directories are treated as directories - Dirs.remove(Dir) - Dirs.append(Dirname) - - for File in Files: - if len(File) > 4 and File[-4:].upper() == ".DEC": - Filename = os.path.normpath(os.path.join(Root, File)) - EdkLogger.quiet("Parsing %s" % Filename) - Op.write("%s\r" % Filename) - Dec(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb) - continue - if len(File) > 4 and File[-4:].upper() == ".DSC": - Filename = os.path.normpath(os.path.join(Root, File)) - EdkLogger.quiet("Parsing %s" % Filename) - Op.write("%s\r" % Filename) - Dsc(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb) - continue - if len(File) > 4 and File[-4:].upper() == ".INF": - Filename = os.path.normpath(os.path.join(Root, File)) - EdkLogger.quiet("Parsing %s" % Filename) - Op.write("%s\r" % Filename) - Inf(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb) - continue - if len(File) > 4 and File[-4:].upper() == ".FDF": - Filename = os.path.normpath(os.path.join(Root, File)) - EdkLogger.quiet("Parsing %s" % Filename) - Op.write("%s\r" % Filename) - Fdf(Filename, True, EccGlobalData.gWorkspace, EccGlobalData.gDb) +# p = re.compile(r'.*[\\/](?:%s)[\\/]?.*' % SkipDirString) + p = re.compile(r'.*[\\/](?:%s^\S)[\\/]?.*' % SkipDirString) + for scanFolder in ScanFolders: + for Root, Dirs, Files in os.walk(scanFolder): + if p.match(Root.upper()): continue + for Dir in Dirs: + Dirname = os.path.join(Root, Dir) + if os.path.islink(Dirname): + Dirname = os.path.realpath(Dirname) + if os.path.isdir(Dirname): + # symlinks to directories are treated as directories + Dirs.remove(Dir) + Dirs.append(Dirname) + + for File in Files: + if len(File) > 4 and File[-4:].upper() == ".DEC": + Filename = os.path.normpath(os.path.join(Root, File)) + EdkLogger.quiet("Parsing %s" % Filename) + Op.write("%s\r" % Filename) + #Dec(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb) + self.MetaFile = DecParser(Filename, MODEL_FILE_DEC, EccGlobalData.gDb.TblDec) + self.MetaFile.Start() + continue + if len(File) > 4 and File[-4:].upper() == ".DSC": + Filename = os.path.normpath(os.path.join(Root, File)) + EdkLogger.quiet("Parsing %s" % Filename) + Op.write("%s\r" % Filename) + #Dsc(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb) + self.MetaFile = DscParser(PathClass(Filename, Root), MODEL_FILE_DSC, MetaFileStorage(EccGlobalData.gDb.TblDsc.Cur, Filename, MODEL_FILE_DSC, True)) + # alwasy do post-process, in case of macros change + self.MetaFile.DoPostProcess() + self.MetaFile.Start() + self.MetaFile._PostProcess() + continue + if len(File) > 4 and File[-4:].upper() == ".INF": + Filename = os.path.normpath(os.path.join(Root, File)) + EdkLogger.quiet("Parsing %s" % Filename) + Op.write("%s\r" % Filename) + #Inf(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb) + self.MetaFile = InfParser(Filename, MODEL_FILE_INF, EccGlobalData.gDb.TblInf) + self.MetaFile.Start() + continue + if len(File) > 4 and File[-4:].upper() == ".FDF": + Filename = os.path.normpath(os.path.join(Root, File)) + EdkLogger.quiet("Parsing %s" % Filename) + Op.write("%s\r" % Filename) + Fdf(Filename, True, EccGlobalData.gWorkspace, EccGlobalData.gDb) + continue + if len(File) > 4 and File[-4:].upper() == ".UNI": + Filename = os.path.normpath(os.path.join(Root, File)) + EdkLogger.quiet("Parsing %s" % Filename) + Op.write("%s\r" % Filename) + FileID = EccGlobalData.gDb.TblFile.InsertFile(Filename, MODEL_FILE_UNI) + EccGlobalData.gDb.TblReport.UpdateBelongsToItemByFile(FileID, File) + continue + Op.close() # Commit to database @@ -222,9 +328,11 @@ class Ecc(object): # Parse options # def ParseOption(self): - EdkLogger.quiet("Loading ECC configuration ... done") (Options, Target) = self.EccOptionParser() + if Options.Workspace: + os.environ["WORKSPACE"] = Options.Workspace + # Check workspace envirnoment if "WORKSPACE" not in os.environ: EdkLogger.error("ECC", BuildToolError.ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found", @@ -244,6 +352,8 @@ class Ecc(object): self.OutputFile = Options.OutputFile if Options.ReportFile != None: self.ReportFile = Options.ReportFile + if Options.ExceptionFile != None: + self.ExceptionFile = Options.ExceptionFile if Options.Target != None: if not os.path.isdir(Options.Target): EdkLogger.error("ECC", BuildToolError.OPTION_VALUE_INVALID, ExtraData="Target [%s] does NOT exist" % Options.Target) @@ -260,6 +370,8 @@ class Ecc(object): self.ScanSourceCode = False if Options.sourcecode != None: self.ScanMetaData = False + if Options.folders != None: + self.OnlyScan = True ## SetLogLevel # @@ -294,6 +406,8 @@ class Ecc(object): help="Specify the name of an output file, if and only if one filename was specified.") Parser.add_option("-r", "--reportfile filename", action="store", type="string", dest="ReportFile", help="Specify the name of an report file, if and only if one filename was specified.") + Parser.add_option("-e", "--exceptionfile filename", action="store", type="string", dest="ExceptionFile", + help="Specify the name of an exception file, if and only if one filename was specified.") Parser.add_option("-m", "--metadata", action="store_true", type=None, help="Only scan meta-data files information if this option is specified.") Parser.add_option("-s", "--sourcecode", action="store_true", type=None, help="Only scan source code files information if this option is specified.") Parser.add_option("-k", "--keepdatabase", action="store_true", type=None, help="The existing Ecc database will not be cleaned except report information if this option is specified.") @@ -307,6 +421,8 @@ class Ecc(object): "including library instances selected, final dependency expression, "\ "and warning messages, etc.") Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.") + Parser.add_option("-w", "--workspace", action="store", type="string", dest='Workspace', help="Specify workspace.") + Parser.add_option("-f", "--folders", action="store_true", type=None, help="Only scanning specified folders which are recorded in config.ini file.") (Opt, Args)=Parser.parse_args() @@ -321,7 +437,6 @@ if __name__ == '__main__': # Initialize log system EdkLogger.Initialize() EdkLogger.IsRaiseError = False - EdkLogger.quiet(time.strftime("%H:%M:%S, %b.%d %Y ", time.localtime()) + "[00:00]" + "\n") StartTime = time.clock() Ecc = Ecc()