2 # This file is used to define checkpoints used by ECC tool
4 # Copyright (c) 2008 - 2014, 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.
13 import Common
.LongFilePathOs
as os
15 from CommonDataClass
.DataClass
import *
16 import Common
.DataType
as DT
17 from EccToolError
import *
18 from MetaDataParser
import ParseHeaderCommentSection
21 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
25 # This class is to define checkpoints used by ECC tool
27 # @param object: Inherited from object class
33 # Check all required checkpoints
36 self
.MetaDataFileCheck()
38 self
.IncludeFileCheck()
39 self
.PredicateExpressionCheck()
40 self
.DeclAndDataTypeCheck()
41 self
.FunctionLayoutCheck()
42 self
.NamingConventionCheck()
46 if EccGlobalData
.gConfig
.GeneralCheckUni
== '1' or EccGlobalData
.gConfig
.GeneralCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
47 EdkLogger
.quiet("Checking whether UNI file is UTF-16 ...")
48 SqlCommand
= """select ID, FullPath, ExtName from File where ExtName like 'uni'"""
49 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
50 for Record
in RecordSet
:
52 FileIn
= open(File
, 'rb').read(2)
53 if FileIn
!= '\xff\xfe':
54 OtherMsg
= "File %s is not a valid UTF-16 UNI file" % Record
[1]
55 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_GENERAL_CHECK_UNI
, OtherMsg
=OtherMsg
, BelongsToTable
='File', BelongsToItem
=Record
[0])
58 def GeneralCheck(self
):
59 self
.GeneralCheckNonAcsii()
62 # Check whether file has non ACSII char
63 def GeneralCheckNonAcsii(self
):
64 if EccGlobalData
.gConfig
.GeneralCheckNonAcsii
== '1' or EccGlobalData
.gConfig
.GeneralCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
65 EdkLogger
.quiet("Checking Non-ACSII char in file ...")
66 SqlCommand
= """select ID, FullPath, ExtName from File"""
67 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
68 for Record
in RecordSet
:
69 if Record
[2].upper() not in EccGlobalData
.gConfig
.BinaryExtList
:
70 op
= open(Record
[1]).readlines()
78 OtherMsg
= "File %s has Non-ASCII char at line %s column %s" % (Record
[1], IndexOfLine
, IndexOfChar
)
79 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_GENERAL_CHECK_NON_ACSII
, OtherMsg
=OtherMsg
, BelongsToTable
='File', BelongsToItem
=Record
[0])
81 # C Function Layout Checking
82 def FunctionLayoutCheck(self
):
83 self
.FunctionLayoutCheckReturnType()
84 self
.FunctionLayoutCheckModifier()
85 self
.FunctionLayoutCheckName()
86 self
.FunctionLayoutCheckPrototype()
87 self
.FunctionLayoutCheckBody()
88 self
.FunctionLayoutCheckLocalVariable()
91 IgnoredPattern
= c
.GetIgnoredDirListPattern()
92 for Dirpath
, Dirnames
, Filenames
in os
.walk(EccGlobalData
.gTarget
):
94 Dirname
= os
.path
.join(Dirpath
, Dir
)
95 if os
.path
.islink(Dirname
):
96 Dirname
= os
.path
.realpath(Dirname
)
97 if os
.path
.isdir(Dirname
):
98 # symlinks to directories are treated as directories
100 Dirnames
.append(Dirname
)
101 if IgnoredPattern
.match(Dirpath
.upper()):
103 yield (Dirpath
, Dirnames
, Filenames
)
105 # Check whether return type exists and in the first line
106 def FunctionLayoutCheckReturnType(self
):
107 if EccGlobalData
.gConfig
.CFunctionLayoutCheckReturnType
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
108 EdkLogger
.quiet("Checking function layout return type ...")
110 # for Dirpath, Dirnames, Filenames in self.WalkTree():
111 # for F in Filenames:
112 # if os.path.splitext(F)[1] in ('.c', '.h'):
113 # FullName = os.path.join(Dirpath, F)
114 # c.CheckFuncLayoutReturnType(FullName)
115 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
116 c
.CheckFuncLayoutReturnType(FullName
)
118 # Check whether any optional functional modifiers exist and next to the return type
119 def FunctionLayoutCheckModifier(self
):
120 if EccGlobalData
.gConfig
.CFunctionLayoutCheckOptionalFunctionalModifier
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
121 EdkLogger
.quiet("Checking function layout modifier ...")
123 # for Dirpath, Dirnames, Filenames in self.WalkTree():
124 # for F in Filenames:
125 # if os.path.splitext(F)[1] in ('.c', '.h'):
126 # FullName = os.path.join(Dirpath, F)
127 # c.CheckFuncLayoutModifier(FullName)
128 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
129 c
.CheckFuncLayoutModifier(FullName
)
131 # Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list
132 # Check whether the closing parenthesis is on its own line and also indented two spaces
133 def FunctionLayoutCheckName(self
):
134 if EccGlobalData
.gConfig
.CFunctionLayoutCheckFunctionName
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
135 EdkLogger
.quiet("Checking function layout function name ...")
137 # for Dirpath, Dirnames, Filenames in self.WalkTree():
138 # for F in Filenames:
139 # if os.path.splitext(F)[1] in ('.c', '.h'):
140 # FullName = os.path.join(Dirpath, F)
141 # c.CheckFuncLayoutName(FullName)
142 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
143 c
.CheckFuncLayoutName(FullName
)
145 # Check whether the function prototypes in include files have the same form as function definitions
146 def FunctionLayoutCheckPrototype(self
):
147 if EccGlobalData
.gConfig
.CFunctionLayoutCheckFunctionPrototype
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
148 EdkLogger
.quiet("Checking function layout function prototype ...")
150 # for Dirpath, Dirnames, Filenames in self.WalkTree():
151 # for F in Filenames:
152 # if os.path.splitext(F)[1] in ('.c'):
153 # FullName = os.path.join(Dirpath, F)
154 # EdkLogger.quiet("[PROTOTYPE]" + FullName)
155 # c.CheckFuncLayoutPrototype(FullName)
156 for FullName
in EccGlobalData
.gCFileList
:
157 EdkLogger
.quiet("[PROTOTYPE]" + FullName
)
158 c
.CheckFuncLayoutPrototype(FullName
)
160 # Check whether the body of a function is contained by open and close braces that must be in the first column
161 def FunctionLayoutCheckBody(self
):
162 if EccGlobalData
.gConfig
.CFunctionLayoutCheckFunctionBody
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
163 EdkLogger
.quiet("Checking function layout function body ...")
165 # for Dirpath, Dirnames, Filenames in self.WalkTree():
166 # for F in Filenames:
167 # if os.path.splitext(F)[1] in ('.c'):
168 # FullName = os.path.join(Dirpath, F)
169 # c.CheckFuncLayoutBody(FullName)
170 for FullName
in EccGlobalData
.gCFileList
:
171 c
.CheckFuncLayoutBody(FullName
)
173 # Check whether the data declarations is the first code in a module.
174 # self.CFunctionLayoutCheckDataDeclaration = 1
175 # Check whether no initialization of a variable as part of its declaration
176 def FunctionLayoutCheckLocalVariable(self
):
177 if EccGlobalData
.gConfig
.CFunctionLayoutCheckNoInitOfVariable
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
178 EdkLogger
.quiet("Checking function layout local variables ...")
180 # for Dirpath, Dirnames, Filenames in self.WalkTree():
181 # for F in Filenames:
182 # if os.path.splitext(F)[1] in ('.c'):
183 # FullName = os.path.join(Dirpath, F)
184 # c.CheckFuncLayoutLocalVariable(FullName)
186 for FullName
in EccGlobalData
.gCFileList
:
187 c
.CheckFuncLayoutLocalVariable(FullName
)
189 # Check whether no use of STATIC for functions
190 # self.CFunctionLayoutCheckNoStatic = 1
192 # Declarations and Data Types Checking
193 def DeclAndDataTypeCheck(self
):
194 self
.DeclCheckNoUseCType()
195 self
.DeclCheckInOutModifier()
196 self
.DeclCheckEFIAPIModifier()
197 self
.DeclCheckEnumeratedType()
198 self
.DeclCheckStructureDeclaration()
199 self
.DeclCheckSameStructure()
200 self
.DeclCheckUnionType()
203 # Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files.
204 def DeclCheckNoUseCType(self
):
205 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckNoUseCType
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
206 EdkLogger
.quiet("Checking Declaration No use C type ...")
208 # for Dirpath, Dirnames, Filenames in self.WalkTree():
209 # for F in Filenames:
210 # if os.path.splitext(F)[1] in ('.h', '.c'):
211 # FullName = os.path.join(Dirpath, F)
212 # c.CheckDeclNoUseCType(FullName)
213 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
214 c
.CheckDeclNoUseCType(FullName
)
216 # 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
217 def DeclCheckInOutModifier(self
):
218 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckInOutModifier
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
219 EdkLogger
.quiet("Checking Declaration argument modifier ...")
221 # for Dirpath, Dirnames, Filenames in self.WalkTree():
222 # for F in Filenames:
223 # if os.path.splitext(F)[1] in ('.h', '.c'):
224 # FullName = os.path.join(Dirpath, F)
225 # c.CheckDeclArgModifier(FullName)
226 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
227 c
.CheckDeclArgModifier(FullName
)
229 # Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols
230 def DeclCheckEFIAPIModifier(self
):
231 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckEFIAPIModifier
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
234 # Check whether Enumerated Type has a 'typedef' and the name is capital
235 def DeclCheckEnumeratedType(self
):
236 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckEnumeratedType
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
237 EdkLogger
.quiet("Checking Declaration enum typedef ...")
239 # for Dirpath, Dirnames, Filenames in self.WalkTree():
240 # for F in Filenames:
241 # if os.path.splitext(F)[1] in ('.h', '.c'):
242 # FullName = os.path.join(Dirpath, F)
243 # EdkLogger.quiet("[ENUM]" + FullName)
244 # c.CheckDeclEnumTypedef(FullName)
245 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
246 EdkLogger
.quiet("[ENUM]" + FullName
)
247 c
.CheckDeclEnumTypedef(FullName
)
249 # Check whether Structure Type has a 'typedef' and the name is capital
250 def DeclCheckStructureDeclaration(self
):
251 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckStructureDeclaration
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
252 EdkLogger
.quiet("Checking Declaration struct typedef ...")
254 # for Dirpath, Dirnames, Filenames in self.WalkTree():
255 # for F in Filenames:
256 # if os.path.splitext(F)[1] in ('.h', '.c'):
257 # FullName = os.path.join(Dirpath, F)
258 # EdkLogger.quiet("[STRUCT]" + FullName)
259 # c.CheckDeclStructTypedef(FullName)
260 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
261 EdkLogger
.quiet("[STRUCT]" + FullName
)
262 c
.CheckDeclStructTypedef(FullName
)
264 # Check whether having same Structure
265 def DeclCheckSameStructure(self
):
266 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckSameStructure
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
267 EdkLogger
.quiet("Checking same struct ...")
269 for IdentifierTable
in EccGlobalData
.gIdentifierTableList
:
270 SqlCommand
= """select ID, Name, BelongsToFile from %s where Model = %s""" % (IdentifierTable
, MODEL_IDENTIFIER_STRUCTURE
)
271 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
272 for Record
in RecordSet
:
274 if Record
[1] not in AllStructure
.keys():
275 AllStructure
[Record
[1]] = Record
[2]
277 ID
= AllStructure
[Record
[1]]
278 SqlCommand
= """select FullPath from File where ID = %s """ % ID
279 NewRecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
280 OtherMsg
= "The structure name '%s' is duplicate" % Record
[1]
281 if NewRecordSet
!= []:
282 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])
283 if not EccGlobalData
.gException
.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE
, Record
[1]):
284 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE
, OtherMsg
=OtherMsg
, BelongsToTable
=IdentifierTable
, BelongsToItem
=Record
[0])
286 # Check whether Union Type has a 'typedef' and the name is capital
287 def DeclCheckUnionType(self
):
288 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckUnionType
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
289 EdkLogger
.quiet("Checking Declaration union typedef ...")
291 # for Dirpath, Dirnames, Filenames in self.WalkTree():
292 # for F in Filenames:
293 # if os.path.splitext(F)[1] in ('.h', '.c'):
294 # FullName = os.path.join(Dirpath, F)
295 # EdkLogger.quiet("[UNION]" + FullName)
296 # c.CheckDeclUnionTypedef(FullName)
297 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
298 EdkLogger
.quiet("[UNION]" + FullName
)
299 c
.CheckDeclUnionTypedef(FullName
)
301 # Predicate Expression Checking
302 def PredicateExpressionCheck(self
):
303 self
.PredicateExpressionCheckBooleanValue()
304 self
.PredicateExpressionCheckNonBooleanOperator()
305 self
.PredicateExpressionCheckComparisonNullType()
307 # Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE
308 def PredicateExpressionCheckBooleanValue(self
):
309 if EccGlobalData
.gConfig
.PredicateExpressionCheckBooleanValue
== '1' or EccGlobalData
.gConfig
.PredicateExpressionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
310 EdkLogger
.quiet("Checking predicate expression Boolean value ...")
312 # for Dirpath, Dirnames, Filenames in self.WalkTree():
313 # for F in Filenames:
314 # if os.path.splitext(F)[1] in ('.c'):
315 # FullName = os.path.join(Dirpath, F)
316 # EdkLogger.quiet("[BOOLEAN]" + FullName)
317 # c.CheckBooleanValueComparison(FullName)
318 for FullName
in EccGlobalData
.gCFileList
:
319 EdkLogger
.quiet("[BOOLEAN]" + FullName
)
320 c
.CheckBooleanValueComparison(FullName
)
322 # Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=).
323 def PredicateExpressionCheckNonBooleanOperator(self
):
324 if EccGlobalData
.gConfig
.PredicateExpressionCheckNonBooleanOperator
== '1' or EccGlobalData
.gConfig
.PredicateExpressionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
325 EdkLogger
.quiet("Checking predicate expression Non-Boolean variable...")
327 # for Dirpath, Dirnames, Filenames in self.WalkTree():
328 # for F in Filenames:
329 # if os.path.splitext(F)[1] in ('.c'):
330 # FullName = os.path.join(Dirpath, F)
331 # EdkLogger.quiet("[NON-BOOLEAN]" + FullName)
332 # c.CheckNonBooleanValueComparison(FullName)
333 for FullName
in EccGlobalData
.gCFileList
:
334 EdkLogger
.quiet("[NON-BOOLEAN]" + FullName
)
335 c
.CheckNonBooleanValueComparison(FullName
)
337 # Check whether a comparison of any pointer to zero must be done via the NULL type
338 def PredicateExpressionCheckComparisonNullType(self
):
339 if EccGlobalData
.gConfig
.PredicateExpressionCheckComparisonNullType
== '1' or EccGlobalData
.gConfig
.PredicateExpressionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
340 EdkLogger
.quiet("Checking predicate expression NULL pointer ...")
342 # for Dirpath, Dirnames, Filenames in self.WalkTree():
343 # for F in Filenames:
344 # if os.path.splitext(F)[1] in ('.c'):
345 # FullName = os.path.join(Dirpath, F)
346 # EdkLogger.quiet("[POINTER]" + FullName)
347 # c.CheckPointerNullComparison(FullName)
348 for FullName
in EccGlobalData
.gCFileList
:
349 EdkLogger
.quiet("[POINTER]" + FullName
)
350 c
.CheckPointerNullComparison(FullName
)
352 # Include file checking
353 def IncludeFileCheck(self
):
354 self
.IncludeFileCheckIfndef()
355 self
.IncludeFileCheckData()
356 self
.IncludeFileCheckSameName()
358 # Check whether having include files with same name
359 def IncludeFileCheckSameName(self
):
360 if EccGlobalData
.gConfig
.IncludeFileCheckSameName
== '1' or EccGlobalData
.gConfig
.IncludeFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
361 EdkLogger
.quiet("Checking same header file name ...")
362 SqlCommand
= """select ID, FullPath from File
363 where Model = 1002 order by Name """
365 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
366 for Record
in RecordSet
:
367 List
= Record
[1].replace('/', '\\').split('\\')
369 Key
= List
[-2] + '\\' + List
[-1]
372 if Key
not in RecordDict
:
373 RecordDict
[Key
] = [Record
]
375 RecordDict
[Key
].append(Record
)
377 for Key
in RecordDict
:
378 if len(RecordDict
[Key
]) > 1:
379 for Item
in RecordDict
[Key
]:
380 Path
= Item
[1].replace(EccGlobalData
.gWorkspace
, '')
381 if Path
.startswith('\\') or Path
.startswith('/'):
383 if not EccGlobalData
.gException
.IsException(ERROR_INCLUDE_FILE_CHECK_NAME
, Path
):
384 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_INCLUDE_FILE_CHECK_NAME
, OtherMsg
="The file name for [%s] is duplicate" % Path
, BelongsToTable
='File', BelongsToItem
=Item
[0])
386 # Check whether all include file contents is guarded by a #ifndef statement.
387 def IncludeFileCheckIfndef(self
):
388 if EccGlobalData
.gConfig
.IncludeFileCheckIfndefStatement
== '1' or EccGlobalData
.gConfig
.IncludeFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
389 EdkLogger
.quiet("Checking header file ifndef ...")
391 # for Dirpath, Dirnames, Filenames in self.WalkTree():
392 # for F in Filenames:
393 # if os.path.splitext(F)[1] in ('.h'):
394 # FullName = os.path.join(Dirpath, F)
395 # MsgList = c.CheckHeaderFileIfndef(FullName)
396 for FullName
in EccGlobalData
.gHFileList
:
397 MsgList
= c
.CheckHeaderFileIfndef(FullName
)
399 # Check whether include files NOT contain code or define data variables
400 def IncludeFileCheckData(self
):
401 if EccGlobalData
.gConfig
.IncludeFileCheckData
== '1' or EccGlobalData
.gConfig
.IncludeFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
402 EdkLogger
.quiet("Checking header file data ...")
404 # for Dirpath, Dirnames, Filenames in self.WalkTree():
405 # for F in Filenames:
406 # if os.path.splitext(F)[1] in ('.h'):
407 # FullName = os.path.join(Dirpath, F)
408 # MsgList = c.CheckHeaderFileData(FullName)
409 for FullName
in EccGlobalData
.gHFileList
:
410 MsgList
= c
.CheckHeaderFileData(FullName
)
412 # Doxygen document checking
413 def DoxygenCheck(self
):
414 self
.DoxygenCheckFileHeader()
415 self
.DoxygenCheckFunctionHeader()
416 self
.DoxygenCheckCommentDescription()
417 self
.DoxygenCheckCommentFormat()
418 self
.DoxygenCheckCommand()
420 # Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5
421 def DoxygenCheckFileHeader(self
):
422 if EccGlobalData
.gConfig
.DoxygenCheckFileHeader
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
423 EdkLogger
.quiet("Checking Doxygen file header ...")
425 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
427 Ext
= os
.path
.splitext(F
)[1]
428 if Ext
in ('.h', '.c'):
429 FullName
= os
.path
.join(Dirpath
, F
)
430 MsgList
= c
.CheckFileHeaderDoxygenComments(FullName
)
431 elif Ext
in ('.inf', '.dec', '.dsc', '.fdf'):
432 FullName
= os
.path
.join(Dirpath
, F
)
433 op
= open(FullName
).readlines()
436 CurrentSection
= MODEL_UNKNOWN
437 HeaderSectionLines
= []
438 HeaderCommentStart
= False
439 HeaderCommentEnd
= False
441 for Line
in FileLinesList
:
444 if (LineNo
< len(FileLinesList
) - 1):
445 NextLine
= FileLinesList
[LineNo
].strip()
450 if (Line
== '' or not Line
) and LineNo
== len(FileLinesList
):
451 LastSectionFalg
= True
454 # check whether file header comment section started
456 if Line
.startswith('#') and \
457 (Line
.find('@file') > -1) and \
458 not HeaderCommentStart
:
459 if CurrentSection
!= MODEL_UNKNOWN
:
460 SqlStatement
= """ select ID from File where FullPath like '%s'""" % FullName
461 ResultSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlStatement
)
462 for Result
in ResultSet
:
463 Msg
= 'INF/DEC/DSC/FDF file header comment should begin with ""## @file"" or ""# @file""at the very top file'
464 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER
, Msg
, "File", Result
[0])
467 CurrentSection
= MODEL_IDENTIFIER_FILE_HEADER
469 # Append the first line to section lines.
471 HeaderSectionLines
.append((Line
, LineNo
))
472 HeaderCommentStart
= True
476 # Collect Header content.
478 if (Line
.startswith('#') and CurrentSection
== MODEL_IDENTIFIER_FILE_HEADER
) and\
479 HeaderCommentStart
and not Line
.startswith('##') and not\
480 HeaderCommentEnd
and NextLine
!= '':
481 HeaderSectionLines
.append((Line
, LineNo
))
486 if (Line
.startswith('##') or not Line
.strip().startswith("#")) and HeaderCommentStart \
487 and not HeaderCommentEnd
:
488 if Line
.startswith('##'):
489 HeaderCommentEnd
= True
490 HeaderSectionLines
.append((Line
, LineNo
))
491 ParseHeaderCommentSection(HeaderSectionLines
, FullName
)
493 if HeaderCommentStart
== False:
494 SqlStatement
= """ select ID from File where FullPath like '%s'""" % FullName
495 ResultSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlStatement
)
496 for Result
in ResultSet
:
497 Msg
= 'INF/DEC/DSC/FDF file header comment should begin with ""## @file"" or ""# @file"" at the very top file'
498 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER
, Msg
, "File", Result
[0])
499 if HeaderCommentEnd
== False:
500 SqlStatement
= """ select ID from File where FullPath like '%s'""" % FullName
501 ResultSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlStatement
)
502 for Result
in ResultSet
:
503 Msg
= 'INF/DEC/DSC/FDF file header comment should end with ""##"" at the end of file header comment block'
504 # Check whether File header Comment End with '##'
505 if EccGlobalData
.gConfig
.HeaderCheckFileCommentEnd
== '1' or EccGlobalData
.gConfig
.HeaderCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
506 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER
, Msg
, "File", Result
[0])
510 # Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5
511 def DoxygenCheckFunctionHeader(self
):
512 if EccGlobalData
.gConfig
.DoxygenCheckFunctionHeader
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
513 EdkLogger
.quiet("Checking Doxygen function header ...")
515 # for Dirpath, Dirnames, Filenames in self.WalkTree():
516 # for F in Filenames:
517 # if os.path.splitext(F)[1] in ('.h', '.c'):
518 # FullName = os.path.join(Dirpath, F)
519 # MsgList = c.CheckFuncHeaderDoxygenComments(FullName)
520 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
521 MsgList
= c
.CheckFuncHeaderDoxygenComments(FullName
)
524 # Check whether the first line of text in a comment block is a brief description of the element being documented.
525 # The brief description must end with a period.
526 def DoxygenCheckCommentDescription(self
):
527 if EccGlobalData
.gConfig
.DoxygenCheckCommentDescription
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
530 # Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.
531 def DoxygenCheckCommentFormat(self
):
532 if EccGlobalData
.gConfig
.DoxygenCheckCommentFormat
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
533 EdkLogger
.quiet("Checking Doxygen comment ///< ...")
535 # for Dirpath, Dirnames, Filenames in self.WalkTree():
536 # for F in Filenames:
537 # if os.path.splitext(F)[1] in ('.h', '.c'):
538 # FullName = os.path.join(Dirpath, F)
539 # MsgList = c.CheckDoxygenTripleForwardSlash(FullName)
540 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
541 MsgList
= c
.CheckDoxygenTripleForwardSlash(FullName
)
543 # Check whether only Doxygen commands allowed to mark the code are @bug and @todo.
544 def DoxygenCheckCommand(self
):
545 if EccGlobalData
.gConfig
.DoxygenCheckCommand
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
546 EdkLogger
.quiet("Checking Doxygen command ...")
548 # for Dirpath, Dirnames, Filenames in self.WalkTree():
549 # for F in Filenames:
550 # if os.path.splitext(F)[1] in ('.h', '.c'):
551 # FullName = os.path.join(Dirpath, F)
552 # MsgList = c.CheckDoxygenCommand(FullName)
553 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
554 MsgList
= c
.CheckDoxygenCommand(FullName
)
556 # Meta-Data File Processing Checking
557 def MetaDataFileCheck(self
):
558 self
.MetaDataFileCheckPathName()
559 self
.MetaDataFileCheckGenerateFileList()
560 self
.MetaDataFileCheckLibraryInstance()
561 self
.MetaDataFileCheckLibraryInstanceDependent()
562 self
.MetaDataFileCheckLibraryInstanceOrder()
563 self
.MetaDataFileCheckLibraryNoUse()
564 self
.MetaDataFileCheckBinaryInfInFdf()
565 self
.MetaDataFileCheckPcdDuplicate()
566 self
.MetaDataFileCheckPcdFlash()
567 self
.MetaDataFileCheckPcdNoUse()
568 self
.MetaDataFileCheckGuidDuplicate()
569 self
.MetaDataFileCheckModuleFileNoUse()
570 self
.MetaDataFileCheckPcdType()
571 self
.MetaDataFileCheckModuleFileGuidDuplication()
572 self
.MetaDataFileCheckModuleFileGuidFormat()
573 self
.MetaDataFileCheckModuleFileProtocolFormat()
574 self
.MetaDataFileCheckModuleFilePpiFormat()
575 self
.MetaDataFileCheckModuleFilePcdFormat()
577 # Check whether each file defined in meta-data exists
578 def MetaDataFileCheckPathName(self
):
579 if EccGlobalData
.gConfig
.MetaDataFileCheckPathName
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
580 # This item is covered when parsing Inf/Dec/Dsc files
583 # Generate a list for all files defined in meta-data files
584 def MetaDataFileCheckGenerateFileList(self
):
585 if EccGlobalData
.gConfig
.MetaDataFileCheckGenerateFileList
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
586 # This item is covered when parsing Inf/Dec/Dsc files
589 # Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.
590 # Each Library Instance must specify the Supported Module Types in its Inf file,
591 # and any module specifying the library instance must be one of the supported types.
592 def MetaDataFileCheckLibraryInstance(self
):
593 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryInstance
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
594 EdkLogger
.quiet("Checking for library instance type issue ...")
595 SqlCommand
= """select A.ID, A.Value3, B.Value3 from Inf as A left join Inf as B
596 where A.Value2 = 'LIBRARY_CLASS' and A.Model = %s
597 and B.Value2 = 'MODULE_TYPE' and B.Model = %s and A.BelongsToFile = B.BelongsToFile
598 group by A.BelongsToFile""" % (MODEL_META_DATA_HEADER
, MODEL_META_DATA_HEADER
)
599 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
601 for Record
in RecordSet
:
602 List
= Record
[1].split('|', 1)
605 SupModType
= DT
.SUP_MODULE_LIST_STRING
.split(DT
.TAB_VALUE_SPLIT
)
607 SupModType
= List
[1].split()
609 if List
[0] not in LibraryClasses
:
610 LibraryClasses
[List
[0]] = SupModType
612 for Item
in SupModType
:
613 if Item
not in LibraryClasses
[List
[0]]:
614 LibraryClasses
[List
[0]].append(Item
)
616 if Record
[2] != 'BASE' and Record
[2] not in SupModType
:
617 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])
619 SqlCommand
= """select A.ID, A.Value1, B.Value3 from Inf as A left join Inf as B
620 where A.Model = %s and B.Value2 = '%s' and B.Model = %s
621 and B.BelongsToFile = A.BelongsToFile""" \
622 % (MODEL_EFI_LIBRARY_CLASS
, 'MODULE_TYPE', MODEL_META_DATA_HEADER
)
623 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
624 # Merge all LibraryClasses' supmodlist
626 for Record
in RecordSet
:
627 if Record
[1] not in RecordDict
:
628 RecordDict
[Record
[1]] = [str(Record
[2])]
630 if Record
[2] not in RecordDict
[Record
[1]]:
631 RecordDict
[Record
[1]].append(Record
[2])
633 for Record
in RecordSet
:
634 if Record
[1] in LibraryClasses
:
635 if Record
[2] not in LibraryClasses
[Record
[1]] and 'BASE' not in RecordDict
[Record
[1]]:
636 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1
, Record
[1]):
637 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])
639 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1
, Record
[1]):
640 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])
642 # Check whether a Library Instance has been defined for all dependent library classes
643 def MetaDataFileCheckLibraryInstanceDependent(self
):
644 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryInstanceDependent
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
645 EdkLogger
.quiet("Checking for library instance dependent issue ...")
646 SqlCommand
= """select ID, Value1, Value2 from Dsc where Model = %s""" % MODEL_EFI_LIBRARY_CLASS
647 LibraryClasses
= EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand
)
648 for LibraryClass
in LibraryClasses
:
649 if LibraryClass
[1].upper() == 'NULL' or LibraryClass
[1].startswith('!ifdef') or LibraryClass
[1].startswith('!ifndef') or LibraryClass
[1].endswith('!endif'):
652 LibraryIns
= os
.path
.normpath(os
.path
.join(EccGlobalData
.gWorkspace
, LibraryClass
[2]))
653 SqlCommand
= """select Value3 from Inf where BelongsToFile =
654 (select ID from File where lower(FullPath) = lower('%s'))
655 and Value2 = '%s'""" % (LibraryIns
, 'LIBRARY_CLASS')
656 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
658 for Record
in RecordSet
:
659 LibName
= Record
[0].split('|', 1)[0]
660 if LibraryClass
[1] == LibName
:
663 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT
, LibraryClass
[1]):
664 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])
666 # Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies
667 def MetaDataFileCheckLibraryInstanceOrder(self
):
668 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryInstanceOrder
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
669 # This checkpoint is not necessary for Ecc check
672 # Check whether the unnecessary inclusion of library classes in the Inf file
673 # Check whether the unnecessary duplication of library classe names in the DSC file
674 def MetaDataFileCheckLibraryNoUse(self
):
675 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryNoUse
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
676 EdkLogger
.quiet("Checking for library instance not used ...")
677 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
)
678 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
679 for Record
in RecordSet
:
680 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE
, Record
[1]):
681 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])
683 select A.ID, A.Value1, A.BelongsToFile, A.StartLine, B.StartLine from Dsc as A left join Dsc as B
684 where A.Model = %s and B.Model = %s and A.Scope1 = B.Scope1 and A.Scope2 = B.Scope2 and A.ID <> B.ID
685 and A.Value1 = B.Value1 and A.Value2 <> B.Value2 and A.BelongsToItem = -1 and B.BelongsToItem = -1 and A.StartLine <> B.StartLine and B.BelongsToFile = A.BelongsToFile""" \
686 % (MODEL_EFI_LIBRARY_CLASS
, MODEL_EFI_LIBRARY_CLASS
)
687 RecordSet
= EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand
)
688 for Record
in RecordSet
:
689 if Record
[3] and Record
[4] and Record
[3] != Record
[4] and Record
[1] != 'NULL':
690 SqlCommand
= """select FullPath from File where ID = %s""" % (Record
[2])
691 FilePathList
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
692 for FilePath
in FilePathList
:
693 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NAME_DUPLICATE
, Record
[1]):
694 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_NAME_DUPLICATE
, OtherMsg
="The Library Class [%s] is duplicated in '%s' line %s and line %s." % (Record
[1], FilePath
, Record
[3], Record
[4]), BelongsToTable
='Dsc', BelongsToItem
=Record
[0])
696 # 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
697 def MetaDataFileCheckBinaryInfInFdf(self
):
698 if EccGlobalData
.gConfig
.MetaDataFileCheckBinaryInfInFdf
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
699 EdkLogger
.quiet("Checking for non-binary modules defined in FDF files ...")
700 SqlCommand
= """select A.ID, A.Value1 from Fdf as A
704 (select B.Value1 from Dsc as B
706 and B.Enabled > -1)""" % (MODEL_META_DATA_COMPONENT
, MODEL_META_DATA_COMPONENT
)
707 RecordSet
= EccGlobalData
.gDb
.TblFdf
.Exec(SqlCommand
)
708 for Record
in RecordSet
:
711 FilePath
= os
.path
.normpath(os
.path
.join(EccGlobalData
.gWorkspace
, FilePath
))
712 SqlCommand
= """select ID from Inf where Model = %s and BelongsToFile = (select ID from File where FullPath like '%s')
713 """ % (MODEL_EFI_SOURCE_FILE
, FilePath
)
714 NewRecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
715 if NewRecordSet
!= []:
716 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF
, FilePath
):
717 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
)
719 # Check whether a PCD is set in a Dsc file or the FDF file, but not in both.
720 def MetaDataFileCheckPcdDuplicate(self
):
721 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdDuplicate
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
722 EdkLogger
.quiet("Checking for duplicate PCDs defined in both DSC and FDF files ...")
724 select A.ID, A.Value1, A.Value2, A.BelongsToFile, B.ID, B.Value1, B.Value2, B.BelongsToFile from Dsc as A, Fdf as B
725 where A.Model >= %s and A.Model < %s
726 and B.Model >= %s and B.Model < %s
727 and A.Value1 = B.Value1
728 and A.Value2 = B.Value2
732 """ % (MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
)
733 RecordSet
= EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand
)
734 for Record
in RecordSet
:
735 SqlCommand1
= """select Name from File where ID = %s""" % Record
[3]
736 SqlCommand2
= """select Name from File where ID = %s""" % Record
[7]
737 DscFileName
= os
.path
.splitext(EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand1
)[0][0])[0]
738 FdfFileName
= os
.path
.splitext(EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand2
)[0][0])[0]
739 if DscFileName
!= FdfFileName
:
741 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE
, Record
[1] + '.' + Record
[2]):
742 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] + '.' + Record
[2]), BelongsToTable
='Dsc', BelongsToItem
=Record
[0])
743 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE
, Record
[5] + '.' + Record
[6]):
744 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
[5] + '.' + Record
[6]), BelongsToTable
='Fdf', BelongsToItem
=Record
[4])
746 EdkLogger
.quiet("Checking for duplicate PCDs defined in DEC files ...")
748 select A.ID, A.Value1, A.Value2, A.Model, B.Model from Dec as A left join Dec as B
749 where A.Model >= %s and A.Model < %s
750 and B.Model >= %s and B.Model < %s
751 and A.Value1 = B.Value1
752 and A.Value2 = B.Value2
753 and A.Scope1 = B.Scope1
755 and A.Model = B.Model
758 and A.BelongsToFile = B.BelongsToFile
760 """ % (MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
)
761 RecordSet
= EccGlobalData
.gDb
.TblDec
.Exec(SqlCommand
)
762 for Record
in RecordSet
:
763 RecordCat
= Record
[1] + '.' + Record
[2]
764 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE
, RecordCat
):
765 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE
, OtherMsg
="The PCD [%s] is defined duplicated in DEC file" % RecordCat
, BelongsToTable
='Dec', BelongsToItem
=Record
[0])
767 # Check whether PCD settings in the FDF file can only be related to flash.
768 def MetaDataFileCheckPcdFlash(self
):
769 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdFlash
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
770 EdkLogger
.quiet("Checking only Flash related PCDs are used in FDF ...")
772 select ID, Value1, Value2, BelongsToFile from Fdf as A
773 where A.Model >= %s and Model < %s
775 and A.Value2 not like '%%Flash%%'
776 """ % (MODEL_PCD
, MODEL_META_DATA_HEADER
)
777 RecordSet
= EccGlobalData
.gDb
.TblFdf
.Exec(SqlCommand
)
778 for Record
in RecordSet
:
779 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_FLASH
, Record
[1] + '.' + Record
[2]):
780 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] + '.' + Record
[2]), BelongsToTable
='Fdf', BelongsToItem
=Record
[0])
782 # Check whether PCDs used in Inf files but not specified in Dsc or FDF files
783 def MetaDataFileCheckPcdNoUse(self
):
784 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdNoUse
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
785 EdkLogger
.quiet("Checking for non-specified PCDs ...")
787 select ID, Value1, Value2, BelongsToFile from Inf as A
788 where A.Model >= %s and Model < %s
790 and (A.Value1, A.Value2) not in
791 (select Value1, Value2 from Dsc as B
792 where B.Model >= %s and B.Model < %s
794 and (A.Value1, A.Value2) not in
795 (select Value1, Value2 from Fdf as C
796 where C.Model >= %s and C.Model < %s
798 """ % (MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
)
799 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
800 for Record
in RecordSet
:
801 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE
, Record
[1] + '.' + Record
[2]):
802 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] + '.' + Record
[2]), BelongsToTable
='Inf', BelongsToItem
=Record
[0])
804 # Check whether having duplicate guids defined for Guid/Protocol/Ppi
805 def MetaDataFileCheckGuidDuplicate(self
):
806 if EccGlobalData
.gConfig
.MetaDataFileCheckGuidDuplicate
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
807 EdkLogger
.quiet("Checking for duplicate GUID/PPI/PROTOCOL ...")
809 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID
, MODEL_EFI_GUID
, EccGlobalData
.gDb
.TblDec
)
810 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID
, MODEL_EFI_GUID
, EccGlobalData
.gDb
.TblDsc
)
811 self
.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID
, MODEL_EFI_GUID
)
813 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL
, MODEL_EFI_PROTOCOL
, EccGlobalData
.gDb
.TblDec
)
814 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL
, MODEL_EFI_PROTOCOL
, EccGlobalData
.gDb
.TblDsc
)
815 self
.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL
, MODEL_EFI_PROTOCOL
)
817 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI
, MODEL_EFI_PPI
, EccGlobalData
.gDb
.TblDec
)
818 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI
, MODEL_EFI_PPI
, EccGlobalData
.gDb
.TblDsc
)
819 self
.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI
, MODEL_EFI_PPI
)
821 # Check whether all files under module directory are described in INF files
822 def MetaDataFileCheckModuleFileNoUse(self
):
823 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFileNoUse
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
824 EdkLogger
.quiet("Checking for no used module files ...")
826 select upper(Path) from File where ID in (select BelongsToFile from Inf where BelongsToFile != -1)
828 InfPathSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
830 for Item
in InfPathSet
:
831 if Item
[0] not in InfPathList
:
832 InfPathList
.append(Item
[0])
834 select ID, Path, FullPath from File where upper(FullPath) not in
835 (select upper(A.Path) || '\\' || upper(B.Value1) from File as A, INF as B
836 where A.ID in (select BelongsToFile from INF where Model = %s group by BelongsToFile) and
837 B.BelongsToFile = A.ID and B.Model = %s)
838 and (Model = %s or Model = %s)
839 """ % (MODEL_EFI_SOURCE_FILE
, MODEL_EFI_SOURCE_FILE
, MODEL_FILE_C
, MODEL_FILE_H
)
840 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
841 for Record
in RecordSet
:
843 Path
= Path
.upper().replace('\X64', '').replace('\IA32', '').replace('\EBC', '').replace('\IPF', '').replace('\ARM', '')
844 if Path
in InfPathList
:
845 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE
, Record
[2]):
846 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])
848 # Check whether the PCD is correctly used in C function via its type
849 def MetaDataFileCheckPcdType(self
):
850 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdType
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
851 EdkLogger
.quiet("Checking for pcd type in c code function usage ...")
853 select ID, Model, Value1, Value2, BelongsToFile from INF where Model > %s and Model < %s
854 """ % (MODEL_PCD
, MODEL_META_DATA_HEADER
)
855 PcdSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
861 BelongsToFile
= Pcd
[4]
863 select ID from File where FullPath in
864 (select B.Path || '\\' || A.Value1 from INF as A, File as B where A.Model = %s and A.BelongsToFile = %s
865 and B.ID = %s and (B.Model = %s or B.Model = %s))
866 """ % (MODEL_EFI_SOURCE_FILE
, BelongsToFile
, BelongsToFile
, MODEL_FILE_C
, MODEL_FILE_H
)
867 TableSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
869 TblName
= 'Identifier' + str(Tbl
[0])
871 select Name, ID from %s where value like '%s' and Model = %s
872 """ % (TblName
, PcdName
, MODEL_IDENTIFIER_FUNCTION_CALLING
)
873 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
874 TblNumber
= TblName
.replace('Identifier', '')
875 for Record
in RecordSet
:
877 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_TYPE
, FunName
):
878 if Model
in [MODEL_PCD_FIXED_AT_BUILD
] and not FunName
.startswith('FixedPcdGet'):
879 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])
880 if Model
in [MODEL_PCD_FEATURE_FLAG
] and (not FunName
.startswith('FeaturePcdGet') and not FunName
.startswith('FeaturePcdSet')):
881 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])
882 if Model
in [MODEL_PCD_PATCHABLE_IN_MODULE
] and (not FunName
.startswith('PatchablePcdGet') and not FunName
.startswith('PatchablePcdSet')):
883 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])
885 #ERROR_META_DATA_FILE_CHECK_PCD_TYPE
888 # Internal worker function to get the INF workspace relative path from FileID
889 def GetInfFilePathFromID(self
, FileID
):
890 Table
= EccGlobalData
.gDb
.TblFile
891 SqlCommand
= """select A.FullPath from %s as A where A.ID = %s""" % (Table
.Table
, FileID
)
892 RecordSet
= Table
.Exec(SqlCommand
)
894 for Record
in RecordSet
:
895 Path
= Record
[0].replace(EccGlobalData
.gWorkspace
, '')
896 if Path
.startswith('\\') or Path
.startswith('/'):
900 # Check whether two module INFs under one workspace has the same FILE_GUID value
901 def MetaDataFileCheckModuleFileGuidDuplication(self
):
902 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFileGuidDuplication
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
903 EdkLogger
.quiet("Checking for pcd type in c code function usage ...")
904 Table
= EccGlobalData
.gDb
.TblInf
906 select A.ID, A.Value3, A.BelongsToFile, B.BelongsToFile from %s as A, %s as B
907 where A.Value2 = 'FILE_GUID' and B.Value2 = 'FILE_GUID' and
908 A.Value3 = B.Value3 and A.ID <> B.ID group by A.ID
909 """ % (Table
.Table
, Table
.Table
)
910 RecordSet
= Table
.Exec(SqlCommand
)
911 for Record
in RecordSet
:
912 InfPath1
= self
.GetInfFilePathFromID(Record
[2])
913 InfPath2
= self
.GetInfFilePathFromID(Record
[3])
914 if InfPath1
and InfPath2
:
915 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION
, InfPath1
):
916 Msg
= "The FILE_GUID of INF file [%s] is duplicated with that of %s" % (InfPath1
, InfPath2
)
917 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
920 # Check Guid Format in module INF
921 def MetaDataFileCheckModuleFileGuidFormat(self
):
922 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFileGuidFormat
or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
923 EdkLogger
.quiet("Check Guid Format in module INF ...")
924 Table
= EccGlobalData
.gDb
.TblInf
926 select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID
927 """ % (Table
.Table
, MODEL_EFI_GUID
)
928 RecordSet
= Table
.Exec(SqlCommand
)
929 for Record
in RecordSet
:
933 InfPath
= self
.GetInfFilePathFromID(Record
[3])
934 Msg
= "The GUID format of %s in INF file [%s] does not follow rules" % (Value1
, InfPath
)
935 if Value2
.startswith(DT
.TAB_SPECIAL_COMMENT
):
936 GuidCommentList
= Value2
[2:].split(DT
.TAB_SPECIAL_COMMENT
)
937 if GuidCommentList
[0].strip().startswith(DT
.TAB_INF_USAGE_UNDEFINED
):
939 elif len(GuidCommentList
) > 1:
940 if not GuidCommentList
[0].strip().startswith((DT
.TAB_INF_USAGE_PRO
,
941 DT
.TAB_INF_USAGE_SOME_PRO
,
942 DT
.TAB_INF_USAGE_CON
,
943 DT
.TAB_INF_USAGE_SOME_CON
)):
944 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
945 if not (GuidCommentList
[1].strip()).startswith(DT
.TAB_INF_GUIDTYPE_VAR
) and \
946 not GuidCommentList
[1].strip().startswith((DT
.TAB_INF_GUIDTYPE_EVENT
,
947 DT
.TAB_INF_GUIDTYPE_HII
,
948 DT
.TAB_INF_GUIDTYPE_FILE
,
949 DT
.TAB_INF_GUIDTYPE_HOB
,
950 DT
.TAB_INF_GUIDTYPE_FV
,
951 DT
.TAB_INF_GUIDTYPE_ST
,
952 DT
.TAB_INF_GUIDTYPE_TSG
,
953 DT
.TAB_INF_GUIDTYPE_GUID
,
954 DT
.TAB_INF_GUIDTYPE_PROTOCOL
,
955 DT
.TAB_INF_GUIDTYPE_PPI
,
956 DT
.TAB_INF_USAGE_UNDEFINED
)):
957 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
959 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
961 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
963 # Check Protocol Format in module INF
964 def MetaDataFileCheckModuleFileProtocolFormat(self
):
965 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFileProtocolFormat
or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
966 EdkLogger
.quiet("Check Protocol Format in module INF ...")
967 Table
= EccGlobalData
.gDb
.TblInf
969 select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID
970 """ % (Table
.Table
, MODEL_EFI_PROTOCOL
)
971 RecordSet
= Table
.Exec(SqlCommand
)
972 for Record
in RecordSet
:
976 InfPath
= self
.GetInfFilePathFromID(Record
[3])
977 Msg
= "The Protocol format of %s in INF file [%s] does not follow rules" % (Value1
, InfPath
)
978 if Value2
.startswith(DT
.TAB_SPECIAL_COMMENT
):
979 GuidCommentList
= Value2
[2:].split(DT
.TAB_SPECIAL_COMMENT
)
980 if len(GuidCommentList
) >= 1:
981 if not GuidCommentList
[0].strip().startswith((DT
.TAB_INF_USAGE_PRO
,
982 DT
.TAB_INF_USAGE_SOME_PRO
,
983 DT
.TAB_INF_USAGE_CON
,
984 DT
.TAB_INF_USAGE_SOME_CON
,
985 DT
.TAB_INF_USAGE_NOTIFY
,
986 DT
.TAB_INF_USAGE_TO_START
,
987 DT
.TAB_INF_USAGE_BY_START
,
988 DT
.TAB_INF_USAGE_UNDEFINED
)):
989 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PROTOCOL
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
991 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PROTOCOL
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
994 # Check Ppi Format in module INF
995 def MetaDataFileCheckModuleFilePpiFormat(self
):
996 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFilePpiFormat
or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
997 EdkLogger
.quiet("Check Ppi Format in module INF ...")
998 Table
= EccGlobalData
.gDb
.TblInf
1000 select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID
1001 """ % (Table
.Table
, MODEL_EFI_PPI
)
1002 RecordSet
= Table
.Exec(SqlCommand
)
1003 for Record
in RecordSet
:
1006 GuidCommentList
= []
1007 InfPath
= self
.GetInfFilePathFromID(Record
[3])
1008 Msg
= "The Ppi format of %s in INF file [%s] does not follow rules" % (Value1
, InfPath
)
1009 if Value2
.startswith(DT
.TAB_SPECIAL_COMMENT
):
1010 GuidCommentList
= Value2
[2:].split(DT
.TAB_SPECIAL_COMMENT
)
1011 if len(GuidCommentList
) >= 1:
1012 if not GuidCommentList
[0].strip().startswith((DT
.TAB_INF_USAGE_PRO
,
1013 DT
.TAB_INF_USAGE_SOME_PRO
,
1014 DT
.TAB_INF_USAGE_CON
,
1015 DT
.TAB_INF_USAGE_SOME_CON
,
1016 DT
.TAB_INF_USAGE_NOTIFY
,
1017 DT
.TAB_INF_USAGE_UNDEFINED
)):
1018 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PPI
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1020 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PPI
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1022 # Check Pcd Format in module INF
1023 def MetaDataFileCheckModuleFilePcdFormat(self
):
1024 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFilePcdFormat
or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1025 EdkLogger
.quiet("Check Pcd Format in module INF ...")
1026 Table
= EccGlobalData
.gDb
.TblInf
1028 select ID, Model, Value1, Value2, Usage, BelongsToFile from %s where Model >= %s and Model < %s group by ID
1029 """ % (Table
.Table
, MODEL_PCD
, MODEL_META_DATA_HEADER
)
1030 RecordSet
= Table
.Exec(SqlCommand
)
1031 for Record
in RecordSet
:
1033 PcdName
= Record
[2] + '.' + Record
[3]
1036 InfPath
= self
.GetInfFilePathFromID(Record
[5])
1037 Msg
= "The Pcd format of %s in INF file [%s] does not follow rules" % (PcdName
, InfPath
)
1038 if Usage
.startswith(DT
.TAB_SPECIAL_COMMENT
):
1039 PcdCommentList
= Usage
[2:].split(DT
.TAB_SPECIAL_COMMENT
)
1040 if len(PcdCommentList
) >= 1:
1041 if Model
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_FEATURE_FLAG
] \
1042 and not PcdCommentList
[0].strip().startswith((DT
.TAB_INF_USAGE_SOME_PRO
,
1043 DT
.TAB_INF_USAGE_CON
,
1044 DT
.TAB_INF_USAGE_UNDEFINED
)):
1045 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PCD
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1046 if Model
in [MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
] \
1047 and not PcdCommentList
[0].strip().startswith((DT
.TAB_INF_USAGE_PRO
,
1048 DT
.TAB_INF_USAGE_SOME_PRO
,
1049 DT
.TAB_INF_USAGE_CON
,
1050 DT
.TAB_INF_USAGE_SOME_CON
,
1051 DT
.TAB_INF_USAGE_UNDEFINED
)):
1052 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PCD
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1054 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PCD
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1056 # Check whether these is duplicate Guid/Ppi/Protocol name
1057 def CheckGuidProtocolPpi(self
, ErrorID
, Model
, Table
):
1059 if Model
== MODEL_EFI_GUID
:
1061 if Model
== MODEL_EFI_PROTOCOL
:
1063 if Model
== MODEL_EFI_PPI
:
1066 select A.ID, A.Value1 from %s as A, %s as B
1067 where A.Model = %s and B.Model = %s
1068 and A.Value1 = B.Value1 and A.ID <> B.ID
1069 and A.Scope1 = B.Scope1
1073 """ % (Table
.Table
, Table
.Table
, Model
, Model
)
1074 RecordSet
= Table
.Exec(SqlCommand
)
1075 for Record
in RecordSet
:
1076 if not EccGlobalData
.gException
.IsException(ErrorID
, Record
[1]):
1077 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])
1079 # Check whether these is duplicate Guid/Ppi/Protocol value
1080 def CheckGuidProtocolPpiValue(self
, ErrorID
, Model
):
1082 Table
= EccGlobalData
.gDb
.TblDec
1083 if Model
== MODEL_EFI_GUID
:
1085 if Model
== MODEL_EFI_PROTOCOL
:
1087 if Model
== MODEL_EFI_PPI
:
1090 select A.ID, A.Value1, A.Value2 from %s as A, %s as B
1091 where A.Model = %s and B.Model = %s
1092 and A.Value2 = B.Value2 and A.ID <> B.ID
1093 and A.Scope1 = B.Scope1 and A.Value1 <> B.Value1
1095 """ % (Table
.Table
, Table
.Table
, Model
, Model
)
1096 RecordSet
= Table
.Exec(SqlCommand
)
1097 for Record
in RecordSet
:
1098 if not EccGlobalData
.gException
.IsException(ErrorID
, Record
[1] + ':' + Record
[2]):
1099 EccGlobalData
.gDb
.TblReport
.Insert(ErrorID
, OtherMsg
="The %s value [%s] is used more than one time" % (Name
.upper(), Record
[2]), BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1101 # Naming Convention Check
1102 def NamingConventionCheck(self
):
1103 if EccGlobalData
.gConfig
.NamingConventionCheckDefineStatement
== '1' \
1104 or EccGlobalData
.gConfig
.NamingConventionCheckTypedefStatement
== '1' \
1105 or EccGlobalData
.gConfig
.NamingConventionCheckIfndefStatement
== '1' \
1106 or EccGlobalData
.gConfig
.NamingConventionCheckVariableName
== '1' \
1107 or EccGlobalData
.gConfig
.NamingConventionCheckSingleCharacterVariable
== '1' \
1108 or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1'\
1109 or EccGlobalData
.gConfig
.CheckAll
== '1':
1110 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
1112 if os
.path
.splitext(F
)[1] in ('.h', '.c'):
1113 FullName
= os
.path
.join(Dirpath
, F
)
1114 Id
= c
.GetTableID(FullName
)
1117 FileTable
= 'Identifier' + str(Id
)
1118 self
.NamingConventionCheckDefineStatement(FileTable
)
1119 self
.NamingConventionCheckTypedefStatement(FileTable
)
1120 self
.NamingConventionCheckIfndefStatement(FileTable
)
1121 self
.NamingConventionCheckVariableName(FileTable
)
1122 self
.NamingConventionCheckSingleCharacterVariable(FileTable
)
1124 self
.NamingConventionCheckPathName()
1125 self
.NamingConventionCheckFunctionName()
1127 # Check whether only capital letters are used for #define declarations
1128 def NamingConventionCheckDefineStatement(self
, FileTable
):
1129 if EccGlobalData
.gConfig
.NamingConventionCheckDefineStatement
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1130 EdkLogger
.quiet("Checking naming covention of #define statement ...")
1132 SqlCommand
= """select ID, Value from %s where Model = %s""" % (FileTable
, MODEL_IDENTIFIER_MACRO_DEFINE
)
1133 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1134 for Record
in RecordSet
:
1135 Name
= Record
[1].strip().split()[1]
1136 if Name
.find('(') != -1:
1137 Name
= Name
[0:Name
.find('(')]
1138 if Name
.upper() != Name
:
1139 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT
, Name
):
1140 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])
1142 # Check whether only capital letters are used for typedef declarations
1143 def NamingConventionCheckTypedefStatement(self
, FileTable
):
1144 if EccGlobalData
.gConfig
.NamingConventionCheckTypedefStatement
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1145 EdkLogger
.quiet("Checking naming covention of #typedef statement ...")
1147 SqlCommand
= """select ID, Name from %s where Model = %s""" % (FileTable
, MODEL_IDENTIFIER_TYPEDEF
)
1148 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1149 for Record
in RecordSet
:
1150 Name
= Record
[1].strip()
1151 if Name
!= '' and Name
!= None:
1153 Name
= Name
[1:Name
.find(')')]
1154 if Name
.find('(') > -1:
1155 Name
= Name
[Name
.find('(') + 1 : Name
.find(')')]
1156 Name
= Name
.replace('WINAPI', '')
1157 Name
= Name
.replace('*', '').strip()
1158 if Name
.upper() != Name
:
1159 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT
, Name
):
1160 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])
1162 # Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'.
1163 def NamingConventionCheckIfndefStatement(self
, FileTable
):
1164 if EccGlobalData
.gConfig
.NamingConventionCheckTypedefStatement
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1165 EdkLogger
.quiet("Checking naming covention of #ifndef statement ...")
1167 SqlCommand
= """select ID, Value from %s where Model = %s""" % (FileTable
, MODEL_IDENTIFIER_MACRO_IFNDEF
)
1168 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1169 for Record
in RecordSet
:
1170 Name
= Record
[1].replace('#ifndef', '').strip()
1171 if Name
[0] != '_' or Name
[-1] != '_':
1172 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT
, Name
):
1173 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])
1175 # Rule for path name, variable name and function name
1176 # 1. First character should be upper case
1177 # 2. Existing lower case in a word
1178 # 3. No space existence
1179 # Check whether the path name followed the rule
1180 def NamingConventionCheckPathName(self
):
1181 if EccGlobalData
.gConfig
.NamingConventionCheckPathName
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1182 EdkLogger
.quiet("Checking naming covention of file path name ...")
1183 Pattern
= re
.compile(r
'^[A-Z]+\S*[a-z]\S*$')
1184 SqlCommand
= """select ID, Name from File"""
1185 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1186 for Record
in RecordSet
:
1187 if not Pattern
.match(Record
[1]):
1188 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_PATH_NAME
, Record
[1]):
1189 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])
1191 # Rule for path name, variable name and function name
1192 # 1. First character should be upper case
1193 # 2. Existing lower case in a word
1194 # 3. No space existence
1195 # 4. Global variable name must start with a 'g'
1196 # Check whether the variable name followed the rule
1197 def NamingConventionCheckVariableName(self
, FileTable
):
1198 if EccGlobalData
.gConfig
.NamingConventionCheckVariableName
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1199 EdkLogger
.quiet("Checking naming covention of variable name ...")
1200 Pattern
= re
.compile(r
'^[A-Zgm]+\S*[a-z]\S*$')
1202 SqlCommand
= """select ID, Name from %s where Model = %s""" % (FileTable
, MODEL_IDENTIFIER_VARIABLE
)
1203 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1204 for Record
in RecordSet
:
1205 if not Pattern
.match(Record
[1]):
1206 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME
, Record
[1]):
1207 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])
1209 # Rule for path name, variable name and function name
1210 # 1. First character should be upper case
1211 # 2. Existing lower case in a word
1212 # 3. No space existence
1213 # Check whether the function name followed the rule
1214 def NamingConventionCheckFunctionName(self
):
1215 if EccGlobalData
.gConfig
.NamingConventionCheckFunctionName
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1216 EdkLogger
.quiet("Checking naming covention of function name ...")
1217 Pattern
= re
.compile(r
'^[A-Z]+\S*[a-z]\S*$')
1218 SqlCommand
= """select ID, Name from Function"""
1219 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1220 for Record
in RecordSet
:
1221 if not Pattern
.match(Record
[1]):
1222 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME
, Record
[1]):
1223 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])
1225 # Check whether NO use short variable name with single character
1226 def NamingConventionCheckSingleCharacterVariable(self
, FileTable
):
1227 if EccGlobalData
.gConfig
.NamingConventionCheckSingleCharacterVariable
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1228 EdkLogger
.quiet("Checking naming covention of single character variable name ...")
1230 SqlCommand
= """select ID, Name from %s where Model = %s""" % (FileTable
, MODEL_IDENTIFIER_VARIABLE
)
1231 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1232 for Record
in RecordSet
:
1233 Variable
= Record
[1].replace('*', '')
1234 if len(Variable
) == 1:
1235 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE
, Record
[1]):
1236 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])
1240 # This acts like the main() function for the script, unless it is 'import'ed into another
1243 if __name__
== '__main__':