2 # This file is used to define checkpoints used by ECC tool
4 # Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
5 # Copyright (c) 2008 - 2020, Intel Corporation. All rights reserved.<BR>
6 # SPDX-License-Identifier: BSD-2-Clause-Patent
8 from __future__
import absolute_import
9 import Common
.LongFilePathOs
as os
11 from CommonDataClass
.DataClass
import *
12 import Common
.DataType
as DT
13 from Ecc
.EccToolError
import *
14 from Ecc
.MetaDataParser
import ParseHeaderCommentSection
15 from Ecc
import EccGlobalData
17 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
18 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
22 # This class is to define checkpoints used by ECC tool
24 # @param object: Inherited from object class
30 # Check all required checkpoints
33 self
.MetaDataFileCheck()
35 self
.IncludeFileCheck()
36 self
.PredicateExpressionCheck()
37 self
.DeclAndDataTypeCheck()
38 self
.FunctionLayoutCheck()
39 self
.NamingConventionCheck()
40 self
.SmmCommParaCheck()
42 def SmmCommParaCheck(self
):
43 self
.SmmCommParaCheckBufferType()
46 # Check if SMM communication function has correct parameter type
47 # 1. Get function calling with instance./->Communicate() interface
48 # and make sure the protocol instance is of type EFI_SMM_COMMUNICATION_PROTOCOL.
49 # 2. Find the origin of the 2nd parameter of Communicate() interface, if -
50 # a. it is a local buffer on stack
52 # b. it is a global buffer, check the driver that holds the global buffer is of type DXE_RUNTIME_DRIVER
54 # c. it is a buffer by AllocatePage/AllocatePool (may be wrapped by nested function calls),
55 # check the EFI_MEMORY_TYPE to be EfiRuntimeServicesCode,EfiRuntimeServicesData,
56 # EfiACPIMemoryNVS or EfiReservedMemoryType
58 # d. it is a buffer located via EFI_SYSTEM_TABLE.ConfigurationTable (may be wrapped by nested function calls)
59 # report warning to indicate human code review.
60 # e. it is a buffer from other kind of pointers (may need to trace into nested function calls to locate),
61 # repeat checks in a.b.c and d.
62 def SmmCommParaCheckBufferType(self
):
63 if EccGlobalData
.gConfig
.SmmCommParaCheckBufferType
== '1' or EccGlobalData
.gConfig
.SmmCommParaCheckAll
== '1':
64 EdkLogger
.quiet("Checking SMM communication parameter type ...")
65 # Get all EFI_SMM_COMMUNICATION_PROTOCOL interface
67 for IdentifierTable
in EccGlobalData
.gIdentifierTableList
:
68 SqlCommand
= """select ID, Name, BelongsToFile from %s
69 where Modifier = 'EFI_SMM_COMMUNICATION_PROTOCOL*' """ % (IdentifierTable
)
70 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
72 for Record
in RecordSet
:
73 if Record
[1] not in CommApiList
:
74 CommApiList
.append(Record
[1])
75 # For each interface, check the second parameter
76 for CommApi
in CommApiList
:
77 for IdentifierTable
in EccGlobalData
.gIdentifierTableList
:
78 SqlCommand
= """select ID, Name, Value, BelongsToFile, StartLine from %s
79 where Name = '%s->Communicate' and Model = %s""" \
80 % (IdentifierTable
, CommApi
, MODEL_IDENTIFIER_FUNCTION_CALLING
)
81 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
83 # print IdentifierTable
84 for Record
in RecordSet
:
85 # Get the second parameter for Communicate function
86 SecondPara
= Record
[2].split(',')[1].strip()
87 SecondParaIndex
= None
88 if SecondPara
.startswith('&'):
89 SecondPara
= SecondPara
[1:]
90 if SecondPara
.endswith(']'):
91 SecondParaIndex
= SecondPara
[SecondPara
.find('[') + 1:-1]
92 SecondPara
= SecondPara
[:SecondPara
.find('[')]
95 # Get the BelongsToFile
96 BelongsToFile
= Record
[3]
97 # Get the source file path
98 SqlCommand
= """select FullPath from File where ID = %s""" % BelongsToFile
99 NewRecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
100 FullPath
= NewRecordSet
[0][0]
101 # Get the line no of function calling
102 StartLine
= Record
[4]
103 # Get the module type
104 SqlCommand
= """select Value3 from INF where BelongsToFile = (select ID from File
105 where Path = (select Path from File where ID = %s) and Model = 1011)
106 and Value2 = 'MODULE_TYPE'""" % BelongsToFile
107 NewRecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
108 ModuleType
= NewRecordSet
[0][0] if NewRecordSet
else None
110 # print BelongsToFile, FullPath, StartLine, ModuleType, SecondPara
112 Value
= FindPara(FullPath
, SecondPara
, StartLine
)
113 # Find the value of the parameter
115 if 'AllocatePage' in Value \
116 or 'AllocatePool' in Value \
117 or 'AllocateRuntimePool' in Value \
118 or 'AllocateZeroPool' in Value
:
122 if not EccGlobalData
.gException
.IsException(
123 ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE
, Value
):
124 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE
,
125 OtherMsg
="Please review the buffer type"
126 + "is correct or not. If it is correct" +
127 " please add [%s] to exception list"
129 BelongsToTable
=IdentifierTable
,
132 if not EccGlobalData
.gException
.IsException(
133 ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE
, Value
):
134 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE
,
135 OtherMsg
="Please review the buffer type"
136 + "is correct or not. If it is correct" +
137 " please add [%s] to exception list"
139 BelongsToTable
=IdentifierTable
,
143 # Not find the value of the parameter
145 SqlCommand
= """select ID, Modifier, Name, Value, Model, BelongsToFunction from %s
146 where Name = '%s' and StartLine < %s order by StartLine DESC""" \
147 % (IdentifierTable
, SecondPara
, StartLine
)
148 NewRecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
150 Value
= NewRecordSet
[0][1]
151 if 'AllocatePage' in Value \
152 or 'AllocatePool' in Value \
153 or 'AllocateRuntimePool' in Value \
154 or 'AllocateZeroPool' in Value
:
157 if not EccGlobalData
.gException
.IsException(
158 ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE
, Value
):
159 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE
,
160 OtherMsg
="Please review the buffer type"
161 + "is correct or not. If it is correct" +
162 " please add [%s] to exception list"
164 BelongsToTable
=IdentifierTable
,
171 if EccGlobalData
.gConfig
.GeneralCheckUni
== '1' or EccGlobalData
.gConfig
.GeneralCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
172 EdkLogger
.quiet("Checking whether UNI file is UTF-16 ...")
173 SqlCommand
= """select ID, FullPath, ExtName from File where ExtName like 'uni'"""
174 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
175 for Record
in RecordSet
:
177 FileIn
= open(File
, 'rb').read(2)
178 if FileIn
!= '\xff\xfe':
179 OtherMsg
= "File %s is not a valid UTF-16 UNI file" % Record
[1]
180 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_GENERAL_CHECK_UNI
, OtherMsg
=OtherMsg
, BelongsToTable
='File', BelongsToItem
=Record
[0])
183 def GeneralCheck(self
):
184 self
.GeneralCheckNonAcsii()
186 self
.GeneralCheckNoTab()
187 self
.GeneralCheckLineEnding()
188 self
.GeneralCheckTrailingWhiteSpaceLine()
190 # Check whether NO Tab is used, replaced with spaces
191 def GeneralCheckNoTab(self
):
192 if EccGlobalData
.gConfig
.GeneralCheckNoTab
== '1' or EccGlobalData
.gConfig
.GeneralCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
193 EdkLogger
.quiet("Checking No TAB used in file ...")
194 SqlCommand
= """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')"""
195 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
196 for Record
in RecordSet
:
197 if Record
[2].upper() not in EccGlobalData
.gConfig
.BinaryExtList
:
198 op
= open(Record
[1]).readlines()
206 OtherMsg
= "File %s has TAB char at line %s column %s" % (Record
[1], IndexOfLine
, IndexOfChar
)
207 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_GENERAL_CHECK_NO_TAB
, OtherMsg
=OtherMsg
, BelongsToTable
='File', BelongsToItem
=Record
[0])
209 # Check Only use CRLF (Carriage Return Line Feed) line endings.
210 def GeneralCheckLineEnding(self
):
211 if EccGlobalData
.gConfig
.GeneralCheckLineEnding
== '1' or EccGlobalData
.gConfig
.GeneralCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
212 EdkLogger
.quiet("Checking line ending in file ...")
213 SqlCommand
= """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')"""
214 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
215 for Record
in RecordSet
:
216 if Record
[2].upper() not in EccGlobalData
.gConfig
.BinaryExtList
:
217 op
= open(Record
[1], 'rb').readlines()
221 if not bytes
.decode(Line
).endswith('\r\n'):
222 OtherMsg
= "File %s has invalid line ending at line %s" % (Record
[1], IndexOfLine
)
223 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_GENERAL_CHECK_INVALID_LINE_ENDING
, OtherMsg
=OtherMsg
, BelongsToTable
='File', BelongsToItem
=Record
[0])
225 # Check if there is no trailing white space in one line.
226 def GeneralCheckTrailingWhiteSpaceLine(self
):
227 if EccGlobalData
.gConfig
.GeneralCheckTrailingWhiteSpaceLine
== '1' or EccGlobalData
.gConfig
.GeneralCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
228 EdkLogger
.quiet("Checking trailing white space line in file ...")
229 SqlCommand
= """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')"""
230 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
231 for Record
in RecordSet
:
232 if Record
[2].upper() not in EccGlobalData
.gConfig
.BinaryExtList
:
233 op
= open(Record
[1], 'r').readlines()
237 if Line
.replace('\r', '').replace('\n', '').endswith(' '):
238 OtherMsg
= "File %s has trailing white spaces at line %s" % (Record
[1], IndexOfLine
)
239 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_GENERAL_CHECK_TRAILING_WHITE_SPACE_LINE
, OtherMsg
=OtherMsg
, BelongsToTable
='File', BelongsToItem
=Record
[0])
241 # Check whether file has non ACSII char
242 def GeneralCheckNonAcsii(self
):
243 if EccGlobalData
.gConfig
.GeneralCheckNonAcsii
== '1' or EccGlobalData
.gConfig
.GeneralCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
244 EdkLogger
.quiet("Checking Non-ACSII char in file ...")
245 SqlCommand
= """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')"""
246 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
247 for Record
in RecordSet
:
248 if Record
[2].upper() not in EccGlobalData
.gConfig
.BinaryExtList
:
249 op
= open(Record
[1]).readlines()
257 OtherMsg
= "File %s has Non-ASCII char at line %s column %s" % (Record
[1], IndexOfLine
, IndexOfChar
)
258 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_GENERAL_CHECK_NON_ACSII
, OtherMsg
=OtherMsg
, BelongsToTable
='File', BelongsToItem
=Record
[0])
260 # C Function Layout Checking
261 def FunctionLayoutCheck(self
):
262 self
.FunctionLayoutCheckReturnType()
263 self
.FunctionLayoutCheckModifier()
264 self
.FunctionLayoutCheckName()
265 self
.FunctionLayoutCheckPrototype()
266 self
.FunctionLayoutCheckBody()
267 self
.FunctionLayoutCheckLocalVariable()
268 self
.FunctionLayoutCheckDeprecated()
270 # To check if the deprecated functions are used
271 def FunctionLayoutCheckDeprecated(self
):
272 if EccGlobalData
.gConfig
.CFunctionLayoutCheckNoDeprecated
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
273 EdkLogger
.quiet("Checking function no deprecated one being used ...")
275 DeprecatedFunctionSet
= ('UnicodeValueToString',
276 'AsciiValueToString',
281 'UnicodeStrToAsciiStr',
286 'AsciiStrToUnicodeStr',
312 'GetEfiGlobalVariable',
315 for IdentifierTable
in EccGlobalData
.gIdentifierTableList
:
316 SqlCommand
= """select ID, Name, BelongsToFile from %s
317 where Model = %s """ % (IdentifierTable
, MODEL_IDENTIFIER_FUNCTION_CALLING
)
318 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
319 for Record
in RecordSet
:
320 for Key
in DeprecatedFunctionSet
:
322 if not EccGlobalData
.gException
.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_DEPRECATE
, Key
):
323 OtherMsg
= 'The function [%s] is deprecated which should NOT be used' % Key
324 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_DEPRECATE
,
326 BelongsToTable
=IdentifierTable
,
327 BelongsToItem
=Record
[0])
330 IgnoredPattern
= c
.GetIgnoredDirListPattern()
331 for Dirpath
, Dirnames
, Filenames
in os
.walk(EccGlobalData
.gTarget
):
333 Dirname
= os
.path
.join(Dirpath
, Dir
)
334 if os
.path
.islink(Dirname
):
335 Dirname
= os
.path
.realpath(Dirname
)
336 if os
.path
.isdir(Dirname
):
337 # symlinks to directories are treated as directories
339 Dirnames
.append(Dirname
)
340 if IgnoredPattern
.match(Dirpath
.upper()):
342 for f
in Filenames
[:]:
343 if f
.lower() in EccGlobalData
.gConfig
.SkipFileList
:
345 yield (Dirpath
, Dirnames
, Filenames
)
347 # Check whether return type exists and in the first line
348 def FunctionLayoutCheckReturnType(self
):
349 if EccGlobalData
.gConfig
.CFunctionLayoutCheckReturnType
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
350 EdkLogger
.quiet("Checking function layout return type ...")
352 # for Dirpath, Dirnames, Filenames in self.WalkTree():
353 # for F in Filenames:
354 # if os.path.splitext(F)[1] in ('.c', '.h'):
355 # FullName = os.path.join(Dirpath, F)
356 # c.CheckFuncLayoutReturnType(FullName)
357 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
358 c
.CheckFuncLayoutReturnType(FullName
)
360 # Check whether any optional functional modifiers exist and next to the return type
361 def FunctionLayoutCheckModifier(self
):
362 if EccGlobalData
.gConfig
.CFunctionLayoutCheckOptionalFunctionalModifier
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
363 EdkLogger
.quiet("Checking function layout modifier ...")
365 # for Dirpath, Dirnames, Filenames in self.WalkTree():
366 # for F in Filenames:
367 # if os.path.splitext(F)[1] in ('.c', '.h'):
368 # FullName = os.path.join(Dirpath, F)
369 # c.CheckFuncLayoutModifier(FullName)
370 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
371 c
.CheckFuncLayoutModifier(FullName
)
373 # Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list
374 # Check whether the closing parenthesis is on its own line and also indented two spaces
375 def FunctionLayoutCheckName(self
):
376 if EccGlobalData
.gConfig
.CFunctionLayoutCheckFunctionName
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
377 EdkLogger
.quiet("Checking function layout function name ...")
379 # for Dirpath, Dirnames, Filenames in self.WalkTree():
380 # for F in Filenames:
381 # if os.path.splitext(F)[1] in ('.c', '.h'):
382 # FullName = os.path.join(Dirpath, F)
383 # c.CheckFuncLayoutName(FullName)
384 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
385 c
.CheckFuncLayoutName(FullName
)
387 # Check whether the function prototypes in include files have the same form as function definitions
388 def FunctionLayoutCheckPrototype(self
):
389 if EccGlobalData
.gConfig
.CFunctionLayoutCheckFunctionPrototype
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
390 EdkLogger
.quiet("Checking function layout function prototype ...")
392 # for Dirpath, Dirnames, Filenames in self.WalkTree():
393 # for F in Filenames:
394 # if os.path.splitext(F)[1] in ('.c'):
395 # FullName = os.path.join(Dirpath, F)
396 # EdkLogger.quiet("[PROTOTYPE]" + FullName)
397 # c.CheckFuncLayoutPrototype(FullName)
398 for FullName
in EccGlobalData
.gCFileList
:
399 EdkLogger
.quiet("[PROTOTYPE]" + FullName
)
400 c
.CheckFuncLayoutPrototype(FullName
)
402 # Check whether the body of a function is contained by open and close braces that must be in the first column
403 def FunctionLayoutCheckBody(self
):
404 if EccGlobalData
.gConfig
.CFunctionLayoutCheckFunctionBody
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
405 EdkLogger
.quiet("Checking function layout function body ...")
407 # for Dirpath, Dirnames, Filenames in self.WalkTree():
408 # for F in Filenames:
409 # if os.path.splitext(F)[1] in ('.c'):
410 # FullName = os.path.join(Dirpath, F)
411 # c.CheckFuncLayoutBody(FullName)
412 for FullName
in EccGlobalData
.gCFileList
:
413 c
.CheckFuncLayoutBody(FullName
)
415 # Check whether the data declarations is the first code in a module.
416 # self.CFunctionLayoutCheckDataDeclaration = 1
417 # Check whether no initialization of a variable as part of its declaration
418 def FunctionLayoutCheckLocalVariable(self
):
419 if EccGlobalData
.gConfig
.CFunctionLayoutCheckNoInitOfVariable
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
420 EdkLogger
.quiet("Checking function layout local variables ...")
422 # for Dirpath, Dirnames, Filenames in self.WalkTree():
423 # for F in Filenames:
424 # if os.path.splitext(F)[1] in ('.c'):
425 # FullName = os.path.join(Dirpath, F)
426 # c.CheckFuncLayoutLocalVariable(FullName)
428 for FullName
in EccGlobalData
.gCFileList
:
429 c
.CheckFuncLayoutLocalVariable(FullName
)
431 # Check whether no use of STATIC for functions
432 # self.CFunctionLayoutCheckNoStatic = 1
434 # Declarations and Data Types Checking
435 def DeclAndDataTypeCheck(self
):
436 self
.DeclCheckNoUseCType()
437 self
.DeclCheckInOutModifier()
438 self
.DeclCheckEFIAPIModifier()
439 self
.DeclCheckEnumeratedType()
440 self
.DeclCheckStructureDeclaration()
441 self
.DeclCheckSameStructure()
442 self
.DeclCheckUnionType()
445 # Check whether no use of int, unsigned, char, void, long in any .c, .h or .asl files.
446 def DeclCheckNoUseCType(self
):
447 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckNoUseCType
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
448 EdkLogger
.quiet("Checking Declaration No use C type ...")
450 # for Dirpath, Dirnames, Filenames in self.WalkTree():
451 # for F in Filenames:
452 # if os.path.splitext(F)[1] in ('.h', '.c'):
453 # FullName = os.path.join(Dirpath, F)
454 # c.CheckDeclNoUseCType(FullName)
455 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
456 c
.CheckDeclNoUseCType(FullName
)
458 # 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
459 def DeclCheckInOutModifier(self
):
460 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckInOutModifier
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
461 EdkLogger
.quiet("Checking Declaration argument modifier ...")
463 # for Dirpath, Dirnames, Filenames in self.WalkTree():
464 # for F in Filenames:
465 # if os.path.splitext(F)[1] in ('.h', '.c'):
466 # FullName = os.path.join(Dirpath, F)
467 # c.CheckDeclArgModifier(FullName)
468 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
469 c
.CheckDeclArgModifier(FullName
)
471 # Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols
472 def DeclCheckEFIAPIModifier(self
):
473 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckEFIAPIModifier
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
476 # Check whether Enumerated Type has a 'typedef' and the name is capital
477 def DeclCheckEnumeratedType(self
):
478 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckEnumeratedType
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
479 EdkLogger
.quiet("Checking Declaration enum typedef ...")
481 # for Dirpath, Dirnames, Filenames in self.WalkTree():
482 # for F in Filenames:
483 # if os.path.splitext(F)[1] in ('.h', '.c'):
484 # FullName = os.path.join(Dirpath, F)
485 # EdkLogger.quiet("[ENUM]" + FullName)
486 # c.CheckDeclEnumTypedef(FullName)
487 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
488 EdkLogger
.quiet("[ENUM]" + FullName
)
489 c
.CheckDeclEnumTypedef(FullName
)
491 # Check whether Structure Type has a 'typedef' and the name is capital
492 def DeclCheckStructureDeclaration(self
):
493 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckStructureDeclaration
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
494 EdkLogger
.quiet("Checking Declaration struct typedef ...")
496 # for Dirpath, Dirnames, Filenames in self.WalkTree():
497 # for F in Filenames:
498 # if os.path.splitext(F)[1] in ('.h', '.c'):
499 # FullName = os.path.join(Dirpath, F)
500 # EdkLogger.quiet("[STRUCT]" + FullName)
501 # c.CheckDeclStructTypedef(FullName)
502 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
503 EdkLogger
.quiet("[STRUCT]" + FullName
)
504 c
.CheckDeclStructTypedef(FullName
)
506 # Check whether having same Structure
507 def DeclCheckSameStructure(self
):
508 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckSameStructure
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
509 EdkLogger
.quiet("Checking same struct ...")
511 for IdentifierTable
in EccGlobalData
.gIdentifierTableList
:
512 SqlCommand
= """select ID, Name, BelongsToFile from %s where Model = %s""" % (IdentifierTable
, MODEL_IDENTIFIER_STRUCTURE
)
513 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
514 for Record
in RecordSet
:
516 if Record
[1] not in AllStructure
.keys():
517 AllStructure
[Record
[1]] = Record
[2]
519 ID
= AllStructure
[Record
[1]]
520 SqlCommand
= """select FullPath from File where ID = %s """ % ID
521 NewRecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
522 OtherMsg
= "The structure name '%s' is duplicate" % Record
[1]
523 if NewRecordSet
!= []:
524 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])
525 if not EccGlobalData
.gException
.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE
, Record
[1]):
526 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE
, OtherMsg
=OtherMsg
, BelongsToTable
=IdentifierTable
, BelongsToItem
=Record
[0])
528 # Check whether Union Type has a 'typedef' and the name is capital
529 def DeclCheckUnionType(self
):
530 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckUnionType
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
531 EdkLogger
.quiet("Checking Declaration union typedef ...")
533 # for Dirpath, Dirnames, Filenames in self.WalkTree():
534 # for F in Filenames:
535 # if os.path.splitext(F)[1] in ('.h', '.c'):
536 # FullName = os.path.join(Dirpath, F)
537 # EdkLogger.quiet("[UNION]" + FullName)
538 # c.CheckDeclUnionTypedef(FullName)
539 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
540 EdkLogger
.quiet("[UNION]" + FullName
)
541 c
.CheckDeclUnionTypedef(FullName
)
543 # Predicate Expression Checking
544 def PredicateExpressionCheck(self
):
545 self
.PredicateExpressionCheckBooleanValue()
546 self
.PredicateExpressionCheckNonBooleanOperator()
547 self
.PredicateExpressionCheckComparisonNullType()
549 # Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE
550 def PredicateExpressionCheckBooleanValue(self
):
551 if EccGlobalData
.gConfig
.PredicateExpressionCheckBooleanValue
== '1' or EccGlobalData
.gConfig
.PredicateExpressionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
552 EdkLogger
.quiet("Checking predicate expression Boolean value ...")
554 # for Dirpath, Dirnames, Filenames in self.WalkTree():
555 # for F in Filenames:
556 # if os.path.splitext(F)[1] in ('.c'):
557 # FullName = os.path.join(Dirpath, F)
558 # EdkLogger.quiet("[BOOLEAN]" + FullName)
559 # c.CheckBooleanValueComparison(FullName)
560 for FullName
in EccGlobalData
.gCFileList
:
561 EdkLogger
.quiet("[BOOLEAN]" + FullName
)
562 c
.CheckBooleanValueComparison(FullName
)
564 # Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=).
565 def PredicateExpressionCheckNonBooleanOperator(self
):
566 if EccGlobalData
.gConfig
.PredicateExpressionCheckNonBooleanOperator
== '1' or EccGlobalData
.gConfig
.PredicateExpressionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
567 EdkLogger
.quiet("Checking predicate expression Non-Boolean variable...")
569 # for Dirpath, Dirnames, Filenames in self.WalkTree():
570 # for F in Filenames:
571 # if os.path.splitext(F)[1] in ('.c'):
572 # FullName = os.path.join(Dirpath, F)
573 # EdkLogger.quiet("[NON-BOOLEAN]" + FullName)
574 # c.CheckNonBooleanValueComparison(FullName)
575 for FullName
in EccGlobalData
.gCFileList
:
576 EdkLogger
.quiet("[NON-BOOLEAN]" + FullName
)
577 c
.CheckNonBooleanValueComparison(FullName
)
579 # Check whether a comparison of any pointer to zero must be done via the NULL type
580 def PredicateExpressionCheckComparisonNullType(self
):
581 if EccGlobalData
.gConfig
.PredicateExpressionCheckComparisonNullType
== '1' or EccGlobalData
.gConfig
.PredicateExpressionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
582 EdkLogger
.quiet("Checking predicate expression NULL pointer ...")
584 # for Dirpath, Dirnames, Filenames in self.WalkTree():
585 # for F in Filenames:
586 # if os.path.splitext(F)[1] in ('.c'):
587 # FullName = os.path.join(Dirpath, F)
588 # EdkLogger.quiet("[POINTER]" + FullName)
589 # c.CheckPointerNullComparison(FullName)
590 for FullName
in EccGlobalData
.gCFileList
:
591 EdkLogger
.quiet("[POINTER]" + FullName
)
592 c
.CheckPointerNullComparison(FullName
)
594 # Include file checking
595 def IncludeFileCheck(self
):
596 self
.IncludeFileCheckIfndef()
597 self
.IncludeFileCheckData()
598 self
.IncludeFileCheckSameName()
600 # Check whether having include files with same name
601 def IncludeFileCheckSameName(self
):
602 if EccGlobalData
.gConfig
.IncludeFileCheckSameName
== '1' or EccGlobalData
.gConfig
.IncludeFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
603 EdkLogger
.quiet("Checking same header file name ...")
604 SqlCommand
= """select ID, FullPath from File
605 where Model = 1002 order by Name """
607 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
608 for Record
in RecordSet
:
609 List
= Record
[1].replace('/', '\\').split('\\')
611 Key
= List
[-2] + '\\' + List
[-1]
614 if Key
not in RecordDict
:
615 RecordDict
[Key
] = [Record
]
617 RecordDict
[Key
].append(Record
)
619 for Key
in RecordDict
:
620 if len(RecordDict
[Key
]) > 1:
621 for Item
in RecordDict
[Key
]:
622 Path
= mws
.relpath(Item
[1], EccGlobalData
.gWorkspace
)
623 if not EccGlobalData
.gException
.IsException(ERROR_INCLUDE_FILE_CHECK_NAME
, Path
):
624 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_INCLUDE_FILE_CHECK_NAME
, OtherMsg
="The file name for [%s] is duplicate" % Path
, BelongsToTable
='File', BelongsToItem
=Item
[0])
626 # Check whether all include file contents is guarded by a #ifndef statement.
627 def IncludeFileCheckIfndef(self
):
628 if EccGlobalData
.gConfig
.IncludeFileCheckIfndefStatement
== '1' or EccGlobalData
.gConfig
.IncludeFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
629 EdkLogger
.quiet("Checking header file ifndef ...")
631 # for Dirpath, Dirnames, Filenames in self.WalkTree():
632 # for F in Filenames:
633 # if os.path.splitext(F)[1] in ('.h'):
634 # FullName = os.path.join(Dirpath, F)
635 # MsgList = c.CheckHeaderFileIfndef(FullName)
636 for FullName
in EccGlobalData
.gHFileList
:
637 MsgList
= c
.CheckHeaderFileIfndef(FullName
)
639 # Check whether include files NOT contain code or define data variables
640 def IncludeFileCheckData(self
):
641 if EccGlobalData
.gConfig
.IncludeFileCheckData
== '1' or EccGlobalData
.gConfig
.IncludeFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
642 EdkLogger
.quiet("Checking header file data ...")
644 # Get all typedef functions
646 for IdentifierTable
in EccGlobalData
.gIdentifierTableList
:
647 SqlCommand
= """select Name from %s
648 where Model = %s """ % (IdentifierTable
, MODEL_IDENTIFIER_TYPEDEF
)
649 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
650 for Record
in RecordSet
:
651 if Record
[0].startswith('('):
652 gAllTypedefFun
.append(Record
[0])
654 # for Dirpath, Dirnames, Filenames in self.WalkTree():
655 # for F in Filenames:
656 # if os.path.splitext(F)[1] in ('.h'):
657 # FullName = os.path.join(Dirpath, F)
658 # MsgList = c.CheckHeaderFileData(FullName)
659 for FullName
in EccGlobalData
.gHFileList
:
660 MsgList
= c
.CheckHeaderFileData(FullName
, gAllTypedefFun
)
662 # Doxygen document checking
663 def DoxygenCheck(self
):
664 self
.DoxygenCheckFileHeader()
665 self
.DoxygenCheckFunctionHeader()
666 self
.DoxygenCheckCommentDescription()
667 self
.DoxygenCheckCommentFormat()
668 self
.DoxygenCheckCommand()
670 # Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5
671 def DoxygenCheckFileHeader(self
):
672 if EccGlobalData
.gConfig
.DoxygenCheckFileHeader
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
673 EdkLogger
.quiet("Checking Doxygen file header ...")
675 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
677 Ext
= os
.path
.splitext(F
)[1]
678 if Ext
in ('.h', '.c'):
679 FullName
= os
.path
.join(Dirpath
, F
)
680 MsgList
= c
.CheckFileHeaderDoxygenComments(FullName
)
681 elif Ext
in ('.inf', '.dec', '.dsc', '.fdf'):
682 FullName
= os
.path
.join(Dirpath
, F
)
683 op
= open(FullName
).readlines()
686 CurrentSection
= MODEL_UNKNOWN
687 HeaderSectionLines
= []
688 HeaderCommentStart
= False
689 HeaderCommentEnd
= False
691 for Line
in FileLinesList
:
694 if (LineNo
< len(FileLinesList
) - 1):
695 NextLine
= FileLinesList
[LineNo
].strip()
700 if (Line
== '' or not Line
) and LineNo
== len(FileLinesList
):
701 LastSectionFalg
= True
704 # check whether file header comment section started
706 if Line
.startswith('#') and \
707 (Line
.find('@file') > -1) and \
708 not HeaderCommentStart
:
709 if CurrentSection
!= MODEL_UNKNOWN
:
710 SqlStatement
= """ select ID from File where FullPath like '%s'""" % FullName
711 ResultSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlStatement
)
712 for Result
in ResultSet
:
713 Msg
= 'INF/DEC/DSC/FDF file header comment should begin with ""## @file"" or ""# @file""at the very top file'
714 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER
, Msg
, "File", Result
[0])
717 CurrentSection
= MODEL_IDENTIFIER_FILE_HEADER
719 # Append the first line to section lines.
721 HeaderSectionLines
.append((Line
, LineNo
))
722 HeaderCommentStart
= True
726 # Collect Header content.
728 if (Line
.startswith('#') and CurrentSection
== MODEL_IDENTIFIER_FILE_HEADER
) and\
729 HeaderCommentStart
and not Line
.startswith('##') and not\
730 HeaderCommentEnd
and NextLine
!= '':
731 HeaderSectionLines
.append((Line
, LineNo
))
736 if (Line
.startswith('##') or not Line
.strip().startswith("#")) and HeaderCommentStart \
737 and not HeaderCommentEnd
:
738 if Line
.startswith('##'):
739 HeaderCommentEnd
= True
740 HeaderSectionLines
.append((Line
, LineNo
))
741 ParseHeaderCommentSection(HeaderSectionLines
, FullName
)
743 if HeaderCommentStart
== False:
744 SqlStatement
= """ select ID from File where FullPath like '%s'""" % FullName
745 ResultSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlStatement
)
746 for Result
in ResultSet
:
747 Msg
= 'INF/DEC/DSC/FDF file header comment should begin with ""## @file"" or ""# @file"" at the very top file'
748 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER
, Msg
, "File", Result
[0])
749 if HeaderCommentEnd
== False:
750 SqlStatement
= """ select ID from File where FullPath like '%s'""" % FullName
751 ResultSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlStatement
)
752 for Result
in ResultSet
:
753 Msg
= 'INF/DEC/DSC/FDF file header comment should end with ""##"" at the end of file header comment block'
754 # Check whether File header Comment End with '##'
755 if EccGlobalData
.gConfig
.HeaderCheckFileCommentEnd
== '1' or EccGlobalData
.gConfig
.HeaderCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
756 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER
, Msg
, "File", Result
[0])
760 # Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5
761 def DoxygenCheckFunctionHeader(self
):
762 if EccGlobalData
.gConfig
.DoxygenCheckFunctionHeader
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
763 EdkLogger
.quiet("Checking Doxygen function header ...")
765 # for Dirpath, Dirnames, Filenames in self.WalkTree():
766 # for F in Filenames:
767 # if os.path.splitext(F)[1] in ('.h', '.c'):
768 # FullName = os.path.join(Dirpath, F)
769 # MsgList = c.CheckFuncHeaderDoxygenComments(FullName)
770 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
771 MsgList
= c
.CheckFuncHeaderDoxygenComments(FullName
)
774 # Check whether the first line of text in a comment block is a brief description of the element being documented.
775 # The brief description must end with a period.
776 def DoxygenCheckCommentDescription(self
):
777 if EccGlobalData
.gConfig
.DoxygenCheckCommentDescription
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
780 # Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.
781 def DoxygenCheckCommentFormat(self
):
782 if EccGlobalData
.gConfig
.DoxygenCheckCommentFormat
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
783 EdkLogger
.quiet("Checking Doxygen comment ///< ...")
785 # for Dirpath, Dirnames, Filenames in self.WalkTree():
786 # for F in Filenames:
787 # if os.path.splitext(F)[1] in ('.h', '.c'):
788 # FullName = os.path.join(Dirpath, F)
789 # MsgList = c.CheckDoxygenTripleForwardSlash(FullName)
790 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
791 MsgList
= c
.CheckDoxygenTripleForwardSlash(FullName
)
793 # Check whether only Doxygen commands allowed to mark the code are @bug and @todo.
794 def DoxygenCheckCommand(self
):
795 if EccGlobalData
.gConfig
.DoxygenCheckCommand
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
796 EdkLogger
.quiet("Checking Doxygen command ...")
798 # for Dirpath, Dirnames, Filenames in self.WalkTree():
799 # for F in Filenames:
800 # if os.path.splitext(F)[1] in ('.h', '.c'):
801 # FullName = os.path.join(Dirpath, F)
802 # MsgList = c.CheckDoxygenCommand(FullName)
803 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
804 MsgList
= c
.CheckDoxygenCommand(FullName
)
806 # Meta-Data File Processing Checking
807 def MetaDataFileCheck(self
):
808 self
.MetaDataFileCheckPathName()
809 self
.MetaDataFileCheckGenerateFileList()
810 self
.MetaDataFileCheckLibraryInstance()
811 self
.MetaDataFileCheckLibraryInstanceDependent()
812 self
.MetaDataFileCheckLibraryInstanceOrder()
813 self
.MetaDataFileCheckLibraryNoUse()
814 self
.MetaDataFileCheckLibraryDefinedInDec()
815 self
.MetaDataFileCheckBinaryInfInFdf()
816 self
.MetaDataFileCheckPcdDuplicate()
817 self
.MetaDataFileCheckPcdFlash()
818 self
.MetaDataFileCheckPcdNoUse()
819 self
.MetaDataFileCheckGuidDuplicate()
820 self
.MetaDataFileCheckModuleFileNoUse()
821 self
.MetaDataFileCheckPcdType()
822 self
.MetaDataFileCheckModuleFileGuidDuplication()
823 self
.MetaDataFileCheckModuleFileGuidFormat()
824 self
.MetaDataFileCheckModuleFileProtocolFormat()
825 self
.MetaDataFileCheckModuleFilePpiFormat()
826 self
.MetaDataFileCheckModuleFilePcdFormat()
828 # Check whether each file defined in meta-data exists
829 def MetaDataFileCheckPathName(self
):
830 if EccGlobalData
.gConfig
.MetaDataFileCheckPathName
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
831 # This item is covered when parsing Inf/Dec/Dsc files
834 # Generate a list for all files defined in meta-data files
835 def MetaDataFileCheckGenerateFileList(self
):
836 if EccGlobalData
.gConfig
.MetaDataFileCheckGenerateFileList
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
837 # This item is covered when parsing Inf/Dec/Dsc files
840 # Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.
841 # Each Library Instance must specify the Supported Module Types in its Inf file,
842 # and any module specifying the library instance must be one of the supported types.
843 def MetaDataFileCheckLibraryInstance(self
):
844 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryInstance
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
845 EdkLogger
.quiet("Checking for library instance type issue ...")
846 SqlCommand
= """select A.ID, A.Value3, B.Value3 from Inf as A left join Inf as B
847 where A.Value2 = 'LIBRARY_CLASS' and A.Model = %s
848 and B.Value2 = 'MODULE_TYPE' and B.Model = %s and A.BelongsToFile = B.BelongsToFile
849 group by A.BelongsToFile""" % (MODEL_META_DATA_HEADER
, MODEL_META_DATA_HEADER
)
850 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
852 for Record
in RecordSet
:
853 List
= Record
[1].split('|', 1)
856 SupModType
= DT
.SUP_MODULE_LIST_STRING
.split(DT
.TAB_VALUE_SPLIT
)
858 SupModType
= List
[1].split()
860 if List
[0] not in LibraryClasses
:
861 LibraryClasses
[List
[0]] = SupModType
863 for Item
in SupModType
:
864 if Item
not in LibraryClasses
[List
[0]]:
865 LibraryClasses
[List
[0]].append(Item
)
867 if Record
[2] != DT
.SUP_MODULE_BASE
and Record
[2] not in SupModType
:
868 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])
870 SqlCommand
= """select A.ID, A.Value1, B.Value3 from Inf as A left join Inf as B
871 where A.Model = %s and B.Value2 = '%s' and B.Model = %s
872 and B.BelongsToFile = A.BelongsToFile""" \
873 % (MODEL_EFI_LIBRARY_CLASS
, 'MODULE_TYPE', MODEL_META_DATA_HEADER
)
874 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
875 # Merge all LibraryClasses' supmodlist
877 for Record
in RecordSet
:
878 if Record
[1] not in RecordDict
:
879 RecordDict
[Record
[1]] = [str(Record
[2])]
881 if Record
[2] not in RecordDict
[Record
[1]]:
882 RecordDict
[Record
[1]].append(Record
[2])
884 for Record
in RecordSet
:
885 if Record
[1] in LibraryClasses
:
886 if Record
[2] not in LibraryClasses
[Record
[1]] and DT
.SUP_MODULE_BASE
not in RecordDict
[Record
[1]]:
887 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1
, Record
[1]):
888 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])
890 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1
, Record
[1]):
891 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])
893 # Check whether a Library Instance has been defined for all dependent library classes
894 def MetaDataFileCheckLibraryInstanceDependent(self
):
895 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryInstanceDependent
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
896 EdkLogger
.quiet("Checking for library instance dependent issue ...")
897 SqlCommand
= """select ID, Value1, Value2 from Dsc where Model = %s""" % MODEL_EFI_LIBRARY_CLASS
898 LibraryClasses
= EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand
)
899 for LibraryClass
in LibraryClasses
:
900 if LibraryClass
[1].upper() == 'NULL' or LibraryClass
[1].startswith('!ifdef') or LibraryClass
[1].startswith('!ifndef') or LibraryClass
[1].endswith('!endif'):
903 LibraryIns
= os
.path
.normpath(mws
.join(EccGlobalData
.gWorkspace
, LibraryClass
[2]))
904 SkipDirString
= '|'.join(EccGlobalData
.gConfig
.SkipDirList
)
905 p
= re
.compile(r
'.*[\\/](?:%s^\S)[\\/]?.*' % SkipDirString
)
906 if p
.match(os
.path
.split(LibraryIns
)[0].upper()):
908 SqlCommand
= """select Value3 from Inf where BelongsToFile =
909 (select ID from File where lower(FullPath) = lower('%s'))
910 and Value2 = '%s'""" % (LibraryIns
, DT
.PLATFORM_COMPONENT_TYPE_LIBRARY_CLASS
)
911 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
913 for Record
in RecordSet
:
914 LibName
= Record
[0].split('|', 1)[0]
915 if LibraryClass
[1] == LibName
:
918 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT
, LibraryClass
[1]):
919 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])
921 # Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies
922 def MetaDataFileCheckLibraryInstanceOrder(self
):
923 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryInstanceOrder
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
924 # This checkpoint is not necessary for Ecc check
927 # Check whether the unnecessary inclusion of library classes in the Inf file
928 # Check whether the unnecessary duplication of library classe names in the DSC file
929 def MetaDataFileCheckLibraryNoUse(self
):
930 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryNoUse
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
931 EdkLogger
.quiet("Checking for library instance not used ...")
932 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
)
933 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
934 for Record
in RecordSet
:
935 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE
, Record
[1]):
936 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])
938 select A.ID, A.Value1, A.BelongsToFile, A.StartLine, B.StartLine from Dsc as A left join Dsc as B
939 where A.Model = %s and B.Model = %s and A.Scope1 = B.Scope1 and A.Scope2 = B.Scope2 and A.ID != B.ID
940 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""" \
941 % (MODEL_EFI_LIBRARY_CLASS
, MODEL_EFI_LIBRARY_CLASS
)
942 RecordSet
= EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand
)
943 for Record
in RecordSet
:
944 if Record
[3] and Record
[4] and Record
[3] != Record
[4] and Record
[1] != 'NULL':
945 SqlCommand
= """select FullPath from File where ID = %s""" % (Record
[2])
946 FilePathList
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
947 for FilePath
in FilePathList
:
948 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NAME_DUPLICATE
, Record
[1]):
949 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])
951 # Check the header file in Include\Library directory whether be defined in the package DEC file.
952 def MetaDataFileCheckLibraryDefinedInDec(self
):
953 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryDefinedInDec
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
954 EdkLogger
.quiet("Checking for library instance whether be defined in the package dec file ...")
956 select A.Value1, A.StartLine, A.ID, B.Value1 from Inf as A left join Dec as B
957 on A.Model = B.Model and A.Value1 = B.Value1 where A.Model=%s
958 """ % MODEL_EFI_LIBRARY_CLASS
959 RecordSet
= EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand
)
960 for Record
in RecordSet
:
961 LibraryInInf
, Line
, ID
, LibraryDec
= Record
963 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NOT_DEFINED
, LibraryInInf
):
964 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_NOT_DEFINED
, \
965 OtherMsg
="The Library Class [%s] in %s line is not defined in the associated package file." % (LibraryInInf
, Line
),
966 BelongsToTable
='Inf', BelongsToItem
=ID
)
968 # 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
969 def MetaDataFileCheckBinaryInfInFdf(self
):
970 if EccGlobalData
.gConfig
.MetaDataFileCheckBinaryInfInFdf
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
971 EdkLogger
.quiet("Checking for non-binary modules defined in FDF files ...")
972 SqlCommand
= """select A.ID, A.Value1 from Fdf as A
976 (select B.Value1 from Dsc as B
978 and B.Enabled > -1)""" % (MODEL_META_DATA_COMPONENT
, MODEL_META_DATA_COMPONENT
)
979 RecordSet
= EccGlobalData
.gDb
.TblFdf
.Exec(SqlCommand
)
980 for Record
in RecordSet
:
983 FilePath
= os
.path
.normpath(mws
.join(EccGlobalData
.gWorkspace
, FilePath
))
984 SqlCommand
= """select ID from Inf where Model = %s and BelongsToFile = (select ID from File where FullPath like '%s')
985 """ % (MODEL_EFI_SOURCE_FILE
, FilePath
)
986 NewRecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
987 if NewRecordSet
!= []:
988 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF
, FilePath
):
989 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
)
991 # Check whether a PCD is set in a Dsc file or the FDF file, but not in both.
992 def MetaDataFileCheckPcdDuplicate(self
):
993 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdDuplicate
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
994 EdkLogger
.quiet("Checking for duplicate PCDs defined in both DSC and FDF files ...")
996 select A.ID, A.Value1, A.Value2, A.BelongsToFile, B.ID, B.Value1, B.Value2, B.BelongsToFile from Dsc as A, Fdf as B
997 where A.Model >= %s and A.Model < %s
998 and B.Model >= %s and B.Model < %s
999 and A.Value1 = B.Value1
1000 and A.Value2 = B.Value2
1004 """ % (MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
)
1005 RecordSet
= EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand
)
1006 for Record
in RecordSet
:
1007 SqlCommand1
= """select Name from File where ID = %s""" % Record
[3]
1008 SqlCommand2
= """select Name from File where ID = %s""" % Record
[7]
1009 DscFileName
= os
.path
.splitext(EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand1
)[0][0])[0]
1010 FdfFileName
= os
.path
.splitext(EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand2
)[0][0])[0]
1011 if DscFileName
!= FdfFileName
:
1013 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE
, Record
[1] + '.' + Record
[2]):
1014 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])
1015 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE
, Record
[5] + '.' + Record
[6]):
1016 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])
1018 EdkLogger
.quiet("Checking for duplicate PCDs defined in DEC files ...")
1020 select A.ID, A.Value1, A.Value2, A.Model, B.Model from Dec as A left join Dec as B
1021 where A.Model >= %s and A.Model < %s
1022 and B.Model >= %s and B.Model < %s
1023 and A.Value1 = B.Value1
1024 and A.Value2 = B.Value2
1025 and A.Scope1 = B.Scope1
1027 and A.Model = B.Model
1030 and A.BelongsToFile = B.BelongsToFile
1032 """ % (MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
)
1033 RecordSet
= EccGlobalData
.gDb
.TblDec
.Exec(SqlCommand
)
1034 for Record
in RecordSet
:
1035 RecordCat
= Record
[1] + '.' + Record
[2]
1036 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE
, RecordCat
):
1037 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])
1039 # Check whether PCD settings in the FDF file can only be related to flash.
1040 def MetaDataFileCheckPcdFlash(self
):
1041 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdFlash
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1042 EdkLogger
.quiet("Checking only Flash related PCDs are used in FDF ...")
1044 select ID, Value1, Value2, BelongsToFile from Fdf as A
1045 where A.Model >= %s and Model < %s
1047 and A.Value2 not like '%%Flash%%'
1048 """ % (MODEL_PCD
, MODEL_META_DATA_HEADER
)
1049 RecordSet
= EccGlobalData
.gDb
.TblFdf
.Exec(SqlCommand
)
1050 for Record
in RecordSet
:
1051 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_FLASH
, Record
[1] + '.' + Record
[2]):
1052 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])
1054 # Check whether PCDs used in Inf files but not specified in Dsc or FDF files
1055 def MetaDataFileCheckPcdNoUse(self
):
1056 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdNoUse
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1057 EdkLogger
.quiet("Checking for non-specified PCDs ...")
1059 select ID, Value1, Value2, BelongsToFile from Inf as A
1060 where A.Model >= %s and Model < %s
1062 and (A.Value1, A.Value2) not in
1063 (select Value1, Value2 from Dsc as B
1064 where B.Model >= %s and B.Model < %s
1066 and (A.Value1, A.Value2) not in
1067 (select Value1, Value2 from Fdf as C
1068 where C.Model >= %s and C.Model < %s
1070 """ % (MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
)
1071 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
1072 for Record
in RecordSet
:
1073 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE
, Record
[1] + '.' + Record
[2]):
1074 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])
1076 # Check whether having duplicate guids defined for Guid/Protocol/Ppi
1077 def MetaDataFileCheckGuidDuplicate(self
):
1078 if EccGlobalData
.gConfig
.MetaDataFileCheckGuidDuplicate
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1079 EdkLogger
.quiet("Checking for duplicate GUID/PPI/PROTOCOL ...")
1081 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID
, MODEL_EFI_GUID
, EccGlobalData
.gDb
.TblDec
)
1082 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID
, MODEL_EFI_GUID
, EccGlobalData
.gDb
.TblDsc
)
1083 self
.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID
, MODEL_EFI_GUID
)
1085 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL
, MODEL_EFI_PROTOCOL
, EccGlobalData
.gDb
.TblDec
)
1086 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL
, MODEL_EFI_PROTOCOL
, EccGlobalData
.gDb
.TblDsc
)
1087 self
.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL
, MODEL_EFI_PROTOCOL
)
1089 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI
, MODEL_EFI_PPI
, EccGlobalData
.gDb
.TblDec
)
1090 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI
, MODEL_EFI_PPI
, EccGlobalData
.gDb
.TblDsc
)
1091 self
.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI
, MODEL_EFI_PPI
)
1093 # Check whether all files under module directory are described in INF files
1094 def MetaDataFileCheckModuleFileNoUse(self
):
1095 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFileNoUse
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1096 EdkLogger
.quiet("Checking for no used module files ...")
1098 select upper(Path) from File where ID in (select BelongsToFile from Inf where BelongsToFile != -1)
1100 InfPathSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
1102 for Item
in InfPathSet
:
1103 if Item
[0] not in InfPathList
:
1104 InfPathList
.append(Item
[0])
1106 select ID, Path, FullPath from File where upper(FullPath) not in
1107 (select upper(A.Path) || '%s' || upper(B.Value1) from File as A, INF as B
1108 where A.ID in (select BelongsToFile from INF where Model = %s group by BelongsToFile) and
1109 B.BelongsToFile = A.ID and B.Model = %s)
1110 and (Model = %s or Model = %s)
1111 """ % (os
.sep
, MODEL_EFI_SOURCE_FILE
, MODEL_EFI_SOURCE_FILE
, MODEL_FILE_C
, MODEL_FILE_H
)
1112 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
1113 for Record
in RecordSet
:
1115 Path
= Path
.upper().replace('\X64', '').replace('\IA32', '').replace('\EBC', '').replace('\IPF', '').replace('\ARM', '')
1116 if Path
in InfPathList
:
1117 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE
, Record
[2]):
1118 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])
1120 # Check whether the PCD is correctly used in C function via its type
1121 def MetaDataFileCheckPcdType(self
):
1122 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdType
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1123 EdkLogger
.quiet("Checking for pcd type in c code function usage ...")
1125 select ID, Model, Value1, Value2, BelongsToFile from INF where Model > %s and Model < %s
1126 """ % (MODEL_PCD
, MODEL_META_DATA_HEADER
)
1127 PcdSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
1133 BelongsToFile
= Pcd
[4]
1135 select ID from File where FullPath in
1136 (select B.Path || '%s' || A.Value1 from INF as A, File as B where A.Model = %s and A.BelongsToFile = %s
1137 and B.ID = %s and (B.Model = %s or B.Model = %s))
1138 """ % (os
.sep
, MODEL_EFI_SOURCE_FILE
, BelongsToFile
, BelongsToFile
, MODEL_FILE_C
, MODEL_FILE_H
)
1139 TableSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1140 for Tbl
in TableSet
:
1141 TblName
= 'Identifier' + str(Tbl
[0])
1143 select Name, ID from %s where value like '%s' and Model = %s
1144 """ % (TblName
, PcdName
, MODEL_IDENTIFIER_FUNCTION_CALLING
)
1145 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
1146 TblNumber
= TblName
.replace('Identifier', '')
1147 for Record
in RecordSet
:
1149 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_TYPE
, FunName
):
1150 if Model
in [MODEL_PCD_FIXED_AT_BUILD
] and not FunName
.startswith('FixedPcdGet'):
1151 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])
1152 if Model
in [MODEL_PCD_FEATURE_FLAG
] and (not FunName
.startswith('FeaturePcdGet') and not FunName
.startswith('FeaturePcdSet')):
1153 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])
1154 if Model
in [MODEL_PCD_PATCHABLE_IN_MODULE
] and (not FunName
.startswith('PatchablePcdGet') and not FunName
.startswith('PatchablePcdSet')):
1155 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])
1157 #ERROR_META_DATA_FILE_CHECK_PCD_TYPE
1160 # Internal worker function to get the INF workspace relative path from FileID
1161 def GetInfFilePathFromID(self
, FileID
):
1162 Table
= EccGlobalData
.gDb
.TblFile
1163 SqlCommand
= """select A.FullPath from %s as A where A.ID = %s""" % (Table
.Table
, FileID
)
1164 RecordSet
= Table
.Exec(SqlCommand
)
1166 for Record
in RecordSet
:
1167 Path
= mws
.relpath(Record
[0], EccGlobalData
.gWorkspace
)
1170 # Check whether two module INFs under one workspace has the same FILE_GUID value
1171 def MetaDataFileCheckModuleFileGuidDuplication(self
):
1172 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFileGuidDuplication
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1173 EdkLogger
.quiet("Checking for pcd type in c code function usage ...")
1174 Table
= EccGlobalData
.gDb
.TblInf
1176 select A.ID, A.Value3, A.BelongsToFile, B.BelongsToFile from %s as A, %s as B
1177 where A.Value2 = 'FILE_GUID' and B.Value2 = 'FILE_GUID' and
1178 A.Value3 = B.Value3 and A.ID != B.ID group by A.ID
1179 """ % (Table
.Table
, Table
.Table
)
1180 RecordSet
= Table
.Exec(SqlCommand
)
1181 for Record
in RecordSet
:
1182 InfPath1
= self
.GetInfFilePathFromID(Record
[2])
1183 InfPath2
= self
.GetInfFilePathFromID(Record
[3])
1184 if InfPath1
and InfPath2
:
1185 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION
, InfPath1
):
1186 Msg
= "The FILE_GUID of INF file [%s] is duplicated with that of %s" % (InfPath1
, InfPath2
)
1187 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1190 # Check Guid Format in module INF
1191 def MetaDataFileCheckModuleFileGuidFormat(self
):
1192 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFileGuidFormat
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1193 EdkLogger
.quiet("Check Guid Format in module INF ...")
1194 Table
= EccGlobalData
.gDb
.TblInf
1196 select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID
1197 """ % (Table
.Table
, MODEL_EFI_GUID
)
1198 RecordSet
= Table
.Exec(SqlCommand
)
1199 for Record
in RecordSet
:
1202 GuidCommentList
= []
1203 InfPath
= self
.GetInfFilePathFromID(Record
[3])
1204 Msg
= "The GUID format of %s in INF file [%s] does not follow rules" % (Value1
, InfPath
)
1205 if Value2
.startswith(DT
.TAB_SPECIAL_COMMENT
):
1206 GuidCommentList
= Value2
[2:].split(DT
.TAB_SPECIAL_COMMENT
)
1207 if GuidCommentList
[0].strip().startswith(DT
.TAB_INF_USAGE_UNDEFINED
):
1209 elif len(GuidCommentList
) > 1:
1210 if not GuidCommentList
[0].strip().startswith((DT
.TAB_INF_USAGE_PRO
,
1211 DT
.TAB_INF_USAGE_SOME_PRO
,
1212 DT
.TAB_INF_USAGE_CON
,
1213 DT
.TAB_INF_USAGE_SOME_CON
)):
1214 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1215 if not (GuidCommentList
[1].strip()).startswith(DT
.TAB_INF_GUIDTYPE_VAR
) and \
1216 not GuidCommentList
[1].strip().startswith((DT
.TAB_INF_GUIDTYPE_EVENT
,
1217 DT
.TAB_INF_GUIDTYPE_HII
,
1218 DT
.TAB_INF_GUIDTYPE_FILE
,
1219 DT
.TAB_INF_GUIDTYPE_HOB
,
1220 DT
.TAB_INF_GUIDTYPE_FV
,
1221 DT
.TAB_INF_GUIDTYPE_ST
,
1222 DT
.TAB_INF_GUIDTYPE_TSG
,
1223 DT
.TAB_INF_GUIDTYPE_GUID
,
1224 DT
.TAB_INF_GUIDTYPE_PROTOCOL
,
1225 DT
.TAB_INF_GUIDTYPE_PPI
,
1226 DT
.TAB_INF_USAGE_UNDEFINED
)):
1227 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1229 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1231 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1233 # Check Protocol Format in module INF
1234 def MetaDataFileCheckModuleFileProtocolFormat(self
):
1235 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFileProtocolFormat
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1236 EdkLogger
.quiet("Check Protocol Format in module INF ...")
1237 Table
= EccGlobalData
.gDb
.TblInf
1239 select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID
1240 """ % (Table
.Table
, MODEL_EFI_PROTOCOL
)
1241 RecordSet
= Table
.Exec(SqlCommand
)
1242 for Record
in RecordSet
:
1245 GuidCommentList
= []
1246 InfPath
= self
.GetInfFilePathFromID(Record
[3])
1247 Msg
= "The Protocol format of %s in INF file [%s] does not follow rules" % (Value1
, InfPath
)
1248 if Value2
.startswith(DT
.TAB_SPECIAL_COMMENT
):
1249 GuidCommentList
= Value2
[2:].split(DT
.TAB_SPECIAL_COMMENT
)
1250 if len(GuidCommentList
) >= 1:
1251 if not GuidCommentList
[0].strip().startswith((DT
.TAB_INF_USAGE_PRO
,
1252 DT
.TAB_INF_USAGE_SOME_PRO
,
1253 DT
.TAB_INF_USAGE_CON
,
1254 DT
.TAB_INF_USAGE_SOME_CON
,
1255 DT
.TAB_INF_USAGE_NOTIFY
,
1256 DT
.TAB_INF_USAGE_TO_START
,
1257 DT
.TAB_INF_USAGE_BY_START
,
1258 DT
.TAB_INF_USAGE_UNDEFINED
)):
1259 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PROTOCOL
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1261 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PROTOCOL
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1264 # Check Ppi Format in module INF
1265 def MetaDataFileCheckModuleFilePpiFormat(self
):
1266 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFilePpiFormat
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1267 EdkLogger
.quiet("Check Ppi Format in module INF ...")
1268 Table
= EccGlobalData
.gDb
.TblInf
1270 select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID
1271 """ % (Table
.Table
, MODEL_EFI_PPI
)
1272 RecordSet
= Table
.Exec(SqlCommand
)
1273 for Record
in RecordSet
:
1276 GuidCommentList
= []
1277 InfPath
= self
.GetInfFilePathFromID(Record
[3])
1278 Msg
= "The Ppi format of %s in INF file [%s] does not follow rules" % (Value1
, InfPath
)
1279 if Value2
.startswith(DT
.TAB_SPECIAL_COMMENT
):
1280 GuidCommentList
= Value2
[2:].split(DT
.TAB_SPECIAL_COMMENT
)
1281 if len(GuidCommentList
) >= 1:
1282 if not GuidCommentList
[0].strip().startswith((DT
.TAB_INF_USAGE_PRO
,
1283 DT
.TAB_INF_USAGE_SOME_PRO
,
1284 DT
.TAB_INF_USAGE_CON
,
1285 DT
.TAB_INF_USAGE_SOME_CON
,
1286 DT
.TAB_INF_USAGE_NOTIFY
,
1287 DT
.TAB_INF_USAGE_UNDEFINED
)):
1288 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PPI
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1290 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PPI
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1292 # Check Pcd Format in module INF
1293 def MetaDataFileCheckModuleFilePcdFormat(self
):
1294 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFilePcdFormat
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1295 EdkLogger
.quiet("Check Pcd Format in module INF ...")
1296 Table
= EccGlobalData
.gDb
.TblInf
1298 select ID, Model, Value1, Value2, Usage, BelongsToFile from %s where Model >= %s and Model < %s group by ID
1299 """ % (Table
.Table
, MODEL_PCD
, MODEL_META_DATA_HEADER
)
1300 RecordSet
= Table
.Exec(SqlCommand
)
1301 for Record
in RecordSet
:
1303 PcdName
= Record
[2] + '.' + Record
[3]
1306 InfPath
= self
.GetInfFilePathFromID(Record
[5])
1307 Msg
= "The Pcd format of %s in INF file [%s] does not follow rules" % (PcdName
, InfPath
)
1308 if Usage
.startswith(DT
.TAB_SPECIAL_COMMENT
):
1309 PcdCommentList
= Usage
[2:].split(DT
.TAB_SPECIAL_COMMENT
)
1310 if len(PcdCommentList
) >= 1:
1311 if Model
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_FEATURE_FLAG
] \
1312 and not PcdCommentList
[0].strip().startswith((DT
.TAB_INF_USAGE_SOME_PRO
,
1313 DT
.TAB_INF_USAGE_CON
,
1314 DT
.TAB_INF_USAGE_UNDEFINED
)):
1315 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PCD
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1316 if Model
in [MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
] \
1317 and not PcdCommentList
[0].strip().startswith((DT
.TAB_INF_USAGE_PRO
,
1318 DT
.TAB_INF_USAGE_SOME_PRO
,
1319 DT
.TAB_INF_USAGE_CON
,
1320 DT
.TAB_INF_USAGE_SOME_CON
,
1321 DT
.TAB_INF_USAGE_UNDEFINED
)):
1322 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PCD
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1324 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PCD
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1326 # Check whether these is duplicate Guid/Ppi/Protocol name
1327 def CheckGuidProtocolPpi(self
, ErrorID
, Model
, Table
):
1329 if Model
== MODEL_EFI_GUID
:
1331 if Model
== MODEL_EFI_PROTOCOL
:
1333 if Model
== MODEL_EFI_PPI
:
1336 select A.ID, A.Value1 from %s as A, %s as B
1337 where A.Model = %s and B.Model = %s
1338 and A.Value1 like B.Value1 and A.ID != B.ID
1339 and A.Scope1 = B.Scope1
1343 """ % (Table
.Table
, Table
.Table
, Model
, Model
)
1344 RecordSet
= Table
.Exec(SqlCommand
)
1345 for Record
in RecordSet
:
1346 if not EccGlobalData
.gException
.IsException(ErrorID
, Record
[1]):
1347 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])
1349 # Check whether these is duplicate Guid/Ppi/Protocol value
1350 def CheckGuidProtocolPpiValue(self
, ErrorID
, Model
):
1352 Table
= EccGlobalData
.gDb
.TblDec
1353 if Model
== MODEL_EFI_GUID
:
1355 if Model
== MODEL_EFI_PROTOCOL
:
1357 if Model
== MODEL_EFI_PPI
:
1360 select A.ID, A.Value1, A.Value2 from %s as A, %s as B
1361 where A.Model = %s and B.Model = %s
1362 and A.Value2 like B.Value2 and A.ID != B.ID
1363 and A.Scope1 = B.Scope1 and A.Value1 != B.Value1
1365 """ % (Table
.Table
, Table
.Table
, Model
, Model
)
1366 RecordSet
= Table
.Exec(SqlCommand
)
1367 for Record
in RecordSet
:
1368 if not EccGlobalData
.gException
.IsException(ErrorID
, Record
[2]):
1369 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])
1371 # Naming Convention Check
1372 def NamingConventionCheck(self
):
1373 if EccGlobalData
.gConfig
.NamingConventionCheckDefineStatement
== '1' \
1374 or EccGlobalData
.gConfig
.NamingConventionCheckTypedefStatement
== '1' \
1375 or EccGlobalData
.gConfig
.NamingConventionCheckIfndefStatement
== '1' \
1376 or EccGlobalData
.gConfig
.NamingConventionCheckVariableName
== '1' \
1377 or EccGlobalData
.gConfig
.NamingConventionCheckSingleCharacterVariable
== '1' \
1378 or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1'\
1379 or EccGlobalData
.gConfig
.CheckAll
== '1':
1380 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
1382 if os
.path
.splitext(F
)[1] in ('.h', '.c'):
1383 FullName
= os
.path
.join(Dirpath
, F
)
1384 Id
= c
.GetTableID(FullName
)
1387 FileTable
= 'Identifier' + str(Id
)
1388 self
.NamingConventionCheckDefineStatement(FileTable
)
1389 self
.NamingConventionCheckTypedefStatement(FileTable
)
1390 self
.NamingConventionCheckVariableName(FileTable
)
1391 self
.NamingConventionCheckSingleCharacterVariable(FileTable
)
1392 if os
.path
.splitext(F
)[1] in ('.h'):
1393 self
.NamingConventionCheckIfndefStatement(FileTable
)
1395 self
.NamingConventionCheckPathName()
1396 self
.NamingConventionCheckFunctionName()
1398 # Check whether only capital letters are used for #define declarations
1399 def NamingConventionCheckDefineStatement(self
, FileTable
):
1400 if EccGlobalData
.gConfig
.NamingConventionCheckDefineStatement
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1401 EdkLogger
.quiet("Checking naming convention of #define statement ...")
1403 SqlCommand
= """select ID, Value from %s where Model = %s""" % (FileTable
, MODEL_IDENTIFIER_MACRO_DEFINE
)
1404 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1405 for Record
in RecordSet
:
1406 Name
= Record
[1].strip().split()[1]
1407 if Name
.find('(') != -1:
1408 Name
= Name
[0:Name
.find('(')]
1409 if Name
.upper() != Name
:
1410 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT
, Name
):
1411 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])
1413 # Check whether only capital letters are used for typedef declarations
1414 def NamingConventionCheckTypedefStatement(self
, FileTable
):
1415 if EccGlobalData
.gConfig
.NamingConventionCheckTypedefStatement
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1416 EdkLogger
.quiet("Checking naming convention of #typedef statement ...")
1418 SqlCommand
= """select ID, Name from %s where Model = %s""" % (FileTable
, MODEL_IDENTIFIER_TYPEDEF
)
1419 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1420 for Record
in RecordSet
:
1421 Name
= Record
[1].strip()
1422 if Name
!= '' and Name
is not None:
1424 Name
= Name
[1:Name
.find(')')]
1425 if Name
.find('(') > -1:
1426 Name
= Name
[Name
.find('(') + 1 : Name
.find(')')]
1427 Name
= Name
.replace('WINAPI', '')
1428 Name
= Name
.replace('*', '').strip()
1429 if Name
.upper() != Name
:
1430 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT
, Name
):
1431 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])
1433 # Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'.
1434 def NamingConventionCheckIfndefStatement(self
, FileTable
):
1435 if EccGlobalData
.gConfig
.NamingConventionCheckIfndefStatement
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1436 EdkLogger
.quiet("Checking naming convention of #ifndef statement ...")
1438 SqlCommand
= """select ID, Value from %s where Model = %s""" % (FileTable
, MODEL_IDENTIFIER_MACRO_IFNDEF
)
1439 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1440 for Record
in RecordSet
:
1441 Name
= Record
[1].replace('#ifndef', '').strip()
1442 if Name
[0] == '_' or Name
[-1] != '_' or Name
[-2] == '_':
1443 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT
, Name
):
1444 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])
1446 # Rule for path name, variable name and function name
1447 # 1. First character should be upper case
1448 # 2. Existing lower case in a word
1449 # 3. No space existence
1450 # Check whether the path name followed the rule
1451 def NamingConventionCheckPathName(self
):
1452 if EccGlobalData
.gConfig
.NamingConventionCheckPathName
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1453 EdkLogger
.quiet("Checking naming convention of file path name ...")
1454 Pattern
= re
.compile(r
'^[A-Z]+\S*[a-z]\S*$')
1455 SqlCommand
= """select ID, Name from File"""
1456 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1457 for Record
in RecordSet
:
1458 if not Pattern
.match(Record
[1]):
1459 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_PATH_NAME
, Record
[1]):
1460 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])
1462 # Rule for path name, variable name and function name
1463 # 1. First character should be upper case
1464 # 2. Existing lower case in a word
1465 # 3. No space existence
1466 # 4. Global variable name must start with a 'g'
1467 # Check whether the variable name followed the rule
1468 def NamingConventionCheckVariableName(self
, FileTable
):
1469 if EccGlobalData
.gConfig
.NamingConventionCheckVariableName
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1470 EdkLogger
.quiet("Checking naming convention of variable name ...")
1471 Pattern
= re
.compile(r
'^[A-Zgm]+\S*[a-z]\S*$')
1473 SqlCommand
= """select ID, Name, Modifier from %s where Model = %s""" % (FileTable
, MODEL_IDENTIFIER_VARIABLE
)
1474 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1475 for Record
in RecordSet
:
1477 Modifier
= Record
[2]
1478 if Var
.startswith('CONST'):
1479 Var
= Var
[5:].lstrip()
1480 if not Pattern
.match(Var
) and not (Modifier
.endswith('*') and Var
.startswith('p')):
1481 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME
, Record
[1]):
1482 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])
1484 # Rule for path name, variable name and function name
1485 # 1. First character should be upper case
1486 # 2. Existing lower case in a word
1487 # 3. No space existence
1488 # Check whether the function name followed the rule
1489 def NamingConventionCheckFunctionName(self
):
1490 if EccGlobalData
.gConfig
.NamingConventionCheckFunctionName
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1491 EdkLogger
.quiet("Checking naming convention of function name ...")
1492 Pattern
= re
.compile(r
'^[A-Z]+\S*[a-z]\S*$')
1493 SqlCommand
= """select ID, Name from Function"""
1494 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1495 for Record
in RecordSet
:
1496 if not Pattern
.match(Record
[1]):
1497 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME
, Record
[1]):
1498 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])
1500 # Check whether NO use short variable name with single character
1501 def NamingConventionCheckSingleCharacterVariable(self
, FileTable
):
1502 if EccGlobalData
.gConfig
.NamingConventionCheckSingleCharacterVariable
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1503 EdkLogger
.quiet("Checking naming convention of single character variable name ...")
1505 SqlCommand
= """select ID, Name from %s where Model = %s""" % (FileTable
, MODEL_IDENTIFIER_VARIABLE
)
1506 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1507 for Record
in RecordSet
:
1508 Variable
= Record
[1].replace('*', '')
1509 if len(Variable
) == 1:
1510 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE
, Record
[1]):
1511 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])
1513 def FindPara(FilePath
, Para
, CallingLine
):
1514 Lines
= open(FilePath
).readlines()
1516 for Index
in range(CallingLine
- 1, 0, -1):
1517 # Find the nearest statement for Para
1518 Line
= Lines
[Index
].strip()
1519 if Line
.startswith('%s = ' % Para
):
1528 # This acts like the main() function for the script, unless it is 'import'ed into another
1531 if __name__
== '__main__':