]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Ecc/Check.py
Sync tool code to BuildTools project r1783.
[mirror_edk2.git] / BaseTools / Source / Python / Ecc / Check.py
CommitLineData
30fdf114
LG
1## @file\r
2# This file is used to define checkpoints used by ECC tool\r
3#\r
4# Copyright (c) 2008, 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
13import os\r
14import re\r
15from CommonDataClass.DataClass import *\r
16from Common.DataType import SUP_MODULE_LIST_STRING, TAB_VALUE_SPLIT\r
17from EccToolError import *\r
18import EccGlobalData\r
19import c\r
20\r
21## Check\r
22#\r
23# This class is to define checkpoints used by ECC tool\r
24#\r
25# @param object: Inherited from object class\r
26#\r
27class Check(object):\r
28 def __init__(self):\r
29 pass\r
30\r
31 # Check all required checkpoints\r
32 def Check(self):\r
33 self.MetaDataFileCheck()\r
34 self.DoxygenCheck()\r
35 self.IncludeFileCheck()\r
36 self.PredicateExpressionCheck()\r
37 self.DeclAndDataTypeCheck()\r
38 self.FunctionLayoutCheck()\r
39 self.NamingConventionCheck()\r
40\r
41 # C Function Layout Checking\r
42 def FunctionLayoutCheck(self):\r
43 self.FunctionLayoutCheckReturnType()\r
44 self.FunctionLayoutCheckModifier()\r
45 self.FunctionLayoutCheckName()\r
46 self.FunctionLayoutCheckPrototype()\r
47 self.FunctionLayoutCheckBody()\r
48 self.FunctionLayoutCheckLocalVariable()\r
49\r
50 def WalkTree(self):\r
51 IgnoredPattern = c.GetIgnoredDirListPattern()\r
52 for Dirpath, Dirnames, Filenames in os.walk(EccGlobalData.gTarget):\r
53 for Dir in Dirnames:\r
54 Dirname = os.path.join(Dirpath, Dir)\r
55 if os.path.islink(Dirname):\r
56 Dirname = os.path.realpath(Dirname)\r
57 if os.path.isdir(Dirname):\r
58 # symlinks to directories are treated as directories\r
59 Dirnames.remove(Dir)\r
60 Dirnames.append(Dirname)\r
61 if IgnoredPattern.match(Dirpath.upper()):\r
62 continue\r
63 yield (Dirpath, Dirnames, Filenames)\r
64\r
65 # Check whether return type exists and in the first line\r
66 def FunctionLayoutCheckReturnType(self):\r
67 if EccGlobalData.gConfig.CFunctionLayoutCheckReturnType == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
68 EdkLogger.quiet("Checking function layout return type ...")\r
69\r
70 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
71 for F in Filenames:\r
72 if os.path.splitext(F)[1] in ('.c', '.h'):\r
73 FullName = os.path.join(Dirpath, F)\r
74 c.CheckFuncLayoutReturnType(FullName)\r
75\r
76 # Check whether any optional functional modifiers exist and next to the return type\r
77 def FunctionLayoutCheckModifier(self):\r
78 if EccGlobalData.gConfig.CFunctionLayoutCheckOptionalFunctionalModifier == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
79 EdkLogger.quiet("Checking function layout modifier ...")\r
80\r
81 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
82 for F in Filenames:\r
83 if os.path.splitext(F)[1] in ('.c', '.h'):\r
84 FullName = os.path.join(Dirpath, F)\r
85 c.CheckFuncLayoutModifier(FullName)\r
86\r
87 # Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list\r
88 # Check whether the closing parenthesis is on its own line and also indented two spaces\r
89 def FunctionLayoutCheckName(self):\r
90 if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionName == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
91 EdkLogger.quiet("Checking function layout function name ...")\r
92\r
93 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
94 for F in Filenames:\r
95 if os.path.splitext(F)[1] in ('.c', '.h'):\r
96 FullName = os.path.join(Dirpath, F)\r
97 c.CheckFuncLayoutName(FullName)\r
98 # Check whether the function prototypes in include files have the same form as function definitions\r
99 def FunctionLayoutCheckPrototype(self):\r
100 if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionPrototype == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
101 EdkLogger.quiet("Checking function layout function prototype ...")\r
102\r
103 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
104 for F in Filenames:\r
105 if os.path.splitext(F)[1] in ('.c'):\r
106 FullName = os.path.join(Dirpath, F)\r
107 EdkLogger.quiet("[PROTOTYPE]" + FullName)\r
108 c.CheckFuncLayoutPrototype(FullName)\r
109\r
110 # Check whether the body of a function is contained by open and close braces that must be in the first column\r
111 def FunctionLayoutCheckBody(self):\r
112 if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionBody == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
113 EdkLogger.quiet("Checking function layout function body ...")\r
114\r
115 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
116 for F in Filenames:\r
117 if os.path.splitext(F)[1] in ('.c'):\r
118 FullName = os.path.join(Dirpath, F)\r
119 c.CheckFuncLayoutBody(FullName)\r
120\r
121 # Check whether the data declarations is the first code in a module.\r
122 # self.CFunctionLayoutCheckDataDeclaration = 1\r
123 # Check whether no initialization of a variable as part of its declaration\r
124 def FunctionLayoutCheckLocalVariable(self):\r
125 if EccGlobalData.gConfig.CFunctionLayoutCheckNoInitOfVariable == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
126 EdkLogger.quiet("Checking function layout local variables ...")\r
127\r
128 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
129 for F in Filenames:\r
130 if os.path.splitext(F)[1] in ('.c'):\r
131 FullName = os.path.join(Dirpath, F)\r
132 c.CheckFuncLayoutLocalVariable(FullName)\r
133\r
134 # Check whether no use of STATIC for functions\r
135 # self.CFunctionLayoutCheckNoStatic = 1\r
136\r
137 # Declarations and Data Types Checking\r
138 def DeclAndDataTypeCheck(self):\r
139 self.DeclCheckNoUseCType()\r
140 self.DeclCheckInOutModifier()\r
141 self.DeclCheckEFIAPIModifier()\r
142 self.DeclCheckEnumeratedType()\r
143 self.DeclCheckStructureDeclaration()\r
144 self.DeclCheckSameStructure()\r
145 self.DeclCheckUnionType()\r
146\r
147\r
148 # Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files.\r
149 def DeclCheckNoUseCType(self):\r
150 if EccGlobalData.gConfig.DeclarationDataTypeCheckNoUseCType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
151 EdkLogger.quiet("Checking Declaration No use C type ...")\r
152\r
153 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
154 for F in Filenames:\r
155 if os.path.splitext(F)[1] in ('.h', '.c'):\r
156 FullName = os.path.join(Dirpath, F)\r
157 c.CheckDeclNoUseCType(FullName)\r
158\r
159 # Check whether the modifiers IN, OUT, OPTIONAL, and UNALIGNED are used only to qualify arguments to a function and should not appear in a data type declaration\r
160 def DeclCheckInOutModifier(self):\r
161 if EccGlobalData.gConfig.DeclarationDataTypeCheckInOutModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
162 EdkLogger.quiet("Checking Declaration argument modifier ...")\r
163\r
164 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
165 for F in Filenames:\r
166 if os.path.splitext(F)[1] in ('.h', '.c'):\r
167 FullName = os.path.join(Dirpath, F)\r
168 c.CheckDeclArgModifier(FullName)\r
169\r
170 # Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols\r
171 def DeclCheckEFIAPIModifier(self):\r
172 if EccGlobalData.gConfig.DeclarationDataTypeCheckEFIAPIModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
173 pass\r
174\r
175 # Check whether Enumerated Type has a 'typedef' and the name is capital\r
176 def DeclCheckEnumeratedType(self):\r
177 if EccGlobalData.gConfig.DeclarationDataTypeCheckEnumeratedType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
178 EdkLogger.quiet("Checking Declaration enum typedef ...")\r
179\r
180 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
181 for F in Filenames:\r
182 if os.path.splitext(F)[1] in ('.h', '.c'):\r
183 FullName = os.path.join(Dirpath, F)\r
184 EdkLogger.quiet("[ENUM]" + FullName)\r
185 c.CheckDeclEnumTypedef(FullName)\r
186\r
187 # Check whether Structure Type has a 'typedef' and the name is capital\r
188 def DeclCheckStructureDeclaration(self):\r
189 if EccGlobalData.gConfig.DeclarationDataTypeCheckStructureDeclaration == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
190 EdkLogger.quiet("Checking Declaration struct typedef ...")\r
191\r
192 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
193 for F in Filenames:\r
194 if os.path.splitext(F)[1] in ('.h', '.c'):\r
195 FullName = os.path.join(Dirpath, F)\r
196 EdkLogger.quiet("[STRUCT]" + FullName)\r
197 c.CheckDeclStructTypedef(FullName)\r
198\r
199 # Check whether having same Structure\r
200 def DeclCheckSameStructure(self):\r
201 if EccGlobalData.gConfig.DeclarationDataTypeCheckSameStructure == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
202 EdkLogger.quiet("Checking same struct ...")\r
203 AllStructure = {}\r
204 for IdentifierTable in EccGlobalData.gIdentifierTableList:\r
205 SqlCommand = """select ID, Name, BelongsToFile from %s where Model = %s""" %(IdentifierTable, MODEL_IDENTIFIER_STRUCTURE)\r
206 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
207 for Record in RecordSet:\r
208 if Record[1] != '':\r
209 if Record[1] not in AllStructure.keys():\r
210 AllStructure[Record[1]] = Record[2]\r
211 else:\r
212 ID = AllStructure[Record[1]]\r
213 SqlCommand = """select FullPath from File where ID = %s """ % ID\r
214 NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
215 OtherMsg = "The structure name '%s' is duplicate" % Record[1]\r
216 if NewRecordSet != []:\r
217 OtherMsg = "The structure name [%s] is duplicate with the one defined in %s, maybe struct NOT typedefed or the typedef new type NOT used to qualify variables" % (Record[1], NewRecordSet[0][0])\r
218 if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE, Record[1]):\r
219 EccGlobalData.gDb.TblReport.Insert(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE, OtherMsg = OtherMsg, BelongsToTable = IdentifierTable, BelongsToItem = Record[0])\r
220\r
221 # Check whether Union Type has a 'typedef' and the name is capital\r
222 def DeclCheckUnionType(self):\r
223 if EccGlobalData.gConfig.DeclarationDataTypeCheckUnionType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
224 EdkLogger.quiet("Checking Declaration union typedef ...")\r
225\r
226 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
227 for F in Filenames:\r
228 if os.path.splitext(F)[1] in ('.h', '.c'):\r
229 FullName = os.path.join(Dirpath, F)\r
230 EdkLogger.quiet("[UNION]" + FullName)\r
231 c.CheckDeclUnionTypedef(FullName)\r
232\r
233 # Predicate Expression Checking\r
234 def PredicateExpressionCheck(self):\r
235 self.PredicateExpressionCheckBooleanValue()\r
236 self.PredicateExpressionCheckNonBooleanOperator()\r
237 self.PredicateExpressionCheckComparisonNullType()\r
238\r
239 # Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE\r
240 def PredicateExpressionCheckBooleanValue(self):\r
241 if EccGlobalData.gConfig.PredicateExpressionCheckBooleanValue == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
242 EdkLogger.quiet("Checking predicate expression Boolean value ...")\r
243\r
244 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
245 for F in Filenames:\r
246 if os.path.splitext(F)[1] in ('.c'):\r
247 FullName = os.path.join(Dirpath, F)\r
248 EdkLogger.quiet("[BOOLEAN]" + FullName)\r
249 c.CheckBooleanValueComparison(FullName)\r
250\r
251 # Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=).\r
252 def PredicateExpressionCheckNonBooleanOperator(self):\r
253 if EccGlobalData.gConfig.PredicateExpressionCheckNonBooleanOperator == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
254 EdkLogger.quiet("Checking predicate expression Non-Boolean variable...")\r
255\r
256 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
257 for F in Filenames:\r
258 if os.path.splitext(F)[1] in ('.c'):\r
259 FullName = os.path.join(Dirpath, F)\r
260 EdkLogger.quiet("[NON-BOOLEAN]" + FullName)\r
261 c.CheckNonBooleanValueComparison(FullName)\r
262 # Check whether a comparison of any pointer to zero must be done via the NULL type\r
263 def PredicateExpressionCheckComparisonNullType(self):\r
264 if EccGlobalData.gConfig.PredicateExpressionCheckComparisonNullType == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
265 EdkLogger.quiet("Checking predicate expression NULL pointer ...")\r
266\r
267 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
268 for F in Filenames:\r
269 if os.path.splitext(F)[1] in ('.c'):\r
270 FullName = os.path.join(Dirpath, F)\r
271 EdkLogger.quiet("[POINTER]" + FullName)\r
272 c.CheckPointerNullComparison(FullName)\r
273 # Include file checking\r
274 def IncludeFileCheck(self):\r
275 self.IncludeFileCheckIfndef()\r
276 self.IncludeFileCheckData()\r
277 self.IncludeFileCheckSameName()\r
278\r
279 # Check whether having include files with same name\r
280 def IncludeFileCheckSameName(self):\r
281 if EccGlobalData.gConfig.IncludeFileCheckSameName == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
282 EdkLogger.quiet("Checking same header file name ...")\r
283 SqlCommand = """select ID, FullPath from File\r
284 where Model = 1002 order by Name """\r
285 RecordDict = {}\r
286 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
287 for Record in RecordSet:\r
288 List = Record[1].replace('/', '\\').split('\\')\r
289 if len(List) >= 2:\r
290 Key = List[-2] + '\\' + List[-1]\r
291 else:\r
292 Key = List[0]\r
293 if Key not in RecordDict:\r
294 RecordDict[Key] = [Record]\r
295 else:\r
296 RecordDict[Key].append(Record)\r
297\r
298 for Key in RecordDict:\r
299 if len(RecordDict[Key]) > 1:\r
300 for Item in RecordDict[Key]:\r
301 EccGlobalData.gDb.TblReport.Insert(ERROR_INCLUDE_FILE_CHECK_NAME, OtherMsg = "The file name for '%s' is duplicate" % (Item[1]), BelongsToTable = 'File', BelongsToItem = Item[0])\r
302\r
303 # Check whether all include file contents is guarded by a #ifndef statement.\r
304 def IncludeFileCheckIfndef(self):\r
305 if EccGlobalData.gConfig.IncludeFileCheckIfndefStatement == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
306 EdkLogger.quiet("Checking header file ifndef ...")\r
307\r
308 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
309 for F in Filenames:\r
310 if os.path.splitext(F)[1] in ('.h'):\r
311 FullName = os.path.join(Dirpath, F)\r
312 MsgList = c.CheckHeaderFileIfndef(FullName)\r
313\r
314 # Check whether include files NOT contain code or define data variables\r
315 def IncludeFileCheckData(self):\r
316 if EccGlobalData.gConfig.IncludeFileCheckData == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
317 EdkLogger.quiet("Checking header file data ...")\r
318\r
319 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
320 for F in Filenames:\r
321 if os.path.splitext(F)[1] in ('.h'):\r
322 FullName = os.path.join(Dirpath, F)\r
323 MsgList = c.CheckHeaderFileData(FullName)\r
324\r
325 # Doxygen document checking\r
326 def DoxygenCheck(self):\r
327 self.DoxygenCheckFileHeader()\r
328 self.DoxygenCheckFunctionHeader()\r
329 self.DoxygenCheckCommentDescription()\r
330 self.DoxygenCheckCommentFormat()\r
331 self.DoxygenCheckCommand()\r
332\r
333 # Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5\r
334 def DoxygenCheckFileHeader(self):\r
335 if EccGlobalData.gConfig.DoxygenCheckFileHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
336 EdkLogger.quiet("Checking Doxygen file header ...")\r
337\r
338 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
339 for F in Filenames:\r
340 if os.path.splitext(F)[1] in ('.h', '.c'):\r
341 FullName = os.path.join(Dirpath, F)\r
342 MsgList = c.CheckFileHeaderDoxygenComments(FullName)\r
343\r
344 # Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5\r
345 def DoxygenCheckFunctionHeader(self):\r
346 if EccGlobalData.gConfig.DoxygenCheckFunctionHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
347 EdkLogger.quiet("Checking Doxygen function header ...")\r
348\r
349 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
350 for F in Filenames:\r
351 if os.path.splitext(F)[1] in ('.h', '.c'):\r
352 FullName = os.path.join(Dirpath, F)\r
353 MsgList = c.CheckFuncHeaderDoxygenComments(FullName)\r
354\r
355 # Check whether the first line of text in a comment block is a brief description of the element being documented.\r
356 # The brief description must end with a period.\r
357 def DoxygenCheckCommentDescription(self):\r
358 if EccGlobalData.gConfig.DoxygenCheckCommentDescription == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
359 pass\r
360\r
361 # Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.\r
362 def DoxygenCheckCommentFormat(self):\r
363 if EccGlobalData.gConfig.DoxygenCheckCommentFormat == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
364 EdkLogger.quiet("Checking Doxygen comment ///< ...")\r
365\r
366 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
367 for F in Filenames:\r
368 if os.path.splitext(F)[1] in ('.h', '.c'):\r
369 FullName = os.path.join(Dirpath, F)\r
370 MsgList = c.CheckDoxygenTripleForwardSlash(FullName)\r
371\r
372 # Check whether only Doxygen commands allowed to mark the code are @bug and @todo.\r
373 def DoxygenCheckCommand(self):\r
374 if EccGlobalData.gConfig.DoxygenCheckCommand == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
375 EdkLogger.quiet("Checking Doxygen command ...")\r
376\r
377 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
378 for F in Filenames:\r
379 if os.path.splitext(F)[1] in ('.h', '.c'):\r
380 FullName = os.path.join(Dirpath, F)\r
381 MsgList = c.CheckDoxygenCommand(FullName)\r
382\r
383 # Meta-Data File Processing Checking\r
384 def MetaDataFileCheck(self):\r
385 self.MetaDataFileCheckPathName()\r
386 self.MetaDataFileCheckGenerateFileList()\r
387 self.MetaDataFileCheckLibraryInstance()\r
388 self.MetaDataFileCheckLibraryInstanceDependent()\r
389 self.MetaDataFileCheckLibraryInstanceOrder()\r
390 self.MetaDataFileCheckLibraryNoUse()\r
391 self.MetaDataFileCheckBinaryInfInFdf()\r
392 self.MetaDataFileCheckPcdDuplicate()\r
393 self.MetaDataFileCheckPcdFlash()\r
394 self.MetaDataFileCheckPcdNoUse()\r
395 self.MetaDataFileCheckGuidDuplicate()\r
396 self.MetaDataFileCheckModuleFileNoUse()\r
397 self.MetaDataFileCheckPcdType()\r
398\r
399 # Check whether each file defined in meta-data exists\r
400 def MetaDataFileCheckPathName(self):\r
401 if EccGlobalData.gConfig.MetaDataFileCheckPathName == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
402 # This item is covered when parsing Inf/Dec/Dsc files\r
403 pass\r
404\r
405 # Generate a list for all files defined in meta-data files\r
406 def MetaDataFileCheckGenerateFileList(self):\r
407 if EccGlobalData.gConfig.MetaDataFileCheckGenerateFileList == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
408 # This item is covered when parsing Inf/Dec/Dsc files\r
409 pass\r
410\r
411 # Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.\r
412 # Each Library Instance must specify the Supported Module Types in its Inf file,\r
413 # and any module specifying the library instance must be one of the supported types.\r
414 def MetaDataFileCheckLibraryInstance(self):\r
415 if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstance == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
416 EdkLogger.quiet("Checking for library instance type issue ...")\r
417 SqlCommand = """select A.ID, A.Value2, B.Value2 from Inf as A left join Inf as B\r
418 where A.Value1 = 'LIBRARY_CLASS' and A.Model = %s\r
419 and B.Value1 = 'MODULE_TYPE' and B.Model = %s and A.BelongsToFile = B.BelongsToFile\r
420 group by A.BelongsToFile""" % (MODEL_META_DATA_HEADER, MODEL_META_DATA_HEADER)\r
421 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
422 LibraryClasses = {}\r
423 for Record in RecordSet:\r
424 List = Record[1].split('|', 1)\r
425 SupModType = []\r
426 if len(List) == 1:\r
427 SupModType = SUP_MODULE_LIST_STRING.split(TAB_VALUE_SPLIT)\r
428 elif len(List) == 2:\r
429 SupModType = List[1].split()\r
430\r
431 if List[0] not in LibraryClasses:\r
432 LibraryClasses[List[0]] = SupModType\r
433 else:\r
434 for Item in SupModType:\r
435 if Item not in LibraryClasses[List[0]]:\r
436 LibraryClasses[List[0]].append(Item)\r
437\r
438 if Record[2] != 'BASE' and Record[2] not in SupModType:\r
439 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_2, OtherMsg = "The Library Class '%s' does not specify its supported module types" % (List[0]), BelongsToTable = 'Inf', BelongsToItem = Record[0])\r
440\r
441 SqlCommand = """select A.ID, A.Value1, B.Value2 from Inf as A left join Inf as B\r
442 where A.Model = %s and B.Value1 = '%s' and B.Model = %s\r
443 and B.BelongsToFile = A.BelongsToFile""" \\r
444 % (MODEL_EFI_LIBRARY_CLASS, 'MODULE_TYPE', MODEL_META_DATA_HEADER)\r
445 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
446 # Merge all LibraryClasses' supmodlist\r
447 RecordDict = {}\r
448 for Record in RecordSet:\r
449 if Record[1] not in RecordDict:\r
450 RecordDict[Record[1]] = [str(Record[2])]\r
451 else:\r
452 if Record[2] not in RecordDict[Record[1]]:\r
453 RecordDict[Record[1]].append(Record[2])\r
454\r
455 for Record in RecordSet:\r
456 if Record[1] in LibraryClasses:\r
457 if Record[2] not in LibraryClasses[Record[1]] and 'BASE' not in RecordDict[Record[1]]:\r
458 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, Record[1]):\r
459 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, OtherMsg = "The type of Library Class [%s] defined in Inf file does not match the type of the module" % (Record[1]), BelongsToTable = 'Inf', BelongsToItem = Record[0])\r
460 else:\r
461 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, Record[1]):\r
462 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, OtherMsg = "The type of Library Class [%s] defined in Inf file does not match the type of the module" % (Record[1]), BelongsToTable = 'Inf', BelongsToItem = Record[0])\r
463\r
464 # Check whether a Library Instance has been defined for all dependent library classes\r
465 def MetaDataFileCheckLibraryInstanceDependent(self):\r
466 if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceDependent == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
467 EdkLogger.quiet("Checking for library instance dependent issue ...")\r
468 SqlCommand = """select ID, Value1, Value2 from Dsc where Model = %s""" % MODEL_EFI_LIBRARY_CLASS\r
469 LibraryClasses = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)\r
470 for LibraryClass in LibraryClasses:\r
471 if LibraryClass[1].upper() != 'NULL':\r
472 LibraryIns = os.path.normpath(os.path.join(EccGlobalData.gWorkspace, LibraryClass[2]))\r
473 SqlCommand = """select Value2 from Inf where BelongsToFile =\r
474 (select ID from File where lower(FullPath) = lower('%s'))\r
475 and Value1 = '%s'""" % (LibraryIns, 'LIBRARY_CLASS')\r
476 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
477 IsFound = False\r
478 for Record in RecordSet:\r
479 LibName = Record[0].split('|', 1)[0]\r
480 if LibraryClass[1] == LibName:\r
481 IsFound = True\r
482 if not IsFound:\r
483 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT, LibraryClass[1]):\r
484 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT, OtherMsg = "The Library Class [%s] is not specified in '%s'" % (LibraryClass[1], LibraryClass[2]), BelongsToTable = 'Dsc', BelongsToItem = LibraryClass[0])\r
485\r
486 # Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies\r
487 def MetaDataFileCheckLibraryInstanceOrder(self):\r
488 if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceOrder == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
489 # This checkpoint is not necessary for Ecc check\r
490 pass\r
491\r
492 # Check whether the unnecessary inclusion of library classes in the Inf file\r
493 def MetaDataFileCheckLibraryNoUse(self):\r
494 if EccGlobalData.gConfig.MetaDataFileCheckLibraryNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
495 EdkLogger.quiet("Checking for library instance not used ...")\r
496 SqlCommand = """select ID, Value1 from Inf as A where A.Model = %s and A.Value1 not in (select B.Value1 from Dsc as B where Model = %s)""" % (MODEL_EFI_LIBRARY_CLASS, MODEL_EFI_LIBRARY_CLASS)\r
497 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
498 for Record in RecordSet:\r
499 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE, Record[1]):\r
500 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE, OtherMsg = "The Library Class [%s] is not used in any platform" % (Record[1]), BelongsToTable = 'Inf', BelongsToItem = Record[0])\r
501\r
502 # Check whether an Inf file is specified in the FDF file, but not in the Dsc file, then the Inf file must be for a Binary module only\r
503 def MetaDataFileCheckBinaryInfInFdf(self):\r
504 if EccGlobalData.gConfig.MetaDataFileCheckBinaryInfInFdf == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
505 EdkLogger.quiet("Checking for non-binary modules defined in FDF files ...")\r
506 SqlCommand = """select A.ID, A.Value1 from Fdf as A\r
507 where A.Model = %s\r
508 and A.Enabled > -1\r
509 and A.Value1 not in\r
510 (select B.Value1 from Dsc as B\r
511 where B.Model = %s\r
512 and B.Enabled > -1)""" % (MODEL_META_DATA_COMPONENT, MODEL_META_DATA_COMPONENT)\r
513 RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)\r
514 for Record in RecordSet:\r
515 FdfID = Record[0]\r
516 FilePath = Record[1]\r
517 FilePath = os.path.normpath(os.path.join(EccGlobalData.gWorkspace, FilePath))\r
518 SqlCommand = """select ID from Inf where Model = %s and BelongsToFile = (select ID from File where FullPath like '%s')\r
519 """ % (MODEL_EFI_SOURCE_FILE, FilePath)\r
520 NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
521 if NewRecordSet!= []:\r
522 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF, FilePath):\r
523 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF, OtherMsg = "File [%s] defined in FDF file and not in DSC file must be a binary module" % (FilePath), BelongsToTable = 'Fdf', BelongsToItem = FdfID)\r
524\r
525 # Check whether a PCD is set in a Dsc file or the FDF file, but not in both.\r
526 def MetaDataFileCheckPcdDuplicate(self):\r
527 if EccGlobalData.gConfig.MetaDataFileCheckPcdDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
528 EdkLogger.quiet("Checking for duplicate PCDs defined in both DSC and FDF files ...")\r
529 SqlCommand = """\r
530 select A.ID, A.Value2, B.ID, B.Value2 from Dsc as A, Fdf as B\r
531 where A.Model >= %s and A.Model < %s\r
532 and B.Model >= %s and B.Model < %s\r
533 and A.Value2 = B.Value2\r
534 and A.Enabled > -1\r
535 and B.Enabled > -1\r
536 group by A.ID\r
537 """% (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)\r
538 RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)\r
539 for Record in RecordSet:\r
540 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[1]):\r
541 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg = "The PCD [%s] is defined in both FDF file and DSC file" % (Record[1]), BelongsToTable = 'Dsc', BelongsToItem = Record[0])\r
542 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[3]):\r
543 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg = "The PCD [%s] is defined in both FDF file and DSC file" % (Record[3]), BelongsToTable = 'Fdf', BelongsToItem = Record[2])\r
544\r
545 EdkLogger.quiet("Checking for duplicate PCDs defined in DEC files ...")\r
546 SqlCommand = """\r
547 select A.ID, A.Value2 from Dec as A, Dec as B\r
548 where A.Model >= %s and A.Model < %s\r
549 and B.Model >= %s and B.Model < %s\r
550 and A.Value2 = B.Value2\r
551 and ((A.Arch = B.Arch) and (A.Arch != 'COMMON' or B.Arch != 'COMMON'))\r
552 and A.ID != B.ID\r
553 and A.Enabled > -1\r
554 and B.Enabled > -1\r
555 and A.BelongsToFile = B.BelongsToFile\r
556 group by A.ID\r
557 """% (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)\r
558 RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)\r
559 for Record in RecordSet:\r
560 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[1]):\r
561 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg = "The PCD [%s] is defined duplicated in DEC file" % (Record[1]), BelongsToTable = 'Dec', BelongsToItem = Record[0])\r
562\r
563 # Check whether PCD settings in the FDF file can only be related to flash.\r
564 def MetaDataFileCheckPcdFlash(self):\r
565 if EccGlobalData.gConfig.MetaDataFileCheckPcdFlash == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
566 EdkLogger.quiet("Checking only Flash related PCDs are used in FDF ...")\r
567 SqlCommand = """\r
568 select ID, Value2, BelongsToFile from Fdf as A\r
569 where A.Model >= %s and Model < %s\r
570 and A.Enabled > -1\r
571 and A.Value2 not like '%%Flash%%'\r
572 """% (MODEL_PCD, MODEL_META_DATA_HEADER)\r
573 RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)\r
574 for Record in RecordSet:\r
575 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_FLASH, Record[1]):\r
576 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_FLASH, OtherMsg = "The PCD [%s] defined in FDF file is not related to Flash" % (Record[1]), BelongsToTable = 'Fdf', BelongsToItem = Record[0])\r
577\r
578 # Check whether PCDs used in Inf files but not specified in Dsc or FDF files\r
579 def MetaDataFileCheckPcdNoUse(self):\r
580 if EccGlobalData.gConfig.MetaDataFileCheckPcdNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
581 EdkLogger.quiet("Checking for non-specified PCDs ...")\r
582 SqlCommand = """\r
583 select ID, Value2, BelongsToFile from Inf as A\r
584 where A.Model >= %s and Model < %s\r
585 and A.Enabled > -1\r
586 and A.Value2 not in\r
587 (select Value2 from Dsc as B\r
588 where B.Model >= %s and B.Model < %s\r
589 and B.Enabled > -1)\r
590 and A.Value2 not in\r
591 (select Value2 from Fdf as C\r
592 where C.Model >= %s and C.Model < %s\r
593 and C.Enabled > -1)\r
594 """% (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)\r
595 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
596 for Record in RecordSet:\r
597 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE, Record[1]):\r
598 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE, OtherMsg = "The PCD [%s] defined in INF file is not specified in either DSC or FDF files" % (Record[1]), BelongsToTable = 'Inf', BelongsToItem = Record[0])\r
599\r
600 # Check whether having duplicate guids defined for Guid/Protocol/Ppi\r
601 def MetaDataFileCheckGuidDuplicate(self):\r
602 if EccGlobalData.gConfig.MetaDataFileCheckGuidDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
603 EdkLogger.quiet("Checking for duplicate GUID/PPI/PROTOCOL ...")\r
604 # Check Guid\r
605 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDec)\r
606 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDsc)\r
607 self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID)\r
608 # Check protocol\r
609 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDec)\r
610 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDsc)\r
611 self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL)\r
612 # Check ppi\r
613 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDec)\r
614 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDsc)\r
615 self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI)\r
616\r
617 # Check whether all files under module directory are described in INF files\r
618 def MetaDataFileCheckModuleFileNoUse(self):\r
619 if EccGlobalData.gConfig.MetaDataFileCheckModuleFileNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
620 EdkLogger.quiet("Checking for no used module files ...")\r
621 SqlCommand = """\r
622 select upper(Path) from File where ID in (select BelongsToFile from INF where BelongsToFile != -1)\r
623 """\r
624 InfPathSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
625 InfPathList = []\r
626 for Item in InfPathSet:\r
627 if Item[0] not in InfPathList:\r
628 InfPathList.append(Item[0])\r
629 SqlCommand = """\r
630 select ID, Path, FullPath from File where upper(FullPath) not in\r
631 (select upper(A.Path) || '\\' || upper(B.Value1) from File as A, INF as B\r
632 where A.ID in (select BelongsToFile from INF where Model = %s group by BelongsToFile) and\r
633 B.BelongsToFile = A.ID and B.Model = %s)\r
634 and (Model = %s or Model = %s)\r
635 """ % (MODEL_EFI_SOURCE_FILE, MODEL_EFI_SOURCE_FILE, MODEL_FILE_C, MODEL_FILE_H)\r
636 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
637 for Record in RecordSet:\r
638 Path = Record[1]\r
639 Path = Path.upper().replace('\X64', '').replace('\IA32', '').replace('\EBC', '').replace('\IPF', '').replace('\ARM', '')\r
640 if Path in InfPathList:\r
641 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE, Record[2]):\r
642 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE, OtherMsg = "The source file [%s] is existing in module directory but it is not described in INF file." % (Record[2]), BelongsToTable = 'File', BelongsToItem = Record[0])\r
643\r
644 # Check whether the PCD is correctly used in C function via its type\r
645 def MetaDataFileCheckPcdType(self):\r
646 if EccGlobalData.gConfig.MetaDataFileCheckPcdType == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
647 EdkLogger.quiet("Checking for pcd type in c code function usage ...")\r
648 SqlCommand = """\r
649 select ID, Model, Value1, BelongsToFile from INF where Model > %s and Model < %s\r
650 """ % (MODEL_PCD, MODEL_META_DATA_HEADER)\r
651 PcdSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
652 for Pcd in PcdSet:\r
653 Model = Pcd[1]\r
654 PcdName = Pcd[2]\r
655 if len(Pcd[2].split(".")) > 1:\r
656 PcdName = Pcd[2].split(".")[1]\r
657 BelongsToFile = Pcd[3]\r
658 SqlCommand = """\r
659 select ID from File where FullPath in\r
660 (select B.Path || '\\' || A.Value1 from INF as A, File as B where A.Model = %s and A.BelongsToFile = %s\r
661 and B.ID = %s)\r
662 """ %(MODEL_EFI_SOURCE_FILE, BelongsToFile, BelongsToFile)\r
663 TableSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
664 for Tbl in TableSet:\r
665 TblName = 'Identifier' + str(Tbl[0])\r
666 SqlCommand = """\r
667 select Name, ID from %s where value like '%%%s%%' and Model = %s\r
668 """ % (TblName, PcdName, MODEL_IDENTIFIER_FUNCTION_CALLING)\r
669 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
670 TblNumber = TblName.replace('Identifier', '')\r
671 for Record in RecordSet:\r
672 FunName = Record[0]\r
673 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, FunName):\r
674 if Model in [MODEL_PCD_FIXED_AT_BUILD] and not FunName.startswith('FixedPcdGet'):\r
675 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, OtherMsg = "The pcd '%s' is defined as a FixPcd but now it is called by c function [%s]" % (PcdName, FunName), BelongsToTable = TblName, BelongsToItem = Record[1])\r
676 if Model in [MODEL_PCD_FEATURE_FLAG] and (not FunName.startswith('FeaturePcdGet') and not FunName.startswith('FeaturePcdSet')):\r
677 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, OtherMsg = "The pcd '%s' is defined as a FeaturePcd but now it is called by c function [%s]" % (PcdName, FunName), BelongsToTable = TblName, BelongsToItem = Record[1])\r
678 if Model in [MODEL_PCD_PATCHABLE_IN_MODULE] and (not FunName.startswith('PatchablePcdGet') and not FunName.startswith('PatchablePcdSet')):\r
679 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, OtherMsg = "The pcd '%s' is defined as a PatchablePcd but now it is called by c function [%s]" % (PcdName, FunName), BelongsToTable = TblName, BelongsToItem = Record[1])\r
680\r
681 #ERROR_META_DATA_FILE_CHECK_PCD_TYPE\r
682 pass\r
683\r
684 # Check whether these is duplicate Guid/Ppi/Protocol name\r
685 def CheckGuidProtocolPpi(self, ErrorID, Model, Table):\r
686 Name = ''\r
687 if Model == MODEL_EFI_GUID:\r
688 Name = 'guid'\r
689 if Model == MODEL_EFI_PROTOCOL:\r
690 Name = 'protocol'\r
691 if Model == MODEL_EFI_PPI:\r
692 Name = 'ppi'\r
693 SqlCommand = """\r
694 select A.ID, A.Value1 from %s as A, %s as B\r
695 where A.Model = %s and B.Model = %s\r
696 and A.Value1 = B.Value1 and A.ID <> B.ID\r
697 and A.Enabled > -1\r
698 and B.Enabled > -1\r
699 group by A.ID\r
700 """ % (Table.Table, Table.Table, Model, Model)\r
701 RecordSet = Table.Exec(SqlCommand)\r
702 for Record in RecordSet:\r
703 if not EccGlobalData.gException.IsException(ErrorID, Record[1]):\r
704 EccGlobalData.gDb.TblReport.Insert(ErrorID, OtherMsg = "The %s name [%s] is defined more than one time" % (Name.upper(), Record[1]), BelongsToTable = Table.Table, BelongsToItem = Record[0])\r
705\r
706 # Check whether these is duplicate Guid/Ppi/Protocol value\r
707 def CheckGuidProtocolPpiValue(self, ErrorID, Model):\r
708 Name = ''\r
709 Table = EccGlobalData.gDb.TblDec\r
710 if Model == MODEL_EFI_GUID:\r
711 Name = 'guid'\r
712 if Model == MODEL_EFI_PROTOCOL:\r
713 Name = 'protocol'\r
714 if Model == MODEL_EFI_PPI:\r
715 Name = 'ppi'\r
716 SqlCommand = """\r
717 select A.ID, A.Value2 from %s as A, %s as B\r
718 where A.Model = %s and B.Model = %s\r
719 and A.Value2 = B.Value2 and A.ID <> B.ID\r
720 group by A.ID\r
721 """ % (Table.Table, Table.Table, Model, Model)\r
722 RecordSet = Table.Exec(SqlCommand)\r
723 for Record in RecordSet:\r
724 if not EccGlobalData.gException.IsException(ErrorID, Record[1]):\r
725 EccGlobalData.gDb.TblReport.Insert(ErrorID, OtherMsg = "The %s value [%s] is used more than one time" % (Name.upper(), Record[1]), BelongsToTable = Table.Table, BelongsToItem = Record[0])\r
726\r
727 # Naming Convention Check\r
728 def NamingConventionCheck(self):\r
729\r
730 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
731 for F in Filenames:\r
732 if os.path.splitext(F)[1] in ('.h', '.c'):\r
733 FullName = os.path.join(Dirpath, F)\r
734 Id = c.GetTableID(FullName)\r
735 if Id < 0:\r
736 continue\r
737 FileTable = 'Identifier' + str(Id)\r
738 self.NamingConventionCheckDefineStatement(FileTable)\r
739 self.NamingConventionCheckTypedefStatement(FileTable)\r
740 self.NamingConventionCheckIfndefStatement(FileTable)\r
741 self.NamingConventionCheckVariableName(FileTable) \r
742 self.NamingConventionCheckSingleCharacterVariable(FileTable)\r
743\r
744 self.NamingConventionCheckPathName()\r
745 self.NamingConventionCheckFunctionName()\r
746 \r
747 # Check whether only capital letters are used for #define declarations\r
748 def NamingConventionCheckDefineStatement(self, FileTable):\r
749 if EccGlobalData.gConfig.NamingConventionCheckDefineStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
750 EdkLogger.quiet("Checking naming covention of #define statement ...")\r
751 \r
752 SqlCommand = """select ID, Value from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_MACRO_DEFINE)\r
753 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
754 for Record in RecordSet:\r
755 Name = Record[1].strip().split()[1]\r
756 if Name.find('(') != -1:\r
757 Name = Name[0:Name.find('(')]\r
758 if Name.upper() != Name:\r
759 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT, Name):\r
760 EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT, OtherMsg = "The #define name [%s] does not follow the rules" % (Name), BelongsToTable = FileTable, BelongsToItem = Record[0])\r
761\r
762 # Check whether only capital letters are used for typedef declarations\r
763 def NamingConventionCheckTypedefStatement(self, FileTable):\r
764 if EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
765 EdkLogger.quiet("Checking naming covention of #typedef statement ...")\r
766 \r
767 SqlCommand = """select ID, Name from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_TYPEDEF)\r
768 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
769 for Record in RecordSet:\r
770 Name = Record[1].strip()\r
771 if Name != '' and Name != None:\r
772 if Name[0] == '(':\r
773 Name = Name[1:Name.find(')')]\r
774 if Name.find('(') > -1:\r
775 Name = Name[Name.find('(') + 1 : Name.find(')')]\r
776 Name = Name.replace('WINAPI', '')\r
777 Name = Name.replace('*', '').strip()\r
778 if Name.upper() != Name:\r
779 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT, Name):\r
780 EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT, OtherMsg = "The #typedef name [%s] does not follow the rules" % (Name), BelongsToTable = FileTable, BelongsToItem = Record[0])\r
781\r
782 # Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'.\r
783 def NamingConventionCheckIfndefStatement(self, FileTable):\r
784 if EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
785 EdkLogger.quiet("Checking naming covention of #ifndef statement ...")\r
786 \r
787 SqlCommand = """select ID, Value from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_MACRO_IFNDEF)\r
788 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
789 for Record in RecordSet:\r
790 Name = Record[1].replace('#ifndef', '').strip()\r
791 if Name[0] != '_' or Name[-1] != '_':\r
792 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT, Name):\r
793 EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT, OtherMsg = "The #ifndef name [%s] does not follow the rules" % (Name), BelongsToTable = FileTable, BelongsToItem = Record[0])\r
794\r
795 # Rule for path name, variable name and function name\r
796 # 1. First character should be upper case\r
797 # 2. Existing lower case in a word\r
798 # 3. No space existence\r
799 # Check whether the path name followed the rule\r
800 def NamingConventionCheckPathName(self):\r
801 if EccGlobalData.gConfig.NamingConventionCheckPathName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
802 EdkLogger.quiet("Checking naming covention of file path name ...")\r
803 Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')\r
804 SqlCommand = """select ID, Name from File"""\r
805 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
806 for Record in RecordSet:\r
807 if not Pattern.match(Record[1]):\r
808 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_PATH_NAME, Record[1]):\r
809 EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_PATH_NAME, OtherMsg = "The file path [%s] does not follow the rules" % (Record[1]), BelongsToTable = 'File', BelongsToItem = Record[0])\r
810\r
811 # Rule for path name, variable name and function name\r
812 # 1. First character should be upper case\r
813 # 2. Existing lower case in a word\r
814 # 3. No space existence\r
815 # 4. Global variable name must start with a 'g'\r
816 # Check whether the variable name followed the rule\r
817 def NamingConventionCheckVariableName(self, FileTable):\r
818 if EccGlobalData.gConfig.NamingConventionCheckVariableName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
819 EdkLogger.quiet("Checking naming covention of variable name ...")\r
820 Pattern = re.compile(r'^[A-Zgm]+\S*[a-z]\S*$')\r
821 \r
822 SqlCommand = """select ID, Name from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_VARIABLE)\r
823 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
824 for Record in RecordSet:\r
825 if not Pattern.match(Record[1]):\r
826 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Record[1]):\r
827 EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, OtherMsg = "The variable name [%s] does not follow the rules" % (Record[1]), BelongsToTable = FileTable, BelongsToItem = Record[0])\r
828\r
829 # Rule for path name, variable name and function name\r
830 # 1. First character should be upper case\r
831 # 2. Existing lower case in a word\r
832 # 3. No space existence\r
833 # Check whether the function name followed the rule\r
834 def NamingConventionCheckFunctionName(self):\r
835 if EccGlobalData.gConfig.NamingConventionCheckFunctionName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
836 EdkLogger.quiet("Checking naming covention of function name ...")\r
837 Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')\r
838 SqlCommand = """select ID, Name from Function"""\r
839 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
840 for Record in RecordSet:\r
841 if not Pattern.match(Record[1]):\r
842 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME, Record[1]):\r
843 EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME, OtherMsg = "The function name [%s] does not follow the rules" % (Record[1]), BelongsToTable = 'Function', BelongsToItem = Record[0])\r
844\r
845 # Check whether NO use short variable name with single character\r
846 def NamingConventionCheckSingleCharacterVariable(self, FileTable):\r
847 if EccGlobalData.gConfig.NamingConventionCheckSingleCharacterVariable == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
848 EdkLogger.quiet("Checking naming covention of single character variable name ...")\r
849 \r
850 SqlCommand = """select ID, Name from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_VARIABLE)\r
851 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
852 for Record in RecordSet:\r
853 Variable = Record[1].replace('*', '')\r
854 if len(Variable) == 1:\r
855 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE, Record[1]):\r
856 EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE, OtherMsg = "The variable name [%s] does not follow the rules" % (Record[1]), BelongsToTable = FileTable, BelongsToItem = Record[0])\r
857\r
858##\r
859#\r
860# This acts like the main() function for the script, unless it is 'import'ed into another\r
861# script.\r
862#\r
863if __name__ == '__main__':\r
864 Check = Check()\r
865 Check.Check()\r