2 # This file is used to define checkpoints used by ECC tool
4 # Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
5 # 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 Path
= Item
[1].replace(EccGlobalData
.gWorkspace
, '')
302 if Path
.startswith('\\') or Path
.startswith('/'):
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])
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 ...")
312 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
314 if os
.path
.splitext(F
)[1] in ('.h'):
315 FullName
= os
.path
.join(Dirpath
, F
)
316 MsgList
= c
.CheckHeaderFileIfndef(FullName
)
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 ...")
323 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
325 if os
.path
.splitext(F
)[1] in ('.h'):
326 FullName
= os
.path
.join(Dirpath
, F
)
327 MsgList
= c
.CheckHeaderFileData(FullName
)
329 # Doxygen document checking
330 def DoxygenCheck(self
):
331 self
.DoxygenCheckFileHeader()
332 self
.DoxygenCheckFunctionHeader()
333 self
.DoxygenCheckCommentDescription()
334 self
.DoxygenCheckCommentFormat()
335 self
.DoxygenCheckCommand()
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 ...")
342 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
344 Ext
= os
.path
.splitext(F
)[1]
345 if Ext
in ('.h', '.c'):
346 FullName
= os
.path
.join(Dirpath
, F
)
347 MsgList
= c
.CheckFileHeaderDoxygenComments(FullName
)
348 elif Ext
in ('.inf', '.dec', '.dsc', '.fdf'):
349 FullName
= os
.path
.join(Dirpath
, F
)
350 if not open(FullName
).read().startswith('## @file'):
351 SqlStatement
= """ select ID from File where FullPath like '%s'""" % FullName
352 ResultSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlStatement
)
353 for Result
in ResultSet
:
354 Msg
= 'INF/DEC/DSC/FDF file header comment should begin with ""## @file""'
355 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER
, Msg
, "File", Result
[0])
358 # Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5
359 def DoxygenCheckFunctionHeader(self
):
360 if EccGlobalData
.gConfig
.DoxygenCheckFunctionHeader
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
361 EdkLogger
.quiet("Checking Doxygen function header ...")
363 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
365 if os
.path
.splitext(F
)[1] in ('.h', '.c'):
366 FullName
= os
.path
.join(Dirpath
, F
)
367 MsgList
= c
.CheckFuncHeaderDoxygenComments(FullName
)
369 # Check whether the first line of text in a comment block is a brief description of the element being documented.
370 # The brief description must end with a period.
371 def DoxygenCheckCommentDescription(self
):
372 if EccGlobalData
.gConfig
.DoxygenCheckCommentDescription
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
375 # Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.
376 def DoxygenCheckCommentFormat(self
):
377 if EccGlobalData
.gConfig
.DoxygenCheckCommentFormat
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
378 EdkLogger
.quiet("Checking Doxygen comment ///< ...")
380 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
382 if os
.path
.splitext(F
)[1] in ('.h', '.c'):
383 FullName
= os
.path
.join(Dirpath
, F
)
384 MsgList
= c
.CheckDoxygenTripleForwardSlash(FullName
)
386 # Check whether only Doxygen commands allowed to mark the code are @bug and @todo.
387 def DoxygenCheckCommand(self
):
388 if EccGlobalData
.gConfig
.DoxygenCheckCommand
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
389 EdkLogger
.quiet("Checking Doxygen command ...")
391 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
393 if os
.path
.splitext(F
)[1] in ('.h', '.c'):
394 FullName
= os
.path
.join(Dirpath
, F
)
395 MsgList
= c
.CheckDoxygenCommand(FullName
)
397 # Meta-Data File Processing Checking
398 def MetaDataFileCheck(self
):
399 self
.MetaDataFileCheckPathName()
400 self
.MetaDataFileCheckGenerateFileList()
401 self
.MetaDataFileCheckLibraryInstance()
402 self
.MetaDataFileCheckLibraryInstanceDependent()
403 self
.MetaDataFileCheckLibraryInstanceOrder()
404 self
.MetaDataFileCheckLibraryNoUse()
405 self
.MetaDataFileCheckBinaryInfInFdf()
406 self
.MetaDataFileCheckPcdDuplicate()
407 self
.MetaDataFileCheckPcdFlash()
408 self
.MetaDataFileCheckPcdNoUse()
409 self
.MetaDataFileCheckGuidDuplicate()
410 self
.MetaDataFileCheckModuleFileNoUse()
411 self
.MetaDataFileCheckPcdType()
412 self
.MetaDataFileCheckModuleFileGuidDuplication()
414 # Check whether each file defined in meta-data exists
415 def MetaDataFileCheckPathName(self
):
416 if EccGlobalData
.gConfig
.MetaDataFileCheckPathName
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
417 # This item is covered when parsing Inf/Dec/Dsc files
420 # Generate a list for all files defined in meta-data files
421 def MetaDataFileCheckGenerateFileList(self
):
422 if EccGlobalData
.gConfig
.MetaDataFileCheckGenerateFileList
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
423 # This item is covered when parsing Inf/Dec/Dsc files
426 # Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.
427 # Each Library Instance must specify the Supported Module Types in its Inf file,
428 # and any module specifying the library instance must be one of the supported types.
429 def MetaDataFileCheckLibraryInstance(self
):
430 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryInstance
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
431 EdkLogger
.quiet("Checking for library instance type issue ...")
432 SqlCommand
= """select A.ID, A.Value2, B.Value2 from Inf as A left join Inf as B
433 where A.Value1 = 'LIBRARY_CLASS' and A.Model = %s
434 and B.Value1 = 'MODULE_TYPE' and B.Model = %s and A.BelongsToFile = B.BelongsToFile
435 group by A.BelongsToFile""" % (MODEL_META_DATA_HEADER
, MODEL_META_DATA_HEADER
)
436 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
438 for Record
in RecordSet
:
439 List
= Record
[1].split('|', 1)
442 SupModType
= SUP_MODULE_LIST_STRING
.split(TAB_VALUE_SPLIT
)
444 SupModType
= List
[1].split()
446 if List
[0] not in LibraryClasses
:
447 LibraryClasses
[List
[0]] = SupModType
449 for Item
in SupModType
:
450 if Item
not in LibraryClasses
[List
[0]]:
451 LibraryClasses
[List
[0]].append(Item
)
453 if Record
[2] != 'BASE' and Record
[2] not in SupModType
:
454 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])
456 SqlCommand
= """select A.ID, A.Value1, B.Value2 from Inf as A left join Inf as B
457 where A.Model = %s and B.Value1 = '%s' and B.Model = %s
458 and B.BelongsToFile = A.BelongsToFile""" \
459 % (MODEL_EFI_LIBRARY_CLASS
, 'MODULE_TYPE', MODEL_META_DATA_HEADER
)
460 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
461 # Merge all LibraryClasses' supmodlist
463 for Record
in RecordSet
:
464 if Record
[1] not in RecordDict
:
465 RecordDict
[Record
[1]] = [str(Record
[2])]
467 if Record
[2] not in RecordDict
[Record
[1]]:
468 RecordDict
[Record
[1]].append(Record
[2])
470 for Record
in RecordSet
:
471 if Record
[1] in LibraryClasses
:
472 if Record
[2] not in LibraryClasses
[Record
[1]] and 'BASE' not in RecordDict
[Record
[1]]:
473 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1
, Record
[1]):
474 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])
476 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1
, Record
[1]):
477 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])
479 # Check whether a Library Instance has been defined for all dependent library classes
480 def MetaDataFileCheckLibraryInstanceDependent(self
):
481 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryInstanceDependent
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
482 EdkLogger
.quiet("Checking for library instance dependent issue ...")
483 SqlCommand
= """select ID, Value1, Value2 from Dsc where Model = %s""" % MODEL_EFI_LIBRARY_CLASS
484 LibraryClasses
= EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand
)
485 for LibraryClass
in LibraryClasses
:
486 if LibraryClass
[1].upper() != 'NULL':
487 LibraryIns
= os
.path
.normpath(os
.path
.join(EccGlobalData
.gWorkspace
, LibraryClass
[2]))
488 SqlCommand
= """select Value2 from Inf where BelongsToFile =
489 (select ID from File where lower(FullPath) = lower('%s'))
490 and Value1 = '%s'""" % (LibraryIns
, 'LIBRARY_CLASS')
491 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
493 for Record
in RecordSet
:
494 LibName
= Record
[0].split('|', 1)[0]
495 if LibraryClass
[1] == LibName
:
498 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT
, LibraryClass
[1]):
499 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])
501 # Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies
502 def MetaDataFileCheckLibraryInstanceOrder(self
):
503 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryInstanceOrder
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
504 # This checkpoint is not necessary for Ecc check
507 # Check whether the unnecessary inclusion of library classes in the Inf file
508 def MetaDataFileCheckLibraryNoUse(self
):
509 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryNoUse
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
510 EdkLogger
.quiet("Checking for library instance not used ...")
511 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
)
512 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
513 for Record
in RecordSet
:
514 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE
, Record
[1]):
515 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])
517 # 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
518 def MetaDataFileCheckBinaryInfInFdf(self
):
519 if EccGlobalData
.gConfig
.MetaDataFileCheckBinaryInfInFdf
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
520 EdkLogger
.quiet("Checking for non-binary modules defined in FDF files ...")
521 SqlCommand
= """select A.ID, A.Value1 from Fdf as A
525 (select B.Value1 from Dsc as B
527 and B.Enabled > -1)""" % (MODEL_META_DATA_COMPONENT
, MODEL_META_DATA_COMPONENT
)
528 RecordSet
= EccGlobalData
.gDb
.TblFdf
.Exec(SqlCommand
)
529 for Record
in RecordSet
:
532 FilePath
= os
.path
.normpath(os
.path
.join(EccGlobalData
.gWorkspace
, FilePath
))
533 SqlCommand
= """select ID from Inf where Model = %s and BelongsToFile = (select ID from File where FullPath like '%s')
534 """ % (MODEL_EFI_SOURCE_FILE
, FilePath
)
535 NewRecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
536 if NewRecordSet
!= []:
537 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF
, FilePath
):
538 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
)
540 # Check whether a PCD is set in a Dsc file or the FDF file, but not in both.
541 def MetaDataFileCheckPcdDuplicate(self
):
542 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdDuplicate
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
543 EdkLogger
.quiet("Checking for duplicate PCDs defined in both DSC and FDF files ...")
545 select A.ID, A.Value2, A.BelongsToFile, B.ID, B.Value2, B.BelongsToFile from Dsc as A, Fdf as B
546 where A.Model >= %s and A.Model < %s
547 and B.Model >= %s and B.Model < %s
548 and A.Value2 = B.Value2
552 """% (MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
)
553 RecordSet
= EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand
)
554 for Record
in RecordSet
:
555 SqlCommand1
= """select Name from File where ID = %s""" %Record
[2]
556 SqlCommand2
= """select Name from File where ID = %s""" %Record
[5]
557 DscFileName
= os
.path
.splitext(EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand1
)[0][0])[0]
558 FdfFileName
= os
.path
.splitext(EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand2
)[0][0])[0]
559 print DscFileName
, 111, FdfFileName
560 if DscFileName
!= FdfFileName
:
562 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE
, Record
[1]):
563 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])
564 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE
, Record
[3]):
565 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])
567 EdkLogger
.quiet("Checking for duplicate PCDs defined in DEC files ...")
569 select A.ID, A.Value2 from Dec as A, Dec as B
570 where A.Model >= %s and A.Model < %s
571 and B.Model >= %s and B.Model < %s
572 and A.Value2 = B.Value2
573 and ((A.Arch = B.Arch) and (A.Arch != 'COMMON' or B.Arch != 'COMMON'))
577 and A.BelongsToFile = B.BelongsToFile
579 """% (MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
)
580 RecordSet
= EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand
)
581 for Record
in RecordSet
:
582 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE
, Record
[1]):
583 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])
585 # Check whether PCD settings in the FDF file can only be related to flash.
586 def MetaDataFileCheckPcdFlash(self
):
587 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdFlash
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
588 EdkLogger
.quiet("Checking only Flash related PCDs are used in FDF ...")
590 select ID, Value2, BelongsToFile from Fdf as A
591 where A.Model >= %s and Model < %s
593 and A.Value2 not like '%%Flash%%'
594 """% (MODEL_PCD
, MODEL_META_DATA_HEADER
)
595 RecordSet
= EccGlobalData
.gDb
.TblFdf
.Exec(SqlCommand
)
596 for Record
in RecordSet
:
597 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_FLASH
, Record
[1]):
598 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])
600 # Check whether PCDs used in Inf files but not specified in Dsc or FDF files
601 def MetaDataFileCheckPcdNoUse(self
):
602 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdNoUse
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
603 EdkLogger
.quiet("Checking for non-specified PCDs ...")
605 select ID, Value2, BelongsToFile from Inf as A
606 where A.Model >= %s and Model < %s
609 (select Value2 from Dsc as B
610 where B.Model >= %s and B.Model < %s
613 (select Value2 from Fdf as C
614 where C.Model >= %s and C.Model < %s
616 """% (MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
)
617 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
618 for Record
in RecordSet
:
619 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE
, Record
[1]):
620 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])
622 # Check whether having duplicate guids defined for Guid/Protocol/Ppi
623 def MetaDataFileCheckGuidDuplicate(self
):
624 if EccGlobalData
.gConfig
.MetaDataFileCheckGuidDuplicate
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
625 EdkLogger
.quiet("Checking for duplicate GUID/PPI/PROTOCOL ...")
627 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID
, MODEL_EFI_GUID
, EccGlobalData
.gDb
.TblDec
)
628 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID
, MODEL_EFI_GUID
, EccGlobalData
.gDb
.TblDsc
)
629 self
.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID
, MODEL_EFI_GUID
)
631 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL
, MODEL_EFI_PROTOCOL
, EccGlobalData
.gDb
.TblDec
)
632 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL
, MODEL_EFI_PROTOCOL
, EccGlobalData
.gDb
.TblDsc
)
633 self
.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL
, MODEL_EFI_PROTOCOL
)
635 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI
, MODEL_EFI_PPI
, EccGlobalData
.gDb
.TblDec
)
636 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI
, MODEL_EFI_PPI
, EccGlobalData
.gDb
.TblDsc
)
637 self
.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI
, MODEL_EFI_PPI
)
639 # Check whether all files under module directory are described in INF files
640 def MetaDataFileCheckModuleFileNoUse(self
):
641 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFileNoUse
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
642 EdkLogger
.quiet("Checking for no used module files ...")
644 select upper(Path) from File where ID in (select BelongsToFile from INF where BelongsToFile != -1)
646 InfPathSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
648 for Item
in InfPathSet
:
649 if Item
[0] not in InfPathList
:
650 InfPathList
.append(Item
[0])
652 select ID, Path, FullPath from File where upper(FullPath) not in
653 (select upper(A.Path) || '\\' || upper(B.Value1) from File as A, INF as B
654 where A.ID in (select BelongsToFile from INF where Model = %s group by BelongsToFile) and
655 B.BelongsToFile = A.ID and B.Model = %s)
656 and (Model = %s or Model = %s)
657 """ % (MODEL_EFI_SOURCE_FILE
, MODEL_EFI_SOURCE_FILE
, MODEL_FILE_C
, MODEL_FILE_H
)
658 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
659 for Record
in RecordSet
:
661 Path
= Path
.upper().replace('\X64', '').replace('\IA32', '').replace('\EBC', '').replace('\IPF', '').replace('\ARM', '')
662 if Path
in InfPathList
:
663 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE
, Record
[2]):
664 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])
666 # Check whether the PCD is correctly used in C function via its type
667 def MetaDataFileCheckPcdType(self
):
668 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdType
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
669 EdkLogger
.quiet("Checking for pcd type in c code function usage ...")
671 select ID, Model, Value1, BelongsToFile from INF where Model > %s and Model < %s
672 """ % (MODEL_PCD
, MODEL_META_DATA_HEADER
)
673 PcdSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
677 if len(Pcd
[2].split(".")) > 1:
678 PcdName
= Pcd
[2].split(".")[1]
679 BelongsToFile
= Pcd
[3]
681 select ID from File where FullPath in
682 (select B.Path || '\\' || A.Value1 from INF as A, File as B where A.Model = %s and A.BelongsToFile = %s
684 """ %(MODEL_EFI_SOURCE_FILE
, BelongsToFile
, BelongsToFile
)
685 TableSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
687 TblName
= 'Identifier' + str(Tbl
[0])
689 select Name, ID from %s where value like '%s' and Model = %s
690 """ % (TblName
, PcdName
, MODEL_IDENTIFIER_FUNCTION_CALLING
)
691 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
692 TblNumber
= TblName
.replace('Identifier', '')
693 for Record
in RecordSet
:
695 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_TYPE
, FunName
):
696 if Model
in [MODEL_PCD_FIXED_AT_BUILD
] and not FunName
.startswith('FixedPcdGet'):
697 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])
698 if Model
in [MODEL_PCD_FEATURE_FLAG
] and (not FunName
.startswith('FeaturePcdGet') and not FunName
.startswith('FeaturePcdSet')):
699 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])
700 if Model
in [MODEL_PCD_PATCHABLE_IN_MODULE
] and (not FunName
.startswith('PatchablePcdGet') and not FunName
.startswith('PatchablePcdSet')):
701 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])
703 #ERROR_META_DATA_FILE_CHECK_PCD_TYPE
706 # Internal worker function to get the INF workspace relative path from FileID
707 def GetInfFilePathFromID(self
, FileID
):
708 Table
= EccGlobalData
.gDb
.TblFile
709 SqlCommand
= """select A.FullPath from %s as A where A.ID = %s""" % (Table
.Table
, FileID
)
710 RecordSet
= Table
.Exec(SqlCommand
)
712 for Record
in RecordSet
:
713 Path
= Record
[0].replace(EccGlobalData
.gWorkspace
, '')
714 if Path
.startswith('\\') or Path
.startswith('/'):
718 # Check whether two module INFs under one workspace has the same FILE_GUID value
719 def MetaDataFileCheckModuleFileGuidDuplication(self
):
720 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFileGuidDuplication
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
721 EdkLogger
.quiet("Checking for pcd type in c code function usage ...")
722 Table
= EccGlobalData
.gDb
.TblInf
724 select A.ID, A.Value2, A.BelongsToFile, B.BelongsToFile from %s as A, %s as B
725 where A.Value1 = 'FILE_GUID' and B.Value1 = 'FILE_GUID' and
726 A.Value2 = B.Value2 and A.ID <> B.ID group by A.ID
727 """ % (Table
.Table
, Table
.Table
)
728 RecordSet
= Table
.Exec(SqlCommand
)
729 for Record
in RecordSet
:
730 InfPath1
= self
.GetInfFilePathFromID(Record
[2])
731 InfPath2
= self
.GetInfFilePathFromID(Record
[3])
732 if InfPath1
and InfPath2
:
733 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION
, InfPath1
):
734 Msg
= "The FILE_GUID of INF file [%s] is duplicated with that of %s" % (InfPath1
, InfPath2
)
735 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION
, OtherMsg
= Msg
, BelongsToTable
= Table
.Table
, BelongsToItem
= Record
[0])
738 # Check whether these is duplicate Guid/Ppi/Protocol name
739 def CheckGuidProtocolPpi(self
, ErrorID
, Model
, Table
):
741 if Model
== MODEL_EFI_GUID
:
743 if Model
== MODEL_EFI_PROTOCOL
:
745 if Model
== MODEL_EFI_PPI
:
748 select A.ID, A.Value1 from %s as A, %s as B
749 where A.Model = %s and B.Model = %s
750 and A.Value1 = B.Value1 and A.ID <> B.ID
754 """ % (Table
.Table
, Table
.Table
, Model
, Model
)
755 RecordSet
= Table
.Exec(SqlCommand
)
756 for Record
in RecordSet
:
757 if not EccGlobalData
.gException
.IsException(ErrorID
, Record
[1]):
758 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])
760 # Check whether these is duplicate Guid/Ppi/Protocol value
761 def CheckGuidProtocolPpiValue(self
, ErrorID
, Model
):
763 Table
= EccGlobalData
.gDb
.TblDec
764 if Model
== MODEL_EFI_GUID
:
766 if Model
== MODEL_EFI_PROTOCOL
:
768 if Model
== MODEL_EFI_PPI
:
771 select A.ID, A.Value2 from %s as A, %s as B
772 where A.Model = %s and B.Model = %s
773 and A.Value2 = B.Value2 and A.ID <> B.ID
775 """ % (Table
.Table
, Table
.Table
, Model
, Model
)
776 RecordSet
= Table
.Exec(SqlCommand
)
777 for Record
in RecordSet
:
778 if not EccGlobalData
.gException
.IsException(ErrorID
, Record
[1]):
779 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])
781 # Naming Convention Check
782 def NamingConventionCheck(self
):
783 if EccGlobalData
.gConfig
.NamingConventionCheckDefineStatement
== '1' \
784 or EccGlobalData
.gConfig
.NamingConventionCheckTypedefStatement
== '1' \
785 or EccGlobalData
.gConfig
.NamingConventionCheckIfndefStatement
== '1' \
786 or EccGlobalData
.gConfig
.NamingConventionCheckVariableName
== '1' \
787 or EccGlobalData
.gConfig
.NamingConventionCheckSingleCharacterVariable
== '1' \
788 or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1'\
789 or EccGlobalData
.gConfig
.CheckAll
== '1':
790 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
792 if os
.path
.splitext(F
)[1] in ('.h', '.c'):
793 FullName
= os
.path
.join(Dirpath
, F
)
794 Id
= c
.GetTableID(FullName
)
797 FileTable
= 'Identifier' + str(Id
)
798 self
.NamingConventionCheckDefineStatement(FileTable
)
799 self
.NamingConventionCheckTypedefStatement(FileTable
)
800 self
.NamingConventionCheckIfndefStatement(FileTable
)
801 self
.NamingConventionCheckVariableName(FileTable
)
802 self
.NamingConventionCheckSingleCharacterVariable(FileTable
)
804 self
.NamingConventionCheckPathName()
805 self
.NamingConventionCheckFunctionName()
807 # Check whether only capital letters are used for #define declarations
808 def NamingConventionCheckDefineStatement(self
, FileTable
):
809 if EccGlobalData
.gConfig
.NamingConventionCheckDefineStatement
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
810 EdkLogger
.quiet("Checking naming covention of #define statement ...")
812 SqlCommand
= """select ID, Value from %s where Model = %s""" %(FileTable
, MODEL_IDENTIFIER_MACRO_DEFINE
)
813 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
814 for Record
in RecordSet
:
815 Name
= Record
[1].strip().split()[1]
816 if Name
.find('(') != -1:
817 Name
= Name
[0:Name
.find('(')]
818 if Name
.upper() != Name
:
819 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT
, Name
):
820 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])
822 # Check whether only capital letters are used for typedef declarations
823 def NamingConventionCheckTypedefStatement(self
, FileTable
):
824 if EccGlobalData
.gConfig
.NamingConventionCheckTypedefStatement
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
825 EdkLogger
.quiet("Checking naming covention of #typedef statement ...")
827 SqlCommand
= """select ID, Name from %s where Model = %s""" %(FileTable
, MODEL_IDENTIFIER_TYPEDEF
)
828 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
829 for Record
in RecordSet
:
830 Name
= Record
[1].strip()
831 if Name
!= '' and Name
!= None:
833 Name
= Name
[1:Name
.find(')')]
834 if Name
.find('(') > -1:
835 Name
= Name
[Name
.find('(') + 1 : Name
.find(')')]
836 Name
= Name
.replace('WINAPI', '')
837 Name
= Name
.replace('*', '').strip()
838 if Name
.upper() != Name
:
839 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT
, Name
):
840 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])
842 # Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'.
843 def NamingConventionCheckIfndefStatement(self
, FileTable
):
844 if EccGlobalData
.gConfig
.NamingConventionCheckTypedefStatement
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
845 EdkLogger
.quiet("Checking naming covention of #ifndef statement ...")
847 SqlCommand
= """select ID, Value from %s where Model = %s""" %(FileTable
, MODEL_IDENTIFIER_MACRO_IFNDEF
)
848 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
849 for Record
in RecordSet
:
850 Name
= Record
[1].replace('#ifndef', '').strip()
851 if Name
[0] != '_' or Name
[-1] != '_':
852 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT
, Name
):
853 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])
855 # Rule for path name, variable name and function name
856 # 1. First character should be upper case
857 # 2. Existing lower case in a word
858 # 3. No space existence
859 # Check whether the path name followed the rule
860 def NamingConventionCheckPathName(self
):
861 if EccGlobalData
.gConfig
.NamingConventionCheckPathName
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
862 EdkLogger
.quiet("Checking naming covention of file path name ...")
863 Pattern
= re
.compile(r
'^[A-Z]+\S*[a-z]\S*$')
864 SqlCommand
= """select ID, Name from File"""
865 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
866 for Record
in RecordSet
:
867 if not Pattern
.match(Record
[1]):
868 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_PATH_NAME
, Record
[1]):
869 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])
871 # Rule for path name, variable name and function name
872 # 1. First character should be upper case
873 # 2. Existing lower case in a word
874 # 3. No space existence
875 # 4. Global variable name must start with a 'g'
876 # Check whether the variable name followed the rule
877 def NamingConventionCheckVariableName(self
, FileTable
):
878 if EccGlobalData
.gConfig
.NamingConventionCheckVariableName
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
879 EdkLogger
.quiet("Checking naming covention of variable name ...")
880 Pattern
= re
.compile(r
'^[A-Zgm]+\S*[a-z]\S*$')
882 SqlCommand
= """select ID, Name from %s where Model = %s""" %(FileTable
, MODEL_IDENTIFIER_VARIABLE
)
883 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
884 for Record
in RecordSet
:
885 if not Pattern
.match(Record
[1]):
886 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME
, Record
[1]):
887 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])
889 # Rule for path name, variable name and function name
890 # 1. First character should be upper case
891 # 2. Existing lower case in a word
892 # 3. No space existence
893 # Check whether the function name followed the rule
894 def NamingConventionCheckFunctionName(self
):
895 if EccGlobalData
.gConfig
.NamingConventionCheckFunctionName
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
896 EdkLogger
.quiet("Checking naming covention of function name ...")
897 Pattern
= re
.compile(r
'^[A-Z]+\S*[a-z]\S*$')
898 SqlCommand
= """select ID, Name from Function"""
899 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
900 for Record
in RecordSet
:
901 if not Pattern
.match(Record
[1]):
902 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME
, Record
[1]):
903 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])
905 # Check whether NO use short variable name with single character
906 def NamingConventionCheckSingleCharacterVariable(self
, FileTable
):
907 if EccGlobalData
.gConfig
.NamingConventionCheckSingleCharacterVariable
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
908 EdkLogger
.quiet("Checking naming covention of single character variable name ...")
910 SqlCommand
= """select ID, Name from %s where Model = %s""" %(FileTable
, MODEL_IDENTIFIER_VARIABLE
)
911 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
912 for Record
in RecordSet
:
913 Variable
= Record
[1].replace('*', '')
914 if len(Variable
) == 1:
915 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE
, Record
[1]):
916 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])
920 # This acts like the main() function for the script, unless it is 'import'ed into another
923 if __name__
== '__main__':