]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Ecc/Check.py
BaseTools/Ecc: Add some new checkpoints
[mirror_edk2.git] / BaseTools / Source / Python / Ecc / Check.py
CommitLineData
30fdf114
LG
1## @file\r
2# This file is used to define checkpoints used by ECC tool\r
3#\r
8bb63e37 4# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>\r
40d841f6 5# This program and the accompanying materials\r
30fdf114
LG
6# are licensed and made available under the terms and conditions of the BSD License\r
7# which accompanies this distribution. The full text of the license may be found at\r
8# http://opensource.org/licenses/bsd-license.php\r
9#\r
10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12#\r
b6f6b636 13from __future__ import absolute_import\r
1be2ed90 14import Common.LongFilePathOs as os\r
30fdf114
LG
15import re\r
16from CommonDataClass.DataClass import *\r
b3d07ff8 17import Common.DataType as DT\r
b6f6b636
GL
18from .EccToolError import *\r
19from .MetaDataParser import ParseHeaderCommentSection\r
20from . import EccGlobalData\r
21from . import c\r
b3d07ff8 22from Common.LongFilePathSupport import OpenLongFilePath as open\r
c4f52e12 23from Common.MultipleWorkspace import MultipleWorkspace as mws\r
30fdf114
LG
24\r
25## Check\r
26#\r
27# This class is to define checkpoints used by ECC tool\r
28#\r
29# @param object: Inherited from object class\r
30#\r
31class Check(object):\r
32 def __init__(self):\r
33 pass\r
34\r
35 # Check all required checkpoints\r
36 def Check(self):\r
e56468c0 37 self.GeneralCheck()\r
30fdf114
LG
38 self.MetaDataFileCheck()\r
39 self.DoxygenCheck()\r
40 self.IncludeFileCheck()\r
41 self.PredicateExpressionCheck()\r
42 self.DeclAndDataTypeCheck()\r
43 self.FunctionLayoutCheck()\r
44 self.NamingConventionCheck()\r
703ef6cf
HC
45 self.SmmCommParaCheck()\r
46\r
47 def SmmCommParaCheck(self):\r
48 self.SmmCommParaCheckBufferType()\r
49\r
50\r
51 # Check if SMM communication function has correct parameter type\r
52 # 1. Get function calling with instance./->Communicate() interface\r
53 # and make sure the protocol instance is of type EFI_SMM_COMMUNICATION_PROTOCOL.\r
54 # 2. Find the origin of the 2nd parameter of Communicate() interface, if -\r
55 # a. it is a local buffer on stack\r
56 # report error.\r
57 # b. it is a global buffer, check the driver that holds the global buffer is of type DXE_RUNTIME_DRIVER\r
58 # report success.\r
59 # c. it is a buffer by AllocatePage/AllocatePool (may be wrapped by nested function calls),\r
60 # check the EFI_MEMORY_TYPE to be EfiRuntimeServicesCode,EfiRuntimeServicesData,\r
61 # EfiACPIMemoryNVS or EfiReservedMemoryType\r
62 # report success.\r
63 # d. it is a buffer located via EFI_SYSTEM_TABLE.ConfigurationTable (may be wrapped by nested function calls)\r
64 # report warning to indicate human code review.\r
65 # e. it is a buffer from other kind of pointers (may need to trace into nested function calls to locate),\r
66 # repeat checks in a.b.c and d.\r
67 def SmmCommParaCheckBufferType(self):\r
68 if EccGlobalData.gConfig.SmmCommParaCheckBufferType == '1' or EccGlobalData.gConfig.SmmCommParaCheckAll == '1':\r
69 EdkLogger.quiet("Checking SMM communication parameter type ...")\r
70 # Get all EFI_SMM_COMMUNICATION_PROTOCOL interface\r
71 CommApiList = []\r
72 for IdentifierTable in EccGlobalData.gIdentifierTableList:\r
73 SqlCommand = """select ID, Name, BelongsToFile from %s\r
74 where Modifier = 'EFI_SMM_COMMUNICATION_PROTOCOL*' """ % (IdentifierTable)\r
75 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
76 if RecordSet:\r
77 for Record in RecordSet:\r
78 if Record[1] not in CommApiList:\r
79 CommApiList.append(Record[1])\r
80 # For each interface, check the second parameter\r
81 for CommApi in CommApiList:\r
82 for IdentifierTable in EccGlobalData.gIdentifierTableList:\r
83 SqlCommand = """select ID, Name, Value, BelongsToFile, StartLine from %s\r
84 where Name = '%s->Communicate' and Model = %s""" \\r
85 % (IdentifierTable, CommApi, MODEL_IDENTIFIER_FUNCTION_CALLING)\r
86 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
87 if RecordSet:\r
88 # print IdentifierTable\r
89 for Record in RecordSet:\r
90 # Get the second parameter for Communicate function\r
91 SecondPara = Record[2].split(',')[1].strip()\r
92 SecondParaIndex = None\r
93 if SecondPara.startswith('&'):\r
94 SecondPara = SecondPara[1:]\r
95 if SecondPara.endswith(']'):\r
96 SecondParaIndex = SecondPara[SecondPara.find('[') + 1:-1]\r
97 SecondPara = SecondPara[:SecondPara.find('[')]\r
98 # Get the ID\r
99 Id = Record[0]\r
100 # Get the BelongsToFile\r
101 BelongsToFile = Record[3]\r
102 # Get the source file path\r
103 SqlCommand = """select FullPath from File where ID = %s""" % BelongsToFile\r
104 NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
105 FullPath = NewRecordSet[0][0]\r
106 # Get the line no of function calling\r
107 StartLine = Record[4]\r
108 # Get the module type\r
109 SqlCommand = """select Value3 from INF where BelongsToFile = (select ID from File\r
110 where Path = (select Path from File where ID = %s) and Model = 1011)\r
111 and Value2 = 'MODULE_TYPE'""" % BelongsToFile\r
112 NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
113 ModuleType = NewRecordSet[0][0] if NewRecordSet else None\r
114\r
115 # print BelongsToFile, FullPath, StartLine, ModuleType, SecondPara\r
116\r
117 Value = FindPara(FullPath, SecondPara, StartLine)\r
118 # Find the value of the parameter\r
119 if Value:\r
120 if 'AllocatePage' in Value \\r
121 or 'AllocatePool' in Value \\r
122 or 'AllocateRuntimePool' in Value \\r
123 or 'AllocateZeroPool' in Value:\r
124 pass\r
125 else:\r
126 if '->' in Value:\r
127 if not EccGlobalData.gException.IsException(\r
128 ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE, Value):\r
129 EccGlobalData.gDb.TblReport.Insert(ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE,\r
130 OtherMsg="Please review the buffer type"\r
131 + "is correct or not. If it is correct" +\r
132 " please add [%s] to exception list"\r
133 % Value,\r
134 BelongsToTable=IdentifierTable,\r
135 BelongsToItem=Id)\r
136 else:\r
137 if not EccGlobalData.gException.IsException(\r
138 ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE, Value):\r
139 EccGlobalData.gDb.TblReport.Insert(ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE,\r
140 OtherMsg="Please review the buffer type"\r
141 + "is correct or not. If it is correct" +\r
142 " please add [%s] to exception list"\r
143 % Value,\r
144 BelongsToTable=IdentifierTable,\r
145 BelongsToItem=Id)\r
146\r
147\r
148 # Not find the value of the parameter\r
149 else:\r
150 SqlCommand = """select ID, Modifier, Name, Value, Model, BelongsToFunction from %s\r
151 where Name = '%s' and StartLine < %s order by StartLine DESC""" \\r
152 % (IdentifierTable, SecondPara, StartLine)\r
153 NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
154 if NewRecordSet:\r
155 Value = NewRecordSet[0][1]\r
156 if 'AllocatePage' in Value \\r
157 or 'AllocatePool' in Value \\r
158 or 'AllocateRuntimePool' in Value \\r
159 or 'AllocateZeroPool' in Value:\r
160 pass\r
161 else:\r
162 if not EccGlobalData.gException.IsException(\r
163 ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE, Value):\r
164 EccGlobalData.gDb.TblReport.Insert(ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE,\r
165 OtherMsg="Please review the buffer type"\r
166 + "is correct or not. If it is correct" +\r
167 " please add [%s] to exception list"\r
168 % Value,\r
169 BelongsToTable=IdentifierTable,\r
170 BelongsToItem=Id)\r
171 else:\r
172 pass\r
30fdf114 173\r
b3d07ff8
HC
174 # Check UNI files\r
175 def UniCheck(self):\r
176 if EccGlobalData.gConfig.GeneralCheckUni == '1' or EccGlobalData.gConfig.GeneralCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
177 EdkLogger.quiet("Checking whether UNI file is UTF-16 ...")\r
178 SqlCommand = """select ID, FullPath, ExtName from File where ExtName like 'uni'"""\r
179 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
180 for Record in RecordSet:\r
181 File = Record[1]\r
182 FileIn = open(File, 'rb').read(2)\r
183 if FileIn != '\xff\xfe':\r
184 OtherMsg = "File %s is not a valid UTF-16 UNI file" % Record[1]\r
185 EccGlobalData.gDb.TblReport.Insert(ERROR_GENERAL_CHECK_UNI, OtherMsg=OtherMsg, BelongsToTable='File', BelongsToItem=Record[0])\r
186\r
e56468c0 187 # General Checking\r
188 def GeneralCheck(self):\r
189 self.GeneralCheckNonAcsii()\r
b3d07ff8 190 self.UniCheck()\r
a1583a87
HC
191 self.GeneralCheckNoTab()\r
192 self.GeneralCheckLineEnding()\r
193 self.GeneralCheckTrailingWhiteSpaceLine()\r
194\r
195 # Check whether NO Tab is used, replaced with spaces\r
196 def GeneralCheckNoTab(self):\r
197 if EccGlobalData.gConfig.GeneralCheckNoTab == '1' or EccGlobalData.gConfig.GeneralCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
198 EdkLogger.quiet("Checking No TAB used in file ...")\r
199 SqlCommand = """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')"""\r
200 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
201 for Record in RecordSet:\r
202 if Record[2].upper() not in EccGlobalData.gConfig.BinaryExtList:\r
203 op = open(Record[1]).readlines()\r
204 IndexOfLine = 0\r
205 for Line in op:\r
206 IndexOfLine += 1\r
207 IndexOfChar = 0\r
208 for Char in Line:\r
209 IndexOfChar += 1\r
210 if Char == '\t':\r
211 OtherMsg = "File %s has TAB char at line %s column %s" % (Record[1], IndexOfLine, IndexOfChar)\r
212 EccGlobalData.gDb.TblReport.Insert(ERROR_GENERAL_CHECK_NO_TAB, OtherMsg=OtherMsg, BelongsToTable='File', BelongsToItem=Record[0])\r
213\r
214 # Check Only use CRLF (Carriage Return Line Feed) line endings.\r
215 def GeneralCheckLineEnding(self):\r
216 if EccGlobalData.gConfig.GeneralCheckLineEnding == '1' or EccGlobalData.gConfig.GeneralCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
217 EdkLogger.quiet("Checking line ending in file ...")\r
218 SqlCommand = """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')"""\r
219 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
220 for Record in RecordSet:\r
221 if Record[2].upper() not in EccGlobalData.gConfig.BinaryExtList:\r
222 op = open(Record[1], 'rb').readlines()\r
223 IndexOfLine = 0\r
224 for Line in op:\r
225 IndexOfLine += 1\r
226 if not Line.endswith('\r\n'):\r
227 OtherMsg = "File %s has invalid line ending at line %s" % (Record[1], IndexOfLine)\r
228 EccGlobalData.gDb.TblReport.Insert(ERROR_GENERAL_CHECK_INVALID_LINE_ENDING, OtherMsg=OtherMsg, BelongsToTable='File', BelongsToItem=Record[0])\r
229\r
230 # Check if there is no trailing white space in one line.\r
231 def GeneralCheckTrailingWhiteSpaceLine(self):\r
232 if EccGlobalData.gConfig.GeneralCheckTrailingWhiteSpaceLine == '1' or EccGlobalData.gConfig.GeneralCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
233 EdkLogger.quiet("Checking trailing white space line in file ...")\r
234 SqlCommand = """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')"""\r
235 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
236 for Record in RecordSet:\r
237 if Record[2].upper() not in EccGlobalData.gConfig.BinaryExtList:\r
238 op = open(Record[1], 'rb').readlines()\r
239 IndexOfLine = 0\r
240 for Line in op:\r
241 IndexOfLine += 1\r
242 if Line.replace('\r', '').replace('\n', '').endswith(' '):\r
243 OtherMsg = "File %s has trailing white spaces at line %s" % (Record[1], IndexOfLine)\r
244 EccGlobalData.gDb.TblReport.Insert(ERROR_GENERAL_CHECK_TRAILING_WHITE_SPACE_LINE, OtherMsg=OtherMsg, BelongsToTable='File', BelongsToItem=Record[0])\r
e56468c0 245\r
246 # Check whether file has non ACSII char\r
247 def GeneralCheckNonAcsii(self):\r
248 if EccGlobalData.gConfig.GeneralCheckNonAcsii == '1' or EccGlobalData.gConfig.GeneralCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
249 EdkLogger.quiet("Checking Non-ACSII char in file ...")\r
8d62ae35 250 SqlCommand = """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')"""\r
d0acc87a 251 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
e56468c0 252 for Record in RecordSet:\r
253 if Record[2].upper() not in EccGlobalData.gConfig.BinaryExtList:\r
254 op = open(Record[1]).readlines()\r
255 IndexOfLine = 0\r
256 for Line in op:\r
257 IndexOfLine += 1\r
258 IndexOfChar = 0\r
259 for Char in Line:\r
260 IndexOfChar += 1\r
261 if ord(Char) > 126:\r
d40b2ee6
LG
262 OtherMsg = "File %s has Non-ASCII char at line %s column %s" % (Record[1], IndexOfLine, IndexOfChar)\r
263 EccGlobalData.gDb.TblReport.Insert(ERROR_GENERAL_CHECK_NON_ACSII, OtherMsg=OtherMsg, BelongsToTable='File', BelongsToItem=Record[0])\r
e56468c0 264\r
30fdf114
LG
265 # C Function Layout Checking\r
266 def FunctionLayoutCheck(self):\r
267 self.FunctionLayoutCheckReturnType()\r
268 self.FunctionLayoutCheckModifier()\r
269 self.FunctionLayoutCheckName()\r
270 self.FunctionLayoutCheckPrototype()\r
271 self.FunctionLayoutCheckBody()\r
272 self.FunctionLayoutCheckLocalVariable()\r
273\r
274 def WalkTree(self):\r
275 IgnoredPattern = c.GetIgnoredDirListPattern()\r
276 for Dirpath, Dirnames, Filenames in os.walk(EccGlobalData.gTarget):\r
277 for Dir in Dirnames:\r
278 Dirname = os.path.join(Dirpath, Dir)\r
279 if os.path.islink(Dirname):\r
280 Dirname = os.path.realpath(Dirname)\r
281 if os.path.isdir(Dirname):\r
282 # symlinks to directories are treated as directories\r
283 Dirnames.remove(Dir)\r
284 Dirnames.append(Dirname)\r
285 if IgnoredPattern.match(Dirpath.upper()):\r
286 continue\r
8c3f9b4e
HC
287 for f in Filenames[:]:\r
288 if f.lower() in EccGlobalData.gConfig.SkipFileList:\r
289 Filenames.remove(f)\r
30fdf114
LG
290 yield (Dirpath, Dirnames, Filenames)\r
291\r
292 # Check whether return type exists and in the first line\r
293 def FunctionLayoutCheckReturnType(self):\r
294 if EccGlobalData.gConfig.CFunctionLayoutCheckReturnType == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
295 EdkLogger.quiet("Checking function layout return type ...")\r
296\r
e56468c0 297# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
298# for F in Filenames:\r
299# if os.path.splitext(F)[1] in ('.c', '.h'):\r
300# FullName = os.path.join(Dirpath, F)\r
301# c.CheckFuncLayoutReturnType(FullName)\r
302 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
303 c.CheckFuncLayoutReturnType(FullName)\r
30fdf114
LG
304\r
305 # Check whether any optional functional modifiers exist and next to the return type\r
306 def FunctionLayoutCheckModifier(self):\r
307 if EccGlobalData.gConfig.CFunctionLayoutCheckOptionalFunctionalModifier == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
308 EdkLogger.quiet("Checking function layout modifier ...")\r
309\r
e56468c0 310# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
311# for F in Filenames:\r
312# if os.path.splitext(F)[1] in ('.c', '.h'):\r
313# FullName = os.path.join(Dirpath, F)\r
314# c.CheckFuncLayoutModifier(FullName)\r
315 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
316 c.CheckFuncLayoutModifier(FullName)\r
30fdf114
LG
317\r
318 # Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list\r
319 # Check whether the closing parenthesis is on its own line and also indented two spaces\r
320 def FunctionLayoutCheckName(self):\r
321 if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionName == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
322 EdkLogger.quiet("Checking function layout function name ...")\r
323\r
e56468c0 324# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
325# for F in Filenames:\r
326# if os.path.splitext(F)[1] in ('.c', '.h'):\r
327# FullName = os.path.join(Dirpath, F)\r
328# c.CheckFuncLayoutName(FullName)\r
329 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
330 c.CheckFuncLayoutName(FullName)\r
331\r
30fdf114
LG
332 # Check whether the function prototypes in include files have the same form as function definitions\r
333 def FunctionLayoutCheckPrototype(self):\r
334 if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionPrototype == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
335 EdkLogger.quiet("Checking function layout function prototype ...")\r
336\r
e56468c0 337# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
338# for F in Filenames:\r
339# if os.path.splitext(F)[1] in ('.c'):\r
340# FullName = os.path.join(Dirpath, F)\r
341# EdkLogger.quiet("[PROTOTYPE]" + FullName)\r
342# c.CheckFuncLayoutPrototype(FullName)\r
343 for FullName in EccGlobalData.gCFileList:\r
344 EdkLogger.quiet("[PROTOTYPE]" + FullName)\r
345 c.CheckFuncLayoutPrototype(FullName)\r
30fdf114
LG
346\r
347 # Check whether the body of a function is contained by open and close braces that must be in the first column\r
348 def FunctionLayoutCheckBody(self):\r
349 if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionBody == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
350 EdkLogger.quiet("Checking function layout function body ...")\r
351\r
e56468c0 352# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
353# for F in Filenames:\r
354# if os.path.splitext(F)[1] in ('.c'):\r
355# FullName = os.path.join(Dirpath, F)\r
356# c.CheckFuncLayoutBody(FullName)\r
357 for FullName in EccGlobalData.gCFileList:\r
358 c.CheckFuncLayoutBody(FullName)\r
30fdf114
LG
359\r
360 # Check whether the data declarations is the first code in a module.\r
361 # self.CFunctionLayoutCheckDataDeclaration = 1\r
362 # Check whether no initialization of a variable as part of its declaration\r
363 def FunctionLayoutCheckLocalVariable(self):\r
364 if EccGlobalData.gConfig.CFunctionLayoutCheckNoInitOfVariable == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
365 EdkLogger.quiet("Checking function layout local variables ...")\r
366\r
e56468c0 367# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
368# for F in Filenames:\r
369# if os.path.splitext(F)[1] in ('.c'):\r
370# FullName = os.path.join(Dirpath, F)\r
371# c.CheckFuncLayoutLocalVariable(FullName)\r
372\r
373 for FullName in EccGlobalData.gCFileList:\r
374 c.CheckFuncLayoutLocalVariable(FullName)\r
30fdf114
LG
375\r
376 # Check whether no use of STATIC for functions\r
377 # self.CFunctionLayoutCheckNoStatic = 1\r
378\r
379 # Declarations and Data Types Checking\r
380 def DeclAndDataTypeCheck(self):\r
381 self.DeclCheckNoUseCType()\r
382 self.DeclCheckInOutModifier()\r
383 self.DeclCheckEFIAPIModifier()\r
384 self.DeclCheckEnumeratedType()\r
385 self.DeclCheckStructureDeclaration()\r
386 self.DeclCheckSameStructure()\r
387 self.DeclCheckUnionType()\r
388\r
389\r
390 # Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files.\r
391 def DeclCheckNoUseCType(self):\r
392 if EccGlobalData.gConfig.DeclarationDataTypeCheckNoUseCType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
393 EdkLogger.quiet("Checking Declaration No use C type ...")\r
394\r
e56468c0 395# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
396# for F in Filenames:\r
397# if os.path.splitext(F)[1] in ('.h', '.c'):\r
398# FullName = os.path.join(Dirpath, F)\r
399# c.CheckDeclNoUseCType(FullName)\r
400 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
401 c.CheckDeclNoUseCType(FullName)\r
30fdf114
LG
402\r
403 # 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\r
404 def DeclCheckInOutModifier(self):\r
405 if EccGlobalData.gConfig.DeclarationDataTypeCheckInOutModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
406 EdkLogger.quiet("Checking Declaration argument modifier ...")\r
407\r
e56468c0 408# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
409# for F in Filenames:\r
410# if os.path.splitext(F)[1] in ('.h', '.c'):\r
411# FullName = os.path.join(Dirpath, F)\r
412# c.CheckDeclArgModifier(FullName)\r
413 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
414 c.CheckDeclArgModifier(FullName)\r
30fdf114
LG
415\r
416 # Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols\r
417 def DeclCheckEFIAPIModifier(self):\r
418 if EccGlobalData.gConfig.DeclarationDataTypeCheckEFIAPIModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
419 pass\r
420\r
421 # Check whether Enumerated Type has a 'typedef' and the name is capital\r
422 def DeclCheckEnumeratedType(self):\r
423 if EccGlobalData.gConfig.DeclarationDataTypeCheckEnumeratedType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
424 EdkLogger.quiet("Checking Declaration enum typedef ...")\r
425\r
e56468c0 426# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
427# for F in Filenames:\r
428# if os.path.splitext(F)[1] in ('.h', '.c'):\r
429# FullName = os.path.join(Dirpath, F)\r
430# EdkLogger.quiet("[ENUM]" + FullName)\r
431# c.CheckDeclEnumTypedef(FullName)\r
432 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
433 EdkLogger.quiet("[ENUM]" + FullName)\r
434 c.CheckDeclEnumTypedef(FullName)\r
30fdf114
LG
435\r
436 # Check whether Structure Type has a 'typedef' and the name is capital\r
437 def DeclCheckStructureDeclaration(self):\r
438 if EccGlobalData.gConfig.DeclarationDataTypeCheckStructureDeclaration == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
439 EdkLogger.quiet("Checking Declaration struct typedef ...")\r
440\r
e56468c0 441# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
442# for F in Filenames:\r
443# if os.path.splitext(F)[1] in ('.h', '.c'):\r
444# FullName = os.path.join(Dirpath, F)\r
445# EdkLogger.quiet("[STRUCT]" + FullName)\r
446# c.CheckDeclStructTypedef(FullName)\r
447 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
448 EdkLogger.quiet("[STRUCT]" + FullName)\r
449 c.CheckDeclStructTypedef(FullName)\r
30fdf114
LG
450\r
451 # Check whether having same Structure\r
452 def DeclCheckSameStructure(self):\r
453 if EccGlobalData.gConfig.DeclarationDataTypeCheckSameStructure == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
454 EdkLogger.quiet("Checking same struct ...")\r
455 AllStructure = {}\r
456 for IdentifierTable in EccGlobalData.gIdentifierTableList:\r
d40b2ee6 457 SqlCommand = """select ID, Name, BelongsToFile from %s where Model = %s""" % (IdentifierTable, MODEL_IDENTIFIER_STRUCTURE)\r
30fdf114
LG
458 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
459 for Record in RecordSet:\r
460 if Record[1] != '':\r
461 if Record[1] not in AllStructure.keys():\r
462 AllStructure[Record[1]] = Record[2]\r
463 else:\r
464 ID = AllStructure[Record[1]]\r
465 SqlCommand = """select FullPath from File where ID = %s """ % ID\r
466 NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
467 OtherMsg = "The structure name '%s' is duplicate" % Record[1]\r
468 if NewRecordSet != []:\r
469 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])\r
470 if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE, Record[1]):\r
d40b2ee6 471 EccGlobalData.gDb.TblReport.Insert(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE, OtherMsg=OtherMsg, BelongsToTable=IdentifierTable, BelongsToItem=Record[0])\r
30fdf114
LG
472\r
473 # Check whether Union Type has a 'typedef' and the name is capital\r
474 def DeclCheckUnionType(self):\r
475 if EccGlobalData.gConfig.DeclarationDataTypeCheckUnionType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
476 EdkLogger.quiet("Checking Declaration union typedef ...")\r
477\r
e56468c0 478# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
479# for F in Filenames:\r
480# if os.path.splitext(F)[1] in ('.h', '.c'):\r
481# FullName = os.path.join(Dirpath, F)\r
482# EdkLogger.quiet("[UNION]" + FullName)\r
483# c.CheckDeclUnionTypedef(FullName)\r
484 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
485 EdkLogger.quiet("[UNION]" + FullName)\r
486 c.CheckDeclUnionTypedef(FullName)\r
30fdf114
LG
487\r
488 # Predicate Expression Checking\r
489 def PredicateExpressionCheck(self):\r
490 self.PredicateExpressionCheckBooleanValue()\r
491 self.PredicateExpressionCheckNonBooleanOperator()\r
492 self.PredicateExpressionCheckComparisonNullType()\r
493\r
494 # Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE\r
495 def PredicateExpressionCheckBooleanValue(self):\r
496 if EccGlobalData.gConfig.PredicateExpressionCheckBooleanValue == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
497 EdkLogger.quiet("Checking predicate expression Boolean value ...")\r
498\r
e56468c0 499# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
500# for F in Filenames:\r
501# if os.path.splitext(F)[1] in ('.c'):\r
502# FullName = os.path.join(Dirpath, F)\r
503# EdkLogger.quiet("[BOOLEAN]" + FullName)\r
504# c.CheckBooleanValueComparison(FullName)\r
505 for FullName in EccGlobalData.gCFileList:\r
506 EdkLogger.quiet("[BOOLEAN]" + FullName)\r
507 c.CheckBooleanValueComparison(FullName)\r
30fdf114
LG
508\r
509 # Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=).\r
510 def PredicateExpressionCheckNonBooleanOperator(self):\r
511 if EccGlobalData.gConfig.PredicateExpressionCheckNonBooleanOperator == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
512 EdkLogger.quiet("Checking predicate expression Non-Boolean variable...")\r
513\r
e56468c0 514# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
515# for F in Filenames:\r
516# if os.path.splitext(F)[1] in ('.c'):\r
517# FullName = os.path.join(Dirpath, F)\r
518# EdkLogger.quiet("[NON-BOOLEAN]" + FullName)\r
519# c.CheckNonBooleanValueComparison(FullName)\r
520 for FullName in EccGlobalData.gCFileList:\r
521 EdkLogger.quiet("[NON-BOOLEAN]" + FullName)\r
522 c.CheckNonBooleanValueComparison(FullName)\r
523\r
30fdf114
LG
524 # Check whether a comparison of any pointer to zero must be done via the NULL type\r
525 def PredicateExpressionCheckComparisonNullType(self):\r
526 if EccGlobalData.gConfig.PredicateExpressionCheckComparisonNullType == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
527 EdkLogger.quiet("Checking predicate expression NULL pointer ...")\r
528\r
e56468c0 529# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
530# for F in Filenames:\r
531# if os.path.splitext(F)[1] in ('.c'):\r
532# FullName = os.path.join(Dirpath, F)\r
533# EdkLogger.quiet("[POINTER]" + FullName)\r
534# c.CheckPointerNullComparison(FullName)\r
535 for FullName in EccGlobalData.gCFileList:\r
536 EdkLogger.quiet("[POINTER]" + FullName)\r
537 c.CheckPointerNullComparison(FullName)\r
538\r
30fdf114
LG
539 # Include file checking\r
540 def IncludeFileCheck(self):\r
541 self.IncludeFileCheckIfndef()\r
542 self.IncludeFileCheckData()\r
543 self.IncludeFileCheckSameName()\r
544\r
545 # Check whether having include files with same name\r
546 def IncludeFileCheckSameName(self):\r
547 if EccGlobalData.gConfig.IncludeFileCheckSameName == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
548 EdkLogger.quiet("Checking same header file name ...")\r
549 SqlCommand = """select ID, FullPath from File\r
550 where Model = 1002 order by Name """\r
551 RecordDict = {}\r
552 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
553 for Record in RecordSet:\r
554 List = Record[1].replace('/', '\\').split('\\')\r
555 if len(List) >= 2:\r
556 Key = List[-2] + '\\' + List[-1]\r
557 else:\r
558 Key = List[0]\r
559 if Key not in RecordDict:\r
560 RecordDict[Key] = [Record]\r
561 else:\r
562 RecordDict[Key].append(Record)\r
563\r
564 for Key in RecordDict:\r
565 if len(RecordDict[Key]) > 1:\r
566 for Item in RecordDict[Key]:\r
c4f52e12 567 Path = mws.relpath(Item[1], EccGlobalData.gWorkspace)\r
52302d4d 568 if not EccGlobalData.gException.IsException(ERROR_INCLUDE_FILE_CHECK_NAME, Path):\r
d40b2ee6 569 EccGlobalData.gDb.TblReport.Insert(ERROR_INCLUDE_FILE_CHECK_NAME, OtherMsg="The file name for [%s] is duplicate" % Path, BelongsToTable='File', BelongsToItem=Item[0])\r
30fdf114
LG
570\r
571 # Check whether all include file contents is guarded by a #ifndef statement.\r
572 def IncludeFileCheckIfndef(self):\r
573 if EccGlobalData.gConfig.IncludeFileCheckIfndefStatement == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
574 EdkLogger.quiet("Checking header file ifndef ...")\r
575\r
e56468c0 576# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
577# for F in Filenames:\r
578# if os.path.splitext(F)[1] in ('.h'):\r
579# FullName = os.path.join(Dirpath, F)\r
580# MsgList = c.CheckHeaderFileIfndef(FullName)\r
581 for FullName in EccGlobalData.gHFileList:\r
582 MsgList = c.CheckHeaderFileIfndef(FullName)\r
30fdf114
LG
583\r
584 # Check whether include files NOT contain code or define data variables\r
585 def IncludeFileCheckData(self):\r
586 if EccGlobalData.gConfig.IncludeFileCheckData == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
587 EdkLogger.quiet("Checking header file data ...")\r
588\r
e56468c0 589# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
590# for F in Filenames:\r
591# if os.path.splitext(F)[1] in ('.h'):\r
592# FullName = os.path.join(Dirpath, F)\r
593# MsgList = c.CheckHeaderFileData(FullName)\r
594 for FullName in EccGlobalData.gHFileList:\r
595 MsgList = c.CheckHeaderFileData(FullName)\r
30fdf114
LG
596\r
597 # Doxygen document checking\r
598 def DoxygenCheck(self):\r
599 self.DoxygenCheckFileHeader()\r
600 self.DoxygenCheckFunctionHeader()\r
601 self.DoxygenCheckCommentDescription()\r
602 self.DoxygenCheckCommentFormat()\r
603 self.DoxygenCheckCommand()\r
604\r
605 # Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5\r
606 def DoxygenCheckFileHeader(self):\r
607 if EccGlobalData.gConfig.DoxygenCheckFileHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
608 EdkLogger.quiet("Checking Doxygen file header ...")\r
609\r
610 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
611 for F in Filenames:\r
40d841f6
LG
612 Ext = os.path.splitext(F)[1]\r
613 if Ext in ('.h', '.c'):\r
30fdf114
LG
614 FullName = os.path.join(Dirpath, F)\r
615 MsgList = c.CheckFileHeaderDoxygenComments(FullName)\r
40d841f6
LG
616 elif Ext in ('.inf', '.dec', '.dsc', '.fdf'):\r
617 FullName = os.path.join(Dirpath, F)\r
e56468c0 618 op = open(FullName).readlines()\r
d0acc87a
LG
619 FileLinesList = op\r
620 LineNo = 0\r
f7496d71 621 CurrentSection = MODEL_UNKNOWN\r
d0acc87a 622 HeaderSectionLines = []\r
f7496d71 623 HeaderCommentStart = False\r
d0acc87a 624 HeaderCommentEnd = False\r
f7496d71 625\r
d0acc87a
LG
626 for Line in FileLinesList:\r
627 LineNo = LineNo + 1\r
628 Line = Line.strip()\r
629 if (LineNo < len(FileLinesList) - 1):\r
630 NextLine = FileLinesList[LineNo].strip()\r
f7496d71 631\r
d0acc87a
LG
632 #\r
633 # blank line\r
634 #\r
635 if (Line == '' or not Line) and LineNo == len(FileLinesList):\r
636 LastSectionFalg = True\r
637\r
638 #\r
639 # check whether file header comment section started\r
640 #\r
641 if Line.startswith('#') and \\r
642 (Line.find('@file') > -1) and \\r
643 not HeaderCommentStart:\r
644 if CurrentSection != MODEL_UNKNOWN:\r
645 SqlStatement = """ select ID from File where FullPath like '%s'""" % FullName\r
646 ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)\r
647 for Result in ResultSet:\r
648 Msg = 'INF/DEC/DSC/FDF file header comment should begin with ""## @file"" or ""# @file""at the very top file'\r
649 EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])\r
650\r
651 else:\r
652 CurrentSection = MODEL_IDENTIFIER_FILE_HEADER\r
653 #\r
654 # Append the first line to section lines.\r
655 #\r
656 HeaderSectionLines.append((Line, LineNo))\r
657 HeaderCommentStart = True\r
f7496d71
LG
658 continue\r
659\r
d0acc87a
LG
660 #\r
661 # Collect Header content.\r
662 #\r
663 if (Line.startswith('#') and CurrentSection == MODEL_IDENTIFIER_FILE_HEADER) and\\r
664 HeaderCommentStart and not Line.startswith('##') and not\\r
665 HeaderCommentEnd and NextLine != '':\r
666 HeaderSectionLines.append((Line, LineNo))\r
667 continue\r
668 #\r
669 # Header content end\r
670 #\r
671 if (Line.startswith('##') or not Line.strip().startswith("#")) and HeaderCommentStart \\r
672 and not HeaderCommentEnd:\r
673 if Line.startswith('##'):\r
674 HeaderCommentEnd = True\r
675 HeaderSectionLines.append((Line, LineNo))\r
676 ParseHeaderCommentSection(HeaderSectionLines, FullName)\r
677 break\r
678 if HeaderCommentStart == False:\r
40d841f6
LG
679 SqlStatement = """ select ID from File where FullPath like '%s'""" % FullName\r
680 ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)\r
681 for Result in ResultSet:\r
d0acc87a 682 Msg = 'INF/DEC/DSC/FDF file header comment should begin with ""## @file"" or ""# @file"" at the very top file'\r
40d841f6 683 EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])\r
d0acc87a
LG
684 if HeaderCommentEnd == False:\r
685 SqlStatement = """ select ID from File where FullPath like '%s'""" % FullName\r
686 ResultSet = EccGlobalData.gDb.TblFile.Exec(SqlStatement)\r
687 for Result in ResultSet:\r
688 Msg = 'INF/DEC/DSC/FDF file header comment should end with ""##"" at the end of file header comment block'\r
689 # Check whether File header Comment End with '##'\r
690 if EccGlobalData.gConfig.HeaderCheckFileCommentEnd == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
691 EccGlobalData.gDb.TblReport.Insert(ERROR_DOXYGEN_CHECK_FILE_HEADER, Msg, "File", Result[0])\r
e56468c0 692\r
f7496d71 693\r
30fdf114
LG
694\r
695 # Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5\r
696 def DoxygenCheckFunctionHeader(self):\r
697 if EccGlobalData.gConfig.DoxygenCheckFunctionHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
698 EdkLogger.quiet("Checking Doxygen function header ...")\r
699\r
e56468c0 700# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
701# for F in Filenames:\r
702# if os.path.splitext(F)[1] in ('.h', '.c'):\r
703# FullName = os.path.join(Dirpath, F)\r
704# MsgList = c.CheckFuncHeaderDoxygenComments(FullName)\r
705 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
706 MsgList = c.CheckFuncHeaderDoxygenComments(FullName)\r
707\r
30fdf114
LG
708\r
709 # Check whether the first line of text in a comment block is a brief description of the element being documented.\r
710 # The brief description must end with a period.\r
711 def DoxygenCheckCommentDescription(self):\r
712 if EccGlobalData.gConfig.DoxygenCheckCommentDescription == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
713 pass\r
714\r
715 # Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.\r
716 def DoxygenCheckCommentFormat(self):\r
717 if EccGlobalData.gConfig.DoxygenCheckCommentFormat == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
718 EdkLogger.quiet("Checking Doxygen comment ///< ...")\r
719\r
e56468c0 720# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
721# for F in Filenames:\r
722# if os.path.splitext(F)[1] in ('.h', '.c'):\r
723# FullName = os.path.join(Dirpath, F)\r
724# MsgList = c.CheckDoxygenTripleForwardSlash(FullName)\r
725 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
726 MsgList = c.CheckDoxygenTripleForwardSlash(FullName)\r
30fdf114
LG
727\r
728 # Check whether only Doxygen commands allowed to mark the code are @bug and @todo.\r
729 def DoxygenCheckCommand(self):\r
730 if EccGlobalData.gConfig.DoxygenCheckCommand == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
731 EdkLogger.quiet("Checking Doxygen command ...")\r
732\r
e56468c0 733# for Dirpath, Dirnames, Filenames in self.WalkTree():\r
734# for F in Filenames:\r
735# if os.path.splitext(F)[1] in ('.h', '.c'):\r
736# FullName = os.path.join(Dirpath, F)\r
737# MsgList = c.CheckDoxygenCommand(FullName)\r
738 for FullName in EccGlobalData.gCFileList + EccGlobalData.gHFileList:\r
739 MsgList = c.CheckDoxygenCommand(FullName)\r
30fdf114
LG
740\r
741 # Meta-Data File Processing Checking\r
742 def MetaDataFileCheck(self):\r
743 self.MetaDataFileCheckPathName()\r
744 self.MetaDataFileCheckGenerateFileList()\r
745 self.MetaDataFileCheckLibraryInstance()\r
746 self.MetaDataFileCheckLibraryInstanceDependent()\r
747 self.MetaDataFileCheckLibraryInstanceOrder()\r
748 self.MetaDataFileCheckLibraryNoUse()\r
14239f66 749 self.MetaDataFileCheckLibraryDefinedInDec()\r
30fdf114
LG
750 self.MetaDataFileCheckBinaryInfInFdf()\r
751 self.MetaDataFileCheckPcdDuplicate()\r
752 self.MetaDataFileCheckPcdFlash()\r
753 self.MetaDataFileCheckPcdNoUse()\r
754 self.MetaDataFileCheckGuidDuplicate()\r
755 self.MetaDataFileCheckModuleFileNoUse()\r
756 self.MetaDataFileCheckPcdType()\r
40d841f6 757 self.MetaDataFileCheckModuleFileGuidDuplication()\r
b3d07ff8
HC
758 self.MetaDataFileCheckModuleFileGuidFormat()\r
759 self.MetaDataFileCheckModuleFileProtocolFormat()\r
760 self.MetaDataFileCheckModuleFilePpiFormat()\r
761 self.MetaDataFileCheckModuleFilePcdFormat()\r
30fdf114
LG
762\r
763 # Check whether each file defined in meta-data exists\r
764 def MetaDataFileCheckPathName(self):\r
765 if EccGlobalData.gConfig.MetaDataFileCheckPathName == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
766 # This item is covered when parsing Inf/Dec/Dsc files\r
767 pass\r
768\r
769 # Generate a list for all files defined in meta-data files\r
770 def MetaDataFileCheckGenerateFileList(self):\r
771 if EccGlobalData.gConfig.MetaDataFileCheckGenerateFileList == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
772 # This item is covered when parsing Inf/Dec/Dsc files\r
773 pass\r
774\r
775 # Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.\r
776 # Each Library Instance must specify the Supported Module Types in its Inf file,\r
777 # and any module specifying the library instance must be one of the supported types.\r
778 def MetaDataFileCheckLibraryInstance(self):\r
779 if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstance == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
780 EdkLogger.quiet("Checking for library instance type issue ...")\r
d0acc87a
LG
781 SqlCommand = """select A.ID, A.Value3, B.Value3 from Inf as A left join Inf as B\r
782 where A.Value2 = 'LIBRARY_CLASS' and A.Model = %s\r
783 and B.Value2 = 'MODULE_TYPE' and B.Model = %s and A.BelongsToFile = B.BelongsToFile\r
30fdf114
LG
784 group by A.BelongsToFile""" % (MODEL_META_DATA_HEADER, MODEL_META_DATA_HEADER)\r
785 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
786 LibraryClasses = {}\r
787 for Record in RecordSet:\r
788 List = Record[1].split('|', 1)\r
789 SupModType = []\r
790 if len(List) == 1:\r
b3d07ff8 791 SupModType = DT.SUP_MODULE_LIST_STRING.split(DT.TAB_VALUE_SPLIT)\r
30fdf114
LG
792 elif len(List) == 2:\r
793 SupModType = List[1].split()\r
794\r
795 if List[0] not in LibraryClasses:\r
796 LibraryClasses[List[0]] = SupModType\r
797 else:\r
798 for Item in SupModType:\r
799 if Item not in LibraryClasses[List[0]]:\r
800 LibraryClasses[List[0]].append(Item)\r
801\r
8bb63e37 802 if Record[2] != DT.SUP_MODULE_BASE and Record[2] not in SupModType:\r
d40b2ee6 803 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])\r
30fdf114 804\r
d0acc87a
LG
805 SqlCommand = """select A.ID, A.Value1, B.Value3 from Inf as A left join Inf as B\r
806 where A.Model = %s and B.Value2 = '%s' and B.Model = %s\r
30fdf114
LG
807 and B.BelongsToFile = A.BelongsToFile""" \\r
808 % (MODEL_EFI_LIBRARY_CLASS, 'MODULE_TYPE', MODEL_META_DATA_HEADER)\r
809 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
810 # Merge all LibraryClasses' supmodlist\r
811 RecordDict = {}\r
812 for Record in RecordSet:\r
813 if Record[1] not in RecordDict:\r
814 RecordDict[Record[1]] = [str(Record[2])]\r
815 else:\r
816 if Record[2] not in RecordDict[Record[1]]:\r
817 RecordDict[Record[1]].append(Record[2])\r
818\r
819 for Record in RecordSet:\r
820 if Record[1] in LibraryClasses:\r
8bb63e37 821 if Record[2] not in LibraryClasses[Record[1]] and DT.SUP_MODULE_BASE not in RecordDict[Record[1]]:\r
30fdf114 822 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, Record[1]):\r
d40b2ee6 823 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])\r
30fdf114
LG
824 else:\r
825 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, Record[1]):\r
d40b2ee6 826 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])\r
30fdf114
LG
827\r
828 # Check whether a Library Instance has been defined for all dependent library classes\r
829 def MetaDataFileCheckLibraryInstanceDependent(self):\r
830 if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceDependent == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
831 EdkLogger.quiet("Checking for library instance dependent issue ...")\r
832 SqlCommand = """select ID, Value1, Value2 from Dsc where Model = %s""" % MODEL_EFI_LIBRARY_CLASS\r
833 LibraryClasses = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)\r
834 for LibraryClass in LibraryClasses:\r
d0acc87a
LG
835 if LibraryClass[1].upper() == 'NULL' or LibraryClass[1].startswith('!ifdef') or LibraryClass[1].startswith('!ifndef') or LibraryClass[1].endswith('!endif'):\r
836 continue\r
837 else:\r
c4f52e12 838 LibraryIns = os.path.normpath(mws.join(EccGlobalData.gWorkspace, LibraryClass[2]))\r
044f6017
HC
839 SkipDirString = '|'.join(EccGlobalData.gConfig.SkipDirList)\r
840 p = re.compile(r'.*[\\/](?:%s^\S)[\\/]?.*' % SkipDirString)\r
841 if p.match(os.path.split(LibraryIns)[0].upper()):\r
842 continue\r
d0acc87a 843 SqlCommand = """select Value3 from Inf where BelongsToFile =\r
30fdf114 844 (select ID from File where lower(FullPath) = lower('%s'))\r
1beb268a 845 and Value2 = '%s'""" % (LibraryIns, DT.PLATFORM_COMPONENT_TYPE_LIBRARY_CLASS)\r
30fdf114
LG
846 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
847 IsFound = False\r
848 for Record in RecordSet:\r
849 LibName = Record[0].split('|', 1)[0]\r
850 if LibraryClass[1] == LibName:\r
851 IsFound = True\r
852 if not IsFound:\r
853 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT, LibraryClass[1]):\r
d40b2ee6 854 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])\r
30fdf114
LG
855\r
856 # Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies\r
857 def MetaDataFileCheckLibraryInstanceOrder(self):\r
858 if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceOrder == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
859 # This checkpoint is not necessary for Ecc check\r
860 pass\r
861\r
862 # Check whether the unnecessary inclusion of library classes in the Inf file\r
2bcc713e 863 # Check whether the unnecessary duplication of library classe names in the DSC file\r
30fdf114
LG
864 def MetaDataFileCheckLibraryNoUse(self):\r
865 if EccGlobalData.gConfig.MetaDataFileCheckLibraryNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
866 EdkLogger.quiet("Checking for library instance not used ...")\r
867 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)\r
868 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
869 for Record in RecordSet:\r
870 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE, Record[1]):\r
d40b2ee6 871 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])\r
2bcc713e
LG
872 SqlCommand = """\r
873 select A.ID, A.Value1, A.BelongsToFile, A.StartLine, B.StartLine from Dsc as A left join Dsc as B\r
87d2afd0
GL
874 where A.Model = %s and B.Model = %s and A.Scope1 = B.Scope1 and A.Scope2 = B.Scope2 and A.ID != B.ID\r
875 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""" \\r
2bcc713e
LG
876 % (MODEL_EFI_LIBRARY_CLASS, MODEL_EFI_LIBRARY_CLASS)\r
877 RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)\r
878 for Record in RecordSet:\r
e7ae4a7c 879 if Record[3] and Record[4] and Record[3] != Record[4] and Record[1] != 'NULL':\r
2bcc713e
LG
880 SqlCommand = """select FullPath from File where ID = %s""" % (Record[2])\r
881 FilePathList = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
882 for FilePath in FilePathList:\r
883 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NAME_DUPLICATE, Record[1]):\r
884 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])\r
f7496d71 885\r
14239f66
HC
886 # Check the header file in Include\Library directory whether be defined in the package DEC file.\r
887 def MetaDataFileCheckLibraryDefinedInDec(self):\r
888 if EccGlobalData.gConfig.MetaDataFileCheckLibraryDefinedInDec == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
889 EdkLogger.quiet("Checking for library instance whether be defined in the package dec file ...")\r
890 SqlCommand = """\r
891 select A.Value1, A.StartLine, A.ID, B.Value1 from Inf as A left join Dec as B\r
892 on A.Model = B.Model and A.Value1 = B.Value1 where A.Model=%s\r
893 """ % MODEL_EFI_LIBRARY_CLASS\r
894 RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)\r
895 for Record in RecordSet:\r
896 LibraryInInf, Line, ID, LibraryDec = Record\r
897 if not LibraryDec:\r
898 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NOT_DEFINED, LibraryInInf):\r
899 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_NOT_DEFINED, \\r
f7496d71 900 OtherMsg="The Library Class [%s] in %s line is not defined in the associated package file." % (LibraryInInf, Line),\r
14239f66 901 BelongsToTable='Inf', BelongsToItem=ID)\r
f7496d71 902\r
30fdf114
LG
903 # 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\r
904 def MetaDataFileCheckBinaryInfInFdf(self):\r
905 if EccGlobalData.gConfig.MetaDataFileCheckBinaryInfInFdf == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
906 EdkLogger.quiet("Checking for non-binary modules defined in FDF files ...")\r
907 SqlCommand = """select A.ID, A.Value1 from Fdf as A\r
908 where A.Model = %s\r
909 and A.Enabled > -1\r
910 and A.Value1 not in\r
911 (select B.Value1 from Dsc as B\r
912 where B.Model = %s\r
913 and B.Enabled > -1)""" % (MODEL_META_DATA_COMPONENT, MODEL_META_DATA_COMPONENT)\r
914 RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)\r
915 for Record in RecordSet:\r
916 FdfID = Record[0]\r
917 FilePath = Record[1]\r
c4f52e12 918 FilePath = os.path.normpath(mws.join(EccGlobalData.gWorkspace, FilePath))\r
30fdf114
LG
919 SqlCommand = """select ID from Inf where Model = %s and BelongsToFile = (select ID from File where FullPath like '%s')\r
920 """ % (MODEL_EFI_SOURCE_FILE, FilePath)\r
921 NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
d40b2ee6 922 if NewRecordSet != []:\r
30fdf114 923 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF, FilePath):\r
d40b2ee6 924 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)\r
30fdf114
LG
925\r
926 # Check whether a PCD is set in a Dsc file or the FDF file, but not in both.\r
927 def MetaDataFileCheckPcdDuplicate(self):\r
928 if EccGlobalData.gConfig.MetaDataFileCheckPcdDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
929 EdkLogger.quiet("Checking for duplicate PCDs defined in both DSC and FDF files ...")\r
930 SqlCommand = """\r
d0acc87a 931 select A.ID, A.Value1, A.Value2, A.BelongsToFile, B.ID, B.Value1, B.Value2, B.BelongsToFile from Dsc as A, Fdf as B\r
30fdf114
LG
932 where A.Model >= %s and A.Model < %s\r
933 and B.Model >= %s and B.Model < %s\r
d0acc87a 934 and A.Value1 = B.Value1\r
30fdf114
LG
935 and A.Value2 = B.Value2\r
936 and A.Enabled > -1\r
937 and B.Enabled > -1\r
938 group by A.ID\r
d40b2ee6 939 """ % (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)\r
30fdf114
LG
940 RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)\r
941 for Record in RecordSet:\r
d0acc87a
LG
942 SqlCommand1 = """select Name from File where ID = %s""" % Record[3]\r
943 SqlCommand2 = """select Name from File where ID = %s""" % Record[7]\r
52302d4d
LG
944 DscFileName = os.path.splitext(EccGlobalData.gDb.TblDsc.Exec(SqlCommand1)[0][0])[0]\r
945 FdfFileName = os.path.splitext(EccGlobalData.gDb.TblDsc.Exec(SqlCommand2)[0][0])[0]\r
52302d4d
LG
946 if DscFileName != FdfFileName:\r
947 continue\r
d0acc87a
LG
948 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[1] + '.' + Record[2]):\r
949 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])\r
950 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[5] + '.' + Record[6]):\r
951 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])\r
30fdf114
LG
952\r
953 EdkLogger.quiet("Checking for duplicate PCDs defined in DEC files ...")\r
954 SqlCommand = """\r
d0acc87a 955 select A.ID, A.Value1, A.Value2, A.Model, B.Model from Dec as A left join Dec as B\r
30fdf114
LG
956 where A.Model >= %s and A.Model < %s\r
957 and B.Model >= %s and B.Model < %s\r
d0acc87a 958 and A.Value1 = B.Value1\r
30fdf114 959 and A.Value2 = B.Value2\r
d0acc87a 960 and A.Scope1 = B.Scope1\r
87d2afd0 961 and A.ID != B.ID\r
d0acc87a 962 and A.Model = B.Model\r
30fdf114
LG
963 and A.Enabled > -1\r
964 and B.Enabled > -1\r
965 and A.BelongsToFile = B.BelongsToFile\r
966 group by A.ID\r
d40b2ee6 967 """ % (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)\r
d0acc87a 968 RecordSet = EccGlobalData.gDb.TblDec.Exec(SqlCommand)\r
30fdf114 969 for Record in RecordSet:\r
d0acc87a
LG
970 RecordCat = Record[1] + '.' + Record[2]\r
971 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, RecordCat):\r
972 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])\r
30fdf114
LG
973\r
974 # Check whether PCD settings in the FDF file can only be related to flash.\r
975 def MetaDataFileCheckPcdFlash(self):\r
976 if EccGlobalData.gConfig.MetaDataFileCheckPcdFlash == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
977 EdkLogger.quiet("Checking only Flash related PCDs are used in FDF ...")\r
978 SqlCommand = """\r
d0acc87a 979 select ID, Value1, Value2, BelongsToFile from Fdf as A\r
30fdf114
LG
980 where A.Model >= %s and Model < %s\r
981 and A.Enabled > -1\r
982 and A.Value2 not like '%%Flash%%'\r
d40b2ee6 983 """ % (MODEL_PCD, MODEL_META_DATA_HEADER)\r
30fdf114
LG
984 RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)\r
985 for Record in RecordSet:\r
d0acc87a
LG
986 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_FLASH, Record[1] + '.' + Record[2]):\r
987 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])\r
30fdf114
LG
988\r
989 # Check whether PCDs used in Inf files but not specified in Dsc or FDF files\r
990 def MetaDataFileCheckPcdNoUse(self):\r
991 if EccGlobalData.gConfig.MetaDataFileCheckPcdNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
992 EdkLogger.quiet("Checking for non-specified PCDs ...")\r
993 SqlCommand = """\r
d0acc87a 994 select ID, Value1, Value2, BelongsToFile from Inf as A\r
30fdf114
LG
995 where A.Model >= %s and Model < %s\r
996 and A.Enabled > -1\r
d0acc87a
LG
997 and (A.Value1, A.Value2) not in\r
998 (select Value1, Value2 from Dsc as B\r
30fdf114
LG
999 where B.Model >= %s and B.Model < %s\r
1000 and B.Enabled > -1)\r
d0acc87a
LG
1001 and (A.Value1, A.Value2) not in\r
1002 (select Value1, Value2 from Fdf as C\r
30fdf114
LG
1003 where C.Model >= %s and C.Model < %s\r
1004 and C.Enabled > -1)\r
d40b2ee6 1005 """ % (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)\r
30fdf114
LG
1006 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
1007 for Record in RecordSet:\r
d0acc87a
LG
1008 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE, Record[1] + '.' + Record[2]):\r
1009 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])\r
30fdf114
LG
1010\r
1011 # Check whether having duplicate guids defined for Guid/Protocol/Ppi\r
1012 def MetaDataFileCheckGuidDuplicate(self):\r
1013 if EccGlobalData.gConfig.MetaDataFileCheckGuidDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1014 EdkLogger.quiet("Checking for duplicate GUID/PPI/PROTOCOL ...")\r
1015 # Check Guid\r
1016 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDec)\r
1017 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDsc)\r
1018 self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID)\r
1019 # Check protocol\r
1020 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDec)\r
1021 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDsc)\r
1022 self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL)\r
1023 # Check ppi\r
1024 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDec)\r
1025 self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDsc)\r
1026 self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI)\r
1027\r
1028 # Check whether all files under module directory are described in INF files\r
1029 def MetaDataFileCheckModuleFileNoUse(self):\r
1030 if EccGlobalData.gConfig.MetaDataFileCheckModuleFileNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1031 EdkLogger.quiet("Checking for no used module files ...")\r
1032 SqlCommand = """\r
d0acc87a 1033 select upper(Path) from File where ID in (select BelongsToFile from Inf where BelongsToFile != -1)\r
30fdf114
LG
1034 """\r
1035 InfPathSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
1036 InfPathList = []\r
1037 for Item in InfPathSet:\r
1038 if Item[0] not in InfPathList:\r
1039 InfPathList.append(Item[0])\r
1040 SqlCommand = """\r
1041 select ID, Path, FullPath from File where upper(FullPath) not in\r
1042 (select upper(A.Path) || '\\' || upper(B.Value1) from File as A, INF as B\r
1043 where A.ID in (select BelongsToFile from INF where Model = %s group by BelongsToFile) and\r
1044 B.BelongsToFile = A.ID and B.Model = %s)\r
1045 and (Model = %s or Model = %s)\r
1046 """ % (MODEL_EFI_SOURCE_FILE, MODEL_EFI_SOURCE_FILE, MODEL_FILE_C, MODEL_FILE_H)\r
1047 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
1048 for Record in RecordSet:\r
1049 Path = Record[1]\r
b3d07ff8 1050 Path = Path.upper().replace('\X64', '').replace('\IA32', '').replace('\EBC', '').replace('\IPF', '').replace('\ARM', '')\r
30fdf114
LG
1051 if Path in InfPathList:\r
1052 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE, Record[2]):\r
d40b2ee6 1053 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])\r
30fdf114
LG
1054\r
1055 # Check whether the PCD is correctly used in C function via its type\r
1056 def MetaDataFileCheckPcdType(self):\r
1057 if EccGlobalData.gConfig.MetaDataFileCheckPcdType == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1058 EdkLogger.quiet("Checking for pcd type in c code function usage ...")\r
1059 SqlCommand = """\r
d0acc87a 1060 select ID, Model, Value1, Value2, BelongsToFile from INF where Model > %s and Model < %s\r
30fdf114
LG
1061 """ % (MODEL_PCD, MODEL_META_DATA_HEADER)\r
1062 PcdSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
1063 for Pcd in PcdSet:\r
1064 Model = Pcd[1]\r
1065 PcdName = Pcd[2]\r
d0acc87a
LG
1066 if Pcd[3]:\r
1067 PcdName = Pcd[3]\r
1068 BelongsToFile = Pcd[4]\r
30fdf114
LG
1069 SqlCommand = """\r
1070 select ID from File where FullPath in\r
1071 (select B.Path || '\\' || A.Value1 from INF as A, File as B where A.Model = %s and A.BelongsToFile = %s\r
e56468c0 1072 and B.ID = %s and (B.Model = %s or B.Model = %s))\r
d40b2ee6 1073 """ % (MODEL_EFI_SOURCE_FILE, BelongsToFile, BelongsToFile, MODEL_FILE_C, MODEL_FILE_H)\r
30fdf114
LG
1074 TableSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1075 for Tbl in TableSet:\r
1076 TblName = 'Identifier' + str(Tbl[0])\r
1077 SqlCommand = """\r
52302d4d 1078 select Name, ID from %s where value like '%s' and Model = %s\r
30fdf114
LG
1079 """ % (TblName, PcdName, MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1080 RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
1081 TblNumber = TblName.replace('Identifier', '')\r
1082 for Record in RecordSet:\r
1083 FunName = Record[0]\r
1084 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, FunName):\r
1085 if Model in [MODEL_PCD_FIXED_AT_BUILD] and not FunName.startswith('FixedPcdGet'):\r
d40b2ee6 1086 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])\r
30fdf114 1087 if Model in [MODEL_PCD_FEATURE_FLAG] and (not FunName.startswith('FeaturePcdGet') and not FunName.startswith('FeaturePcdSet')):\r
d40b2ee6 1088 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])\r
30fdf114 1089 if Model in [MODEL_PCD_PATCHABLE_IN_MODULE] and (not FunName.startswith('PatchablePcdGet') and not FunName.startswith('PatchablePcdSet')):\r
d40b2ee6 1090 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])\r
30fdf114
LG
1091\r
1092 #ERROR_META_DATA_FILE_CHECK_PCD_TYPE\r
1093 pass\r
1094\r
40d841f6
LG
1095 # Internal worker function to get the INF workspace relative path from FileID\r
1096 def GetInfFilePathFromID(self, FileID):\r
1097 Table = EccGlobalData.gDb.TblFile\r
1098 SqlCommand = """select A.FullPath from %s as A where A.ID = %s""" % (Table.Table, FileID)\r
1099 RecordSet = Table.Exec(SqlCommand)\r
1100 Path = ""\r
1101 for Record in RecordSet:\r
c4f52e12 1102 Path = mws.relpath(Record[0], EccGlobalData.gWorkspace)\r
40d841f6 1103 return Path\r
e56468c0 1104\r
40d841f6
LG
1105 # Check whether two module INFs under one workspace has the same FILE_GUID value\r
1106 def MetaDataFileCheckModuleFileGuidDuplication(self):\r
1107 if EccGlobalData.gConfig.MetaDataFileCheckModuleFileGuidDuplication == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1108 EdkLogger.quiet("Checking for pcd type in c code function usage ...")\r
1109 Table = EccGlobalData.gDb.TblInf\r
1110 SqlCommand = """\r
d0acc87a
LG
1111 select A.ID, A.Value3, A.BelongsToFile, B.BelongsToFile from %s as A, %s as B\r
1112 where A.Value2 = 'FILE_GUID' and B.Value2 = 'FILE_GUID' and\r
87d2afd0 1113 A.Value3 = B.Value3 and A.ID != B.ID group by A.ID\r
40d841f6
LG
1114 """ % (Table.Table, Table.Table)\r
1115 RecordSet = Table.Exec(SqlCommand)\r
1116 for Record in RecordSet:\r
1117 InfPath1 = self.GetInfFilePathFromID(Record[2])\r
1118 InfPath2 = self.GetInfFilePathFromID(Record[3])\r
1119 if InfPath1 and InfPath2:\r
1120 if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION, InfPath1):\r
1121 Msg = "The FILE_GUID of INF file [%s] is duplicated with that of %s" % (InfPath1, InfPath2)\r
d40b2ee6 1122 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_GUID_DUPLICATION, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
e56468c0 1123\r
40d841f6 1124\r
b3d07ff8
HC
1125 # Check Guid Format in module INF\r
1126 def MetaDataFileCheckModuleFileGuidFormat(self):\r
f8c1facf 1127 if EccGlobalData.gConfig.MetaDataFileCheckModuleFileGuidFormat == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
b3d07ff8
HC
1128 EdkLogger.quiet("Check Guid Format in module INF ...")\r
1129 Table = EccGlobalData.gDb.TblInf\r
1130 SqlCommand = """\r
1131 select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID\r
1132 """ % (Table.Table, MODEL_EFI_GUID)\r
1133 RecordSet = Table.Exec(SqlCommand)\r
1134 for Record in RecordSet:\r
1135 Value1 = Record[1]\r
1136 Value2 = Record[2]\r
1137 GuidCommentList = []\r
1138 InfPath = self.GetInfFilePathFromID(Record[3])\r
1139 Msg = "The GUID format of %s in INF file [%s] does not follow rules" % (Value1, InfPath)\r
1140 if Value2.startswith(DT.TAB_SPECIAL_COMMENT):\r
1141 GuidCommentList = Value2[2:].split(DT.TAB_SPECIAL_COMMENT)\r
1142 if GuidCommentList[0].strip().startswith(DT.TAB_INF_USAGE_UNDEFINED):\r
1143 continue\r
1144 elif len(GuidCommentList) > 1:\r
1145 if not GuidCommentList[0].strip().startswith((DT.TAB_INF_USAGE_PRO,\r
1146 DT.TAB_INF_USAGE_SOME_PRO,\r
1147 DT.TAB_INF_USAGE_CON,\r
1148 DT.TAB_INF_USAGE_SOME_CON)):\r
1149 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1150 if not (GuidCommentList[1].strip()).startswith(DT.TAB_INF_GUIDTYPE_VAR) and \\r
1151 not GuidCommentList[1].strip().startswith((DT.TAB_INF_GUIDTYPE_EVENT,\r
1152 DT.TAB_INF_GUIDTYPE_HII,\r
1153 DT.TAB_INF_GUIDTYPE_FILE,\r
1154 DT.TAB_INF_GUIDTYPE_HOB,\r
1155 DT.TAB_INF_GUIDTYPE_FV,\r
1156 DT.TAB_INF_GUIDTYPE_ST,\r
1157 DT.TAB_INF_GUIDTYPE_TSG,\r
1158 DT.TAB_INF_GUIDTYPE_GUID,\r
1159 DT.TAB_INF_GUIDTYPE_PROTOCOL,\r
1160 DT.TAB_INF_GUIDTYPE_PPI,\r
1161 DT.TAB_INF_USAGE_UNDEFINED)):\r
1162 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1163 else:\r
1164 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1165 else:\r
1166 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_GUID, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1167\r
1168 # Check Protocol Format in module INF\r
1169 def MetaDataFileCheckModuleFileProtocolFormat(self):\r
f8c1facf 1170 if EccGlobalData.gConfig.MetaDataFileCheckModuleFileProtocolFormat == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
b3d07ff8
HC
1171 EdkLogger.quiet("Check Protocol Format in module INF ...")\r
1172 Table = EccGlobalData.gDb.TblInf\r
1173 SqlCommand = """\r
1174 select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID\r
1175 """ % (Table.Table, MODEL_EFI_PROTOCOL)\r
1176 RecordSet = Table.Exec(SqlCommand)\r
1177 for Record in RecordSet:\r
1178 Value1 = Record[1]\r
1179 Value2 = Record[2]\r
1180 GuidCommentList = []\r
1181 InfPath = self.GetInfFilePathFromID(Record[3])\r
1182 Msg = "The Protocol format of %s in INF file [%s] does not follow rules" % (Value1, InfPath)\r
1183 if Value2.startswith(DT.TAB_SPECIAL_COMMENT):\r
1184 GuidCommentList = Value2[2:].split(DT.TAB_SPECIAL_COMMENT)\r
1185 if len(GuidCommentList) >= 1:\r
1186 if not GuidCommentList[0].strip().startswith((DT.TAB_INF_USAGE_PRO,\r
1187 DT.TAB_INF_USAGE_SOME_PRO,\r
1188 DT.TAB_INF_USAGE_CON,\r
1189 DT.TAB_INF_USAGE_SOME_CON,\r
1190 DT.TAB_INF_USAGE_NOTIFY,\r
1191 DT.TAB_INF_USAGE_TO_START,\r
1192 DT.TAB_INF_USAGE_BY_START,\r
1193 DT.TAB_INF_USAGE_UNDEFINED)):\r
1194 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PROTOCOL, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1195 else:\r
1196 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PROTOCOL, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1197\r
1198\r
1199 # Check Ppi Format in module INF\r
1200 def MetaDataFileCheckModuleFilePpiFormat(self):\r
f8c1facf 1201 if EccGlobalData.gConfig.MetaDataFileCheckModuleFilePpiFormat == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
b3d07ff8
HC
1202 EdkLogger.quiet("Check Ppi Format in module INF ...")\r
1203 Table = EccGlobalData.gDb.TblInf\r
1204 SqlCommand = """\r
1205 select ID, Value1, Usage, BelongsToFile from %s where Model = %s group by ID\r
1206 """ % (Table.Table, MODEL_EFI_PPI)\r
1207 RecordSet = Table.Exec(SqlCommand)\r
1208 for Record in RecordSet:\r
1209 Value1 = Record[1]\r
1210 Value2 = Record[2]\r
1211 GuidCommentList = []\r
1212 InfPath = self.GetInfFilePathFromID(Record[3])\r
1213 Msg = "The Ppi format of %s in INF file [%s] does not follow rules" % (Value1, InfPath)\r
1214 if Value2.startswith(DT.TAB_SPECIAL_COMMENT):\r
1215 GuidCommentList = Value2[2:].split(DT.TAB_SPECIAL_COMMENT)\r
1216 if len(GuidCommentList) >= 1:\r
1217 if not GuidCommentList[0].strip().startswith((DT.TAB_INF_USAGE_PRO,\r
1218 DT.TAB_INF_USAGE_SOME_PRO,\r
1219 DT.TAB_INF_USAGE_CON,\r
1220 DT.TAB_INF_USAGE_SOME_CON,\r
1221 DT.TAB_INF_USAGE_NOTIFY,\r
1222 DT.TAB_INF_USAGE_UNDEFINED)):\r
1223 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PPI, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1224 else:\r
1225 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PPI, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1226\r
1227 # Check Pcd Format in module INF\r
1228 def MetaDataFileCheckModuleFilePcdFormat(self):\r
f8c1facf 1229 if EccGlobalData.gConfig.MetaDataFileCheckModuleFilePcdFormat == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
b3d07ff8
HC
1230 EdkLogger.quiet("Check Pcd Format in module INF ...")\r
1231 Table = EccGlobalData.gDb.TblInf\r
1232 SqlCommand = """\r
1233 select ID, Model, Value1, Value2, Usage, BelongsToFile from %s where Model >= %s and Model < %s group by ID\r
1234 """ % (Table.Table, MODEL_PCD, MODEL_META_DATA_HEADER)\r
1235 RecordSet = Table.Exec(SqlCommand)\r
1236 for Record in RecordSet:\r
1237 Model = Record[1]\r
1238 PcdName = Record[2] + '.' + Record[3]\r
1239 Usage = Record[4]\r
1240 PcdCommentList = []\r
1241 InfPath = self.GetInfFilePathFromID(Record[5])\r
1242 Msg = "The Pcd format of %s in INF file [%s] does not follow rules" % (PcdName, InfPath)\r
1243 if Usage.startswith(DT.TAB_SPECIAL_COMMENT):\r
1244 PcdCommentList = Usage[2:].split(DT.TAB_SPECIAL_COMMENT)\r
1245 if len(PcdCommentList) >= 1:\r
1246 if Model in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_FEATURE_FLAG] \\r
1247 and not PcdCommentList[0].strip().startswith((DT.TAB_INF_USAGE_SOME_PRO,\r
1248 DT.TAB_INF_USAGE_CON,\r
1249 DT.TAB_INF_USAGE_UNDEFINED)):\r
1250 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PCD, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1251 if Model in [MODEL_PCD_PATCHABLE_IN_MODULE, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX] \\r
1252 and not PcdCommentList[0].strip().startswith((DT.TAB_INF_USAGE_PRO,\r
1253 DT.TAB_INF_USAGE_SOME_PRO,\r
1254 DT.TAB_INF_USAGE_CON,\r
1255 DT.TAB_INF_USAGE_SOME_CON,\r
1256 DT.TAB_INF_USAGE_UNDEFINED)):\r
1257 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PCD, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1258 else:\r
1259 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_FORMAT_PCD, OtherMsg=Msg, BelongsToTable=Table.Table, BelongsToItem=Record[0])\r
1260\r
30fdf114
LG
1261 # Check whether these is duplicate Guid/Ppi/Protocol name\r
1262 def CheckGuidProtocolPpi(self, ErrorID, Model, Table):\r
1263 Name = ''\r
1264 if Model == MODEL_EFI_GUID:\r
1265 Name = 'guid'\r
1266 if Model == MODEL_EFI_PROTOCOL:\r
1267 Name = 'protocol'\r
1268 if Model == MODEL_EFI_PPI:\r
1269 Name = 'ppi'\r
1270 SqlCommand = """\r
1271 select A.ID, A.Value1 from %s as A, %s as B\r
1272 where A.Model = %s and B.Model = %s\r
87d2afd0 1273 and A.Value1 like B.Value1 and A.ID != B.ID\r
d0acc87a 1274 and A.Scope1 = B.Scope1\r
30fdf114
LG
1275 and A.Enabled > -1\r
1276 and B.Enabled > -1\r
1277 group by A.ID\r
1278 """ % (Table.Table, Table.Table, Model, Model)\r
1279 RecordSet = Table.Exec(SqlCommand)\r
1280 for Record in RecordSet:\r
1281 if not EccGlobalData.gException.IsException(ErrorID, Record[1]):\r
d40b2ee6 1282 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])\r
30fdf114
LG
1283\r
1284 # Check whether these is duplicate Guid/Ppi/Protocol value\r
1285 def CheckGuidProtocolPpiValue(self, ErrorID, Model):\r
1286 Name = ''\r
1287 Table = EccGlobalData.gDb.TblDec\r
1288 if Model == MODEL_EFI_GUID:\r
1289 Name = 'guid'\r
1290 if Model == MODEL_EFI_PROTOCOL:\r
1291 Name = 'protocol'\r
1292 if Model == MODEL_EFI_PPI:\r
1293 Name = 'ppi'\r
1294 SqlCommand = """\r
d0acc87a 1295 select A.ID, A.Value1, A.Value2 from %s as A, %s as B\r
30fdf114 1296 where A.Model = %s and B.Model = %s\r
87d2afd0
GL
1297 and A.Value2 like B.Value2 and A.ID != B.ID\r
1298 and A.Scope1 = B.Scope1 and A.Value1 != B.Value1\r
30fdf114
LG
1299 group by A.ID\r
1300 """ % (Table.Table, Table.Table, Model, Model)\r
1301 RecordSet = Table.Exec(SqlCommand)\r
f7496d71 1302 for Record in RecordSet:\r
e84d2b70 1303 if not EccGlobalData.gException.IsException(ErrorID, Record[2]):\r
d0acc87a 1304 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])\r
30fdf114
LG
1305\r
1306 # Naming Convention Check\r
1307 def NamingConventionCheck(self):\r
52302d4d
LG
1308 if EccGlobalData.gConfig.NamingConventionCheckDefineStatement == '1' \\r
1309 or EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' \\r
1310 or EccGlobalData.gConfig.NamingConventionCheckIfndefStatement == '1' \\r
1311 or EccGlobalData.gConfig.NamingConventionCheckVariableName == '1' \\r
1312 or EccGlobalData.gConfig.NamingConventionCheckSingleCharacterVariable == '1' \\r
1313 or EccGlobalData.gConfig.NamingConventionCheckAll == '1'\\r
1314 or EccGlobalData.gConfig.CheckAll == '1':\r
1315 for Dirpath, Dirnames, Filenames in self.WalkTree():\r
1316 for F in Filenames:\r
1317 if os.path.splitext(F)[1] in ('.h', '.c'):\r
1318 FullName = os.path.join(Dirpath, F)\r
1319 Id = c.GetTableID(FullName)\r
1320 if Id < 0:\r
1321 continue\r
1322 FileTable = 'Identifier' + str(Id)\r
1323 self.NamingConventionCheckDefineStatement(FileTable)\r
1324 self.NamingConventionCheckTypedefStatement(FileTable)\r
52302d4d
LG
1325 self.NamingConventionCheckVariableName(FileTable)\r
1326 self.NamingConventionCheckSingleCharacterVariable(FileTable)\r
f8c1facf
HC
1327 if os.path.splitext(F)[1] in ('.h'):\r
1328 self.NamingConventionCheckIfndefStatement(FileTable)\r
30fdf114
LG
1329\r
1330 self.NamingConventionCheckPathName()\r
1331 self.NamingConventionCheckFunctionName()\r
52302d4d 1332\r
30fdf114
LG
1333 # Check whether only capital letters are used for #define declarations\r
1334 def NamingConventionCheckDefineStatement(self, FileTable):\r
1335 if EccGlobalData.gConfig.NamingConventionCheckDefineStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1336 EdkLogger.quiet("Checking naming covention of #define statement ...")\r
52302d4d 1337\r
d40b2ee6 1338 SqlCommand = """select ID, Value from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_MACRO_DEFINE)\r
30fdf114
LG
1339 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1340 for Record in RecordSet:\r
1341 Name = Record[1].strip().split()[1]\r
1342 if Name.find('(') != -1:\r
1343 Name = Name[0:Name.find('(')]\r
1344 if Name.upper() != Name:\r
1345 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT, Name):\r
d40b2ee6 1346 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])\r
30fdf114
LG
1347\r
1348 # Check whether only capital letters are used for typedef declarations\r
1349 def NamingConventionCheckTypedefStatement(self, FileTable):\r
1350 if EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1351 EdkLogger.quiet("Checking naming covention of #typedef statement ...")\r
52302d4d 1352\r
d40b2ee6 1353 SqlCommand = """select ID, Name from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_TYPEDEF)\r
30fdf114
LG
1354 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1355 for Record in RecordSet:\r
1356 Name = Record[1].strip()\r
4231a819 1357 if Name != '' and Name is not None:\r
30fdf114
LG
1358 if Name[0] == '(':\r
1359 Name = Name[1:Name.find(')')]\r
1360 if Name.find('(') > -1:\r
1361 Name = Name[Name.find('(') + 1 : Name.find(')')]\r
1362 Name = Name.replace('WINAPI', '')\r
1363 Name = Name.replace('*', '').strip()\r
1364 if Name.upper() != Name:\r
1365 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT, Name):\r
d40b2ee6 1366 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])\r
30fdf114
LG
1367\r
1368 # Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'.\r
1369 def NamingConventionCheckIfndefStatement(self, FileTable):\r
f8c1facf 1370 if EccGlobalData.gConfig.NamingConventionCheckIfndefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
30fdf114 1371 EdkLogger.quiet("Checking naming covention of #ifndef statement ...")\r
52302d4d 1372\r
d40b2ee6 1373 SqlCommand = """select ID, Value from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_MACRO_IFNDEF)\r
30fdf114
LG
1374 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1375 for Record in RecordSet:\r
1376 Name = Record[1].replace('#ifndef', '').strip()\r
1377 if Name[0] != '_' or Name[-1] != '_':\r
1378 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT, Name):\r
d40b2ee6 1379 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])\r
30fdf114
LG
1380\r
1381 # Rule for path name, variable name and function name\r
1382 # 1. First character should be upper case\r
1383 # 2. Existing lower case in a word\r
1384 # 3. No space existence\r
1385 # Check whether the path name followed the rule\r
1386 def NamingConventionCheckPathName(self):\r
1387 if EccGlobalData.gConfig.NamingConventionCheckPathName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1388 EdkLogger.quiet("Checking naming covention of file path name ...")\r
1389 Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')\r
1390 SqlCommand = """select ID, Name from File"""\r
1391 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1392 for Record in RecordSet:\r
1393 if not Pattern.match(Record[1]):\r
1394 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_PATH_NAME, Record[1]):\r
d40b2ee6 1395 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])\r
30fdf114
LG
1396\r
1397 # Rule for path name, variable name and function name\r
1398 # 1. First character should be upper case\r
1399 # 2. Existing lower case in a word\r
1400 # 3. No space existence\r
1401 # 4. Global variable name must start with a 'g'\r
1402 # Check whether the variable name followed the rule\r
1403 def NamingConventionCheckVariableName(self, FileTable):\r
1404 if EccGlobalData.gConfig.NamingConventionCheckVariableName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1405 EdkLogger.quiet("Checking naming covention of variable name ...")\r
1406 Pattern = re.compile(r'^[A-Zgm]+\S*[a-z]\S*$')\r
52302d4d 1407\r
d40b2ee6 1408 SqlCommand = """select ID, Name from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_VARIABLE)\r
30fdf114
LG
1409 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1410 for Record in RecordSet:\r
00261e1d
HC
1411 Var = Record[1]\r
1412 if Var.startswith('CONST'):\r
1413 Var = Var[5:].lstrip()\r
1414 if not Pattern.match(Var):\r
30fdf114 1415 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Record[1]):\r
d40b2ee6 1416 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])\r
30fdf114
LG
1417\r
1418 # Rule for path name, variable name and function name\r
1419 # 1. First character should be upper case\r
1420 # 2. Existing lower case in a word\r
1421 # 3. No space existence\r
1422 # Check whether the function name followed the rule\r
1423 def NamingConventionCheckFunctionName(self):\r
1424 if EccGlobalData.gConfig.NamingConventionCheckFunctionName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1425 EdkLogger.quiet("Checking naming covention of function name ...")\r
1426 Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')\r
1427 SqlCommand = """select ID, Name from Function"""\r
1428 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1429 for Record in RecordSet:\r
1430 if not Pattern.match(Record[1]):\r
1431 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME, Record[1]):\r
d40b2ee6 1432 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])\r
30fdf114
LG
1433\r
1434 # Check whether NO use short variable name with single character\r
1435 def NamingConventionCheckSingleCharacterVariable(self, FileTable):\r
1436 if EccGlobalData.gConfig.NamingConventionCheckSingleCharacterVariable == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
1437 EdkLogger.quiet("Checking naming covention of single character variable name ...")\r
52302d4d 1438\r
d40b2ee6 1439 SqlCommand = """select ID, Name from %s where Model = %s""" % (FileTable, MODEL_IDENTIFIER_VARIABLE)\r
30fdf114
LG
1440 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
1441 for Record in RecordSet:\r
1442 Variable = Record[1].replace('*', '')\r
1443 if len(Variable) == 1:\r
1444 if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE, Record[1]):\r
d40b2ee6 1445 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])\r
30fdf114 1446\r
703ef6cf
HC
1447def FindPara(FilePath, Para, CallingLine):\r
1448 Lines = open(FilePath).readlines()\r
1449 Line = ''\r
1450 for Index in range(CallingLine - 1, 0, -1):\r
1451 # Find the nearest statement for Para\r
1452 Line = Lines[Index].strip()\r
1453 if Line.startswith('%s = ' % Para):\r
1454 Line = Line.strip()\r
1455 return Line\r
1456 break\r
1457\r
1458 return ''\r
1459\r
30fdf114
LG
1460##\r
1461#\r
1462# This acts like the main() function for the script, unless it is 'import'ed into another\r
1463# script.\r
1464#\r
1465if __name__ == '__main__':\r
1466 Check = Check()\r
1467 Check.Check()\r