]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Ecc/Check.py
Sync EDKII BaseTools to BaseTools project r1903.
[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 - 2010, 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 Path = Item[1].replace(EccGlobalData.gWorkspace, '')
302 if Path.startswith('\\') or Path.startswith('/'):
303 Path = Path[1:]
304 if not EccGlobalData.gException.IsException(ERROR_INCLUDE_FILE_CHECK_NAME, Path):
305 EccGlobalData.gDb.TblReport.Insert(ERROR_INCLUDE_FILE_CHECK_NAME, OtherMsg = "The file name for [%s] is duplicate" % Path, BelongsToTable = 'File', BelongsToItem = Item[0])
306
307 # Check whether all include file contents is guarded by a #ifndef statement.
308 def IncludeFileCheckIfndef(self):
309 if EccGlobalData.gConfig.IncludeFileCheckIfndefStatement == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
310 EdkLogger.quiet("Checking header file ifndef ...")
311
312 for Dirpath, Dirnames, Filenames in self.WalkTree():
313 for F in Filenames:
314 if os.path.splitext(F)[1] in ('.h'):
315 FullName = os.path.join(Dirpath, F)
316 MsgList = c.CheckHeaderFileIfndef(FullName)
317
318 # Check whether include files NOT contain code or define data variables
319 def IncludeFileCheckData(self):
320 if EccGlobalData.gConfig.IncludeFileCheckData == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
321 EdkLogger.quiet("Checking header file data ...")
322
323 for Dirpath, Dirnames, Filenames in self.WalkTree():
324 for F in Filenames:
325 if os.path.splitext(F)[1] in ('.h'):
326 FullName = os.path.join(Dirpath, F)
327 MsgList = c.CheckHeaderFileData(FullName)
328
329 # Doxygen document checking
330 def DoxygenCheck(self):
331 self.DoxygenCheckFileHeader()
332 self.DoxygenCheckFunctionHeader()
333 self.DoxygenCheckCommentDescription()
334 self.DoxygenCheckCommentFormat()
335 self.DoxygenCheckCommand()
336
337 # Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5
338 def DoxygenCheckFileHeader(self):
339 if EccGlobalData.gConfig.DoxygenCheckFileHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
340 EdkLogger.quiet("Checking Doxygen file header ...")
341
342 for Dirpath, Dirnames, Filenames in self.WalkTree():
343 for F in Filenames:
344 if os.path.splitext(F)[1] in ('.h', '.c'):
345 FullName = os.path.join(Dirpath, F)
346 MsgList = c.CheckFileHeaderDoxygenComments(FullName)
347
348 # Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5
349 def DoxygenCheckFunctionHeader(self):
350 if EccGlobalData.gConfig.DoxygenCheckFunctionHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
351 EdkLogger.quiet("Checking Doxygen function header ...")
352
353 for Dirpath, Dirnames, Filenames in self.WalkTree():
354 for F in Filenames:
355 if os.path.splitext(F)[1] in ('.h', '.c'):
356 FullName = os.path.join(Dirpath, F)
357 MsgList = c.CheckFuncHeaderDoxygenComments(FullName)
358
359 # Check whether the first line of text in a comment block is a brief description of the element being documented.
360 # The brief description must end with a period.
361 def DoxygenCheckCommentDescription(self):
362 if EccGlobalData.gConfig.DoxygenCheckCommentDescription == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
363 pass
364
365 # Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.
366 def DoxygenCheckCommentFormat(self):
367 if EccGlobalData.gConfig.DoxygenCheckCommentFormat == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
368 EdkLogger.quiet("Checking Doxygen comment ///< ...")
369
370 for Dirpath, Dirnames, Filenames in self.WalkTree():
371 for F in Filenames:
372 if os.path.splitext(F)[1] in ('.h', '.c'):
373 FullName = os.path.join(Dirpath, F)
374 MsgList = c.CheckDoxygenTripleForwardSlash(FullName)
375
376 # Check whether only Doxygen commands allowed to mark the code are @bug and @todo.
377 def DoxygenCheckCommand(self):
378 if EccGlobalData.gConfig.DoxygenCheckCommand == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
379 EdkLogger.quiet("Checking Doxygen command ...")
380
381 for Dirpath, Dirnames, Filenames in self.WalkTree():
382 for F in Filenames:
383 if os.path.splitext(F)[1] in ('.h', '.c'):
384 FullName = os.path.join(Dirpath, F)
385 MsgList = c.CheckDoxygenCommand(FullName)
386
387 # Meta-Data File Processing Checking
388 def MetaDataFileCheck(self):
389 self.MetaDataFileCheckPathName()
390 self.MetaDataFileCheckGenerateFileList()
391 self.MetaDataFileCheckLibraryInstance()
392 self.MetaDataFileCheckLibraryInstanceDependent()
393 self.MetaDataFileCheckLibraryInstanceOrder()
394 self.MetaDataFileCheckLibraryNoUse()
395 self.MetaDataFileCheckBinaryInfInFdf()
396 self.MetaDataFileCheckPcdDuplicate()
397 self.MetaDataFileCheckPcdFlash()
398 self.MetaDataFileCheckPcdNoUse()
399 self.MetaDataFileCheckGuidDuplicate()
400 self.MetaDataFileCheckModuleFileNoUse()
401 self.MetaDataFileCheckPcdType()
402
403 # Check whether each file defined in meta-data exists
404 def MetaDataFileCheckPathName(self):
405 if EccGlobalData.gConfig.MetaDataFileCheckPathName == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
406 # This item is covered when parsing Inf/Dec/Dsc files
407 pass
408
409 # Generate a list for all files defined in meta-data files
410 def MetaDataFileCheckGenerateFileList(self):
411 if EccGlobalData.gConfig.MetaDataFileCheckGenerateFileList == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
412 # This item is covered when parsing Inf/Dec/Dsc files
413 pass
414
415 # Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.
416 # Each Library Instance must specify the Supported Module Types in its Inf file,
417 # and any module specifying the library instance must be one of the supported types.
418 def MetaDataFileCheckLibraryInstance(self):
419 if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstance == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
420 EdkLogger.quiet("Checking for library instance type issue ...")
421 SqlCommand = """select A.ID, A.Value2, B.Value2 from Inf as A left join Inf as B
422 where A.Value1 = 'LIBRARY_CLASS' and A.Model = %s
423 and B.Value1 = 'MODULE_TYPE' and B.Model = %s and A.BelongsToFile = B.BelongsToFile
424 group by A.BelongsToFile""" % (MODEL_META_DATA_HEADER, MODEL_META_DATA_HEADER)
425 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
426 LibraryClasses = {}
427 for Record in RecordSet:
428 List = Record[1].split('|', 1)
429 SupModType = []
430 if len(List) == 1:
431 SupModType = SUP_MODULE_LIST_STRING.split(TAB_VALUE_SPLIT)
432 elif len(List) == 2:
433 SupModType = List[1].split()
434
435 if List[0] not in LibraryClasses:
436 LibraryClasses[List[0]] = SupModType
437 else:
438 for Item in SupModType:
439 if Item not in LibraryClasses[List[0]]:
440 LibraryClasses[List[0]].append(Item)
441
442 if Record[2] != 'BASE' and Record[2] not in SupModType:
443 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])
444
445 SqlCommand = """select A.ID, A.Value1, B.Value2 from Inf as A left join Inf as B
446 where A.Model = %s and B.Value1 = '%s' and B.Model = %s
447 and B.BelongsToFile = A.BelongsToFile""" \
448 % (MODEL_EFI_LIBRARY_CLASS, 'MODULE_TYPE', MODEL_META_DATA_HEADER)
449 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
450 # Merge all LibraryClasses' supmodlist
451 RecordDict = {}
452 for Record in RecordSet:
453 if Record[1] not in RecordDict:
454 RecordDict[Record[1]] = [str(Record[2])]
455 else:
456 if Record[2] not in RecordDict[Record[1]]:
457 RecordDict[Record[1]].append(Record[2])
458
459 for Record in RecordSet:
460 if Record[1] in LibraryClasses:
461 if Record[2] not in LibraryClasses[Record[1]] and 'BASE' not in RecordDict[Record[1]]:
462 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, Record[1]):
463 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])
464 else:
465 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, Record[1]):
466 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])
467
468 # Check whether a Library Instance has been defined for all dependent library classes
469 def MetaDataFileCheckLibraryInstanceDependent(self):
470 if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceDependent == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
471 EdkLogger.quiet("Checking for library instance dependent issue ...")
472 SqlCommand = """select ID, Value1, Value2 from Dsc where Model = %s""" % MODEL_EFI_LIBRARY_CLASS
473 LibraryClasses = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)
474 for LibraryClass in LibraryClasses:
475 if LibraryClass[1].upper() != 'NULL':
476 LibraryIns = os.path.normpath(os.path.join(EccGlobalData.gWorkspace, LibraryClass[2]))
477 SqlCommand = """select Value2 from Inf where BelongsToFile =
478 (select ID from File where lower(FullPath) = lower('%s'))
479 and Value1 = '%s'""" % (LibraryIns, 'LIBRARY_CLASS')
480 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
481 IsFound = False
482 for Record in RecordSet:
483 LibName = Record[0].split('|', 1)[0]
484 if LibraryClass[1] == LibName:
485 IsFound = True
486 if not IsFound:
487 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT, LibraryClass[1]):
488 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])
489
490 # Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies
491 def MetaDataFileCheckLibraryInstanceOrder(self):
492 if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceOrder == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
493 # This checkpoint is not necessary for Ecc check
494 pass
495
496 # Check whether the unnecessary inclusion of library classes in the Inf file
497 def MetaDataFileCheckLibraryNoUse(self):
498 if EccGlobalData.gConfig.MetaDataFileCheckLibraryNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
499 EdkLogger.quiet("Checking for library instance not used ...")
500 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)
501 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
502 for Record in RecordSet:
503 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE, Record[1]):
504 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])
505
506 # 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
507 def MetaDataFileCheckBinaryInfInFdf(self):
508 if EccGlobalData.gConfig.MetaDataFileCheckBinaryInfInFdf == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
509 EdkLogger.quiet("Checking for non-binary modules defined in FDF files ...")
510 SqlCommand = """select A.ID, A.Value1 from Fdf as A
511 where A.Model = %s
512 and A.Enabled > -1
513 and A.Value1 not in
514 (select B.Value1 from Dsc as B
515 where B.Model = %s
516 and B.Enabled > -1)""" % (MODEL_META_DATA_COMPONENT, MODEL_META_DATA_COMPONENT)
517 RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)
518 for Record in RecordSet:
519 FdfID = Record[0]
520 FilePath = Record[1]
521 FilePath = os.path.normpath(os.path.join(EccGlobalData.gWorkspace, FilePath))
522 SqlCommand = """select ID from Inf where Model = %s and BelongsToFile = (select ID from File where FullPath like '%s')
523 """ % (MODEL_EFI_SOURCE_FILE, FilePath)
524 NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
525 if NewRecordSet!= []:
526 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF, FilePath):
527 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)
528
529 # Check whether a PCD is set in a Dsc file or the FDF file, but not in both.
530 def MetaDataFileCheckPcdDuplicate(self):
531 if EccGlobalData.gConfig.MetaDataFileCheckPcdDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
532 EdkLogger.quiet("Checking for duplicate PCDs defined in both DSC and FDF files ...")
533 SqlCommand = """
534 select A.ID, A.Value2, A.BelongsToFile, B.ID, B.Value2, B.BelongsToFile from Dsc as A, Fdf as B
535 where A.Model >= %s and A.Model < %s
536 and B.Model >= %s and B.Model < %s
537 and A.Value2 = B.Value2
538 and A.Enabled > -1
539 and B.Enabled > -1
540 group by A.ID
541 """% (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)
542 RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)
543 for Record in RecordSet:
544 SqlCommand1 = """select Name from File where ID = %s""" %Record[2]
545 SqlCommand2 = """select Name from File where ID = %s""" %Record[5]
546 DscFileName = os.path.splitext(EccGlobalData.gDb.TblDsc.Exec(SqlCommand1)[0][0])[0]
547 FdfFileName = os.path.splitext(EccGlobalData.gDb.TblDsc.Exec(SqlCommand2)[0][0])[0]
548 print DscFileName, 111, FdfFileName
549 if DscFileName != FdfFileName:
550 continue
551 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[1]):
552 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])
553 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[3]):
554 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[4]), BelongsToTable = 'Fdf', BelongsToItem = Record[3])
555
556 EdkLogger.quiet("Checking for duplicate PCDs defined in DEC files ...")
557 SqlCommand = """
558 select A.ID, A.Value2 from Dec as A, Dec as B
559 where A.Model >= %s and A.Model < %s
560 and B.Model >= %s and B.Model < %s
561 and A.Value2 = B.Value2
562 and ((A.Arch = B.Arch) and (A.Arch != 'COMMON' or B.Arch != 'COMMON'))
563 and A.ID != B.ID
564 and A.Enabled > -1
565 and B.Enabled > -1
566 and A.BelongsToFile = B.BelongsToFile
567 group by A.ID
568 """% (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)
569 RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)
570 for Record in RecordSet:
571 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[1]):
572 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])
573
574 # Check whether PCD settings in the FDF file can only be related to flash.
575 def MetaDataFileCheckPcdFlash(self):
576 if EccGlobalData.gConfig.MetaDataFileCheckPcdFlash == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
577 EdkLogger.quiet("Checking only Flash related PCDs are used in FDF ...")
578 SqlCommand = """
579 select ID, Value2, BelongsToFile from Fdf as A
580 where A.Model >= %s and Model < %s
581 and A.Enabled > -1
582 and A.Value2 not like '%%Flash%%'
583 """% (MODEL_PCD, MODEL_META_DATA_HEADER)
584 RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)
585 for Record in RecordSet:
586 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_FLASH, Record[1]):
587 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])
588
589 # Check whether PCDs used in Inf files but not specified in Dsc or FDF files
590 def MetaDataFileCheckPcdNoUse(self):
591 if EccGlobalData.gConfig.MetaDataFileCheckPcdNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
592 EdkLogger.quiet("Checking for non-specified PCDs ...")
593 SqlCommand = """
594 select ID, Value2, BelongsToFile from Inf as A
595 where A.Model >= %s and Model < %s
596 and A.Enabled > -1
597 and A.Value2 not in
598 (select Value2 from Dsc as B
599 where B.Model >= %s and B.Model < %s
600 and B.Enabled > -1)
601 and A.Value2 not in
602 (select Value2 from Fdf as C
603 where C.Model >= %s and C.Model < %s
604 and C.Enabled > -1)
605 """% (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)
606 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
607 for Record in RecordSet:
608 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE, Record[1]):
609 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])
610
611 # Check whether having duplicate guids defined for Guid/Protocol/Ppi
612 def MetaDataFileCheckGuidDuplicate(self):
613 if EccGlobalData.gConfig.MetaDataFileCheckGuidDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
614 EdkLogger.quiet("Checking for duplicate GUID/PPI/PROTOCOL ...")
615 # Check Guid
616 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDec)
617 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDsc)
618 self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID)
619 # Check protocol
620 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDec)
621 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDsc)
622 self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL)
623 # Check ppi
624 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDec)
625 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDsc)
626 self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI)
627
628 # Check whether all files under module directory are described in INF files
629 def MetaDataFileCheckModuleFileNoUse(self):
630 if EccGlobalData.gConfig.MetaDataFileCheckModuleFileNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
631 EdkLogger.quiet("Checking for no used module files ...")
632 SqlCommand = """
633 select upper(Path) from File where ID in (select BelongsToFile from INF where BelongsToFile != -1)
634 """
635 InfPathSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
636 InfPathList = []
637 for Item in InfPathSet:
638 if Item[0] not in InfPathList:
639 InfPathList.append(Item[0])
640 SqlCommand = """
641 select ID, Path, FullPath from File where upper(FullPath) not in
642 (select upper(A.Path) || '\\' || upper(B.Value1) from File as A, INF as B
643 where A.ID in (select BelongsToFile from INF where Model = %s group by BelongsToFile) and
644 B.BelongsToFile = A.ID and B.Model = %s)
645 and (Model = %s or Model = %s)
646 """ % (MODEL_EFI_SOURCE_FILE, MODEL_EFI_SOURCE_FILE, MODEL_FILE_C, MODEL_FILE_H)
647 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
648 for Record in RecordSet:
649 Path = Record[1]
650 Path = Path.upper().replace('\X64', '').replace('\IA32', '').replace('\EBC', '').replace('\IPF', '').replace('\ARM', '')
651 if Path in InfPathList:
652 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE, Record[2]):
653 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])
654
655 # Check whether the PCD is correctly used in C function via its type
656 def MetaDataFileCheckPcdType(self):
657 if EccGlobalData.gConfig.MetaDataFileCheckPcdType == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
658 EdkLogger.quiet("Checking for pcd type in c code function usage ...")
659 SqlCommand = """
660 select ID, Model, Value1, BelongsToFile from INF where Model > %s and Model < %s
661 """ % (MODEL_PCD, MODEL_META_DATA_HEADER)
662 PcdSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
663 for Pcd in PcdSet:
664 Model = Pcd[1]
665 PcdName = Pcd[2]
666 if len(Pcd[2].split(".")) > 1:
667 PcdName = Pcd[2].split(".")[1]
668 BelongsToFile = Pcd[3]
669 SqlCommand = """
670 select ID from File where FullPath in
671 (select B.Path || '\\' || A.Value1 from INF as A, File as B where A.Model = %s and A.BelongsToFile = %s
672 and B.ID = %s)
673 """ %(MODEL_EFI_SOURCE_FILE, BelongsToFile, BelongsToFile)
674 TableSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
675 for Tbl in TableSet:
676 TblName = 'Identifier' + str(Tbl[0])
677 SqlCommand = """
678 select Name, ID from %s where value like '%s' and Model = %s
679 """ % (TblName, PcdName, MODEL_IDENTIFIER_FUNCTION_CALLING)
680 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
681 TblNumber = TblName.replace('Identifier', '')
682 for Record in RecordSet:
683 FunName = Record[0]
684 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, FunName):
685 if Model in [MODEL_PCD_FIXED_AT_BUILD] and not FunName.startswith('FixedPcdGet'):
686 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])
687 if Model in [MODEL_PCD_FEATURE_FLAG] and (not FunName.startswith('FeaturePcdGet') and not FunName.startswith('FeaturePcdSet')):
688 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])
689 if Model in [MODEL_PCD_PATCHABLE_IN_MODULE] and (not FunName.startswith('PatchablePcdGet') and not FunName.startswith('PatchablePcdSet')):
690 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])
691
692 #ERROR_META_DATA_FILE_CHECK_PCD_TYPE
693 pass
694
695 # Check whether these is duplicate Guid/Ppi/Protocol name
696 def CheckGuidProtocolPpi(self, ErrorID, Model, Table):
697 Name = ''
698 if Model == MODEL_EFI_GUID:
699 Name = 'guid'
700 if Model == MODEL_EFI_PROTOCOL:
701 Name = 'protocol'
702 if Model == MODEL_EFI_PPI:
703 Name = 'ppi'
704 SqlCommand = """
705 select A.ID, A.Value1 from %s as A, %s as B
706 where A.Model = %s and B.Model = %s
707 and A.Value1 = B.Value1 and A.ID <> B.ID
708 and A.Enabled > -1
709 and B.Enabled > -1
710 group by A.ID
711 """ % (Table.Table, Table.Table, Model, Model)
712 RecordSet = Table.Exec(SqlCommand)
713 for Record in RecordSet:
714 if not EccGlobalData.gException.IsException(ErrorID, Record[1]):
715 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])
716
717 # Check whether these is duplicate Guid/Ppi/Protocol value
718 def CheckGuidProtocolPpiValue(self, ErrorID, Model):
719 Name = ''
720 Table = EccGlobalData.gDb.TblDec
721 if Model == MODEL_EFI_GUID:
722 Name = 'guid'
723 if Model == MODEL_EFI_PROTOCOL:
724 Name = 'protocol'
725 if Model == MODEL_EFI_PPI:
726 Name = 'ppi'
727 SqlCommand = """
728 select A.ID, A.Value2 from %s as A, %s as B
729 where A.Model = %s and B.Model = %s
730 and A.Value2 = B.Value2 and A.ID <> B.ID
731 group by A.ID
732 """ % (Table.Table, Table.Table, Model, Model)
733 RecordSet = Table.Exec(SqlCommand)
734 for Record in RecordSet:
735 if not EccGlobalData.gException.IsException(ErrorID, Record[1]):
736 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])
737
738 # Naming Convention Check
739 def NamingConventionCheck(self):
740 if EccGlobalData.gConfig.NamingConventionCheckDefineStatement == '1' \
741 or EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' \
742 or EccGlobalData.gConfig.NamingConventionCheckIfndefStatement == '1' \
743 or EccGlobalData.gConfig.NamingConventionCheckVariableName == '1' \
744 or EccGlobalData.gConfig.NamingConventionCheckSingleCharacterVariable == '1' \
745 or EccGlobalData.gConfig.NamingConventionCheckAll == '1'\
746 or EccGlobalData.gConfig.CheckAll == '1':
747 for Dirpath, Dirnames, Filenames in self.WalkTree():
748 for F in Filenames:
749 if os.path.splitext(F)[1] in ('.h', '.c'):
750 FullName = os.path.join(Dirpath, F)
751 Id = c.GetTableID(FullName)
752 if Id < 0:
753 continue
754 FileTable = 'Identifier' + str(Id)
755 self.NamingConventionCheckDefineStatement(FileTable)
756 self.NamingConventionCheckTypedefStatement(FileTable)
757 self.NamingConventionCheckIfndefStatement(FileTable)
758 self.NamingConventionCheckVariableName(FileTable)
759 self.NamingConventionCheckSingleCharacterVariable(FileTable)
760
761 self.NamingConventionCheckPathName()
762 self.NamingConventionCheckFunctionName()
763
764 # Check whether only capital letters are used for #define declarations
765 def NamingConventionCheckDefineStatement(self, FileTable):
766 if EccGlobalData.gConfig.NamingConventionCheckDefineStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
767 EdkLogger.quiet("Checking naming covention of #define statement ...")
768
769 SqlCommand = """select ID, Value from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_MACRO_DEFINE)
770 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
771 for Record in RecordSet:
772 Name = Record[1].strip().split()[1]
773 if Name.find('(') != -1:
774 Name = Name[0:Name.find('(')]
775 if Name.upper() != Name:
776 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT, Name):
777 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])
778
779 # Check whether only capital letters are used for typedef declarations
780 def NamingConventionCheckTypedefStatement(self, FileTable):
781 if EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
782 EdkLogger.quiet("Checking naming covention of #typedef statement ...")
783
784 SqlCommand = """select ID, Name from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_TYPEDEF)
785 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
786 for Record in RecordSet:
787 Name = Record[1].strip()
788 if Name != '' and Name != None:
789 if Name[0] == '(':
790 Name = Name[1:Name.find(')')]
791 if Name.find('(') > -1:
792 Name = Name[Name.find('(') + 1 : Name.find(')')]
793 Name = Name.replace('WINAPI', '')
794 Name = Name.replace('*', '').strip()
795 if Name.upper() != Name:
796 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT, Name):
797 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])
798
799 # Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'.
800 def NamingConventionCheckIfndefStatement(self, FileTable):
801 if EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
802 EdkLogger.quiet("Checking naming covention of #ifndef statement ...")
803
804 SqlCommand = """select ID, Value from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_MACRO_IFNDEF)
805 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
806 for Record in RecordSet:
807 Name = Record[1].replace('#ifndef', '').strip()
808 if Name[0] != '_' or Name[-1] != '_':
809 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT, Name):
810 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])
811
812 # Rule for path name, variable name and function name
813 # 1. First character should be upper case
814 # 2. Existing lower case in a word
815 # 3. No space existence
816 # Check whether the path name followed the rule
817 def NamingConventionCheckPathName(self):
818 if EccGlobalData.gConfig.NamingConventionCheckPathName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
819 EdkLogger.quiet("Checking naming covention of file path name ...")
820 Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')
821 SqlCommand = """select ID, Name from File"""
822 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
823 for Record in RecordSet:
824 if not Pattern.match(Record[1]):
825 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_PATH_NAME, Record[1]):
826 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])
827
828 # Rule for path name, variable name and function name
829 # 1. First character should be upper case
830 # 2. Existing lower case in a word
831 # 3. No space existence
832 # 4. Global variable name must start with a 'g'
833 # Check whether the variable name followed the rule
834 def NamingConventionCheckVariableName(self, FileTable):
835 if EccGlobalData.gConfig.NamingConventionCheckVariableName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
836 EdkLogger.quiet("Checking naming covention of variable name ...")
837 Pattern = re.compile(r'^[A-Zgm]+\S*[a-z]\S*$')
838
839 SqlCommand = """select ID, Name from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_VARIABLE)
840 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
841 for Record in RecordSet:
842 if not Pattern.match(Record[1]):
843 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Record[1]):
844 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])
845
846 # Rule for path name, variable name and function name
847 # 1. First character should be upper case
848 # 2. Existing lower case in a word
849 # 3. No space existence
850 # Check whether the function name followed the rule
851 def NamingConventionCheckFunctionName(self):
852 if EccGlobalData.gConfig.NamingConventionCheckFunctionName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
853 EdkLogger.quiet("Checking naming covention of function name ...")
854 Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')
855 SqlCommand = """select ID, Name from Function"""
856 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
857 for Record in RecordSet:
858 if not Pattern.match(Record[1]):
859 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME, Record[1]):
860 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])
861
862 # Check whether NO use short variable name with single character
863 def NamingConventionCheckSingleCharacterVariable(self, FileTable):
864 if EccGlobalData.gConfig.NamingConventionCheckSingleCharacterVariable == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
865 EdkLogger.quiet("Checking naming covention of single character variable name ...")
866
867 SqlCommand = """select ID, Name from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_VARIABLE)
868 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
869 for Record in RecordSet:
870 Variable = Record[1].replace('*', '')
871 if len(Variable) == 1:
872 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE, Record[1]):
873 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])
874
875 ##
876 #
877 # This acts like the main() function for the script, unless it is 'import'ed into another
878 # script.
879 #
880 if __name__ == '__main__':
881 Check = Check()
882 Check.Check()