]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Ecc/Ecc.py
Sync EDKII BaseTools to BaseTools project r1971
[mirror_edk2.git] / BaseTools / Source / Python / Ecc / Ecc.py
CommitLineData
30fdf114
LG
1## @file\r
2# This file is used to be the main entrance of ECC tool\r
3#\r
40d841f6
LG
4# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
5# This program and the accompanying materials\r
30fdf114
LG
6# are licensed and made available under the terms and conditions of the BSD License\r
7# which accompanies this distribution. The full text of the license may be found at\r
8# http://opensource.org/licenses/bsd-license.php\r
9#\r
10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12#\r
13\r
14##\r
15# Import Modules\r
16#\r
17import os, time, glob, sys\r
18import Common.EdkLogger as EdkLogger\r
19import Database\r
20import EccGlobalData\r
21from MetaDataParser import *\r
22from optparse import OptionParser\r
23from Configuration import Configuration\r
24from Check import Check\r
25from Common.InfClassObject import Inf\r
26from Common.DecClassObject import Dec\r
27from Common.DscClassObject import Dsc\r
28from Common.FdfClassObject import Fdf\r
29from Common.String import NormPath\r
30from Common import BuildToolError\r
31import c\r
fd171542 32import re, string\r
30fdf114
LG
33from Exception import *\r
34\r
35## Ecc\r
36#\r
37# This class is used to define Ecc main entrance\r
38#\r
39# @param object: Inherited from object class\r
40#\r
41class Ecc(object):\r
42 def __init__(self):\r
43 # Version and Copyright\r
44 self.VersionNumber = "0.01"\r
45 self.Version = "%prog Version " + self.VersionNumber\r
52302d4d 46 self.Copyright = "Copyright (c) 2009 - 2010, Intel Corporation All rights reserved."\r
30fdf114
LG
47\r
48 self.InitDefaultConfigIni()\r
49 self.OutputFile = 'output.txt'\r
50 self.ReportFile = 'Report.csv'\r
51 self.ExceptionFile = 'exception.xml'\r
52 self.IsInit = True\r
53 self.ScanSourceCode = True\r
54 self.ScanMetaData = True\r
fd171542 55\r
30fdf114
LG
56 # Parse the options and args\r
57 self.ParseOption()\r
58\r
59 # Generate checkpoints list\r
60 EccGlobalData.gConfig = Configuration(self.ConfigFile)\r
fd171542 61\r
30fdf114
LG
62 # Generate exception list\r
63 EccGlobalData.gException = ExceptionCheck(self.ExceptionFile)\r
fd171542 64\r
30fdf114
LG
65 # Init Ecc database\r
66 EccGlobalData.gDb = Database.Database(Database.DATABASE_PATH)\r
67 EccGlobalData.gDb.InitDatabase(self.IsInit)\r
fd171542 68\r
30fdf114
LG
69 # Build ECC database\r
70 self.BuildDatabase()\r
fd171542 71\r
30fdf114
LG
72 # Start to check\r
73 self.Check()\r
fd171542 74\r
30fdf114
LG
75 # Show report\r
76 self.GenReport()\r
fd171542 77\r
30fdf114
LG
78 # Close Database\r
79 EccGlobalData.gDb.Close()\r
80\r
81 def InitDefaultConfigIni(self):\r
82 paths = map(lambda p: os.path.join(p, 'Ecc', 'config.ini'), sys.path)\r
83 paths = (os.path.realpath('config.ini'),) + tuple(paths)\r
84 for path in paths:\r
85 if os.path.exists(path):\r
86 self.ConfigFile = path\r
87 return\r
88 self.ConfigFile = 'config.ini'\r
89\r
90 ## BuildDatabase\r
91 #\r
92 # Build the database for target\r
93 #\r
94 def BuildDatabase(self):\r
95 # Clean report table\r
96 EccGlobalData.gDb.TblReport.Drop()\r
97 EccGlobalData.gDb.TblReport.Create()\r
fd171542 98\r
30fdf114
LG
99 # Build database\r
100 if self.IsInit:\r
101 if self.ScanSourceCode:\r
102 EdkLogger.quiet("Building database for source code ...")\r
103 c.CollectSourceCodeDataIntoDB(EccGlobalData.gTarget)\r
104 if self.ScanMetaData:\r
105 EdkLogger.quiet("Building database for source code done!")\r
106 self.BuildMetaDataFileDatabase()\r
fd171542 107\r
30fdf114 108 EccGlobalData.gIdentifierTableList = GetTableList((MODEL_FILE_C, MODEL_FILE_H), 'Identifier', EccGlobalData.gDb)\r
fd171542 109\r
30fdf114
LG
110 ## BuildMetaDataFileDatabase\r
111 #\r
112 # Build the database for meta data files\r
113 #\r
114 def BuildMetaDataFileDatabase(self):\r
115 EdkLogger.quiet("Building database for meta data files ...")\r
116 Op = open(EccGlobalData.gConfig.MetaDataFileCheckPathOfGenerateFileList, 'w+')\r
117 #SkipDirs = Read from config file\r
118 SkipDirs = EccGlobalData.gConfig.SkipDirList\r
fd171542 119 SkipDirString = string.join(SkipDirs, '|')\r
120 p = re.compile(r'.*[\\/](?:%s)[\\/]?.*' % SkipDirString)\r
30fdf114 121 for Root, Dirs, Files in os.walk(EccGlobalData.gTarget):\r
fd171542 122 if p.match(Root.upper()):\r
123 continue\r
30fdf114
LG
124\r
125 for Dir in Dirs:\r
126 Dirname = os.path.join(Root, Dir)\r
127 if os.path.islink(Dirname):\r
128 Dirname = os.path.realpath(Dirname)\r
129 if os.path.isdir(Dirname):\r
130 # symlinks to directories are treated as directories\r
131 Dirs.remove(Dir)\r
132 Dirs.append(Dirname)\r
133\r
134 for File in Files:\r
135 if len(File) > 4 and File[-4:].upper() == ".DEC":\r
136 Filename = os.path.normpath(os.path.join(Root, File))\r
137 EdkLogger.quiet("Parsing %s" % Filename)\r
138 Op.write("%s\r" % Filename)\r
139 Dec(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)\r
140 continue\r
141 if len(File) > 4 and File[-4:].upper() == ".DSC":\r
142 Filename = os.path.normpath(os.path.join(Root, File))\r
143 EdkLogger.quiet("Parsing %s" % Filename)\r
144 Op.write("%s\r" % Filename)\r
145 Dsc(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)\r
146 continue\r
147 if len(File) > 4 and File[-4:].upper() == ".INF":\r
148 Filename = os.path.normpath(os.path.join(Root, File))\r
149 EdkLogger.quiet("Parsing %s" % Filename)\r
150 Op.write("%s\r" % Filename)\r
151 Inf(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)\r
152 continue\r
153 if len(File) > 4 and File[-4:].upper() == ".FDF":\r
154 Filename = os.path.normpath(os.path.join(Root, File))\r
155 EdkLogger.quiet("Parsing %s" % Filename)\r
156 Op.write("%s\r" % Filename)\r
fd171542 157 Fdf(Filename, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)\r
30fdf114
LG
158 continue\r
159 Op.close()\r
fd171542 160\r
30fdf114
LG
161 # Commit to database\r
162 EccGlobalData.gDb.Conn.commit()\r
fd171542 163\r
30fdf114 164 EdkLogger.quiet("Building database for meta data files done!")\r
fd171542 165\r
30fdf114
LG
166 ##\r
167 #\r
168 # Check each checkpoint\r
169 #\r
170 def Check(self):\r
171 EdkLogger.quiet("Checking ...")\r
172 EccCheck = Check()\r
173 EccCheck.Check()\r
174 EdkLogger.quiet("Checking done!")\r
fd171542 175\r
30fdf114
LG
176 ##\r
177 #\r
178 # Generate the scan report\r
179 #\r
180 def GenReport(self):\r
181 EdkLogger.quiet("Generating report ...")\r
182 EccGlobalData.gDb.TblReport.ToCSV(self.ReportFile)\r
183 EdkLogger.quiet("Generating report done!")\r
fd171542 184\r
30fdf114
LG
185 def GetRealPathCase(self, path):\r
186 TmpPath = path.rstrip(os.sep)\r
187 PathParts = TmpPath.split(os.sep)\r
188 if len(PathParts) == 0:\r
189 return path\r
190 if len(PathParts) == 1:\r
191 if PathParts[0].strip().endswith(':'):\r
192 return PathParts[0].upper()\r
193 # Relative dir, list . current dir\r
194 Dirs = os.listdir('.')\r
195 for Dir in Dirs:\r
196 if Dir.upper() == PathParts[0].upper():\r
197 return Dir\r
fd171542 198\r
30fdf114
LG
199 if PathParts[0].strip().endswith(':'):\r
200 PathParts[0] = PathParts[0].upper()\r
201 ParentDir = PathParts[0]\r
202 RealPath = ParentDir\r
203 if PathParts[0] == '':\r
204 RealPath = os.sep\r
205 ParentDir = os.sep\r
fd171542 206\r
30fdf114
LG
207 PathParts.remove(PathParts[0]) # need to remove the parent\r
208 for Part in PathParts:\r
209 Dirs = os.listdir(ParentDir + os.sep)\r
210 for Dir in Dirs:\r
211 if Dir.upper() == Part.upper():\r
212 RealPath += os.sep\r
213 RealPath += Dir\r
214 break\r
215 ParentDir += os.sep\r
216 ParentDir += Dir\r
fd171542 217\r
30fdf114 218 return RealPath\r
fd171542 219\r
30fdf114
LG
220 ## ParseOption\r
221 #\r
222 # Parse options\r
223 #\r
224 def ParseOption(self):\r
225 EdkLogger.quiet("Loading ECC configuration ... done")\r
226 (Options, Target) = self.EccOptionParser()\r
fd171542 227\r
52302d4d
LG
228 if Options.Workspace:\r
229 os.environ["WORKSPACE"] = Options.Workspace\r
230 \r
30fdf114
LG
231 # Check workspace envirnoment\r
232 if "WORKSPACE" not in os.environ:\r
fd171542 233 EdkLogger.error("ECC", BuildToolError.ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",\r
30fdf114
LG
234 ExtraData="WORKSPACE")\r
235 else:\r
236 EccGlobalData.gWorkspace = os.path.normpath(os.getenv("WORKSPACE"))\r
237 if not os.path.exists(EccGlobalData.gWorkspace):\r
238 EdkLogger.error("ECC", BuildToolError.FILE_NOT_FOUND, ExtraData="WORKSPACE = %s" % EccGlobalData.gWorkspace)\r
239 os.environ["WORKSPACE"] = EccGlobalData.gWorkspace\r
240 # Set log level\r
241 self.SetLogLevel(Options)\r
fd171542 242\r
30fdf114
LG
243 # Set other options\r
244 if Options.ConfigFile != None:\r
245 self.ConfigFile = Options.ConfigFile\r
246 if Options.OutputFile != None:\r
247 self.OutputFile = Options.OutputFile\r
248 if Options.ReportFile != None:\r
249 self.ReportFile = Options.ReportFile\r
52302d4d
LG
250 if Options.ExceptionFile != None:\r
251 self.ExceptionFile = Options.ExceptionFile\r
30fdf114
LG
252 if Options.Target != None:\r
253 if not os.path.isdir(Options.Target):\r
254 EdkLogger.error("ECC", BuildToolError.OPTION_VALUE_INVALID, ExtraData="Target [%s] does NOT exist" % Options.Target)\r
255 else:\r
256 EccGlobalData.gTarget = self.GetRealPathCase(os.path.normpath(Options.Target))\r
257 else:\r
258 EdkLogger.warn("Ecc", EdkLogger.ECC_ERROR, "The target source tree was not specified, using current WORKSPACE instead!")\r
259 EccGlobalData.gTarget = os.path.normpath(os.getenv("WORKSPACE"))\r
260 if Options.keepdatabase != None:\r
261 self.IsInit = False\r
262 if Options.metadata != None and Options.sourcecode != None:\r
263 EdkLogger.error("ECC", BuildToolError.OPTION_CONFLICT, ExtraData="-m and -s can't be specified at one time")\r
264 if Options.metadata != None:\r
265 self.ScanSourceCode = False\r
266 if Options.sourcecode != None:\r
267 self.ScanMetaData = False\r
fd171542 268\r
30fdf114
LG
269 ## SetLogLevel\r
270 #\r
271 # Set current log level of the tool based on args\r
272 #\r
fd171542 273 # @param Option: The option list including log level setting\r
30fdf114
LG
274 #\r
275 def SetLogLevel(self, Option):\r
276 if Option.verbose != None:\r
277 EdkLogger.SetLevel(EdkLogger.VERBOSE)\r
278 elif Option.quiet != None:\r
279 EdkLogger.SetLevel(EdkLogger.QUIET)\r
280 elif Option.debug != None:\r
281 EdkLogger.SetLevel(Option.debug + 1)\r
282 else:\r
283 EdkLogger.SetLevel(EdkLogger.INFO)\r
284\r
285 ## Parse command line options\r
286 #\r
287 # Using standard Python module optparse to parse command line option of this tool.\r
288 #\r
289 # @retval Opt A optparse.Values object containing the parsed options\r
290 # @retval Args Target of build command\r
291 #\r
292 def EccOptionParser(self):\r
293 Parser = OptionParser(description = self.Copyright, version = self.Version, prog = "Ecc.exe", usage = "%prog [options]")\r
294 Parser.add_option("-t", "--target sourcepath", action="store", type="string", dest='Target',\r
295 help="Check all files under the target workspace.")\r
296 Parser.add_option("-c", "--config filename", action="store", type="string", dest="ConfigFile",\r
297 help="Specify a configuration file. Defaultly use config.ini under ECC tool directory.")\r
298 Parser.add_option("-o", "--outfile filename", action="store", type="string", dest="OutputFile",\r
299 help="Specify the name of an output file, if and only if one filename was specified.")\r
300 Parser.add_option("-r", "--reportfile filename", action="store", type="string", dest="ReportFile",\r
301 help="Specify the name of an report file, if and only if one filename was specified.")\r
52302d4d
LG
302 Parser.add_option("-e", "--exceptionfile filename", action="store", type="string", dest="ExceptionFile",\r
303 help="Specify the name of an exception file, if and only if one filename was specified.")\r
30fdf114
LG
304 Parser.add_option("-m", "--metadata", action="store_true", type=None, help="Only scan meta-data files information if this option is specified.")\r
305 Parser.add_option("-s", "--sourcecode", action="store_true", type=None, help="Only scan source code files information if this option is specified.")\r
306 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.")\r
fd171542 307 Parser.add_option("-l", "--log filename", action="store", dest="LogFile", help="""If specified, the tool should emit the changes that\r
308 were made by the tool after printing the result message.\r
309 If filename, the emit to the file, otherwise emit to\r
310 standard output. If no modifications were made, then do not\r
30fdf114
LG
311 create a log file, or output a log message.""")\r
312 Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")\r
313 Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed, "\\r
314 "including library instances selected, final dependency expression, "\\r
315 "and warning messages, etc.")\r
316 Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
52302d4d 317 Parser.add_option("-w", "--workspace", action="store", type="string", dest='Workspace', help="Specify workspace.")\r
fd171542 318\r
30fdf114 319 (Opt, Args)=Parser.parse_args()\r
fd171542 320\r
30fdf114
LG
321 return (Opt, Args)\r
322\r
323##\r
324#\r
325# This acts like the main() function for the script, unless it is 'import'ed into another\r
326# script.\r
327#\r
328if __name__ == '__main__':\r
329 # Initialize log system\r
330 EdkLogger.Initialize()\r
331 EdkLogger.IsRaiseError = False\r
332 EdkLogger.quiet(time.strftime("%H:%M:%S, %b.%d %Y ", time.localtime()) + "[00:00]" + "\n")\r
333\r
334 StartTime = time.clock()\r
335 Ecc = Ecc()\r
336 FinishTime = time.clock()\r
337\r
338 BuildDuration = time.strftime("%M:%S", time.gmtime(int(round(FinishTime - StartTime))))\r
339 EdkLogger.quiet("\n%s [%s]" % (time.strftime("%H:%M:%S, %b.%d %Y", time.localtime()), BuildDuration))\r