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