2 # This file is used to define checkpoints used by ECC tool
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
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.
15 from CommonDataClass
.DataClass
import *
16 from Common
.DataType
import SUP_MODULE_LIST_STRING
, TAB_VALUE_SPLIT
17 from EccToolError
import *
23 # This class is to define checkpoints used by ECC tool
25 # @param object: Inherited from object class
31 # Check all required checkpoints
33 self
.MetaDataFileCheck()
35 self
.IncludeFileCheck()
36 self
.PredicateExpressionCheck()
37 self
.DeclAndDataTypeCheck()
38 self
.FunctionLayoutCheck()
39 self
.NamingConventionCheck()
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()
51 IgnoredPattern
= c
.GetIgnoredDirListPattern()
52 for Dirpath
, Dirnames
, Filenames
in os
.walk(EccGlobalData
.gTarget
):
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
60 Dirnames
.append(Dirname
)
61 if IgnoredPattern
.match(Dirpath
.upper()):
63 yield (Dirpath
, Dirnames
, Filenames
)
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 ...")
70 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
72 if os
.path
.splitext(F
)[1] in ('.c', '.h'):
73 FullName
= os
.path
.join(Dirpath
, F
)
74 c
.CheckFuncLayoutReturnType(FullName
)
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 ...")
81 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
83 if os
.path
.splitext(F
)[1] in ('.c', '.h'):
84 FullName
= os
.path
.join(Dirpath
, F
)
85 c
.CheckFuncLayoutModifier(FullName
)
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 ...")
93 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
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 ...")
103 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
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
)
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 ...")
115 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
117 if os
.path
.splitext(F
)[1] in ('.c'):
118 FullName
= os
.path
.join(Dirpath
, F
)
119 c
.CheckFuncLayoutBody(FullName
)
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 ...")
128 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
130 if os
.path
.splitext(F
)[1] in ('.c'):
131 FullName
= os
.path
.join(Dirpath
, F
)
132 c
.CheckFuncLayoutLocalVariable(FullName
)
134 # Check whether no use of STATIC for functions
135 # self.CFunctionLayoutCheckNoStatic = 1
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()
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 ...")
153 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
155 if os
.path
.splitext(F
)[1] in ('.h', '.c'):
156 FullName
= os
.path
.join(Dirpath
, F
)
157 c
.CheckDeclNoUseCType(FullName
)
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 ...")
164 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
166 if os
.path
.splitext(F
)[1] in ('.h', '.c'):
167 FullName
= os
.path
.join(Dirpath
, F
)
168 c
.CheckDeclArgModifier(FullName
)
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':
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 ...")
180 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
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
)
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 ...")
192 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
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
)
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 ...")
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
:
209 if Record
[1] not in AllStructure
.keys():
210 AllStructure
[Record
[1]] = Record
[2]
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])
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 ...")
226 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
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
)
233 # Predicate Expression Checking
234 def PredicateExpressionCheck(self
):
235 self
.PredicateExpressionCheckBooleanValue()
236 self
.PredicateExpressionCheckNonBooleanOperator()
237 self
.PredicateExpressionCheckComparisonNullType()
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 ...")
244 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
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
)
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...")
256 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
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 ...")
267 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
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()
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 """
286 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
287 for Record
in RecordSet
:
288 List
= Record
[1].replace('/', '\\').split('\\')
290 Key
= List
[-2] + '\\' + List
[-1]
293 if Key
not in RecordDict
:
294 RecordDict
[Key
] = [Record
]
296 RecordDict
[Key
].append(Record
)
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])
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 ...")
308 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
310 if os
.path
.splitext(F
)[1] in ('.h'):
311 FullName
= os
.path
.join(Dirpath
, F
)
312 MsgList
= c
.CheckHeaderFileIfndef(FullName
)
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 ...")
319 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
321 if os
.path
.splitext(F
)[1] in ('.h'):
322 FullName
= os
.path
.join(Dirpath
, F
)
323 MsgList
= c
.CheckHeaderFileData(FullName
)
325 # Doxygen document checking
326 def DoxygenCheck(self
):
327 self
.DoxygenCheckFileHeader()
328 self
.DoxygenCheckFunctionHeader()
329 self
.DoxygenCheckCommentDescription()
330 self
.DoxygenCheckCommentFormat()
331 self
.DoxygenCheckCommand()
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 ...")
338 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
340 if os
.path
.splitext(F
)[1] in ('.h', '.c'):
341 FullName
= os
.path
.join(Dirpath
, F
)
342 MsgList
= c
.CheckFileHeaderDoxygenComments(FullName
)
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 ...")
349 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
351 if os
.path
.splitext(F
)[1] in ('.h', '.c'):
352 FullName
= os
.path
.join(Dirpath
, F
)
353 MsgList
= c
.CheckFuncHeaderDoxygenComments(FullName
)
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':
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 ///< ...")
366 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
368 if os
.path
.splitext(F
)[1] in ('.h', '.c'):
369 FullName
= os
.path
.join(Dirpath
, F
)
370 MsgList
= c
.CheckDoxygenTripleForwardSlash(FullName
)
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 ...")
377 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
379 if os
.path
.splitext(F
)[1] in ('.h', '.c'):
380 FullName
= os
.path
.join(Dirpath
, F
)
381 MsgList
= c
.CheckDoxygenCommand(FullName
)
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()
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
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
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
)
423 for Record
in RecordSet
:
424 List
= Record
[1].split('|', 1)
427 SupModType
= SUP_MODULE_LIST_STRING
.split(TAB_VALUE_SPLIT
)
429 SupModType
= List
[1].split()
431 if List
[0] not in LibraryClasses
:
432 LibraryClasses
[List
[0]] = SupModType
434 for Item
in SupModType
:
435 if Item
not in LibraryClasses
[List
[0]]:
436 LibraryClasses
[List
[0]].append(Item
)
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])
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
448 for Record
in RecordSet
:
449 if Record
[1] not in RecordDict
:
450 RecordDict
[Record
[1]] = [str(Record
[2])]
452 if Record
[2] not in RecordDict
[Record
[1]]:
453 RecordDict
[Record
[1]].append(Record
[2])
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])
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])
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
)
478 for Record
in RecordSet
:
479 LibName
= Record
[0].split('|', 1)[0]
480 if LibraryClass
[1] == LibName
:
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])
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
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])
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
510 (select B.Value1 from Dsc as B
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
:
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
)
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 ...")
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
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])
545 EdkLogger
.quiet("Checking for duplicate PCDs defined in DEC files ...")
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'))
555 and A.BelongsToFile = B.BelongsToFile
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])
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 ...")
568 select ID, Value2, BelongsToFile from Fdf as A
569 where A.Model >= %s and Model < %s
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])
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 ...")
583 select ID, Value2, BelongsToFile from Inf as A
584 where A.Model >= %s and Model < %s
587 (select Value2 from Dsc as B
588 where B.Model >= %s and B.Model < %s
591 (select Value2 from Fdf as C
592 where C.Model >= %s and C.Model < %s
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])
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 ...")
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
)
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
)
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
)
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 ...")
622 select upper(Path) from File where ID in (select BelongsToFile from INF where BelongsToFile != -1)
624 InfPathSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
626 for Item
in InfPathSet
:
627 if Item
[0] not in InfPathList
:
628 InfPathList
.append(Item
[0])
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
:
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])
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 ...")
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
)
655 if len(Pcd
[2].split(".")) > 1:
656 PcdName
= Pcd
[2].split(".")[1]
657 BelongsToFile
= Pcd
[3]
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
662 """ %(MODEL_EFI_SOURCE_FILE
, BelongsToFile
, BelongsToFile
)
663 TableSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
665 TblName
= 'Identifier' + str(Tbl
[0])
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
:
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])
681 #ERROR_META_DATA_FILE_CHECK_PCD_TYPE
684 # Check whether these is duplicate Guid/Ppi/Protocol name
685 def CheckGuidProtocolPpi(self
, ErrorID
, Model
, Table
):
687 if Model
== MODEL_EFI_GUID
:
689 if Model
== MODEL_EFI_PROTOCOL
:
691 if Model
== MODEL_EFI_PPI
:
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
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])
706 # Check whether these is duplicate Guid/Ppi/Protocol value
707 def CheckGuidProtocolPpiValue(self
, ErrorID
, Model
):
709 Table
= EccGlobalData
.gDb
.TblDec
710 if Model
== MODEL_EFI_GUID
:
712 if Model
== MODEL_EFI_PROTOCOL
:
714 if Model
== MODEL_EFI_PPI
:
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
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])
727 # Naming Convention Check
728 def NamingConventionCheck(self
):
730 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
732 if os
.path
.splitext(F
)[1] in ('.h', '.c'):
733 FullName
= os
.path
.join(Dirpath
, F
)
734 Id
= c
.GetTableID(FullName
)
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
)
744 self
.NamingConventionCheckPathName()
745 self
.NamingConventionCheckFunctionName()
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 ...")
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])
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 ...")
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:
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])
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 ...")
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])
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])
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*$')
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])
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])
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 ...")
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])
860 # This acts like the main() function for the script, unless it is 'import'ed into another
863 if __name__
== '__main__':