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