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