2 # This file is used to define checkpoints used by ECC tool
4 # Copyright (c) 2008 - 2018, 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 from __future__
import absolute_import
14 import Common
.LongFilePathOs
as os
16 from CommonDataClass
.DataClass
import *
17 import Common
.DataType
as DT
18 from Ecc
.EccToolError
import *
19 from Ecc
.MetaDataParser
import ParseHeaderCommentSection
20 from Ecc
import EccGlobalData
22 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
23 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
27 # This class is to define checkpoints used by ECC tool
29 # @param object: Inherited from object class
35 # Check all required checkpoints
38 self
.MetaDataFileCheck()
40 self
.IncludeFileCheck()
41 self
.PredicateExpressionCheck()
42 self
.DeclAndDataTypeCheck()
43 self
.FunctionLayoutCheck()
44 self
.NamingConventionCheck()
45 self
.SmmCommParaCheck()
47 def SmmCommParaCheck(self
):
48 self
.SmmCommParaCheckBufferType()
51 # Check if SMM communication function has correct parameter type
52 # 1. Get function calling with instance./->Communicate() interface
53 # and make sure the protocol instance is of type EFI_SMM_COMMUNICATION_PROTOCOL.
54 # 2. Find the origin of the 2nd parameter of Communicate() interface, if -
55 # a. it is a local buffer on stack
57 # b. it is a global buffer, check the driver that holds the global buffer is of type DXE_RUNTIME_DRIVER
59 # c. it is a buffer by AllocatePage/AllocatePool (may be wrapped by nested function calls),
60 # check the EFI_MEMORY_TYPE to be EfiRuntimeServicesCode,EfiRuntimeServicesData,
61 # EfiACPIMemoryNVS or EfiReservedMemoryType
63 # d. it is a buffer located via EFI_SYSTEM_TABLE.ConfigurationTable (may be wrapped by nested function calls)
64 # report warning to indicate human code review.
65 # e. it is a buffer from other kind of pointers (may need to trace into nested function calls to locate),
66 # repeat checks in a.b.c and d.
67 def SmmCommParaCheckBufferType(self
):
68 if EccGlobalData
.gConfig
.SmmCommParaCheckBufferType
== '1' or EccGlobalData
.gConfig
.SmmCommParaCheckAll
== '1':
69 EdkLogger
.quiet("Checking SMM communication parameter type ...")
70 # Get all EFI_SMM_COMMUNICATION_PROTOCOL interface
72 for IdentifierTable
in EccGlobalData
.gIdentifierTableList
:
73 SqlCommand
= """select ID, Name, BelongsToFile from %s
74 where Modifier = 'EFI_SMM_COMMUNICATION_PROTOCOL*' """ % (IdentifierTable
)
75 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
77 for Record
in RecordSet
:
78 if Record
[1] not in CommApiList
:
79 CommApiList
.append(Record
[1])
80 # For each interface, check the second parameter
81 for CommApi
in CommApiList
:
82 for IdentifierTable
in EccGlobalData
.gIdentifierTableList
:
83 SqlCommand
= """select ID, Name, Value, BelongsToFile, StartLine from %s
84 where Name = '%s->Communicate' and Model = %s""" \
85 % (IdentifierTable
, CommApi
, MODEL_IDENTIFIER_FUNCTION_CALLING
)
86 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
88 # print IdentifierTable
89 for Record
in RecordSet
:
90 # Get the second parameter for Communicate function
91 SecondPara
= Record
[2].split(',')[1].strip()
92 SecondParaIndex
= None
93 if SecondPara
.startswith('&'):
94 SecondPara
= SecondPara
[1:]
95 if SecondPara
.endswith(']'):
96 SecondParaIndex
= SecondPara
[SecondPara
.find('[') + 1:-1]
97 SecondPara
= SecondPara
[:SecondPara
.find('[')]
100 # Get the BelongsToFile
101 BelongsToFile
= Record
[3]
102 # Get the source file path
103 SqlCommand
= """select FullPath from File where ID = %s""" % BelongsToFile
104 NewRecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
105 FullPath
= NewRecordSet
[0][0]
106 # Get the line no of function calling
107 StartLine
= Record
[4]
108 # Get the module type
109 SqlCommand
= """select Value3 from INF where BelongsToFile = (select ID from File
110 where Path = (select Path from File where ID = %s) and Model = 1011)
111 and Value2 = 'MODULE_TYPE'""" % BelongsToFile
112 NewRecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
113 ModuleType
= NewRecordSet
[0][0] if NewRecordSet
else None
115 # print BelongsToFile, FullPath, StartLine, ModuleType, SecondPara
117 Value
= FindPara(FullPath
, SecondPara
, StartLine
)
118 # Find the value of the parameter
120 if 'AllocatePage' in Value \
121 or 'AllocatePool' in Value \
122 or 'AllocateRuntimePool' in Value \
123 or 'AllocateZeroPool' in Value
:
127 if not EccGlobalData
.gException
.IsException(
128 ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE
, Value
):
129 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE
,
130 OtherMsg
="Please review the buffer type"
131 + "is correct or not. If it is correct" +
132 " please add [%s] to exception list"
134 BelongsToTable
=IdentifierTable
,
137 if not EccGlobalData
.gException
.IsException(
138 ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE
, Value
):
139 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE
,
140 OtherMsg
="Please review the buffer type"
141 + "is correct or not. If it is correct" +
142 " please add [%s] to exception list"
144 BelongsToTable
=IdentifierTable
,
148 # Not find the value of the parameter
150 SqlCommand
= """select ID, Modifier, Name, Value, Model, BelongsToFunction from %s
151 where Name = '%s' and StartLine < %s order by StartLine DESC""" \
152 % (IdentifierTable
, SecondPara
, StartLine
)
153 NewRecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
155 Value
= NewRecordSet
[0][1]
156 if 'AllocatePage' in Value \
157 or 'AllocatePool' in Value \
158 or 'AllocateRuntimePool' in Value \
159 or 'AllocateZeroPool' in Value
:
162 if not EccGlobalData
.gException
.IsException(
163 ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE
, Value
):
164 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE
,
165 OtherMsg
="Please review the buffer type"
166 + "is correct or not. If it is correct" +
167 " please add [%s] to exception list"
169 BelongsToTable
=IdentifierTable
,
176 if EccGlobalData
.gConfig
.GeneralCheckUni
== '1' or EccGlobalData
.gConfig
.GeneralCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
177 EdkLogger
.quiet("Checking whether UNI file is UTF-16 ...")
178 SqlCommand
= """select ID, FullPath, ExtName from File where ExtName like 'uni'"""
179 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
180 for Record
in RecordSet
:
182 FileIn
= open(File
, 'rb').read(2)
183 if FileIn
!= '\xff\xfe':
184 OtherMsg
= "File %s is not a valid UTF-16 UNI file" % Record
[1]
185 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_GENERAL_CHECK_UNI
, OtherMsg
=OtherMsg
, BelongsToTable
='File', BelongsToItem
=Record
[0])
188 def GeneralCheck(self
):
189 self
.GeneralCheckNonAcsii()
191 self
.GeneralCheckNoTab()
192 self
.GeneralCheckLineEnding()
193 self
.GeneralCheckTrailingWhiteSpaceLine()
195 # Check whether NO Tab is used, replaced with spaces
196 def GeneralCheckNoTab(self
):
197 if EccGlobalData
.gConfig
.GeneralCheckNoTab
== '1' or EccGlobalData
.gConfig
.GeneralCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
198 EdkLogger
.quiet("Checking No TAB used in file ...")
199 SqlCommand
= """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')"""
200 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
201 for Record
in RecordSet
:
202 if Record
[2].upper() not in EccGlobalData
.gConfig
.BinaryExtList
:
203 op
= open(Record
[1]).readlines()
211 OtherMsg
= "File %s has TAB char at line %s column %s" % (Record
[1], IndexOfLine
, IndexOfChar
)
212 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_GENERAL_CHECK_NO_TAB
, OtherMsg
=OtherMsg
, BelongsToTable
='File', BelongsToItem
=Record
[0])
214 # Check Only use CRLF (Carriage Return Line Feed) line endings.
215 def GeneralCheckLineEnding(self
):
216 if EccGlobalData
.gConfig
.GeneralCheckLineEnding
== '1' or EccGlobalData
.gConfig
.GeneralCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
217 EdkLogger
.quiet("Checking line ending in file ...")
218 SqlCommand
= """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')"""
219 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
220 for Record
in RecordSet
:
221 if Record
[2].upper() not in EccGlobalData
.gConfig
.BinaryExtList
:
222 op
= open(Record
[1], 'rb').readlines()
226 if not bytes
.decode(Line
).endswith('\r\n'):
227 OtherMsg
= "File %s has invalid line ending at line %s" % (Record
[1], IndexOfLine
)
228 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_GENERAL_CHECK_INVALID_LINE_ENDING
, OtherMsg
=OtherMsg
, BelongsToTable
='File', BelongsToItem
=Record
[0])
230 # Check if there is no trailing white space in one line.
231 def GeneralCheckTrailingWhiteSpaceLine(self
):
232 if EccGlobalData
.gConfig
.GeneralCheckTrailingWhiteSpaceLine
== '1' or EccGlobalData
.gConfig
.GeneralCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
233 EdkLogger
.quiet("Checking trailing white space line in file ...")
234 SqlCommand
= """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')"""
235 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
236 for Record
in RecordSet
:
237 if Record
[2].upper() not in EccGlobalData
.gConfig
.BinaryExtList
:
238 op
= open(Record
[1], 'r').readlines()
242 if Line
.replace('\r', '').replace('\n', '').endswith(' '):
243 OtherMsg
= "File %s has trailing white spaces at line %s" % (Record
[1], IndexOfLine
)
244 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_GENERAL_CHECK_TRAILING_WHITE_SPACE_LINE
, OtherMsg
=OtherMsg
, BelongsToTable
='File', BelongsToItem
=Record
[0])
246 # Check whether file has non ACSII char
247 def GeneralCheckNonAcsii(self
):
248 if EccGlobalData
.gConfig
.GeneralCheckNonAcsii
== '1' or EccGlobalData
.gConfig
.GeneralCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
249 EdkLogger
.quiet("Checking Non-ACSII char in file ...")
250 SqlCommand
= """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')"""
251 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
252 for Record
in RecordSet
:
253 if Record
[2].upper() not in EccGlobalData
.gConfig
.BinaryExtList
:
254 op
= open(Record
[1]).readlines()
262 OtherMsg
= "File %s has Non-ASCII char at line %s column %s" % (Record
[1], IndexOfLine
, IndexOfChar
)
263 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_GENERAL_CHECK_NON_ACSII
, OtherMsg
=OtherMsg
, BelongsToTable
='File', BelongsToItem
=Record
[0])
265 # C Function Layout Checking
266 def FunctionLayoutCheck(self
):
267 self
.FunctionLayoutCheckReturnType()
268 self
.FunctionLayoutCheckModifier()
269 self
.FunctionLayoutCheckName()
270 self
.FunctionLayoutCheckPrototype()
271 self
.FunctionLayoutCheckBody()
272 self
.FunctionLayoutCheckLocalVariable()
273 self
.FunctionLayoutCheckDeprecated()
275 # To check if the deprecated functions are used
276 def FunctionLayoutCheckDeprecated(self
):
277 if EccGlobalData
.gConfig
.CFunctionLayoutCheckNoDeprecated
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
278 EdkLogger
.quiet("Checking function no deprecated one being used ...")
280 DeprecatedFunctionSet
= ('UnicodeValueToString',
281 'AsciiValueToString',
286 'UnicodeStrToAsciiStr',
291 'AsciiStrToUnicodeStr',
317 'GetEfiGlobalVariable',
320 for IdentifierTable
in EccGlobalData
.gIdentifierTableList
:
321 SqlCommand
= """select ID, Name, BelongsToFile from %s
322 where Model = %s """ % (IdentifierTable
, MODEL_IDENTIFIER_FUNCTION_CALLING
)
323 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
324 for Record
in RecordSet
:
325 for Key
in DeprecatedFunctionSet
:
327 if not EccGlobalData
.gException
.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_DEPRECATE
, Key
):
328 OtherMsg
= 'The function [%s] is deprecated which should NOT be used' % Key
329 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_DEPRECATE
,
331 BelongsToTable
=IdentifierTable
,
332 BelongsToItem
=Record
[0])
335 IgnoredPattern
= c
.GetIgnoredDirListPattern()
336 for Dirpath
, Dirnames
, Filenames
in os
.walk(EccGlobalData
.gTarget
):
338 Dirname
= os
.path
.join(Dirpath
, Dir
)
339 if os
.path
.islink(Dirname
):
340 Dirname
= os
.path
.realpath(Dirname
)
341 if os
.path
.isdir(Dirname
):
342 # symlinks to directories are treated as directories
344 Dirnames
.append(Dirname
)
345 if IgnoredPattern
.match(Dirpath
.upper()):
347 for f
in Filenames
[:]:
348 if f
.lower() in EccGlobalData
.gConfig
.SkipFileList
:
350 yield (Dirpath
, Dirnames
, Filenames
)
352 # Check whether return type exists and in the first line
353 def FunctionLayoutCheckReturnType(self
):
354 if EccGlobalData
.gConfig
.CFunctionLayoutCheckReturnType
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
355 EdkLogger
.quiet("Checking function layout return type ...")
357 # for Dirpath, Dirnames, Filenames in self.WalkTree():
358 # for F in Filenames:
359 # if os.path.splitext(F)[1] in ('.c', '.h'):
360 # FullName = os.path.join(Dirpath, F)
361 # c.CheckFuncLayoutReturnType(FullName)
362 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
363 c
.CheckFuncLayoutReturnType(FullName
)
365 # Check whether any optional functional modifiers exist and next to the return type
366 def FunctionLayoutCheckModifier(self
):
367 if EccGlobalData
.gConfig
.CFunctionLayoutCheckOptionalFunctionalModifier
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
368 EdkLogger
.quiet("Checking function layout modifier ...")
370 # for Dirpath, Dirnames, Filenames in self.WalkTree():
371 # for F in Filenames:
372 # if os.path.splitext(F)[1] in ('.c', '.h'):
373 # FullName = os.path.join(Dirpath, F)
374 # c.CheckFuncLayoutModifier(FullName)
375 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
376 c
.CheckFuncLayoutModifier(FullName
)
378 # Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list
379 # Check whether the closing parenthesis is on its own line and also indented two spaces
380 def FunctionLayoutCheckName(self
):
381 if EccGlobalData
.gConfig
.CFunctionLayoutCheckFunctionName
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
382 EdkLogger
.quiet("Checking function layout function name ...")
384 # for Dirpath, Dirnames, Filenames in self.WalkTree():
385 # for F in Filenames:
386 # if os.path.splitext(F)[1] in ('.c', '.h'):
387 # FullName = os.path.join(Dirpath, F)
388 # c.CheckFuncLayoutName(FullName)
389 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
390 c
.CheckFuncLayoutName(FullName
)
392 # Check whether the function prototypes in include files have the same form as function definitions
393 def FunctionLayoutCheckPrototype(self
):
394 if EccGlobalData
.gConfig
.CFunctionLayoutCheckFunctionPrototype
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
395 EdkLogger
.quiet("Checking function layout function prototype ...")
397 # for Dirpath, Dirnames, Filenames in self.WalkTree():
398 # for F in Filenames:
399 # if os.path.splitext(F)[1] in ('.c'):
400 # FullName = os.path.join(Dirpath, F)
401 # EdkLogger.quiet("[PROTOTYPE]" + FullName)
402 # c.CheckFuncLayoutPrototype(FullName)
403 for FullName
in EccGlobalData
.gCFileList
:
404 EdkLogger
.quiet("[PROTOTYPE]" + FullName
)
405 c
.CheckFuncLayoutPrototype(FullName
)
407 # Check whether the body of a function is contained by open and close braces that must be in the first column
408 def FunctionLayoutCheckBody(self
):
409 if EccGlobalData
.gConfig
.CFunctionLayoutCheckFunctionBody
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
410 EdkLogger
.quiet("Checking function layout function body ...")
412 # for Dirpath, Dirnames, Filenames in self.WalkTree():
413 # for F in Filenames:
414 # if os.path.splitext(F)[1] in ('.c'):
415 # FullName = os.path.join(Dirpath, F)
416 # c.CheckFuncLayoutBody(FullName)
417 for FullName
in EccGlobalData
.gCFileList
:
418 c
.CheckFuncLayoutBody(FullName
)
420 # Check whether the data declarations is the first code in a module.
421 # self.CFunctionLayoutCheckDataDeclaration = 1
422 # Check whether no initialization of a variable as part of its declaration
423 def FunctionLayoutCheckLocalVariable(self
):
424 if EccGlobalData
.gConfig
.CFunctionLayoutCheckNoInitOfVariable
== '1' or EccGlobalData
.gConfig
.CFunctionLayoutCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
425 EdkLogger
.quiet("Checking function layout local variables ...")
427 # for Dirpath, Dirnames, Filenames in self.WalkTree():
428 # for F in Filenames:
429 # if os.path.splitext(F)[1] in ('.c'):
430 # FullName = os.path.join(Dirpath, F)
431 # c.CheckFuncLayoutLocalVariable(FullName)
433 for FullName
in EccGlobalData
.gCFileList
:
434 c
.CheckFuncLayoutLocalVariable(FullName
)
436 # Check whether no use of STATIC for functions
437 # self.CFunctionLayoutCheckNoStatic = 1
439 # Declarations and Data Types Checking
440 def DeclAndDataTypeCheck(self
):
441 self
.DeclCheckNoUseCType()
442 self
.DeclCheckInOutModifier()
443 self
.DeclCheckEFIAPIModifier()
444 self
.DeclCheckEnumeratedType()
445 self
.DeclCheckStructureDeclaration()
446 self
.DeclCheckSameStructure()
447 self
.DeclCheckUnionType()
450 # Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files.
451 def DeclCheckNoUseCType(self
):
452 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckNoUseCType
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
453 EdkLogger
.quiet("Checking Declaration No use C type ...")
455 # for Dirpath, Dirnames, Filenames in self.WalkTree():
456 # for F in Filenames:
457 # if os.path.splitext(F)[1] in ('.h', '.c'):
458 # FullName = os.path.join(Dirpath, F)
459 # c.CheckDeclNoUseCType(FullName)
460 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
461 c
.CheckDeclNoUseCType(FullName
)
463 # 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
464 def DeclCheckInOutModifier(self
):
465 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckInOutModifier
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
466 EdkLogger
.quiet("Checking Declaration argument modifier ...")
468 # for Dirpath, Dirnames, Filenames in self.WalkTree():
469 # for F in Filenames:
470 # if os.path.splitext(F)[1] in ('.h', '.c'):
471 # FullName = os.path.join(Dirpath, F)
472 # c.CheckDeclArgModifier(FullName)
473 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
474 c
.CheckDeclArgModifier(FullName
)
476 # Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols
477 def DeclCheckEFIAPIModifier(self
):
478 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckEFIAPIModifier
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
481 # Check whether Enumerated Type has a 'typedef' and the name is capital
482 def DeclCheckEnumeratedType(self
):
483 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckEnumeratedType
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
484 EdkLogger
.quiet("Checking Declaration enum typedef ...")
486 # for Dirpath, Dirnames, Filenames in self.WalkTree():
487 # for F in Filenames:
488 # if os.path.splitext(F)[1] in ('.h', '.c'):
489 # FullName = os.path.join(Dirpath, F)
490 # EdkLogger.quiet("[ENUM]" + FullName)
491 # c.CheckDeclEnumTypedef(FullName)
492 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
493 EdkLogger
.quiet("[ENUM]" + FullName
)
494 c
.CheckDeclEnumTypedef(FullName
)
496 # Check whether Structure Type has a 'typedef' and the name is capital
497 def DeclCheckStructureDeclaration(self
):
498 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckStructureDeclaration
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
499 EdkLogger
.quiet("Checking Declaration struct typedef ...")
501 # for Dirpath, Dirnames, Filenames in self.WalkTree():
502 # for F in Filenames:
503 # if os.path.splitext(F)[1] in ('.h', '.c'):
504 # FullName = os.path.join(Dirpath, F)
505 # EdkLogger.quiet("[STRUCT]" + FullName)
506 # c.CheckDeclStructTypedef(FullName)
507 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
508 EdkLogger
.quiet("[STRUCT]" + FullName
)
509 c
.CheckDeclStructTypedef(FullName
)
511 # Check whether having same Structure
512 def DeclCheckSameStructure(self
):
513 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckSameStructure
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
514 EdkLogger
.quiet("Checking same struct ...")
516 for IdentifierTable
in EccGlobalData
.gIdentifierTableList
:
517 SqlCommand
= """select ID, Name, BelongsToFile from %s where Model = %s""" % (IdentifierTable
, MODEL_IDENTIFIER_STRUCTURE
)
518 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
519 for Record
in RecordSet
:
521 if Record
[1] not in AllStructure
.keys():
522 AllStructure
[Record
[1]] = Record
[2]
524 ID
= AllStructure
[Record
[1]]
525 SqlCommand
= """select FullPath from File where ID = %s """ % ID
526 NewRecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
527 OtherMsg
= "The structure name '%s' is duplicate" % Record
[1]
528 if NewRecordSet
!= []:
529 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])
530 if not EccGlobalData
.gException
.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE
, Record
[1]):
531 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE
, OtherMsg
=OtherMsg
, BelongsToTable
=IdentifierTable
, BelongsToItem
=Record
[0])
533 # Check whether Union Type has a 'typedef' and the name is capital
534 def DeclCheckUnionType(self
):
535 if EccGlobalData
.gConfig
.DeclarationDataTypeCheckUnionType
== '1' or EccGlobalData
.gConfig
.DeclarationDataTypeCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
536 EdkLogger
.quiet("Checking Declaration union typedef ...")
538 # for Dirpath, Dirnames, Filenames in self.WalkTree():
539 # for F in Filenames:
540 # if os.path.splitext(F)[1] in ('.h', '.c'):
541 # FullName = os.path.join(Dirpath, F)
542 # EdkLogger.quiet("[UNION]" + FullName)
543 # c.CheckDeclUnionTypedef(FullName)
544 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
545 EdkLogger
.quiet("[UNION]" + FullName
)
546 c
.CheckDeclUnionTypedef(FullName
)
548 # Predicate Expression Checking
549 def PredicateExpressionCheck(self
):
550 self
.PredicateExpressionCheckBooleanValue()
551 self
.PredicateExpressionCheckNonBooleanOperator()
552 self
.PredicateExpressionCheckComparisonNullType()
554 # Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE
555 def PredicateExpressionCheckBooleanValue(self
):
556 if EccGlobalData
.gConfig
.PredicateExpressionCheckBooleanValue
== '1' or EccGlobalData
.gConfig
.PredicateExpressionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
557 EdkLogger
.quiet("Checking predicate expression Boolean value ...")
559 # for Dirpath, Dirnames, Filenames in self.WalkTree():
560 # for F in Filenames:
561 # if os.path.splitext(F)[1] in ('.c'):
562 # FullName = os.path.join(Dirpath, F)
563 # EdkLogger.quiet("[BOOLEAN]" + FullName)
564 # c.CheckBooleanValueComparison(FullName)
565 for FullName
in EccGlobalData
.gCFileList
:
566 EdkLogger
.quiet("[BOOLEAN]" + FullName
)
567 c
.CheckBooleanValueComparison(FullName
)
569 # Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=).
570 def PredicateExpressionCheckNonBooleanOperator(self
):
571 if EccGlobalData
.gConfig
.PredicateExpressionCheckNonBooleanOperator
== '1' or EccGlobalData
.gConfig
.PredicateExpressionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
572 EdkLogger
.quiet("Checking predicate expression Non-Boolean variable...")
574 # for Dirpath, Dirnames, Filenames in self.WalkTree():
575 # for F in Filenames:
576 # if os.path.splitext(F)[1] in ('.c'):
577 # FullName = os.path.join(Dirpath, F)
578 # EdkLogger.quiet("[NON-BOOLEAN]" + FullName)
579 # c.CheckNonBooleanValueComparison(FullName)
580 for FullName
in EccGlobalData
.gCFileList
:
581 EdkLogger
.quiet("[NON-BOOLEAN]" + FullName
)
582 c
.CheckNonBooleanValueComparison(FullName
)
584 # Check whether a comparison of any pointer to zero must be done via the NULL type
585 def PredicateExpressionCheckComparisonNullType(self
):
586 if EccGlobalData
.gConfig
.PredicateExpressionCheckComparisonNullType
== '1' or EccGlobalData
.gConfig
.PredicateExpressionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
587 EdkLogger
.quiet("Checking predicate expression NULL pointer ...")
589 # for Dirpath, Dirnames, Filenames in self.WalkTree():
590 # for F in Filenames:
591 # if os.path.splitext(F)[1] in ('.c'):
592 # FullName = os.path.join(Dirpath, F)
593 # EdkLogger.quiet("[POINTER]" + FullName)
594 # c.CheckPointerNullComparison(FullName)
595 for FullName
in EccGlobalData
.gCFileList
:
596 EdkLogger
.quiet("[POINTER]" + FullName
)
597 c
.CheckPointerNullComparison(FullName
)
599 # Include file checking
600 def IncludeFileCheck(self
):
601 self
.IncludeFileCheckIfndef()
602 self
.IncludeFileCheckData()
603 self
.IncludeFileCheckSameName()
605 # Check whether having include files with same name
606 def IncludeFileCheckSameName(self
):
607 if EccGlobalData
.gConfig
.IncludeFileCheckSameName
== '1' or EccGlobalData
.gConfig
.IncludeFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
608 EdkLogger
.quiet("Checking same header file name ...")
609 SqlCommand
= """select ID, FullPath from File
610 where Model = 1002 order by Name """
612 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
613 for Record
in RecordSet
:
614 List
= Record
[1].replace('/', '\\').split('\\')
616 Key
= List
[-2] + '\\' + List
[-1]
619 if Key
not in RecordDict
:
620 RecordDict
[Key
] = [Record
]
622 RecordDict
[Key
].append(Record
)
624 for Key
in RecordDict
:
625 if len(RecordDict
[Key
]) > 1:
626 for Item
in RecordDict
[Key
]:
627 Path
= mws
.relpath(Item
[1], EccGlobalData
.gWorkspace
)
628 if not EccGlobalData
.gException
.IsException(ERROR_INCLUDE_FILE_CHECK_NAME
, Path
):
629 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_INCLUDE_FILE_CHECK_NAME
, OtherMsg
="The file name for [%s] is duplicate" % Path
, BelongsToTable
='File', BelongsToItem
=Item
[0])
631 # Check whether all include file contents is guarded by a #ifndef statement.
632 def IncludeFileCheckIfndef(self
):
633 if EccGlobalData
.gConfig
.IncludeFileCheckIfndefStatement
== '1' or EccGlobalData
.gConfig
.IncludeFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
634 EdkLogger
.quiet("Checking header file ifndef ...")
636 # for Dirpath, Dirnames, Filenames in self.WalkTree():
637 # for F in Filenames:
638 # if os.path.splitext(F)[1] in ('.h'):
639 # FullName = os.path.join(Dirpath, F)
640 # MsgList = c.CheckHeaderFileIfndef(FullName)
641 for FullName
in EccGlobalData
.gHFileList
:
642 MsgList
= c
.CheckHeaderFileIfndef(FullName
)
644 # Check whether include files NOT contain code or define data variables
645 def IncludeFileCheckData(self
):
646 if EccGlobalData
.gConfig
.IncludeFileCheckData
== '1' or EccGlobalData
.gConfig
.IncludeFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
647 EdkLogger
.quiet("Checking header file data ...")
649 # Get all typedef functions
651 for IdentifierTable
in EccGlobalData
.gIdentifierTableList
:
652 SqlCommand
= """select Name from %s
653 where Model = %s """ % (IdentifierTable
, MODEL_IDENTIFIER_TYPEDEF
)
654 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
655 for Record
in RecordSet
:
656 if Record
[0].startswith('('):
657 gAllTypedefFun
.append(Record
[0])
659 # for Dirpath, Dirnames, Filenames in self.WalkTree():
660 # for F in Filenames:
661 # if os.path.splitext(F)[1] in ('.h'):
662 # FullName = os.path.join(Dirpath, F)
663 # MsgList = c.CheckHeaderFileData(FullName)
664 for FullName
in EccGlobalData
.gHFileList
:
665 MsgList
= c
.CheckHeaderFileData(FullName
, gAllTypedefFun
)
667 # Doxygen document checking
668 def DoxygenCheck(self
):
669 self
.DoxygenCheckFileHeader()
670 self
.DoxygenCheckFunctionHeader()
671 self
.DoxygenCheckCommentDescription()
672 self
.DoxygenCheckCommentFormat()
673 self
.DoxygenCheckCommand()
675 # Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5
676 def DoxygenCheckFileHeader(self
):
677 if EccGlobalData
.gConfig
.DoxygenCheckFileHeader
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
678 EdkLogger
.quiet("Checking Doxygen file header ...")
680 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
682 Ext
= os
.path
.splitext(F
)[1]
683 if Ext
in ('.h', '.c'):
684 FullName
= os
.path
.join(Dirpath
, F
)
685 MsgList
= c
.CheckFileHeaderDoxygenComments(FullName
)
686 elif Ext
in ('.inf', '.dec', '.dsc', '.fdf'):
687 FullName
= os
.path
.join(Dirpath
, F
)
688 op
= open(FullName
).readlines()
691 CurrentSection
= MODEL_UNKNOWN
692 HeaderSectionLines
= []
693 HeaderCommentStart
= False
694 HeaderCommentEnd
= False
696 for Line
in FileLinesList
:
699 if (LineNo
< len(FileLinesList
) - 1):
700 NextLine
= FileLinesList
[LineNo
].strip()
705 if (Line
== '' or not Line
) and LineNo
== len(FileLinesList
):
706 LastSectionFalg
= True
709 # check whether file header comment section started
711 if Line
.startswith('#') and \
712 (Line
.find('@file') > -1) and \
713 not HeaderCommentStart
:
714 if CurrentSection
!= MODEL_UNKNOWN
:
715 SqlStatement
= """ select ID from File where FullPath like '%s'""" % FullName
716 ResultSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlStatement
)
717 for Result
in ResultSet
:
718 Msg
= 'INF/DEC/DSC/FDF file header comment should begin with ""## @file"" or ""# @file""at the very top file'
719 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER
, Msg
, "File", Result
[0])
722 CurrentSection
= MODEL_IDENTIFIER_FILE_HEADER
724 # Append the first line to section lines.
726 HeaderSectionLines
.append((Line
, LineNo
))
727 HeaderCommentStart
= True
731 # Collect Header content.
733 if (Line
.startswith('#') and CurrentSection
== MODEL_IDENTIFIER_FILE_HEADER
) and\
734 HeaderCommentStart
and not Line
.startswith('##') and not\
735 HeaderCommentEnd
and NextLine
!= '':
736 HeaderSectionLines
.append((Line
, LineNo
))
741 if (Line
.startswith('##') or not Line
.strip().startswith("#")) and HeaderCommentStart \
742 and not HeaderCommentEnd
:
743 if Line
.startswith('##'):
744 HeaderCommentEnd
= True
745 HeaderSectionLines
.append((Line
, LineNo
))
746 ParseHeaderCommentSection(HeaderSectionLines
, FullName
)
748 if HeaderCommentStart
== False:
749 SqlStatement
= """ select ID from File where FullPath like '%s'""" % FullName
750 ResultSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlStatement
)
751 for Result
in ResultSet
:
752 Msg
= 'INF/DEC/DSC/FDF file header comment should begin with ""## @file"" or ""# @file"" at the very top file'
753 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER
, Msg
, "File", Result
[0])
754 if HeaderCommentEnd
== False:
755 SqlStatement
= """ select ID from File where FullPath like '%s'""" % FullName
756 ResultSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlStatement
)
757 for Result
in ResultSet
:
758 Msg
= 'INF/DEC/DSC/FDF file header comment should end with ""##"" at the end of file header comment block'
759 # Check whether File header Comment End with '##'
760 if EccGlobalData
.gConfig
.HeaderCheckFileCommentEnd
== '1' or EccGlobalData
.gConfig
.HeaderCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
761 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER
, Msg
, "File", Result
[0])
765 # Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5
766 def DoxygenCheckFunctionHeader(self
):
767 if EccGlobalData
.gConfig
.DoxygenCheckFunctionHeader
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
768 EdkLogger
.quiet("Checking Doxygen function header ...")
770 # for Dirpath, Dirnames, Filenames in self.WalkTree():
771 # for F in Filenames:
772 # if os.path.splitext(F)[1] in ('.h', '.c'):
773 # FullName = os.path.join(Dirpath, F)
774 # MsgList = c.CheckFuncHeaderDoxygenComments(FullName)
775 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
776 MsgList
= c
.CheckFuncHeaderDoxygenComments(FullName
)
779 # Check whether the first line of text in a comment block is a brief description of the element being documented.
780 # The brief description must end with a period.
781 def DoxygenCheckCommentDescription(self
):
782 if EccGlobalData
.gConfig
.DoxygenCheckCommentDescription
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
785 # Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.
786 def DoxygenCheckCommentFormat(self
):
787 if EccGlobalData
.gConfig
.DoxygenCheckCommentFormat
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
788 EdkLogger
.quiet("Checking Doxygen comment ///< ...")
790 # for Dirpath, Dirnames, Filenames in self.WalkTree():
791 # for F in Filenames:
792 # if os.path.splitext(F)[1] in ('.h', '.c'):
793 # FullName = os.path.join(Dirpath, F)
794 # MsgList = c.CheckDoxygenTripleForwardSlash(FullName)
795 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
796 MsgList
= c
.CheckDoxygenTripleForwardSlash(FullName
)
798 # Check whether only Doxygen commands allowed to mark the code are @bug and @todo.
799 def DoxygenCheckCommand(self
):
800 if EccGlobalData
.gConfig
.DoxygenCheckCommand
== '1' or EccGlobalData
.gConfig
.DoxygenCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
801 EdkLogger
.quiet("Checking Doxygen command ...")
803 # for Dirpath, Dirnames, Filenames in self.WalkTree():
804 # for F in Filenames:
805 # if os.path.splitext(F)[1] in ('.h', '.c'):
806 # FullName = os.path.join(Dirpath, F)
807 # MsgList = c.CheckDoxygenCommand(FullName)
808 for FullName
in EccGlobalData
.gCFileList
+ EccGlobalData
.gHFileList
:
809 MsgList
= c
.CheckDoxygenCommand(FullName
)
811 # Meta-Data File Processing Checking
812 def MetaDataFileCheck(self
):
813 self
.MetaDataFileCheckPathName()
814 self
.MetaDataFileCheckGenerateFileList()
815 self
.MetaDataFileCheckLibraryInstance()
816 self
.MetaDataFileCheckLibraryInstanceDependent()
817 self
.MetaDataFileCheckLibraryInstanceOrder()
818 self
.MetaDataFileCheckLibraryNoUse()
819 self
.MetaDataFileCheckLibraryDefinedInDec()
820 self
.MetaDataFileCheckBinaryInfInFdf()
821 self
.MetaDataFileCheckPcdDuplicate()
822 self
.MetaDataFileCheckPcdFlash()
823 self
.MetaDataFileCheckPcdNoUse()
824 self
.MetaDataFileCheckGuidDuplicate()
825 self
.MetaDataFileCheckModuleFileNoUse()
826 self
.MetaDataFileCheckPcdType()
827 self
.MetaDataFileCheckModuleFileGuidDuplication()
828 self
.MetaDataFileCheckModuleFileGuidFormat()
829 self
.MetaDataFileCheckModuleFileProtocolFormat()
830 self
.MetaDataFileCheckModuleFilePpiFormat()
831 self
.MetaDataFileCheckModuleFilePcdFormat()
833 # Check whether each file defined in meta-data exists
834 def MetaDataFileCheckPathName(self
):
835 if EccGlobalData
.gConfig
.MetaDataFileCheckPathName
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
836 # This item is covered when parsing Inf/Dec/Dsc files
839 # Generate a list for all files defined in meta-data files
840 def MetaDataFileCheckGenerateFileList(self
):
841 if EccGlobalData
.gConfig
.MetaDataFileCheckGenerateFileList
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
842 # This item is covered when parsing Inf/Dec/Dsc files
845 # Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.
846 # Each Library Instance must specify the Supported Module Types in its Inf file,
847 # and any module specifying the library instance must be one of the supported types.
848 def MetaDataFileCheckLibraryInstance(self
):
849 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryInstance
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
850 EdkLogger
.quiet("Checking for library instance type issue ...")
851 SqlCommand
= """select A.ID, A.Value3, B.Value3 from Inf as A left join Inf as B
852 where A.Value2 = 'LIBRARY_CLASS' and A.Model = %s
853 and B.Value2 = 'MODULE_TYPE' and B.Model = %s and A.BelongsToFile = B.BelongsToFile
854 group by A.BelongsToFile""" % (MODEL_META_DATA_HEADER
, MODEL_META_DATA_HEADER
)
855 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
857 for Record
in RecordSet
:
858 List
= Record
[1].split('|', 1)
861 SupModType
= DT
.SUP_MODULE_LIST_STRING
.split(DT
.TAB_VALUE_SPLIT
)
863 SupModType
= List
[1].split()
865 if List
[0] not in LibraryClasses
:
866 LibraryClasses
[List
[0]] = SupModType
868 for Item
in SupModType
:
869 if Item
not in LibraryClasses
[List
[0]]:
870 LibraryClasses
[List
[0]].append(Item
)
872 if Record
[2] != DT
.SUP_MODULE_BASE
and Record
[2] not in SupModType
:
873 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])
875 SqlCommand
= """select A.ID, A.Value1, B.Value3 from Inf as A left join Inf as B
876 where A.Model = %s and B.Value2 = '%s' and B.Model = %s
877 and B.BelongsToFile = A.BelongsToFile""" \
878 % (MODEL_EFI_LIBRARY_CLASS
, 'MODULE_TYPE', MODEL_META_DATA_HEADER
)
879 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
880 # Merge all LibraryClasses' supmodlist
882 for Record
in RecordSet
:
883 if Record
[1] not in RecordDict
:
884 RecordDict
[Record
[1]] = [str(Record
[2])]
886 if Record
[2] not in RecordDict
[Record
[1]]:
887 RecordDict
[Record
[1]].append(Record
[2])
889 for Record
in RecordSet
:
890 if Record
[1] in LibraryClasses
:
891 if Record
[2] not in LibraryClasses
[Record
[1]] and DT
.SUP_MODULE_BASE
not in RecordDict
[Record
[1]]:
892 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1
, Record
[1]):
893 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])
895 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1
, Record
[1]):
896 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])
898 # Check whether a Library Instance has been defined for all dependent library classes
899 def MetaDataFileCheckLibraryInstanceDependent(self
):
900 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryInstanceDependent
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
901 EdkLogger
.quiet("Checking for library instance dependent issue ...")
902 SqlCommand
= """select ID, Value1, Value2 from Dsc where Model = %s""" % MODEL_EFI_LIBRARY_CLASS
903 LibraryClasses
= EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand
)
904 for LibraryClass
in LibraryClasses
:
905 if LibraryClass
[1].upper() == 'NULL' or LibraryClass
[1].startswith('!ifdef') or LibraryClass
[1].startswith('!ifndef') or LibraryClass
[1].endswith('!endif'):
908 LibraryIns
= os
.path
.normpath(mws
.join(EccGlobalData
.gWorkspace
, LibraryClass
[2]))
909 SkipDirString
= '|'.join(EccGlobalData
.gConfig
.SkipDirList
)
910 p
= re
.compile(r
'.*[\\/](?:%s^\S)[\\/]?.*' % SkipDirString
)
911 if p
.match(os
.path
.split(LibraryIns
)[0].upper()):
913 SqlCommand
= """select Value3 from Inf where BelongsToFile =
914 (select ID from File where lower(FullPath) = lower('%s'))
915 and Value2 = '%s'""" % (LibraryIns
, DT
.PLATFORM_COMPONENT_TYPE_LIBRARY_CLASS
)
916 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
918 for Record
in RecordSet
:
919 LibName
= Record
[0].split('|', 1)[0]
920 if LibraryClass
[1] == LibName
:
923 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT
, LibraryClass
[1]):
924 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])
926 # Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies
927 def MetaDataFileCheckLibraryInstanceOrder(self
):
928 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryInstanceOrder
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
929 # This checkpoint is not necessary for Ecc check
932 # Check whether the unnecessary inclusion of library classes in the Inf file
933 # Check whether the unnecessary duplication of library classe names in the DSC file
934 def MetaDataFileCheckLibraryNoUse(self
):
935 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryNoUse
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
936 EdkLogger
.quiet("Checking for library instance not used ...")
937 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
)
938 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
939 for Record
in RecordSet
:
940 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE
, Record
[1]):
941 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])
943 select A.ID, A.Value1, A.BelongsToFile, A.StartLine, B.StartLine from Dsc as A left join Dsc as B
944 where A.Model = %s and B.Model = %s and A.Scope1 = B.Scope1 and A.Scope2 = B.Scope2 and A.ID != B.ID
945 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""" \
946 % (MODEL_EFI_LIBRARY_CLASS
, MODEL_EFI_LIBRARY_CLASS
)
947 RecordSet
= EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand
)
948 for Record
in RecordSet
:
949 if Record
[3] and Record
[4] and Record
[3] != Record
[4] and Record
[1] != 'NULL':
950 SqlCommand
= """select FullPath from File where ID = %s""" % (Record
[2])
951 FilePathList
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
952 for FilePath
in FilePathList
:
953 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NAME_DUPLICATE
, Record
[1]):
954 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])
956 # Check the header file in Include\Library directory whether be defined in the package DEC file.
957 def MetaDataFileCheckLibraryDefinedInDec(self
):
958 if EccGlobalData
.gConfig
.MetaDataFileCheckLibraryDefinedInDec
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
959 EdkLogger
.quiet("Checking for library instance whether be defined in the package dec file ...")
961 select A.Value1, A.StartLine, A.ID, B.Value1 from Inf as A left join Dec as B
962 on A.Model = B.Model and A.Value1 = B.Value1 where A.Model=%s
963 """ % MODEL_EFI_LIBRARY_CLASS
964 RecordSet
= EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand
)
965 for Record
in RecordSet
:
966 LibraryInInf
, Line
, ID
, LibraryDec
= Record
968 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NOT_DEFINED
, LibraryInInf
):
969 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_NOT_DEFINED
, \
970 OtherMsg
="The Library Class [%s] in %s line is not defined in the associated package file." % (LibraryInInf
, Line
),
971 BelongsToTable
='Inf', BelongsToItem
=ID
)
973 # 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
974 def MetaDataFileCheckBinaryInfInFdf(self
):
975 if EccGlobalData
.gConfig
.MetaDataFileCheckBinaryInfInFdf
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
976 EdkLogger
.quiet("Checking for non-binary modules defined in FDF files ...")
977 SqlCommand
= """select A.ID, A.Value1 from Fdf as A
981 (select B.Value1 from Dsc as B
983 and B.Enabled > -1)""" % (MODEL_META_DATA_COMPONENT
, MODEL_META_DATA_COMPONENT
)
984 RecordSet
= EccGlobalData
.gDb
.TblFdf
.Exec(SqlCommand
)
985 for Record
in RecordSet
:
988 FilePath
= os
.path
.normpath(mws
.join(EccGlobalData
.gWorkspace
, FilePath
))
989 SqlCommand
= """select ID from Inf where Model = %s and BelongsToFile = (select ID from File where FullPath like '%s')
990 """ % (MODEL_EFI_SOURCE_FILE
, FilePath
)
991 NewRecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
992 if NewRecordSet
!= []:
993 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF
, FilePath
):
994 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
)
996 # Check whether a PCD is set in a Dsc file or the FDF file, but not in both.
997 def MetaDataFileCheckPcdDuplicate(self
):
998 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdDuplicate
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
999 EdkLogger
.quiet("Checking for duplicate PCDs defined in both DSC and FDF files ...")
1001 select A.ID, A.Value1, A.Value2, A.BelongsToFile, B.ID, B.Value1, B.Value2, B.BelongsToFile from Dsc as A, Fdf as B
1002 where A.Model >= %s and A.Model < %s
1003 and B.Model >= %s and B.Model < %s
1004 and A.Value1 = B.Value1
1005 and A.Value2 = B.Value2
1009 """ % (MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
)
1010 RecordSet
= EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand
)
1011 for Record
in RecordSet
:
1012 SqlCommand1
= """select Name from File where ID = %s""" % Record
[3]
1013 SqlCommand2
= """select Name from File where ID = %s""" % Record
[7]
1014 DscFileName
= os
.path
.splitext(EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand1
)[0][0])[0]
1015 FdfFileName
= os
.path
.splitext(EccGlobalData
.gDb
.TblDsc
.Exec(SqlCommand2
)[0][0])[0]
1016 if DscFileName
!= FdfFileName
:
1018 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE
, Record
[1] + '.' + Record
[2]):
1019 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])
1020 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE
, Record
[5] + '.' + Record
[6]):
1021 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])
1023 EdkLogger
.quiet("Checking for duplicate PCDs defined in DEC files ...")
1025 select A.ID, A.Value1, A.Value2, A.Model, B.Model from Dec as A left join Dec as B
1026 where A.Model >= %s and A.Model < %s
1027 and B.Model >= %s and B.Model < %s
1028 and A.Value1 = B.Value1
1029 and A.Value2 = B.Value2
1030 and A.Scope1 = B.Scope1
1032 and A.Model = B.Model
1035 and A.BelongsToFile = B.BelongsToFile
1037 """ % (MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
)
1038 RecordSet
= EccGlobalData
.gDb
.TblDec
.Exec(SqlCommand
)
1039 for Record
in RecordSet
:
1040 RecordCat
= Record
[1] + '.' + Record
[2]
1041 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE
, RecordCat
):
1042 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])
1044 # Check whether PCD settings in the FDF file can only be related to flash.
1045 def MetaDataFileCheckPcdFlash(self
):
1046 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdFlash
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1047 EdkLogger
.quiet("Checking only Flash related PCDs are used in FDF ...")
1049 select ID, Value1, Value2, BelongsToFile from Fdf as A
1050 where A.Model >= %s and Model < %s
1052 and A.Value2 not like '%%Flash%%'
1053 """ % (MODEL_PCD
, MODEL_META_DATA_HEADER
)
1054 RecordSet
= EccGlobalData
.gDb
.TblFdf
.Exec(SqlCommand
)
1055 for Record
in RecordSet
:
1056 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_FLASH
, Record
[1] + '.' + Record
[2]):
1057 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])
1059 # Check whether PCDs used in Inf files but not specified in Dsc or FDF files
1060 def MetaDataFileCheckPcdNoUse(self
):
1061 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdNoUse
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1062 EdkLogger
.quiet("Checking for non-specified PCDs ...")
1064 select ID, Value1, Value2, BelongsToFile from Inf as A
1065 where A.Model >= %s and Model < %s
1067 and (A.Value1, A.Value2) not in
1068 (select Value1, Value2 from Dsc as B
1069 where B.Model >= %s and B.Model < %s
1071 and (A.Value1, A.Value2) not in
1072 (select Value1, Value2 from Fdf as C
1073 where C.Model >= %s and C.Model < %s
1075 """ % (MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
, MODEL_PCD
, MODEL_META_DATA_HEADER
)
1076 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
1077 for Record
in RecordSet
:
1078 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE
, Record
[1] + '.' + Record
[2]):
1079 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])
1081 # Check whether having duplicate guids defined for Guid/Protocol/Ppi
1082 def MetaDataFileCheckGuidDuplicate(self
):
1083 if EccGlobalData
.gConfig
.MetaDataFileCheckGuidDuplicate
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1084 EdkLogger
.quiet("Checking for duplicate GUID/PPI/PROTOCOL ...")
1086 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID
, MODEL_EFI_GUID
, EccGlobalData
.gDb
.TblDec
)
1087 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID
, MODEL_EFI_GUID
, EccGlobalData
.gDb
.TblDsc
)
1088 self
.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID
, MODEL_EFI_GUID
)
1090 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL
, MODEL_EFI_PROTOCOL
, EccGlobalData
.gDb
.TblDec
)
1091 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL
, MODEL_EFI_PROTOCOL
, EccGlobalData
.gDb
.TblDsc
)
1092 self
.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL
, MODEL_EFI_PROTOCOL
)
1094 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI
, MODEL_EFI_PPI
, EccGlobalData
.gDb
.TblDec
)
1095 self
.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI
, MODEL_EFI_PPI
, EccGlobalData
.gDb
.TblDsc
)
1096 self
.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI
, MODEL_EFI_PPI
)
1098 # Check whether all files under module directory are described in INF files
1099 def MetaDataFileCheckModuleFileNoUse(self
):
1100 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFileNoUse
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1101 EdkLogger
.quiet("Checking for no used module files ...")
1103 select upper(Path) from File where ID in (select BelongsToFile from Inf where BelongsToFile != -1)
1105 InfPathSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
1107 for Item
in InfPathSet
:
1108 if Item
[0] not in InfPathList
:
1109 InfPathList
.append(Item
[0])
1111 select ID, Path, FullPath from File where upper(FullPath) not in
1112 (select upper(A.Path) || '\\' || upper(B.Value1) from File as A, INF as B
1113 where A.ID in (select BelongsToFile from INF where Model = %s group by BelongsToFile) and
1114 B.BelongsToFile = A.ID and B.Model = %s)
1115 and (Model = %s or Model = %s)
1116 """ % (MODEL_EFI_SOURCE_FILE
, MODEL_EFI_SOURCE_FILE
, MODEL_FILE_C
, MODEL_FILE_H
)
1117 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
1118 for Record
in RecordSet
:
1120 Path
= Path
.upper().replace('\X64', '').replace('\IA32', '').replace('\EBC', '').replace('\IPF', '').replace('\ARM', '')
1121 if Path
in InfPathList
:
1122 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE
, Record
[2]):
1123 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])
1125 # Check whether the PCD is correctly used in C function via its type
1126 def MetaDataFileCheckPcdType(self
):
1127 if EccGlobalData
.gConfig
.MetaDataFileCheckPcdType
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1128 EdkLogger
.quiet("Checking for pcd type in c code function usage ...")
1130 select ID, Model, Value1, Value2, BelongsToFile from INF where Model > %s and Model < %s
1131 """ % (MODEL_PCD
, MODEL_META_DATA_HEADER
)
1132 PcdSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
1138 BelongsToFile
= Pcd
[4]
1140 select ID from File where FullPath in
1141 (select B.Path || '\\' || A.Value1 from INF as A, File as B where A.Model = %s and A.BelongsToFile = %s
1142 and B.ID = %s and (B.Model = %s or B.Model = %s))
1143 """ % (MODEL_EFI_SOURCE_FILE
, BelongsToFile
, BelongsToFile
, MODEL_FILE_C
, MODEL_FILE_H
)
1144 TableSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1145 for Tbl
in TableSet
:
1146 TblName
= 'Identifier' + str(Tbl
[0])
1148 select Name, ID from %s where value like '%s' and Model = %s
1149 """ % (TblName
, PcdName
, MODEL_IDENTIFIER_FUNCTION_CALLING
)
1150 RecordSet
= EccGlobalData
.gDb
.TblInf
.Exec(SqlCommand
)
1151 TblNumber
= TblName
.replace('Identifier', '')
1152 for Record
in RecordSet
:
1154 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_PCD_TYPE
, FunName
):
1155 if Model
in [MODEL_PCD_FIXED_AT_BUILD
] and not FunName
.startswith('FixedPcdGet'):
1156 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])
1157 if Model
in [MODEL_PCD_FEATURE_FLAG
] and (not FunName
.startswith('FeaturePcdGet') and not FunName
.startswith('FeaturePcdSet')):
1158 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])
1159 if Model
in [MODEL_PCD_PATCHABLE_IN_MODULE
] and (not FunName
.startswith('PatchablePcdGet') and not FunName
.startswith('PatchablePcdSet')):
1160 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])
1162 #ERROR_META_DATA_FILE_CHECK_PCD_TYPE
1165 # Internal worker function to get the INF workspace relative path from FileID
1166 def GetInfFilePathFromID(self
, FileID
):
1167 Table
= EccGlobalData
.gDb
.TblFile
1168 SqlCommand
= """select A.FullPath from %s as A where A.ID = %s""" % (Table
.Table
, FileID
)
1169 RecordSet
= Table
.Exec(SqlCommand
)
1171 for Record
in RecordSet
:
1172 Path
= mws
.relpath(Record
[0], EccGlobalData
.gWorkspace
)
1175 # Check whether two module INFs under one workspace has the same FILE_GUID value
1176 def MetaDataFileCheckModuleFileGuidDuplication(self
):
1177 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFileGuidDuplication
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1178 EdkLogger
.quiet("Checking for pcd type in c code function usage ...")
1179 Table
= EccGlobalData
.gDb
.TblInf
1181 select A.ID, A.Value3, A.BelongsToFile, B.BelongsToFile from %s as A, %s as B
1182 where A.Value2 = 'FILE_GUID' and B.Value2 = 'FILE_GUID' and
1183 A.Value3 = B.Value3 and A.ID != B.ID group by A.ID
1184 """ % (Table
.Table
, Table
.Table
)
1185 RecordSet
= Table
.Exec(SqlCommand
)
1186 for Record
in RecordSet
:
1187 InfPath1
= self
.GetInfFilePathFromID(Record
[2])
1188 InfPath2
= self
.GetInfFilePathFromID(Record
[3])
1189 if InfPath1
and InfPath2
:
1190 if not EccGlobalData
.gException
.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION
, InfPath1
):
1191 Msg
= "The FILE_GUID of INF file [%s] is duplicated with that of %s" % (InfPath1
, InfPath2
)
1192 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1195 # Check Guid Format in module INF
1196 def MetaDataFileCheckModuleFileGuidFormat(self
):
1197 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFileGuidFormat
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1198 EdkLogger
.quiet("Check Guid Format in module INF ...")
1199 Table
= EccGlobalData
.gDb
.TblInf
1201 select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID
1202 """ % (Table
.Table
, MODEL_EFI_GUID
)
1203 RecordSet
= Table
.Exec(SqlCommand
)
1204 for Record
in RecordSet
:
1207 GuidCommentList
= []
1208 InfPath
= self
.GetInfFilePathFromID(Record
[3])
1209 Msg
= "The GUID format of %s in INF file [%s] does not follow rules" % (Value1
, InfPath
)
1210 if Value2
.startswith(DT
.TAB_SPECIAL_COMMENT
):
1211 GuidCommentList
= Value2
[2:].split(DT
.TAB_SPECIAL_COMMENT
)
1212 if GuidCommentList
[0].strip().startswith(DT
.TAB_INF_USAGE_UNDEFINED
):
1214 elif len(GuidCommentList
) > 1:
1215 if not GuidCommentList
[0].strip().startswith((DT
.TAB_INF_USAGE_PRO
,
1216 DT
.TAB_INF_USAGE_SOME_PRO
,
1217 DT
.TAB_INF_USAGE_CON
,
1218 DT
.TAB_INF_USAGE_SOME_CON
)):
1219 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1220 if not (GuidCommentList
[1].strip()).startswith(DT
.TAB_INF_GUIDTYPE_VAR
) and \
1221 not GuidCommentList
[1].strip().startswith((DT
.TAB_INF_GUIDTYPE_EVENT
,
1222 DT
.TAB_INF_GUIDTYPE_HII
,
1223 DT
.TAB_INF_GUIDTYPE_FILE
,
1224 DT
.TAB_INF_GUIDTYPE_HOB
,
1225 DT
.TAB_INF_GUIDTYPE_FV
,
1226 DT
.TAB_INF_GUIDTYPE_ST
,
1227 DT
.TAB_INF_GUIDTYPE_TSG
,
1228 DT
.TAB_INF_GUIDTYPE_GUID
,
1229 DT
.TAB_INF_GUIDTYPE_PROTOCOL
,
1230 DT
.TAB_INF_GUIDTYPE_PPI
,
1231 DT
.TAB_INF_USAGE_UNDEFINED
)):
1232 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1234 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1236 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1238 # Check Protocol Format in module INF
1239 def MetaDataFileCheckModuleFileProtocolFormat(self
):
1240 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFileProtocolFormat
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1241 EdkLogger
.quiet("Check Protocol Format in module INF ...")
1242 Table
= EccGlobalData
.gDb
.TblInf
1244 select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID
1245 """ % (Table
.Table
, MODEL_EFI_PROTOCOL
)
1246 RecordSet
= Table
.Exec(SqlCommand
)
1247 for Record
in RecordSet
:
1250 GuidCommentList
= []
1251 InfPath
= self
.GetInfFilePathFromID(Record
[3])
1252 Msg
= "The Protocol format of %s in INF file [%s] does not follow rules" % (Value1
, InfPath
)
1253 if Value2
.startswith(DT
.TAB_SPECIAL_COMMENT
):
1254 GuidCommentList
= Value2
[2:].split(DT
.TAB_SPECIAL_COMMENT
)
1255 if len(GuidCommentList
) >= 1:
1256 if not GuidCommentList
[0].strip().startswith((DT
.TAB_INF_USAGE_PRO
,
1257 DT
.TAB_INF_USAGE_SOME_PRO
,
1258 DT
.TAB_INF_USAGE_CON
,
1259 DT
.TAB_INF_USAGE_SOME_CON
,
1260 DT
.TAB_INF_USAGE_NOTIFY
,
1261 DT
.TAB_INF_USAGE_TO_START
,
1262 DT
.TAB_INF_USAGE_BY_START
,
1263 DT
.TAB_INF_USAGE_UNDEFINED
)):
1264 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PROTOCOL
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1266 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PROTOCOL
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1269 # Check Ppi Format in module INF
1270 def MetaDataFileCheckModuleFilePpiFormat(self
):
1271 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFilePpiFormat
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1272 EdkLogger
.quiet("Check Ppi Format in module INF ...")
1273 Table
= EccGlobalData
.gDb
.TblInf
1275 select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID
1276 """ % (Table
.Table
, MODEL_EFI_PPI
)
1277 RecordSet
= Table
.Exec(SqlCommand
)
1278 for Record
in RecordSet
:
1281 GuidCommentList
= []
1282 InfPath
= self
.GetInfFilePathFromID(Record
[3])
1283 Msg
= "The Ppi format of %s in INF file [%s] does not follow rules" % (Value1
, InfPath
)
1284 if Value2
.startswith(DT
.TAB_SPECIAL_COMMENT
):
1285 GuidCommentList
= Value2
[2:].split(DT
.TAB_SPECIAL_COMMENT
)
1286 if len(GuidCommentList
) >= 1:
1287 if not GuidCommentList
[0].strip().startswith((DT
.TAB_INF_USAGE_PRO
,
1288 DT
.TAB_INF_USAGE_SOME_PRO
,
1289 DT
.TAB_INF_USAGE_CON
,
1290 DT
.TAB_INF_USAGE_SOME_CON
,
1291 DT
.TAB_INF_USAGE_NOTIFY
,
1292 DT
.TAB_INF_USAGE_UNDEFINED
)):
1293 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PPI
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1295 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PPI
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1297 # Check Pcd Format in module INF
1298 def MetaDataFileCheckModuleFilePcdFormat(self
):
1299 if EccGlobalData
.gConfig
.MetaDataFileCheckModuleFilePcdFormat
== '1' or EccGlobalData
.gConfig
.MetaDataFileCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1300 EdkLogger
.quiet("Check Pcd Format in module INF ...")
1301 Table
= EccGlobalData
.gDb
.TblInf
1303 select ID, Model, Value1, Value2, Usage, BelongsToFile from %s where Model >= %s and Model < %s group by ID
1304 """ % (Table
.Table
, MODEL_PCD
, MODEL_META_DATA_HEADER
)
1305 RecordSet
= Table
.Exec(SqlCommand
)
1306 for Record
in RecordSet
:
1308 PcdName
= Record
[2] + '.' + Record
[3]
1311 InfPath
= self
.GetInfFilePathFromID(Record
[5])
1312 Msg
= "The Pcd format of %s in INF file [%s] does not follow rules" % (PcdName
, InfPath
)
1313 if Usage
.startswith(DT
.TAB_SPECIAL_COMMENT
):
1314 PcdCommentList
= Usage
[2:].split(DT
.TAB_SPECIAL_COMMENT
)
1315 if len(PcdCommentList
) >= 1:
1316 if Model
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_FEATURE_FLAG
] \
1317 and not PcdCommentList
[0].strip().startswith((DT
.TAB_INF_USAGE_SOME_PRO
,
1318 DT
.TAB_INF_USAGE_CON
,
1319 DT
.TAB_INF_USAGE_UNDEFINED
)):
1320 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PCD
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1321 if Model
in [MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
] \
1322 and not PcdCommentList
[0].strip().startswith((DT
.TAB_INF_USAGE_PRO
,
1323 DT
.TAB_INF_USAGE_SOME_PRO
,
1324 DT
.TAB_INF_USAGE_CON
,
1325 DT
.TAB_INF_USAGE_SOME_CON
,
1326 DT
.TAB_INF_USAGE_UNDEFINED
)):
1327 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PCD
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1329 EccGlobalData
.gDb
.TblReport
.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PCD
, OtherMsg
=Msg
, BelongsToTable
=Table
.Table
, BelongsToItem
=Record
[0])
1331 # Check whether these is duplicate Guid/Ppi/Protocol name
1332 def CheckGuidProtocolPpi(self
, ErrorID
, Model
, Table
):
1334 if Model
== MODEL_EFI_GUID
:
1336 if Model
== MODEL_EFI_PROTOCOL
:
1338 if Model
== MODEL_EFI_PPI
:
1341 select A.ID, A.Value1 from %s as A, %s as B
1342 where A.Model = %s and B.Model = %s
1343 and A.Value1 like B.Value1 and A.ID != B.ID
1344 and A.Scope1 = B.Scope1
1348 """ % (Table
.Table
, Table
.Table
, Model
, Model
)
1349 RecordSet
= Table
.Exec(SqlCommand
)
1350 for Record
in RecordSet
:
1351 if not EccGlobalData
.gException
.IsException(ErrorID
, Record
[1]):
1352 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])
1354 # Check whether these is duplicate Guid/Ppi/Protocol value
1355 def CheckGuidProtocolPpiValue(self
, ErrorID
, Model
):
1357 Table
= EccGlobalData
.gDb
.TblDec
1358 if Model
== MODEL_EFI_GUID
:
1360 if Model
== MODEL_EFI_PROTOCOL
:
1362 if Model
== MODEL_EFI_PPI
:
1365 select A.ID, A.Value1, A.Value2 from %s as A, %s as B
1366 where A.Model = %s and B.Model = %s
1367 and A.Value2 like B.Value2 and A.ID != B.ID
1368 and A.Scope1 = B.Scope1 and A.Value1 != B.Value1
1370 """ % (Table
.Table
, Table
.Table
, Model
, Model
)
1371 RecordSet
= Table
.Exec(SqlCommand
)
1372 for Record
in RecordSet
:
1373 if not EccGlobalData
.gException
.IsException(ErrorID
, Record
[2]):
1374 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])
1376 # Naming Convention Check
1377 def NamingConventionCheck(self
):
1378 if EccGlobalData
.gConfig
.NamingConventionCheckDefineStatement
== '1' \
1379 or EccGlobalData
.gConfig
.NamingConventionCheckTypedefStatement
== '1' \
1380 or EccGlobalData
.gConfig
.NamingConventionCheckIfndefStatement
== '1' \
1381 or EccGlobalData
.gConfig
.NamingConventionCheckVariableName
== '1' \
1382 or EccGlobalData
.gConfig
.NamingConventionCheckSingleCharacterVariable
== '1' \
1383 or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1'\
1384 or EccGlobalData
.gConfig
.CheckAll
== '1':
1385 for Dirpath
, Dirnames
, Filenames
in self
.WalkTree():
1387 if os
.path
.splitext(F
)[1] in ('.h', '.c'):
1388 FullName
= os
.path
.join(Dirpath
, F
)
1389 Id
= c
.GetTableID(FullName
)
1392 FileTable
= 'Identifier' + str(Id
)
1393 self
.NamingConventionCheckDefineStatement(FileTable
)
1394 self
.NamingConventionCheckTypedefStatement(FileTable
)
1395 self
.NamingConventionCheckVariableName(FileTable
)
1396 self
.NamingConventionCheckSingleCharacterVariable(FileTable
)
1397 if os
.path
.splitext(F
)[1] in ('.h'):
1398 self
.NamingConventionCheckIfndefStatement(FileTable
)
1400 self
.NamingConventionCheckPathName()
1401 self
.NamingConventionCheckFunctionName()
1403 # Check whether only capital letters are used for #define declarations
1404 def NamingConventionCheckDefineStatement(self
, FileTable
):
1405 if EccGlobalData
.gConfig
.NamingConventionCheckDefineStatement
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1406 EdkLogger
.quiet("Checking naming convention of #define statement ...")
1408 SqlCommand
= """select ID, Value from %s where Model = %s""" % (FileTable
, MODEL_IDENTIFIER_MACRO_DEFINE
)
1409 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1410 for Record
in RecordSet
:
1411 Name
= Record
[1].strip().split()[1]
1412 if Name
.find('(') != -1:
1413 Name
= Name
[0:Name
.find('(')]
1414 if Name
.upper() != Name
:
1415 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT
, Name
):
1416 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])
1418 # Check whether only capital letters are used for typedef declarations
1419 def NamingConventionCheckTypedefStatement(self
, FileTable
):
1420 if EccGlobalData
.gConfig
.NamingConventionCheckTypedefStatement
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1421 EdkLogger
.quiet("Checking naming convention of #typedef statement ...")
1423 SqlCommand
= """select ID, Name from %s where Model = %s""" % (FileTable
, MODEL_IDENTIFIER_TYPEDEF
)
1424 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1425 for Record
in RecordSet
:
1426 Name
= Record
[1].strip()
1427 if Name
!= '' and Name
is not None:
1429 Name
= Name
[1:Name
.find(')')]
1430 if Name
.find('(') > -1:
1431 Name
= Name
[Name
.find('(') + 1 : Name
.find(')')]
1432 Name
= Name
.replace('WINAPI', '')
1433 Name
= Name
.replace('*', '').strip()
1434 if Name
.upper() != Name
:
1435 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT
, Name
):
1436 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])
1438 # Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'.
1439 def NamingConventionCheckIfndefStatement(self
, FileTable
):
1440 if EccGlobalData
.gConfig
.NamingConventionCheckIfndefStatement
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1441 EdkLogger
.quiet("Checking naming convention of #ifndef statement ...")
1443 SqlCommand
= """select ID, Value from %s where Model = %s""" % (FileTable
, MODEL_IDENTIFIER_MACRO_IFNDEF
)
1444 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1445 for Record
in RecordSet
:
1446 Name
= Record
[1].replace('#ifndef', '').strip()
1448 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT
, Name
):
1449 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])
1451 # Rule for path name, variable name and function name
1452 # 1. First character should be upper case
1453 # 2. Existing lower case in a word
1454 # 3. No space existence
1455 # Check whether the path name followed the rule
1456 def NamingConventionCheckPathName(self
):
1457 if EccGlobalData
.gConfig
.NamingConventionCheckPathName
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1458 EdkLogger
.quiet("Checking naming convention of file path name ...")
1459 Pattern
= re
.compile(r
'^[A-Z]+\S*[a-z]\S*$')
1460 SqlCommand
= """select ID, Name from File"""
1461 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1462 for Record
in RecordSet
:
1463 if not Pattern
.match(Record
[1]):
1464 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_PATH_NAME
, Record
[1]):
1465 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])
1467 # Rule for path name, variable name and function name
1468 # 1. First character should be upper case
1469 # 2. Existing lower case in a word
1470 # 3. No space existence
1471 # 4. Global variable name must start with a 'g'
1472 # Check whether the variable name followed the rule
1473 def NamingConventionCheckVariableName(self
, FileTable
):
1474 if EccGlobalData
.gConfig
.NamingConventionCheckVariableName
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1475 EdkLogger
.quiet("Checking naming convention of variable name ...")
1476 Pattern
= re
.compile(r
'^[A-Zgm]+\S*[a-z]\S*$')
1478 SqlCommand
= """select ID, Name from %s where Model = %s""" % (FileTable
, MODEL_IDENTIFIER_VARIABLE
)
1479 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1480 for Record
in RecordSet
:
1482 if Var
.startswith('CONST'):
1483 Var
= Var
[5:].lstrip()
1484 if not Pattern
.match(Var
):
1485 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME
, Record
[1]):
1486 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])
1488 # Rule for path name, variable name and function name
1489 # 1. First character should be upper case
1490 # 2. Existing lower case in a word
1491 # 3. No space existence
1492 # Check whether the function name followed the rule
1493 def NamingConventionCheckFunctionName(self
):
1494 if EccGlobalData
.gConfig
.NamingConventionCheckFunctionName
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1495 EdkLogger
.quiet("Checking naming convention of function name ...")
1496 Pattern
= re
.compile(r
'^[A-Z]+\S*[a-z]\S*$')
1497 SqlCommand
= """select ID, Name from Function"""
1498 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1499 for Record
in RecordSet
:
1500 if not Pattern
.match(Record
[1]):
1501 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME
, Record
[1]):
1502 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])
1504 # Check whether NO use short variable name with single character
1505 def NamingConventionCheckSingleCharacterVariable(self
, FileTable
):
1506 if EccGlobalData
.gConfig
.NamingConventionCheckSingleCharacterVariable
== '1' or EccGlobalData
.gConfig
.NamingConventionCheckAll
== '1' or EccGlobalData
.gConfig
.CheckAll
== '1':
1507 EdkLogger
.quiet("Checking naming convention of single character variable name ...")
1509 SqlCommand
= """select ID, Name from %s where Model = %s""" % (FileTable
, MODEL_IDENTIFIER_VARIABLE
)
1510 RecordSet
= EccGlobalData
.gDb
.TblFile
.Exec(SqlCommand
)
1511 for Record
in RecordSet
:
1512 Variable
= Record
[1].replace('*', '')
1513 if len(Variable
) == 1:
1514 if not EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE
, Record
[1]):
1515 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])
1517 def FindPara(FilePath
, Para
, CallingLine
):
1518 Lines
= open(FilePath
).readlines()
1520 for Index
in range(CallingLine
- 1, 0, -1):
1521 # Find the nearest statement for Para
1522 Line
= Lines
[Index
].strip()
1523 if Line
.startswith('%s = ' % Para
):
1532 # This acts like the main() function for the script, unless it is 'import'ed into another
1535 if __name__
== '__main__':