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