]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Ecc/Check.py
BaseTools: Align include guards policy
[mirror_edk2.git] / BaseTools / Source / Python / Ecc / Check.py
1 ## @file
2 # This file is used to define checkpoints used by ECC tool
3 #
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
7 #
8 from __future__ import absolute_import
9 import Common.LongFilePathOs as os
10 import re
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
16 from Ecc import c
17 from Common.LongFilePathSupport import OpenLongFilePath as open
18 from Common.MultipleWorkspace import MultipleWorkspace as mws
19
20 ## Check
21 #
22 # This class is to define checkpoints used by ECC tool
23 #
24 # @param object: Inherited from object class
25 #
26 class Check(object):
27 def __init__(self):
28 pass
29
30 # Check all required checkpoints
31 def Check(self):
32 self.GeneralCheck()
33 self.MetaDataFileCheck()
34 self.DoxygenCheck()
35 self.IncludeFileCheck()
36 self.PredicateExpressionCheck()
37 self.DeclAndDataTypeCheck()
38 self.FunctionLayoutCheck()
39 self.NamingConventionCheck()
40 self.SmmCommParaCheck()
41
42 def SmmCommParaCheck(self):
43 self.SmmCommParaCheckBufferType()
44
45
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
51 # report error.
52 # b. it is a global buffer, check the driver that holds the global buffer is of type DXE_RUNTIME_DRIVER
53 # report success.
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
57 # report success.
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
66 CommApiList = []
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)
71 if RecordSet:
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)
82 if RecordSet:
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('[')]
93 # Get the ID
94 Id = Record[0]
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
109
110 # print BelongsToFile, FullPath, StartLine, ModuleType, SecondPara
111
112 Value = FindPara(FullPath, SecondPara, StartLine)
113 # Find the value of the parameter
114 if Value:
115 if 'AllocatePage' in Value \
116 or 'AllocatePool' in Value \
117 or 'AllocateRuntimePool' in Value \
118 or 'AllocateZeroPool' in Value:
119 pass
120 else:
121 if '->' 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"
128 % Value,
129 BelongsToTable=IdentifierTable,
130 BelongsToItem=Id)
131 else:
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"
138 % Value,
139 BelongsToTable=IdentifierTable,
140 BelongsToItem=Id)
141
142
143 # Not find the value of the parameter
144 else:
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)
149 if NewRecordSet:
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:
155 pass
156 else:
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"
163 % Value,
164 BelongsToTable=IdentifierTable,
165 BelongsToItem=Id)
166 else:
167 pass
168
169 # Check UNI files
170 def UniCheck(self):
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:
176 File = Record[1]
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])
181
182 # General Checking
183 def GeneralCheck(self):
184 self.GeneralCheckNonAcsii()
185 self.UniCheck()
186 self.GeneralCheckNoTab()
187 self.GeneralCheckLineEnding()
188 self.GeneralCheckTrailingWhiteSpaceLine()
189
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()
199 IndexOfLine = 0
200 for Line in op:
201 IndexOfLine += 1
202 IndexOfChar = 0
203 for Char in Line:
204 IndexOfChar += 1
205 if Char == '\t':
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])
208
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()
218 IndexOfLine = 0
219 for Line in op:
220 IndexOfLine += 1
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])
224
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()
234 IndexOfLine = 0
235 for Line in op:
236 IndexOfLine += 1
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])
240
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()
250 IndexOfLine = 0
251 for Line in op:
252 IndexOfLine += 1
253 IndexOfChar = 0
254 for Char in Line:
255 IndexOfChar += 1
256 if ord(Char) > 126:
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])
259
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()
269
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 ...")
274
275 DeprecatedFunctionSet = ('UnicodeValueToString',
276 'AsciiValueToString',
277 'StrCpy',
278 'StrnCpy',
279 'StrCat',
280 'StrnCat',
281 'UnicodeStrToAsciiStr',
282 'AsciiStrCpy',
283 'AsciiStrnCpy',
284 'AsciiStrCat',
285 'AsciiStrnCat',
286 'AsciiStrToUnicodeStr',
287 'PcdSet8',
288 'PcdSet16',
289 'PcdSet32',
290 'PcdSet64',
291 'PcdSetPtr',
292 'PcdSetBool',
293 'PcdSetEx8',
294 'PcdSetEx16',
295 'PcdSetEx32',
296 'PcdSetEx64',
297 'PcdSetExPtr',
298 'PcdSetExBool',
299 'LibPcdSet8',
300 'LibPcdSet16',
301 'LibPcdSet32',
302 'LibPcdSet64',
303 'LibPcdSetPtr',
304 'LibPcdSetBool',
305 'LibPcdSetEx8',
306 'LibPcdSetEx16',
307 'LibPcdSetEx32',
308 'LibPcdSetEx64',
309 'LibPcdSetExPtr',
310 'LibPcdSetExBool',
311 'GetVariable',
312 'GetEfiGlobalVariable',
313 )
314
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:
321 if Key == Record[1]:
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,
325 OtherMsg=OtherMsg,
326 BelongsToTable=IdentifierTable,
327 BelongsToItem=Record[0])
328
329 def WalkTree(self):
330 IgnoredPattern = c.GetIgnoredDirListPattern()
331 for Dirpath, Dirnames, Filenames in os.walk(EccGlobalData.gTarget):
332 for Dir in Dirnames:
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
338 Dirnames.remove(Dir)
339 Dirnames.append(Dirname)
340 if IgnoredPattern.match(Dirpath.upper()):
341 continue
342 for f in Filenames[:]:
343 if f.lower() in EccGlobalData.gConfig.SkipFileList:
344 Filenames.remove(f)
345 yield (Dirpath, Dirnames, Filenames)
346
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 ...")
351
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)
359
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 ...")
364
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)
372
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 ...")
378
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)
386
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 ...")
391
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)
401
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 ...")
406
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)
414
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 ...")
421
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)
427
428 for FullName in EccGlobalData.gCFileList:
429 c.CheckFuncLayoutLocalVariable(FullName)
430
431 # Check whether no use of STATIC for functions
432 # self.CFunctionLayoutCheckNoStatic = 1
433
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()
443
444
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 ...")
449
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)
457
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 ...")
462
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)
470
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':
474 pass
475
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 ...")
480
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)
490
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 ...")
495
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)
505
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 ...")
510 AllStructure = {}
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:
515 if Record[1] != '':
516 if Record[1] not in AllStructure.keys():
517 AllStructure[Record[1]] = Record[2]
518 else:
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])
527
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 ...")
532
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)
542
543 # Predicate Expression Checking
544 def PredicateExpressionCheck(self):
545 self.PredicateExpressionCheckBooleanValue()
546 self.PredicateExpressionCheckNonBooleanOperator()
547 self.PredicateExpressionCheckComparisonNullType()
548
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 ...")
553
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)
563
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...")
568
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)
578
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 ...")
583
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)
593
594 # Include file checking
595 def IncludeFileCheck(self):
596 self.IncludeFileCheckIfndef()
597 self.IncludeFileCheckData()
598 self.IncludeFileCheckSameName()
599
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 """
606 RecordDict = {}
607 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
608 for Record in RecordSet:
609 List = Record[1].replace('/', '\\').split('\\')
610 if len(List) >= 2:
611 Key = List[-2] + '\\' + List[-1]
612 else:
613 Key = List[0]
614 if Key not in RecordDict:
615 RecordDict[Key] = [Record]
616 else:
617 RecordDict[Key].append(Record)
618
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])
625
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 ...")
630
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)
638
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 ...")
643
644 # Get all typedef functions
645 gAllTypedefFun = []
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])
653
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)
661
662 # Doxygen document checking
663 def DoxygenCheck(self):
664 self.DoxygenCheckFileHeader()
665 self.DoxygenCheckFunctionHeader()
666 self.DoxygenCheckCommentDescription()
667 self.DoxygenCheckCommentFormat()
668 self.DoxygenCheckCommand()
669
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 ...")
674
675 for Dirpath, Dirnames, Filenames in self.WalkTree():
676 for F in Filenames:
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()
684 FileLinesList = op
685 LineNo = 0
686 CurrentSection = MODEL_UNKNOWN
687 HeaderSectionLines = []
688 HeaderCommentStart = False
689 HeaderCommentEnd = False
690
691 for Line in FileLinesList:
692 LineNo = LineNo + 1
693 Line = Line.strip()
694 if (LineNo < len(FileLinesList) - 1):
695 NextLine = FileLinesList[LineNo].strip()
696
697 #
698 # blank line
699 #
700 if (Line == '' or not Line) and LineNo == len(FileLinesList):
701 LastSectionFalg = True
702
703 #
704 # check whether file header comment section started
705 #
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])
715
716 else:
717 CurrentSection = MODEL_IDENTIFIER_FILE_HEADER
718 #
719 # Append the first line to section lines.
720 #
721 HeaderSectionLines.append((Line, LineNo))
722 HeaderCommentStart = True
723 continue
724
725 #
726 # Collect Header content.
727 #
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))
732 continue
733 #
734 # Header content end
735 #
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)
742 break
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])
757
758
759
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 ...")
764
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)
772
773
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':
778 pass
779
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 ///< ...")
784
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)
792
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 ...")
797
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)
805
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()
827
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
832 pass
833
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
838 pass
839
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)
851 LibraryClasses = {}
852 for Record in RecordSet:
853 List = Record[1].split('|', 1)
854 SupModType = []
855 if len(List) == 1:
856 SupModType = DT.SUP_MODULE_LIST_STRING.split(DT.TAB_VALUE_SPLIT)
857 elif len(List) == 2:
858 SupModType = List[1].split()
859
860 if List[0] not in LibraryClasses:
861 LibraryClasses[List[0]] = SupModType
862 else:
863 for Item in SupModType:
864 if Item not in LibraryClasses[List[0]]:
865 LibraryClasses[List[0]].append(Item)
866
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])
869
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
876 RecordDict = {}
877 for Record in RecordSet:
878 if Record[1] not in RecordDict:
879 RecordDict[Record[1]] = [str(Record[2])]
880 else:
881 if Record[2] not in RecordDict[Record[1]]:
882 RecordDict[Record[1]].append(Record[2])
883
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])
889 else:
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])
892
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'):
901 continue
902 else:
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()):
907 continue
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)
912 IsFound = False
913 for Record in RecordSet:
914 LibName = Record[0].split('|', 1)[0]
915 if LibraryClass[1] == LibName:
916 IsFound = True
917 if not IsFound:
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])
920
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
925 pass
926
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])
937 SqlCommand = """
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])
950
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 ...")
955 SqlCommand = """
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
962 if not LibraryDec:
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)
967
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
973 where A.Model = %s
974 and A.Enabled > -1
975 and A.Value1 not in
976 (select B.Value1 from Dsc as B
977 where B.Model = %s
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:
981 FdfID = Record[0]
982 FilePath = Record[1]
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)
990
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 ...")
995 SqlCommand = """
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
1001 and A.Enabled > -1
1002 and B.Enabled > -1
1003 group by A.ID
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:
1012 continue
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])
1017
1018 EdkLogger.quiet("Checking for duplicate PCDs defined in DEC files ...")
1019 SqlCommand = """
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
1026 and A.ID != B.ID
1027 and A.Model = B.Model
1028 and A.Enabled > -1
1029 and B.Enabled > -1
1030 and A.BelongsToFile = B.BelongsToFile
1031 group by A.ID
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])
1038
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 ...")
1043 SqlCommand = """
1044 select ID, Value1, Value2, BelongsToFile from Fdf as A
1045 where A.Model >= %s and Model < %s
1046 and A.Enabled > -1
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])
1053
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 ...")
1058 SqlCommand = """
1059 select ID, Value1, Value2, BelongsToFile from Inf as A
1060 where A.Model >= %s and Model < %s
1061 and A.Enabled > -1
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
1065 and B.Enabled > -1)
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
1069 and C.Enabled > -1)
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])
1075
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 ...")
1080 # Check Guid
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)
1084 # Check protocol
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)
1088 # Check ppi
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)
1092
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 ...")
1097 SqlCommand = """
1098 select upper(Path) from File where ID in (select BelongsToFile from Inf where BelongsToFile != -1)
1099 """
1100 InfPathSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
1101 InfPathList = []
1102 for Item in InfPathSet:
1103 if Item[0] not in InfPathList:
1104 InfPathList.append(Item[0])
1105 SqlCommand = """
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:
1114 Path = Record[1]
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])
1119
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 ...")
1124 SqlCommand = """
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)
1128 for Pcd in PcdSet:
1129 Model = Pcd[1]
1130 PcdName = Pcd[2]
1131 if Pcd[3]:
1132 PcdName = Pcd[3]
1133 BelongsToFile = Pcd[4]
1134 SqlCommand = """
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])
1142 SqlCommand = """
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:
1148 FunName = Record[0]
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])
1156
1157 #ERROR_META_DATA_FILE_CHECK_PCD_TYPE
1158 pass
1159
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)
1165 Path = ""
1166 for Record in RecordSet:
1167 Path = mws.relpath(Record[0], EccGlobalData.gWorkspace)
1168 return Path
1169
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
1175 SqlCommand = """
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])
1188
1189
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
1195 SqlCommand = """
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:
1200 Value1 = Record[1]
1201 Value2 = Record[2]
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):
1208 continue
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])
1228 else:
1229 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])
1230 else:
1231 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])
1232
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
1238 SqlCommand = """
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:
1243 Value1 = Record[1]
1244 Value2 = Record[2]
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])
1260 else:
1261 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PROTOCOL, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])
1262
1263
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
1269 SqlCommand = """
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:
1274 Value1 = Record[1]
1275 Value2 = Record[2]
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])
1289 else:
1290 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PPI, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])
1291
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
1297 SqlCommand = """
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:
1302 Model = Record[1]
1303 PcdName = Record[2] + '.' + Record[3]
1304 Usage = Record[4]
1305 PcdCommentList = []
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])
1323 else:
1324 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PCD, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])
1325
1326 # Check whether these is duplicate Guid/Ppi/Protocol name
1327 def CheckGuidProtocolPpi(self, ErrorID, Model, Table):
1328 Name = ''
1329 if Model == MODEL_EFI_GUID:
1330 Name = 'guid'
1331 if Model == MODEL_EFI_PROTOCOL:
1332 Name = 'protocol'
1333 if Model == MODEL_EFI_PPI:
1334 Name = 'ppi'
1335 SqlCommand = """
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
1340 and A.Enabled > -1
1341 and B.Enabled > -1
1342 group by A.ID
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])
1348
1349 # Check whether these is duplicate Guid/Ppi/Protocol value
1350 def CheckGuidProtocolPpiValue(self, ErrorID, Model):
1351 Name = ''
1352 Table = EccGlobalData.gDb.TblDec
1353 if Model == MODEL_EFI_GUID:
1354 Name = 'guid'
1355 if Model == MODEL_EFI_PROTOCOL:
1356 Name = 'protocol'
1357 if Model == MODEL_EFI_PPI:
1358 Name = 'ppi'
1359 SqlCommand = """
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
1364 group by A.ID
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])
1370
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():
1381 for F in Filenames:
1382 if os.path.splitext(F)[1] in ('.h', '.c'):
1383 FullName = os.path.join(Dirpath, F)
1384 Id = c.GetTableID(FullName)
1385 if Id < 0:
1386 continue
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)
1394
1395 self.NamingConventionCheckPathName()
1396 self.NamingConventionCheckFunctionName()
1397
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 ...")
1402
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])
1412
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 ...")
1417
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:
1423 if Name[0] == '(':
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])
1432
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 ...")
1437
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])
1445
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])
1461
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*$')
1472
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:
1476 Var = Record[1]
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])
1483
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])
1499
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 ...")
1504
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])
1512
1513 def FindPara(FilePath, Para, CallingLine):
1514 Lines = open(FilePath).readlines()
1515 Line = ''
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):
1520 Line = Line.strip()
1521 return Line
1522 break
1523
1524 return ''
1525
1526 ##
1527 #
1528 # This acts like the main() function for the script, unless it is 'import'ed into another
1529 # script.
1530 #
1531 if __name__ == '__main__':
1532 Check = Check()
1533 Check.Check()