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
34 self
.MetaDataFileCheck()
36 self
.IncludeFileCheck()
37 self
.PredicateExpressionCheck()
38 self
.DeclAndDataTypeCheck()
39 self
.FunctionLayoutCheck()
40 self
.NamingConventionCheck()
43 def GeneralCheck(self
):
44 self
.GeneralCheckNonAcsii()
46 # Check whether file has non ACSII char
47 def GeneralCheckNonAcsii(self
):
48 if EccGlobalData
.gConfig
.GeneralCheckNonAcsii
== '1' or EccGlobalData
.gConfig
.GeneralCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
49 EdkLogger
.quiet("Checking Non-ACSII char in file ...")
50 SqlCommand
= """select ID, FullPath, ExtName from File"""
51 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
52 for Record
in RecordSet
:
53 if Record
[2].upper() not in EccGlobalData
.gConfig
.BinaryExtList
:
54 op
= open(Record
[1]).readlines()
62 OtherMsg
= "File %s has Non-ASCII char at line %s column %s" %(Record
[1], IndexOfLine
, IndexOfChar
)
63 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_GENERAL_CHECK_NON_ACSII
, OtherMsg
= OtherMsg
, BelongsToTable
= 'File', BelongsToItem
= Record
[0])
65 # C Function Layout Checking
66 def FunctionLayoutCheck(self
):
67 self
.FunctionLayoutCheckReturnType()
68 self
.FunctionLayoutCheckModifier()
69 self
.FunctionLayoutCheckName()
70 self
.FunctionLayoutCheckPrototype()
71 self
.FunctionLayoutCheckBody()
72 self
.FunctionLayoutCheckLocalVariable()
75 IgnoredPattern
= c
.GetIgnoredDirListPattern()
76 for Dirpath
, Dirnames
, Filenames
in os
.walk(EccGlobalData
.gTarget
):
78 Dirname
= os
.path
.join(Dirpath
, Dir
)
79 if os
.path
.islink(Dirname
):
80 Dirname
= os
.path
.realpath(Dirname
)
81 if os
.path
.isdir(Dirname
):
82 # symlinks to directories are treated as directories
84 Dirnames
.append(Dirname
)
85 if IgnoredPattern
.match(Dirpath
.upper()):
87 yield (Dirpath
, Dirnames
, Filenames
)
89 # Check whether return type exists and in the first line
90 def FunctionLayoutCheckReturnType(self
):
91 if EccGlobalData
.gConfig
.CFunctionLayoutCheckReturnType
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
92 EdkLogger
.quiet("Checking function layout return type ...")
94 # for Dirpath, Dirnames, Filenames in self.WalkTree():
96 # if os.path.splitext(F)[1] in ('.c', '.h'):
97 # FullName = os.path.join(Dirpath, F)
98 # c.CheckFuncLayoutReturnType(FullName)
99 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
100 c
.CheckFuncLayoutReturnType(FullName
)
102 # Check whether any optional functional modifiers exist and next to the return type
103 def FunctionLayoutCheckModifier(self
):
104 if EccGlobalData
.gConfig
.CFunctionLayoutCheckOptionalFunctionalModifier
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
105 EdkLogger
.quiet("Checking function layout modifier ...")
107 # for Dirpath, Dirnames, Filenames in self.WalkTree():
108 # for F in Filenames:
109 # if os.path.splitext(F)[1] in ('.c', '.h'):
110 # FullName = os.path.join(Dirpath, F)
111 # c.CheckFuncLayoutModifier(FullName)
112 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
113 c
.CheckFuncLayoutModifier(FullName
)
115 # Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list
116 # Check whether the closing parenthesis is on its own line and also indented two spaces
117 def FunctionLayoutCheckName(self
):
118 if EccGlobalData
.gConfig
.CFunctionLayoutCheckFunctionName
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
119 EdkLogger
.quiet("Checking function layout function name ...")
121 # for Dirpath, Dirnames, Filenames in self.WalkTree():
122 # for F in Filenames:
123 # if os.path.splitext(F)[1] in ('.c', '.h'):
124 # FullName = os.path.join(Dirpath, F)
125 # c.CheckFuncLayoutName(FullName)
126 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
127 c
.CheckFuncLayoutName(FullName
)
129 # Check whether the function prototypes in include files have the same form as function definitions
130 def FunctionLayoutCheckPrototype(self
):
131 if EccGlobalData
.gConfig
.CFunctionLayoutCheckFunctionPrototype
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
132 EdkLogger
.quiet("Checking function layout function prototype ...")
134 # for Dirpath, Dirnames, Filenames in self.WalkTree():
135 # for F in Filenames:
136 # if os.path.splitext(F)[1] in ('.c'):
137 # FullName = os.path.join(Dirpath, F)
138 # EdkLogger.quiet("[PROTOTYPE]" + FullName)
139 # c.CheckFuncLayoutPrototype(FullName)
140 for FullName
in EccGlobalData
.gCFileList
:
141 EdkLogger
.quiet("[PROTOTYPE]" + FullName
)
142 c
.CheckFuncLayoutPrototype(FullName
)
144 # Check whether the body of a function is contained by open and close braces that must be in the first column
145 def FunctionLayoutCheckBody(self
):
146 if EccGlobalData
.gConfig
.CFunctionLayoutCheckFunctionBody
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
147 EdkLogger
.quiet("Checking function layout function body ...")
149 # for Dirpath, Dirnames, Filenames in self.WalkTree():
150 # for F in Filenames:
151 # if os.path.splitext(F)[1] in ('.c'):
152 # FullName = os.path.join(Dirpath, F)
153 # c.CheckFuncLayoutBody(FullName)
154 for FullName
in EccGlobalData
.gCFileList
:
155 c
.CheckFuncLayoutBody(FullName
)
157 # Check whether the data declarations is the first code in a module.
158 # self.CFunctionLayoutCheckDataDeclaration = 1
159 # Check whether no initialization of a variable as part of its declaration
160 def FunctionLayoutCheckLocalVariable(self
):
161 if EccGlobalData
.gConfig
.CFunctionLayoutCheckNoInitOfVariable
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
162 EdkLogger
.quiet("Checking function layout local variables ...")
164 # for Dirpath, Dirnames, Filenames in self.WalkTree():
165 # for F in Filenames:
166 # if os.path.splitext(F)[1] in ('.c'):
167 # FullName = os.path.join(Dirpath, F)
168 # c.CheckFuncLayoutLocalVariable(FullName)
170 for FullName
in EccGlobalData
.gCFileList
:
171 c
.CheckFuncLayoutLocalVariable(FullName
)
173 # Check whether no use of STATIC for functions
174 # self.CFunctionLayoutCheckNoStatic = 1
176 # Declarations and Data Types Checking
177 def DeclAndDataTypeCheck(self
):
178 self
.DeclCheckNoUseCType()
179 self
.DeclCheckInOutModifier()
180 self
.DeclCheckEFIAPIModifier()
181 self
.DeclCheckEnumeratedType()
182 self
.DeclCheckStructureDeclaration()
183 self
.DeclCheckSameStructure()
184 self
.DeclCheckUnionType()
187 # Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files.
188 def DeclCheckNoUseCType(self
):
189 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckNoUseCType
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
190 EdkLogger
.quiet("Checking Declaration No use C type ...")
192 # for Dirpath, Dirnames, Filenames in self.WalkTree():
193 # for F in Filenames:
194 # if os.path.splitext(F)[1] in ('.h', '.c'):
195 # FullName = os.path.join(Dirpath, F)
196 # c.CheckDeclNoUseCType(FullName)
197 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
198 c
.CheckDeclNoUseCType(FullName
)
200 # 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
201 def DeclCheckInOutModifier(self
):
202 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckInOutModifier
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
203 EdkLogger
.quiet("Checking Declaration argument modifier ...")
205 # for Dirpath, Dirnames, Filenames in self.WalkTree():
206 # for F in Filenames:
207 # if os.path.splitext(F)[1] in ('.h', '.c'):
208 # FullName = os.path.join(Dirpath, F)
209 # c.CheckDeclArgModifier(FullName)
210 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
211 c
.CheckDeclArgModifier(FullName
)
213 # Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols
214 def DeclCheckEFIAPIModifier(self
):
215 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckEFIAPIModifier
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
218 # Check whether Enumerated Type has a 'typedef' and the name is capital
219 def DeclCheckEnumeratedType(self
):
220 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckEnumeratedType
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
221 EdkLogger
.quiet("Checking Declaration enum typedef ...")
223 # for Dirpath, Dirnames, Filenames in self.WalkTree():
224 # for F in Filenames:
225 # if os.path.splitext(F)[1] in ('.h', '.c'):
226 # FullName = os.path.join(Dirpath, F)
227 # EdkLogger.quiet("[ENUM]" + FullName)
228 # c.CheckDeclEnumTypedef(FullName)
229 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
230 EdkLogger
.quiet("[ENUM]" + FullName
)
231 c
.CheckDeclEnumTypedef(FullName
)
233 # Check whether Structure Type has a 'typedef' and the name is capital
234 def DeclCheckStructureDeclaration(self
):
235 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckStructureDeclaration
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
236 EdkLogger
.quiet("Checking Declaration struct typedef ...")
238 # for Dirpath, Dirnames, Filenames in self.WalkTree():
239 # for F in Filenames:
240 # if os.path.splitext(F)[1] in ('.h', '.c'):
241 # FullName = os.path.join(Dirpath, F)
242 # EdkLogger.quiet("[STRUCT]" + FullName)
243 # c.CheckDeclStructTypedef(FullName)
244 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
245 EdkLogger
.quiet("[STRUCT]" + FullName
)
246 c
.CheckDeclStructTypedef(FullName
)
248 # Check whether having same Structure
249 def DeclCheckSameStructure(self
):
250 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckSameStructure
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
251 EdkLogger
.quiet("Checking same struct ...")
253 for IdentifierTable
in EccGlobalData
.gIdentifierTableList
:
254 SqlCommand
= """select ID, Name, BelongsToFile from %s where Model = %s""" %(IdentifierTable
, MODEL_IDENTIFIER_STRUCTURE
)
255 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
256 for Record
in RecordSet
:
258 if Record
[1] not in AllStructure
.keys():
259 AllStructure
[Record
[1]] = Record
[2]
261 ID
= AllStructure
[Record
[1]]
262 SqlCommand
= """select FullPath from File where ID = %s """ % ID
263 NewRecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
264 OtherMsg
= "The structure name '%s' is duplicate" % Record
[1]
265 if NewRecordSet
!= []:
266 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])
267 if not EccGlobalData
.gException
.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE
, Record
[1]):
268 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE
, OtherMsg
= OtherMsg
, BelongsToTable
= IdentifierTable
, BelongsToItem
= Record
[0])
270 # Check whether Union Type has a 'typedef' and the name is capital
271 def DeclCheckUnionType(self
):
272 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckUnionType
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
273 EdkLogger
.quiet("Checking Declaration union typedef ...")
275 # for Dirpath, Dirnames, Filenames in self.WalkTree():
276 # for F in Filenames:
277 # if os.path.splitext(F)[1] in ('.h', '.c'):
278 # FullName = os.path.join(Dirpath, F)
279 # EdkLogger.quiet("[UNION]" + FullName)
280 # c.CheckDeclUnionTypedef(FullName)
281 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
282 EdkLogger
.quiet("[UNION]" + FullName
)
283 c
.CheckDeclUnionTypedef(FullName
)
285 # Predicate Expression Checking
286 def PredicateExpressionCheck(self
):
287 self
.PredicateExpressionCheckBooleanValue()
288 self
.PredicateExpressionCheckNonBooleanOperator()
289 self
.PredicateExpressionCheckComparisonNullType()
291 # Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE
292 def PredicateExpressionCheckBooleanValue(self
):
293 if EccGlobalData
.gConfig
.PredicateExpressionCheckBooleanValue
== '1' or EccGlobalData
.gConfig
.PredicateExpressionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
294 EdkLogger
.quiet("Checking predicate expression Boolean value ...")
296 # for Dirpath, Dirnames, Filenames in self.WalkTree():
297 # for F in Filenames:
298 # if os.path.splitext(F)[1] in ('.c'):
299 # FullName = os.path.join(Dirpath, F)
300 # EdkLogger.quiet("[BOOLEAN]" + FullName)
301 # c.CheckBooleanValueComparison(FullName)
302 for FullName
in EccGlobalData
.gCFileList
:
303 EdkLogger
.quiet("[BOOLEAN]" + FullName
)
304 c
.CheckBooleanValueComparison(FullName
)
306 # Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=).
307 def PredicateExpressionCheckNonBooleanOperator(self
):
308 if EccGlobalData
.gConfig
.PredicateExpressionCheckNonBooleanOperator
== '1' or EccGlobalData
.gConfig
.PredicateExpressionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
309 EdkLogger
.quiet("Checking predicate expression Non-Boolean variable...")
311 # for Dirpath, Dirnames, Filenames in self.WalkTree():
312 # for F in Filenames:
313 # if os.path.splitext(F)[1] in ('.c'):
314 # FullName = os.path.join(Dirpath, F)
315 # EdkLogger.quiet("[NON-BOOLEAN]" + FullName)
316 # c.CheckNonBooleanValueComparison(FullName)
317 for FullName
in EccGlobalData
.gCFileList
:
318 EdkLogger
.quiet("[NON-BOOLEAN]" + FullName
)
319 c
.CheckNonBooleanValueComparison(FullName
)
321 # Check whether a comparison of any pointer to zero must be done via the NULL type
322 def PredicateExpressionCheckComparisonNullType(self
):
323 if EccGlobalData
.gConfig
.PredicateExpressionCheckComparisonNullType
== '1' or EccGlobalData
.gConfig
.PredicateExpressionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
324 EdkLogger
.quiet("Checking predicate expression NULL pointer ...")
326 # for Dirpath, Dirnames, Filenames in self.WalkTree():
327 # for F in Filenames:
328 # if os.path.splitext(F)[1] in ('.c'):
329 # FullName = os.path.join(Dirpath, F)
330 # EdkLogger.quiet("[POINTER]" + FullName)
331 # c.CheckPointerNullComparison(FullName)
332 for FullName
in EccGlobalData
.gCFileList
:
333 EdkLogger
.quiet("[POINTER]" + FullName
)
334 c
.CheckPointerNullComparison(FullName
)
336 # Include file checking
337 def IncludeFileCheck(self
):
338 self
.IncludeFileCheckIfndef()
339 self
.IncludeFileCheckData()
340 self
.IncludeFileCheckSameName()
342 # Check whether having include files with same name
343 def IncludeFileCheckSameName(self
):
344 if EccGlobalData
.gConfig
.IncludeFileCheckSameName
== '1' or EccGlobalData
.gConfig
.IncludeFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
345 EdkLogger
.quiet("Checking same header file name ...")
346 SqlCommand
= """select ID, FullPath from File
347 where Model = 1002 order by Name """
349 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
350 for Record
in RecordSet
:
351 List
= Record
[1].replace('/', '\\').split('\\')
353 Key
= List
[-2] + '\\' + List
[-1]
356 if Key
not in RecordDict
:
357 RecordDict
[Key
] = [Record
]
359 RecordDict
[Key
].append(Record
)
361 for Key
in RecordDict
:
362 if len(RecordDict
[Key
]) > 1:
363 for Item
in RecordDict
[Key
]:
364 Path
= Item
[1].replace(EccGlobalData
.gWorkspace
, '')
365 if Path
.startswith('\\') or Path
.startswith('/'):
367 if not EccGlobalData
.gException
.IsException(ERROR_INCLUDE_FILE_CHECK_NAME
, Path
):
368 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_INCLUDE_FILE_CHECK_NAME
, OtherMsg
= "The file name for [%s] is duplicate" % Path
, BelongsToTable
= 'File', BelongsToItem
= Item
[0])
370 # Check whether all include file contents is guarded by a #ifndef statement.
371 def IncludeFileCheckIfndef(self
):
372 if EccGlobalData
.gConfig
.IncludeFileCheckIfndefStatement
== '1' or EccGlobalData
.gConfig
.IncludeFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
373 EdkLogger
.quiet("Checking header file ifndef ...")
375 # for Dirpath, Dirnames, Filenames in self.WalkTree():
376 # for F in Filenames:
377 # if os.path.splitext(F)[1] in ('.h'):
378 # FullName = os.path.join(Dirpath, F)
379 # MsgList = c.CheckHeaderFileIfndef(FullName)
380 for FullName
in EccGlobalData
.gHFileList
:
381 MsgList
= c
.CheckHeaderFileIfndef(FullName
)
383 # Check whether include files NOT contain code or define data variables
384 def IncludeFileCheckData(self
):
385 if EccGlobalData
.gConfig
.IncludeFileCheckData
== '1' or EccGlobalData
.gConfig
.IncludeFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
386 EdkLogger
.quiet("Checking header file data ...")
388 # for Dirpath, Dirnames, Filenames in self.WalkTree():
389 # for F in Filenames:
390 # if os.path.splitext(F)[1] in ('.h'):
391 # FullName = os.path.join(Dirpath, F)
392 # MsgList = c.CheckHeaderFileData(FullName)
393 for FullName
in EccGlobalData
.gHFileList
:
394 MsgList
= c
.CheckHeaderFileData(FullName
)
396 # Doxygen document checking
397 def DoxygenCheck(self
):
398 self
.DoxygenCheckFileHeader()
399 self
.DoxygenCheckFunctionHeader()
400 self
.DoxygenCheckCommentDescription()
401 self
.DoxygenCheckCommentFormat()
402 self
.DoxygenCheckCommand()
404 # Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5
405 def DoxygenCheckFileHeader(self
):
406 if EccGlobalData
.gConfig
.DoxygenCheckFileHeader
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
407 EdkLogger
.quiet("Checking Doxygen file header ...")
409 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
411 Ext
= os
.path
.splitext(F
)[1]
412 if Ext
in ('.h', '.c'):
413 FullName
= os
.path
.join(Dirpath
, F
)
414 MsgList
= c
.CheckFileHeaderDoxygenComments(FullName
)
415 elif Ext
in ('.inf', '.dec', '.dsc', '.fdf'):
416 FullName
= os
.path
.join(Dirpath
, F
)
417 op
= open(FullName
).readlines()
418 if not op
[0].startswith('## @file') and op
[6].startswith('## @file') and op
[7].startswith('## @file'):
419 SqlStatement
= """ select ID from File where FullPath like '%s'""" % FullName
420 ResultSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlStatement
)
421 for Result
in ResultSet
:
422 Msg
= 'INF/DEC/DSC/FDF file header comment should begin with ""## @file""'
423 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER
, Msg
, "File", Result
[0])
426 # Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5
427 def DoxygenCheckFunctionHeader(self
):
428 if EccGlobalData
.gConfig
.DoxygenCheckFunctionHeader
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
429 EdkLogger
.quiet("Checking Doxygen function header ...")
431 # for Dirpath, Dirnames, Filenames in self.WalkTree():
432 # for F in Filenames:
433 # if os.path.splitext(F)[1] in ('.h', '.c'):
434 # FullName = os.path.join(Dirpath, F)
435 # MsgList = c.CheckFuncHeaderDoxygenComments(FullName)
436 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
437 MsgList
= c
.CheckFuncHeaderDoxygenComments(FullName
)
440 # Check whether the first line of text in a comment block is a brief description of the element being documented.
441 # The brief description must end with a period.
442 def DoxygenCheckCommentDescription(self
):
443 if EccGlobalData
.gConfig
.DoxygenCheckCommentDescription
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
446 # Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.
447 def DoxygenCheckCommentFormat(self
):
448 if EccGlobalData
.gConfig
.DoxygenCheckCommentFormat
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
449 EdkLogger
.quiet("Checking Doxygen comment ///< ...")
451 # for Dirpath, Dirnames, Filenames in self.WalkTree():
452 # for F in Filenames:
453 # if os.path.splitext(F)[1] in ('.h', '.c'):
454 # FullName = os.path.join(Dirpath, F)
455 # MsgList = c.CheckDoxygenTripleForwardSlash(FullName)
456 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
457 MsgList
= c
.CheckDoxygenTripleForwardSlash(FullName
)
459 # Check whether only Doxygen commands allowed to mark the code are @bug and @todo.
460 def DoxygenCheckCommand(self
):
461 if EccGlobalData
.gConfig
.DoxygenCheckCommand
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
462 EdkLogger
.quiet("Checking Doxygen command ...")
464 # for Dirpath, Dirnames, Filenames in self.WalkTree():
465 # for F in Filenames:
466 # if os.path.splitext(F)[1] in ('.h', '.c'):
467 # FullName = os.path.join(Dirpath, F)
468 # MsgList = c.CheckDoxygenCommand(FullName)
469 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
470 MsgList
= c
.CheckDoxygenCommand(FullName
)
472 # Meta-Data File Processing Checking
473 def MetaDataFileCheck(self
):
474 self
.MetaDataFileCheckPathName()
475 self
.MetaDataFileCheckGenerateFileList()
476 self
.MetaDataFileCheckLibraryInstance()
477 self
.MetaDataFileCheckLibraryInstanceDependent()
478 self
.MetaDataFileCheckLibraryInstanceOrder()
479 self
.MetaDataFileCheckLibraryNoUse()
480 self
.MetaDataFileCheckBinaryInfInFdf()
481 self
.MetaDataFileCheckPcdDuplicate()
482 self
.MetaDataFileCheckPcdFlash()
483 self
.MetaDataFileCheckPcdNoUse()
484 self
.MetaDataFileCheckGuidDuplicate()
485 self
.MetaDataFileCheckModuleFileNoUse()
486 self
.MetaDataFileCheckPcdType()
487 self
.MetaDataFileCheckModuleFileGuidDuplication()
489 # Check whether each file defined in meta-data exists
490 def MetaDataFileCheckPathName(self
):
491 if EccGlobalData
.gConfig
.MetaDataFileCheckPathName
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
492 # This item is covered when parsing Inf/Dec/Dsc files
495 # Generate a list for all files defined in meta-data files
496 def MetaDataFileCheckGenerateFileList(self
):
497 if EccGlobalData
.gConfig
.MetaDataFileCheckGenerateFileList
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
498 # This item is covered when parsing Inf/Dec/Dsc files
501 # Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.
502 # Each Library Instance must specify the Supported Module Types in its Inf file,
503 # and any module specifying the library instance must be one of the supported types.
504 def MetaDataFileCheckLibraryInstance(self
):
505 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryInstance
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
506 EdkLogger
.quiet("Checking for library instance type issue ...")
507 SqlCommand
= """select A.ID, A.Value2, B.Value2 from Inf as A left join Inf as B
508 where A.Value1 = 'LIBRARY_CLASS' and A.Model = %s
509 and B.Value1 = 'MODULE_TYPE' and B.Model = %s and A.BelongsToFile = B.BelongsToFile
510 group by A.BelongsToFile""" % (MODEL_META_DATA_HEADER
, MODEL_META_DATA_HEADER
)
511 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
513 for Record
in RecordSet
:
514 List
= Record
[1].split('|', 1)
517 SupModType
= SUP_MODULE_LIST_STRING
.split(TAB_VALUE_SPLIT
)
519 SupModType
= List
[1].split()
521 if List
[0] not in LibraryClasses
:
522 LibraryClasses
[List
[0]] = SupModType
524 for Item
in SupModType
:
525 if Item
not in LibraryClasses
[List
[0]]:
526 LibraryClasses
[List
[0]].append(Item
)
528 if Record
[2] != 'BASE' and Record
[2] not in SupModType
:
529 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])
531 SqlCommand
= """select A.ID, A.Value1, B.Value2 from Inf as A left join Inf as B
532 where A.Model = %s and B.Value1 = '%s' and B.Model = %s
533 and B.BelongsToFile = A.BelongsToFile""" \
534 % (MODEL_EFI_LIBRARY_CLASS
, 'MODULE_TYPE', MODEL_META_DATA_HEADER
)
535 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
536 # Merge all LibraryClasses' supmodlist
538 for Record
in RecordSet
:
539 if Record
[1] not in RecordDict
:
540 RecordDict
[Record
[1]] = [str(Record
[2])]
542 if Record
[2] not in RecordDict
[Record
[1]]:
543 RecordDict
[Record
[1]].append(Record
[2])
545 for Record
in RecordSet
:
546 if Record
[1] in LibraryClasses
:
547 if Record
[2] not in LibraryClasses
[Record
[1]] and 'BASE' not in RecordDict
[Record
[1]]:
548 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1
, Record
[1]):
549 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])
551 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1
, Record
[1]):
552 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])
554 # Check whether a Library Instance has been defined for all dependent library classes
555 def MetaDataFileCheckLibraryInstanceDependent(self
):
556 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryInstanceDependent
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
557 EdkLogger
.quiet("Checking for library instance dependent issue ...")
558 SqlCommand
= """select ID, Value1, Value2 from Dsc where Model = %s""" % MODEL_EFI_LIBRARY_CLASS
559 LibraryClasses
= EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand
)
560 for LibraryClass
in LibraryClasses
:
561 if LibraryClass
[1].upper() != 'NULL':
562 LibraryIns
= os
.path
.normpath(os
.path
.join(EccGlobalData
.gWorkspace
, LibraryClass
[2]))
563 SqlCommand
= """select Value2 from Inf where BelongsToFile =
564 (select ID from File where lower(FullPath) = lower('%s'))
565 and Value1 = '%s'""" % (LibraryIns
, 'LIBRARY_CLASS')
566 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
568 for Record
in RecordSet
:
569 LibName
= Record
[0].split('|', 1)[0]
570 if LibraryClass
[1] == LibName
:
573 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT
, LibraryClass
[1]):
574 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])
576 # Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies
577 def MetaDataFileCheckLibraryInstanceOrder(self
):
578 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryInstanceOrder
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
579 # This checkpoint is not necessary for Ecc check
582 # Check whether the unnecessary inclusion of library classes in the Inf file
583 def MetaDataFileCheckLibraryNoUse(self
):
584 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryNoUse
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
585 EdkLogger
.quiet("Checking for library instance not used ...")
586 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
)
587 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
588 for Record
in RecordSet
:
589 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE
, Record
[1]):
590 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])
592 # 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
593 def MetaDataFileCheckBinaryInfInFdf(self
):
594 if EccGlobalData
.gConfig
.MetaDataFileCheckBinaryInfInFdf
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
595 EdkLogger
.quiet("Checking for non-binary modules defined in FDF files ...")
596 SqlCommand
= """select A.ID, A.Value1 from Fdf as A
600 (select B.Value1 from Dsc as B
602 and B.Enabled > -1)""" % (MODEL_META_DATA_COMPONENT
, MODEL_META_DATA_COMPONENT
)
603 RecordSet
= EccGlobalData
.gDb
.TblFdf
.Exec(SqlCommand
)
604 for Record
in RecordSet
:
607 FilePath
= os
.path
.normpath(os
.path
.join(EccGlobalData
.gWorkspace
, FilePath
))
608 SqlCommand
= """select ID from Inf where Model = %s and BelongsToFile = (select ID from File where FullPath like '%s')
609 """ % (MODEL_EFI_SOURCE_FILE
, FilePath
)
610 NewRecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
611 if NewRecordSet
!= []:
612 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF
, FilePath
):
613 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
)
615 # Check whether a PCD is set in a Dsc file or the FDF file, but not in both.
616 def MetaDataFileCheckPcdDuplicate(self
):
617 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdDuplicate
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
618 EdkLogger
.quiet("Checking for duplicate PCDs defined in both DSC and FDF files ...")
620 select A.ID, A.Value2, A.BelongsToFile, B.ID, B.Value2, B.BelongsToFile from Dsc as A, Fdf as B
621 where A.Model >= %s and A.Model < %s
622 and B.Model >= %s and B.Model < %s
623 and A.Value2 = B.Value2
627 """% (MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
)
628 RecordSet
= EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand
)
629 for Record
in RecordSet
:
630 SqlCommand1
= """select Name from File where ID = %s""" %Record
[2]
631 SqlCommand2
= """select Name from File where ID = %s""" %Record
[5]
632 DscFileName
= os
.path
.splitext(EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand1
)[0][0])[0]
633 FdfFileName
= os
.path
.splitext(EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand2
)[0][0])[0]
634 if DscFileName
!= FdfFileName
:
636 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE
, Record
[1]):
637 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])
638 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE
, Record
[3]):
639 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])
641 EdkLogger
.quiet("Checking for duplicate PCDs defined in DEC files ...")
643 select A.ID, A.Value2 from Dec as A, Dec as B
644 where A.Model >= %s and A.Model < %s
645 and B.Model >= %s and B.Model < %s
646 and A.Value2 = B.Value2
647 and ((A.Arch = B.Arch) and (A.Arch != 'COMMON' or B.Arch != 'COMMON'))
651 and A.BelongsToFile = B.BelongsToFile
653 """% (MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
)
654 RecordSet
= EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand
)
655 for Record
in RecordSet
:
656 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE
, Record
[1]):
657 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])
659 # Check whether PCD settings in the FDF file can only be related to flash.
660 def MetaDataFileCheckPcdFlash(self
):
661 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdFlash
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
662 EdkLogger
.quiet("Checking only Flash related PCDs are used in FDF ...")
664 select ID, Value2, BelongsToFile from Fdf as A
665 where A.Model >= %s and Model < %s
667 and A.Value2 not like '%%Flash%%'
668 """% (MODEL_PCD
, MODEL_META_DATA_HEADER
)
669 RecordSet
= EccGlobalData
.gDb
.TblFdf
.Exec(SqlCommand
)
670 for Record
in RecordSet
:
671 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_FLASH
, Record
[1]):
672 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])
674 # Check whether PCDs used in Inf files but not specified in Dsc or FDF files
675 def MetaDataFileCheckPcdNoUse(self
):
676 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdNoUse
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
677 EdkLogger
.quiet("Checking for non-specified PCDs ...")
679 select ID, Value2, BelongsToFile from Inf as A
680 where A.Model >= %s and Model < %s
683 (select Value2 from Dsc as B
684 where B.Model >= %s and B.Model < %s
687 (select Value2 from Fdf as C
688 where C.Model >= %s and C.Model < %s
690 """% (MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
)
691 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
692 for Record
in RecordSet
:
693 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE
, Record
[1]):
694 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])
696 # Check whether having duplicate guids defined for Guid/Protocol/Ppi
697 def MetaDataFileCheckGuidDuplicate(self
):
698 if EccGlobalData
.gConfig
.MetaDataFileCheckGuidDuplicate
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
699 EdkLogger
.quiet("Checking for duplicate GUID/PPI/PROTOCOL ...")
701 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID
, MODEL_EFI_GUID
, EccGlobalData
.gDb
.TblDec
)
702 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID
, MODEL_EFI_GUID
, EccGlobalData
.gDb
.TblDsc
)
703 self
.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID
, MODEL_EFI_GUID
)
705 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL
, MODEL_EFI_PROTOCOL
, EccGlobalData
.gDb
.TblDec
)
706 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL
, MODEL_EFI_PROTOCOL
, EccGlobalData
.gDb
.TblDsc
)
707 self
.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL
, MODEL_EFI_PROTOCOL
)
709 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI
, MODEL_EFI_PPI
, EccGlobalData
.gDb
.TblDec
)
710 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI
, MODEL_EFI_PPI
, EccGlobalData
.gDb
.TblDsc
)
711 self
.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI
, MODEL_EFI_PPI
)
713 # Check whether all files under module directory are described in INF files
714 def MetaDataFileCheckModuleFileNoUse(self
):
715 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFileNoUse
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
716 EdkLogger
.quiet("Checking for no used module files ...")
718 select upper(Path) from File where ID in (select BelongsToFile from INF where BelongsToFile != -1)
720 InfPathSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
722 for Item
in InfPathSet
:
723 if Item
[0] not in InfPathList
:
724 InfPathList
.append(Item
[0])
726 select ID, Path, FullPath from File where upper(FullPath) not in
727 (select upper(A.Path) || '\\' || upper(B.Value1) from File as A, INF as B
728 where A.ID in (select BelongsToFile from INF where Model = %s group by BelongsToFile) and
729 B.BelongsToFile = A.ID and B.Model = %s)
730 and (Model = %s or Model = %s)
731 """ % (MODEL_EFI_SOURCE_FILE
, MODEL_EFI_SOURCE_FILE
, MODEL_FILE_C
, MODEL_FILE_H
)
732 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
733 for Record
in RecordSet
:
735 Path
= Path
.upper().replace('\X64', '').replace('\IA32', '').replace('\EBC', '').replace('\IPF', '').replace('\ARM', '')
736 if Path
in InfPathList
:
737 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE
, Record
[2]):
738 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])
740 # Check whether the PCD is correctly used in C function via its type
741 def MetaDataFileCheckPcdType(self
):
742 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdType
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
743 EdkLogger
.quiet("Checking for pcd type in c code function usage ...")
745 select ID, Model, Value1, BelongsToFile from INF where Model > %s and Model < %s
746 """ % (MODEL_PCD
, MODEL_META_DATA_HEADER
)
747 PcdSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
751 if len(Pcd
[2].split(".")) > 1:
752 PcdName
= Pcd
[2].split(".")[1]
753 BelongsToFile
= Pcd
[3]
755 select ID from File where FullPath in
756 (select B.Path || '\\' || A.Value1 from INF as A, File as B where A.Model = %s and A.BelongsToFile = %s
757 and B.ID = %s and (B.Model = %s or B.Model = %s))
758 """ %(MODEL_EFI_SOURCE_FILE
, BelongsToFile
, BelongsToFile
, MODEL_FILE_C
, MODEL_FILE_H
)
759 TableSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
761 TblName
= 'Identifier' + str(Tbl
[0])
763 select Name, ID from %s where value like '%s' and Model = %s
764 """ % (TblName
, PcdName
, MODEL_IDENTIFIER_FUNCTION_CALLING
)
765 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
766 TblNumber
= TblName
.replace('Identifier', '')
767 for Record
in RecordSet
:
769 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_TYPE
, FunName
):
770 if Model
in [MODEL_PCD_FIXED_AT_BUILD
] and not FunName
.startswith('FixedPcdGet'):
771 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])
772 if Model
in [MODEL_PCD_FEATURE_FLAG
] and (not FunName
.startswith('FeaturePcdGet') and not FunName
.startswith('FeaturePcdSet')):
773 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])
774 if Model
in [MODEL_PCD_PATCHABLE_IN_MODULE
] and (not FunName
.startswith('PatchablePcdGet') and not FunName
.startswith('PatchablePcdSet')):
775 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])
777 #ERROR_META_DATA_FILE_CHECK_PCD_TYPE
780 # Internal worker function to get the INF workspace relative path from FileID
781 def GetInfFilePathFromID(self
, FileID
):
782 Table
= EccGlobalData
.gDb
.TblFile
783 SqlCommand
= """select A.FullPath from %s as A where A.ID = %s""" % (Table
.Table
, FileID
)
784 RecordSet
= Table
.Exec(SqlCommand
)
786 for Record
in RecordSet
:
787 Path
= Record
[0].replace(EccGlobalData
.gWorkspace
, '')
788 if Path
.startswith('\\') or Path
.startswith('/'):
792 # Check whether two module INFs under one workspace has the same FILE_GUID value
793 def MetaDataFileCheckModuleFileGuidDuplication(self
):
794 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFileGuidDuplication
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
795 EdkLogger
.quiet("Checking for pcd type in c code function usage ...")
796 Table
= EccGlobalData
.gDb
.TblInf
798 select A.ID, A.Value2, A.BelongsToFile, B.BelongsToFile from %s as A, %s as B
799 where A.Value1 = 'FILE_GUID' and B.Value1 = 'FILE_GUID' and
800 A.Value2 = B.Value2 and A.ID <> B.ID group by A.ID
801 """ % (Table
.Table
, Table
.Table
)
802 RecordSet
= Table
.Exec(SqlCommand
)
803 for Record
in RecordSet
:
804 InfPath1
= self
.GetInfFilePathFromID(Record
[2])
805 InfPath2
= self
.GetInfFilePathFromID(Record
[3])
806 if InfPath1
and InfPath2
:
807 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION
, InfPath1
):
808 Msg
= "The FILE_GUID of INF file [%s] is duplicated with that of %s" % (InfPath1
, InfPath2
)
809 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION
, OtherMsg
= Msg
, BelongsToTable
= Table
.Table
, BelongsToItem
= Record
[0])
812 # Check whether these is duplicate Guid/Ppi/Protocol name
813 def CheckGuidProtocolPpi(self
, ErrorID
, Model
, Table
):
815 if Model
== MODEL_EFI_GUID
:
817 if Model
== MODEL_EFI_PROTOCOL
:
819 if Model
== MODEL_EFI_PPI
:
822 select A.ID, A.Value1 from %s as A, %s as B
823 where A.Model = %s and B.Model = %s
824 and A.Value1 = B.Value1 and A.ID <> B.ID
828 """ % (Table
.Table
, Table
.Table
, Model
, Model
)
829 RecordSet
= Table
.Exec(SqlCommand
)
830 for Record
in RecordSet
:
831 if not EccGlobalData
.gException
.IsException(ErrorID
, Record
[1]):
832 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])
834 # Check whether these is duplicate Guid/Ppi/Protocol value
835 def CheckGuidProtocolPpiValue(self
, ErrorID
, Model
):
837 Table
= EccGlobalData
.gDb
.TblDec
838 if Model
== MODEL_EFI_GUID
:
840 if Model
== MODEL_EFI_PROTOCOL
:
842 if Model
== MODEL_EFI_PPI
:
845 select A.ID, A.Value2 from %s as A, %s as B
846 where A.Model = %s and B.Model = %s
847 and A.Value2 = B.Value2 and A.ID <> B.ID
849 """ % (Table
.Table
, Table
.Table
, Model
, Model
)
850 RecordSet
= Table
.Exec(SqlCommand
)
851 for Record
in RecordSet
:
852 if not EccGlobalData
.gException
.IsException(ErrorID
, Record
[1]):
853 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])
855 # Naming Convention Check
856 def NamingConventionCheck(self
):
857 if EccGlobalData
.gConfig
.NamingConventionCheckDefineStatement
== '1' \
858 or EccGlobalData
.gConfig
.NamingConventionCheckTypedefStatement
== '1' \
859 or EccGlobalData
.gConfig
.NamingConventionCheckIfndefStatement
== '1' \
860 or EccGlobalData
.gConfig
.NamingConventionCheckVariableName
== '1' \
861 or EccGlobalData
.gConfig
.NamingConventionCheckSingleCharacterVariable
== '1' \
862 or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1'\
863 or EccGlobalData
.gConfig
.CheckAll
== '1':
864 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
866 if os
.path
.splitext(F
)[1] in ('.h', '.c'):
867 FullName
= os
.path
.join(Dirpath
, F
)
868 Id
= c
.GetTableID(FullName
)
871 FileTable
= 'Identifier' + str(Id
)
872 self
.NamingConventionCheckDefineStatement(FileTable
)
873 self
.NamingConventionCheckTypedefStatement(FileTable
)
874 self
.NamingConventionCheckIfndefStatement(FileTable
)
875 self
.NamingConventionCheckVariableName(FileTable
)
876 self
.NamingConventionCheckSingleCharacterVariable(FileTable
)
878 self
.NamingConventionCheckPathName()
879 self
.NamingConventionCheckFunctionName()
881 # Check whether only capital letters are used for #define declarations
882 def NamingConventionCheckDefineStatement(self
, FileTable
):
883 if EccGlobalData
.gConfig
.NamingConventionCheckDefineStatement
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
884 EdkLogger
.quiet("Checking naming covention of #define statement ...")
886 SqlCommand
= """select ID, Value from %s where Model = %s""" %(FileTable
, MODEL_IDENTIFIER_MACRO_DEFINE
)
887 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
888 for Record
in RecordSet
:
889 Name
= Record
[1].strip().split()[1]
890 if Name
.find('(') != -1:
891 Name
= Name
[0:Name
.find('(')]
892 if Name
.upper() != Name
:
893 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT
, Name
):
894 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])
896 # Check whether only capital letters are used for typedef declarations
897 def NamingConventionCheckTypedefStatement(self
, FileTable
):
898 if EccGlobalData
.gConfig
.NamingConventionCheckTypedefStatement
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
899 EdkLogger
.quiet("Checking naming covention of #typedef statement ...")
901 SqlCommand
= """select ID, Name from %s where Model = %s""" %(FileTable
, MODEL_IDENTIFIER_TYPEDEF
)
902 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
903 for Record
in RecordSet
:
904 Name
= Record
[1].strip()
905 if Name
!= '' and Name
!= None:
907 Name
= Name
[1:Name
.find(')')]
908 if Name
.find('(') > -1:
909 Name
= Name
[Name
.find('(') + 1 : Name
.find(')')]
910 Name
= Name
.replace('WINAPI', '')
911 Name
= Name
.replace('*', '').strip()
912 if Name
.upper() != Name
:
913 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT
, Name
):
914 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])
916 # Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'.
917 def NamingConventionCheckIfndefStatement(self
, FileTable
):
918 if EccGlobalData
.gConfig
.NamingConventionCheckTypedefStatement
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
919 EdkLogger
.quiet("Checking naming covention of #ifndef statement ...")
921 SqlCommand
= """select ID, Value from %s where Model = %s""" %(FileTable
, MODEL_IDENTIFIER_MACRO_IFNDEF
)
922 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
923 for Record
in RecordSet
:
924 Name
= Record
[1].replace('#ifndef', '').strip()
925 if Name
[0] != '_' or Name
[-1] != '_':
926 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT
, Name
):
927 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])
929 # Rule for path name, variable name and function name
930 # 1. First character should be upper case
931 # 2. Existing lower case in a word
932 # 3. No space existence
933 # Check whether the path name followed the rule
934 def NamingConventionCheckPathName(self
):
935 if EccGlobalData
.gConfig
.NamingConventionCheckPathName
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
936 EdkLogger
.quiet("Checking naming covention of file path name ...")
937 Pattern
= re
.compile(r
'^[A-Z]+\S*[a-z]\S*$')
938 SqlCommand
= """select ID, Name from File"""
939 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
940 for Record
in RecordSet
:
941 if not Pattern
.match(Record
[1]):
942 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_PATH_NAME
, Record
[1]):
943 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])
945 # Rule for path name, variable name and function name
946 # 1. First character should be upper case
947 # 2. Existing lower case in a word
948 # 3. No space existence
949 # 4. Global variable name must start with a 'g'
950 # Check whether the variable name followed the rule
951 def NamingConventionCheckVariableName(self
, FileTable
):
952 if EccGlobalData
.gConfig
.NamingConventionCheckVariableName
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
953 EdkLogger
.quiet("Checking naming covention of variable name ...")
954 Pattern
= re
.compile(r
'^[A-Zgm]+\S*[a-z]\S*$')
956 SqlCommand
= """select ID, Name from %s where Model = %s""" %(FileTable
, MODEL_IDENTIFIER_VARIABLE
)
957 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
958 for Record
in RecordSet
:
959 if not Pattern
.match(Record
[1]):
960 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME
, Record
[1]):
961 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])
963 # Rule for path name, variable name and function name
964 # 1. First character should be upper case
965 # 2. Existing lower case in a word
966 # 3. No space existence
967 # Check whether the function name followed the rule
968 def NamingConventionCheckFunctionName(self
):
969 if EccGlobalData
.gConfig
.NamingConventionCheckFunctionName
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
970 EdkLogger
.quiet("Checking naming covention of function name ...")
971 Pattern
= re
.compile(r
'^[A-Z]+\S*[a-z]\S*$')
972 SqlCommand
= """select ID, Name from Function"""
973 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
974 for Record
in RecordSet
:
975 if not Pattern
.match(Record
[1]):
976 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME
, Record
[1]):
977 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])
979 # Check whether NO use short variable name with single character
980 def NamingConventionCheckSingleCharacterVariable(self
, FileTable
):
981 if EccGlobalData
.gConfig
.NamingConventionCheckSingleCharacterVariable
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
982 EdkLogger
.quiet("Checking naming covention of single character variable name ...")
984 SqlCommand
= """select ID, Name from %s where Model = %s""" %(FileTable
, MODEL_IDENTIFIER_VARIABLE
)
985 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
986 for Record
in RecordSet
:
987 Variable
= Record
[1].replace('*', '')
988 if len(Variable
) == 1:
989 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE
, Record
[1]):
990 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])
994 # This acts like the main() function for the script, unless it is 'import'ed into another
997 if __name__
== '__main__':