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