09f47e80a3d9925f2177d950459a62163ef0d6eb
[people/mcb30/basetools.git] / Source / Python / Ecc / Check.py
1 ## @file\r
2 # This file is used to define checkpoints used by ECC tool\r
3 #\r
4 # Copyright (c) 2008, Intel Corporation\r
5 # All rights reserved. This program and the accompanying materials\r
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
13 import os\r
14 import re\r
15 from CommonDataClass.DataClass import *\r
16 from EccToolError import *\r
17 import EccGlobalData\r
18 import c\r
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
26 class Check(object):\r
27     def __init__(self):\r
28         pass\r
29      \r
30     #\r
31     # Check all required checkpoints\r
32     #   \r
33     def Check(self):\r
34         self.MetaDataFileCheck()\r
35         self.DoxygenCheck()\r
36         self.IncludeFileCheck()\r
37         self.PredicateExpressionCheck()\r
38         self.DeclAndDataTypeCheck()\r
39     \r
40     #\r
41     # Declarations and Data Types Checking\r
42     #\r
43     def DeclAndDataTypeCheck(self):\r
44         self.DeclCheckNoUseCType()\r
45         self.DeclCheckInOutModifier()\r
46         self.DeclCheckEFIAPIModifier()\r
47         self.DeclCheckEnumeratedType()\r
48         self.DeclCheckStructureDeclaration()\r
49         self.DeclCheckUnionType()\r
50     \r
51     \r
52     # Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files.\r
53     def DeclCheckNoUseCType(self):\r
54         if EccGlobalData.gConfig.DeclarationDataTypeCheckNoUseCType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1':\r
55             EdkLogger.quiet("Checking Declaration No use C type ...")\r
56             Tuple = os.walk(EccGlobalData.gTarget)\r
57             IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
58         \r
59             for Dirpath, Dirnames, Filenames in Tuple:\r
60                 if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
61                     continue\r
62                 for F in Filenames:\r
63                     if os.path.splitext(F)[1] in ('.h', '.c'):\r
64                         FullName = os.path.join(Dirpath, F)\r
65                         c.CheckDeclNoUseCType(FullName)\r
66     \r
67     # 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
68     def DeclCheckInOutModifier(self):\r
69         if EccGlobalData.gConfig.DeclarationDataTypeCheckInOutModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1':\r
70             EdkLogger.quiet("Checking Declaration argument modifier ...")\r
71             Tuple = os.walk(EccGlobalData.gTarget)\r
72             IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
73         \r
74             for Dirpath, Dirnames, Filenames in Tuple:\r
75                 if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
76                     continue\r
77                 for F in Filenames:\r
78                     if os.path.splitext(F)[1] in ('.h', '.c'):\r
79                         FullName = os.path.join(Dirpath, F)\r
80                         c.CheckDeclArgModifier(FullName)\r
81     \r
82     # Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols\r
83     def DeclCheckEFIAPIModifier(self):\r
84         if EccGlobalData.gConfig.DeclarationDataTypeCheckEFIAPIModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1':\r
85             pass\r
86     \r
87     # Check whether Enumerated Type has a 'typedef' and the name is capital\r
88     def DeclCheckEnumeratedType(self):\r
89         if EccGlobalData.gConfig.DeclarationDataTypeCheckEnumeratedType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1':\r
90             pass\r
91     \r
92     # Check whether Structure Type has a 'typedef' and the name is capital\r
93     def DeclCheckStructureDeclaration(self):\r
94         if EccGlobalData.gConfig.DeclarationDataTypeCheckStructureDeclaration == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1':\r
95             pass\r
96     \r
97     # Check whether Union Type has a 'typedef' and the name is capital\r
98     def DeclCheckUnionType(self):\r
99         if EccGlobalData.gConfig.DeclarationDataTypeCheckUnionType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1':\r
100             pass\r
101     \r
102     #\r
103     # Predicate Expression Checking\r
104     #\r
105     def PredicateExpressionCheck(self):\r
106         self.PredicateExpressionCheckBooleanValue()\r
107         self.PredicateExpressionCheckNonBooleanOperator()\r
108         self.PredicateExpressionCheckComparisonNullType()\r
109     \r
110     # Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE\r
111     def PredicateExpressionCheckBooleanValue(self):\r
112         if EccGlobalData.gConfig.PredicateExpressionCheckBooleanValue == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1':\r
113             EdkLogger.quiet("Checking predicate expression Boolean value ...")\r
114             Tuple = os.walk(EccGlobalData.gTarget)\r
115             IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
116         \r
117             for Dirpath, Dirnames, Filenames in Tuple:\r
118                 if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
119                     continue\r
120                 for F in Filenames:\r
121                     if os.path.splitext(F)[1] in ('.c'):\r
122                         FullName = os.path.join(Dirpath, F)\r
123                         c.CheckBooleanValueComparison(FullName)\r
124     # Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=). \r
125     def PredicateExpressionCheckNonBooleanOperator(self):\r
126         if EccGlobalData.gConfig.PredicateExpressionCheckNonBooleanOperator == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1':\r
127             EdkLogger.quiet("Checking predicate expression Non-Boolean variable...")\r
128             Tuple = os.walk(EccGlobalData.gTarget)\r
129             IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
130         \r
131             for Dirpath, Dirnames, Filenames in Tuple:\r
132                 if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
133                     continue\r
134                 for F in Filenames:\r
135                     if os.path.splitext(F)[1] in ('.c'):\r
136                         FullName = os.path.join(Dirpath, F)\r
137                         c.CheckNonBooleanValueComparison(FullName)\r
138     # Check whether a comparison of any pointer to zero must be done via the NULL type\r
139     def PredicateExpressionCheckComparisonNullType(self):\r
140         if EccGlobalData.gConfig.PredicateExpressionCheckComparisonNullType == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1':\r
141             EdkLogger.quiet("Checking predicate expression NULL pointer ...")\r
142             Tuple = os.walk(EccGlobalData.gTarget)\r
143             IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
144         \r
145             for Dirpath, Dirnames, Filenames in Tuple:\r
146                 if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
147                     continue\r
148                 for F in Filenames:\r
149                     if os.path.splitext(F)[1] in ('.c'):\r
150                         FullName = os.path.join(Dirpath, F)\r
151                         c.CheckPointerNullComparison(FullName)\r
152     #\r
153     # Include file checking\r
154     #\r
155     def IncludeFileCheck(self):\r
156         self.IncludeFileCheckIfndef()\r
157         self.IncludeFileCheckData()\r
158     \r
159     #\r
160     # Check whether all include file contents is guarded by a #ifndef statement.\r
161     #\r
162     def IncludeFileCheckIfndef(self):\r
163         if EccGlobalData.gConfig.IncludeFileCheckIfndefStatement == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1':\r
164             EdkLogger.quiet("Checking header file ifndef ...")\r
165             Tuple = os.walk(EccGlobalData.gTarget)\r
166             IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
167         \r
168             for Dirpath, Dirnames, Filenames in Tuple:\r
169                 if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
170                     continue\r
171                 for F in Filenames:\r
172                     if os.path.splitext(F)[1] in ('.h'):\r
173                         FullName = os.path.join(Dirpath, F)\r
174                         MsgList = c.CheckHeaderFileIfndef(FullName)\r
175     \r
176     #\r
177     # Check whether include files NOT contain code or define data variables\r
178     #\r
179     def IncludeFileCheckData(self):\r
180         if EccGlobalData.gConfig.IncludeFileCheckData == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1':\r
181             EdkLogger.quiet("Checking header file data ...")\r
182             Tuple = os.walk(EccGlobalData.gTarget)\r
183             IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
184         \r
185             for Dirpath, Dirnames, Filenames in Tuple:\r
186                 if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
187                     continue\r
188                 for F in Filenames:\r
189                     if os.path.splitext(F)[1] in ('.h'):\r
190                         FullName = os.path.join(Dirpath, F)\r
191                         MsgList = c.CheckHeaderFileData(FullName)\r
192         \r
193     #\r
194     # Doxygen document checking\r
195     #\r
196     def DoxygenCheck(self):\r
197         self.DoxygenCheckFileHeader()\r
198         self.DoxygenCheckFunctionHeader()\r
199         self.DoxygenCheckCommentDescription()\r
200         self.DoxygenCheckCommentFormat()\r
201         self.DoxygenCheckCommand()\r
202     \r
203     #\r
204     # Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5\r
205     #\r
206     def DoxygenCheckFileHeader(self):\r
207         if EccGlobalData.gConfig.DoxygenCheckFileHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1':\r
208             EdkLogger.quiet("Checking Doxygen file header ...")\r
209             Tuple = os.walk(EccGlobalData.gTarget)\r
210             IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
211         \r
212             for Dirpath, Dirnames, Filenames in Tuple:\r
213                 if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
214                     continue\r
215                 for F in Filenames:\r
216                     if os.path.splitext(F)[1] in ('.h', '.c'):\r
217                         FullName = os.path.join(Dirpath, F)\r
218                         MsgList = c.CheckFileHeaderDoxygenComments(FullName)\r
219     \r
220     #\r
221     # Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5\r
222     #\r
223     def DoxygenCheckFunctionHeader(self):\r
224         if EccGlobalData.gConfig.DoxygenCheckFunctionHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1':\r
225             EdkLogger.quiet("Checking Doxygen function header ...")\r
226             Tuple = os.walk(EccGlobalData.gTarget)\r
227             IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
228 #            ParseErrorFileList = []\r
229         \r
230             for Dirpath, Dirnames, Filenames in Tuple:\r
231                 if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
232                     continue\r
233                 for F in Filenames:\r
234                     if os.path.splitext(F)[1] in ('.h', '.c'):\r
235                         FullName = os.path.join(Dirpath, F)\r
236                         MsgList = c.CheckFuncHeaderDoxygenComments(FullName)\r
237 #                        for Msg in MsgList:\r
238 #                            print Msg                \r
239                             \r
240     #\r
241     # Check whether the first line of text in a comment block is a brief description of the element being documented. \r
242     # The brief description must end with a period.\r
243     #\r
244     def DoxygenCheckCommentDescription(self):\r
245         if EccGlobalData.gConfig.DoxygenCheckCommentDescription == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1':\r
246             pass\r
247 \r
248     #\r
249     # Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.\r
250     #\r
251     def DoxygenCheckCommentFormat(self):\r
252         if EccGlobalData.gConfig.DoxygenCheckCommentFormat == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1':\r
253             EdkLogger.quiet("Checking Doxygen comment ///< ...")\r
254             Tuple = os.walk(EccGlobalData.gTarget)\r
255             IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
256         \r
257             for Dirpath, Dirnames, Filenames in Tuple:\r
258                 if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
259                     continue\r
260                 for F in Filenames:\r
261                     if os.path.splitext(F)[1] in ('.h', '.c'):\r
262                         FullName = os.path.join(Dirpath, F)\r
263                         MsgList = c.CheckDoxygenTripleForwardSlash(FullName)\r
264         \r
265     #\r
266     # Check whether only Doxygen commands allowed to mark the code are @bug and @todo.\r
267     #\r
268     def DoxygenCheckCommand(self):\r
269         if EccGlobalData.gConfig.DoxygenCheckCommand == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1':\r
270             EdkLogger.quiet("Checking Doxygen command ...")\r
271             Tuple = os.walk(EccGlobalData.gTarget)\r
272             IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
273         \r
274             for Dirpath, Dirnames, Filenames in Tuple:\r
275                 if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
276                     continue\r
277                 for F in Filenames:\r
278                     if os.path.splitext(F)[1] in ('.h', '.c'):\r
279                         FullName = os.path.join(Dirpath, F)\r
280                         MsgList = c.CheckDoxygenCommand(FullName)\r
281     \r
282     #\r
283     # Meta-Data File Processing Checking\r
284     #\r
285     def MetaDataFileCheck(self):\r
286         self.MetaDataFileCheckPathName()\r
287         self.MetaDataFileCheckGenerateFileList()\r
288         self.MetaDataFileCheckLibraryInstance()\r
289         self.MetaDataFileCheckLibraryInstanceDependent()\r
290         self.MetaDataFileCheckLibraryInstanceOrder()\r
291         self.MetaDataFileCheckLibraryNoUse()\r
292         self.MetaDataFileCheckBinaryInfInFdf()\r
293         self.MetaDataFileCheckPcdDuplicate()\r
294         self.MetaDataFileCheckPcdFlash()\r
295         self.MetaDataFileCheckPcdNoUse()\r
296         self.MetaDataFileCheckGuidDuplicate()\r
297 \r
298     #\r
299     # Check whether each file defined in meta-data exists\r
300     #\r
301     def MetaDataFileCheckPathName(self):\r
302         if EccGlobalData.gConfig.MetaDataFileCheckPathName == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
303             # This item is covered when parsing Inf/Dec/Dsc files\r
304             pass\r
305     \r
306     #\r
307     # Generate a list for all files defined in meta-data files\r
308     #\r
309     def MetaDataFileCheckGenerateFileList(self):\r
310         if EccGlobalData.gConfig.MetaDataFileCheckGenerateFileList == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
311             # This item is covered when parsing Inf/Dec/Dsc files\r
312             pass\r
313     \r
314     #\r
315     # Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.  \r
316     # Each Library Instance must specify the Supported Module Types in its Inf file, \r
317     # and any module specifying the library instance must be one of the supported types.\r
318     #\r
319     def MetaDataFileCheckLibraryInstance(self):\r
320         if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstance == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
321             pass\r
322 \r
323     #\r
324     # Check whether a Library Instance has been defined for all dependent library classes\r
325     #\r
326     def MetaDataFileCheckLibraryInstanceDependent(self):\r
327         if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceDependent == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
328             pass\r
329 \r
330     #\r
331     # Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies\r
332     #\r
333     def MetaDataFileCheckLibraryInstanceOrder(self):\r
334         if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceOrder == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
335             pass\r
336 \r
337     #\r
338     # Check whether the unnecessary inclusion of library classes in the Inf file\r
339     #\r
340     def MetaDataFileCheckLibraryNoUse(self):\r
341         if EccGlobalData.gConfig.MetaDataFileCheckLibraryNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
342             pass\r
343 \r
344     #\r
345     # 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
346     #\r
347     def MetaDataFileCheckBinaryInfInFdf(self):\r
348         if EccGlobalData.gConfig.MetaDataFileCheckBinaryInfInFdf == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
349             EdkLogger.quiet("Checking for non-binary modules defined in FDF files ...")\r
350             SqlCommand = """select A.ID, A.Value1 from Fdf as A\r
351                          where A.Model = %s\r
352                          and A.Enabled > -1\r
353                          and A.Value1 not in \r
354                          (select B.Value1 from Dsc as B\r
355                          where B.Model = %s\r
356                          and B.Enabled > -1)""" % (MODEL_META_DATA_COMPONENT, MODEL_META_DATA_COMPONENT)\r
357             RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)\r
358             for Record in RecordSet:\r
359                 FdfID = Record[0]\r
360                 FilePath = Record[1]\r
361                 FilePath = os.path.normpath(os.path.join(EccGlobalData.gWorkspace, FilePath))\r
362                 SqlCommand = """select ID from Inf where Model = %s and BelongsToFile = (select ID from File where FullPath like '%s')\r
363                                 """ % (MODEL_EFI_SOURCE_FILE, FilePath)\r
364                 NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
365                 if NewRecordSet!= []:\r
366                     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
367 \r
368     #\r
369     # Check whether a PCD is set in a Dsc file or the FDF file, but not in both.\r
370     #\r
371     def MetaDataFileCheckPcdDuplicate(self):\r
372         if EccGlobalData.gConfig.MetaDataFileCheckPcdDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
373             EdkLogger.quiet("Checking for duplicate PCDs defined in both DSC and FDF files ...")\r
374             SqlCommand = """\r
375                          select A.ID, A.Value2, B.ID, B.Value2 from Dsc as A, Fdf as B \r
376                          where A.Model >= %s and A.Model < %s \r
377                          and B.Model >= %s and B.Model < %s \r
378                          and A.Value2 = B.Value2\r
379                          and A.Enabled > -1\r
380                          and B.Enabled > -1\r
381                          """% (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)\r
382             RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)\r
383             for Record in RecordSet:\r
384                 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]), BelongsToTable = 'Dsc', BelongsToItem = Record[0])\r
385                 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[3]), BelongsToTable = 'Fdf', BelongsToItem = Record[2])\r
386 \r
387     #\r
388     # Check whether PCD settings in the FDF file can only be related to flash.\r
389     #\r
390     def MetaDataFileCheckPcdFlash(self):\r
391         if EccGlobalData.gConfig.MetaDataFileCheckPcdFlash == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
392             EdkLogger.quiet("Checking only Flash related PCDs are used in FDF ...")\r
393             SqlCommand = """\r
394                          select ID, Value2, BelongsToFile from Fdf as A\r
395                          where A.Model >= %s and Model < %s\r
396                          and A.Enabled > -1\r
397                          and A.Value2 not like '%%Flash%%'\r
398                          """% (MODEL_PCD, MODEL_META_DATA_HEADER)\r
399             RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)\r
400             for Record in RecordSet:\r
401                 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]), BelongsToTable = 'Fdf', BelongsToItem = Record[0])\r
402         \r
403     #\r
404     # Check whether PCDs used in Inf files but not specified in Dsc or FDF files\r
405     #\r
406     def MetaDataFileCheckPcdNoUse(self):\r
407         if EccGlobalData.gConfig.MetaDataFileCheckPcdNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
408             EdkLogger.quiet("Checking for non-specified PCDs ...")\r
409             SqlCommand = """\r
410                          select ID, Value2, BelongsToFile from Inf as A \r
411                          where A.Model >= %s and Model < %s\r
412                          and A.Enabled > -1\r
413                          and A.Value2 not in \r
414                              (select Value2 from Dsc as B \r
415                               where B.Model >= %s and B.Model < %s\r
416                               and B.Enabled > -1)\r
417                          and A.Value2 not in\r
418                              (select Value2 from Fdf as C \r
419                               where C.Model >= %s and C.Model < %s\r
420                               and C.Enabled > -1)\r
421                          """% (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)\r
422             RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
423             for Record in RecordSet:\r
424                 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]), BelongsToTable = 'Inf', BelongsToItem = Record[0])\r
425         \r
426     #\r
427     # Check whether having duplicate guids defined for Guid/Protocol/Ppi\r
428     #\r
429     def MetaDataFileCheckGuidDuplicate(self):\r
430         if EccGlobalData.gConfig.MetaDataFileCheckGuidDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
431             EdkLogger.quiet("Checking for duplicate GUID/PPI/PROTOCOL ...")\r
432             #\r
433             # Check Guid\r
434             #\r
435             self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDec)\r
436             self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDsc)\r
437             self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID)\r
438             #\r
439             # Check protocol\r
440             #\r
441             self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDec)\r
442             self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDsc)\r
443             self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL)\r
444             #\r
445             # Check ppi\r
446             #\r
447             self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDec)\r
448             self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDsc)\r
449             self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI)\r
450 \r
451             #EdkLogger.quiet("Checking duplicate guid/ppi/protocol done!")\r
452     \r
453     #\r
454     # Check whether these is duplicate Guid/Ppi/Protocol name\r
455     #\r
456     def CheckGuidProtocolPpi(self, ErrorID, Model, Table):\r
457         Name = ''\r
458         if Model == MODEL_EFI_GUID:\r
459             Name = 'guid'\r
460         if Model == MODEL_EFI_PROTOCOL:\r
461             Name = 'protocol'\r
462         if Model == MODEL_EFI_PPI:\r
463             Name = 'ppi'\r
464         SqlCommand = """\r
465                      select A.ID, A.Value1 from %s as A, %s as B \r
466                      where A.Model = %s and B.Model = %s \r
467                      and A.Value1 = B.Value1 and A.ID <> B.ID \r
468                      and A.Enabled > -1\r
469                      and B.Enabled > -1\r
470                      group by A.ID\r
471                      """ % (Table.Table, Table.Table, Model, Model)\r
472         RecordSet = Table.Exec(SqlCommand)\r
473         for Record in RecordSet:\r
474             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
475 \r
476     #\r
477     # Check whether these is duplicate Guid/Ppi/Protocol value\r
478     #\r
479     def CheckGuidProtocolPpiValue(self, ErrorID, Model):\r
480         Name = ''\r
481         Table = EccGlobalData.gDb.TblDec\r
482         if Model == MODEL_EFI_GUID:\r
483             Name = 'guid'\r
484         if Model == MODEL_EFI_PROTOCOL:\r
485             Name = 'protocol'\r
486         if Model == MODEL_EFI_PPI:\r
487             Name = 'ppi'\r
488         SqlCommand = """\r
489                      select A.ID, A.Value2 from %s as A, %s as B \r
490                      where A.Model = %s and B.Model = %s \r
491                      and A.Value2 = B.Value2 and A.ID <> B.ID \r
492                      group by A.ID\r
493                      """ % (Table.Table, Table.Table, Model, Model)\r
494         RecordSet = Table.Exec(SqlCommand)\r
495         for Record in RecordSet:\r
496             EccGlobalData.gDb.TblReport.Insert(ErrorID, OtherMsg = "The %s value '%s' is used more than one time" % (Name.upper(), Record[1]), BelongsToTable = Table.Table, BelongsToItem = Record[0])\r
497 \r
498     #\r
499     # Naming Convention Check\r
500     #\r
501     def NamingConventionCheck(self):\r
502         self.NamingConventionCheckDefineStatement()\r
503         self.NamingConventionCheckTypedefStatement()\r
504         self.NamingConventionCheckIfndefStatement()\r
505         self.NamingConventionCheckPathName()\r
506         self.NamingConventionCheckVariableName()\r
507         self.NamingConventionCheckFunctionName()\r
508         self.NamingConventionCheckSingleCharacterVariable()\r
509         \r
510     #\r
511     # Check whether only capital letters are used for #define declarations\r
512     #\r
513     def NamingConventionCheckDefineStatement(self):\r
514         pass\r
515     \r
516     #\r
517     # Check whether only capital letters are used for typedef declarations\r
518     #\r
519     def NamingConventionCheckTypedefStatement(self):\r
520         pass\r
521     \r
522     #\r
523     # Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'.\r
524     #\r
525     def NamingConventionCheckIfndefStatement(self):\r
526         pass\r
527     \r
528     #\r
529     # Rule for path name, variable name and function name\r
530     # 1. First character should be upper case\r
531     # 2. Existing lower case in a word\r
532     # 3. No space existence\r
533     # Check whether the path name followed the rule\r
534     #\r
535     def NamingConventionCheckPathName(self):\r
536         if EccGlobalData.gConfig.NamingConventionCheckPathName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1':\r
537             EdkLogger.quiet("Checking naming covention of file path name ...")\r
538             Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')\r
539             SqlCommand = """select ID, Name from File"""\r
540             RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
541             for Record in RecordSet:\r
542                 if not Pattern.match(Record[1]):\r
543                     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
544     \r
545     #\r
546     # Rule for path name, variable name and function name\r
547     # 1. First character should be upper case\r
548     # 2. Existing lower case in a word\r
549     # 3. No space existence\r
550     # 4. Global variable name must start with a 'g'\r
551     # Check whether the variable name followed the rule\r
552     #\r
553     def NamingConventionCheckVariableName(self):\r
554         if EccGlobalData.gConfig.NamingConventionCheckVariableName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1':\r
555             EdkLogger.quiet("Checking naming covention of variable name ...")\r
556             Pattern = re.compile(r'^[A-Zgm]+\S*[a-z]\S*$')\r
557             for IdentifierTable in EccGlobalData.gIdentifierTableList:\r
558                 SqlCommand = """select ID, Name from %s where Model = %s""" %(IdentifierTable, MODEL_IDENTIFIER_VARIABLE)\r
559                 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
560                 for Record in RecordSet:\r
561                     if not Pattern.match(Record[1]):\r
562                         EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, OtherMsg = "The variable name '%s' does not follow the rules" % (Record[1]), BelongsToTable = IdentifierTable, BelongsToItem = Record[0])\r
563 \r
564 \r
565     #\r
566     # Rule for path name, variable name and function name\r
567     # 1. First character should be upper case\r
568     # 2. Existing lower case in a word\r
569     # 3. No space existence\r
570     # Check whether the function name followed the rule\r
571     #\r
572     def NamingConventionCheckFunctionName(self):\r
573         if EccGlobalData.gConfig.NamingConventionCheckFunctionName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1':\r
574             EdkLogger.quiet("Checking naming covention of function name ...")\r
575             Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')\r
576             SqlCommand = """select ID, Name from Function"""\r
577             RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
578             for Record in RecordSet:\r
579                 if not Pattern.match(Record[1]):\r
580                     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
581 \r
582     #\r
583     # Check whether NO use short variable name with single character\r
584     #\r
585     def NamingConventionCheckSingleCharacterVariable(self):\r
586         if EccGlobalData.gConfig.NamingConventionCheckSingleCharacterVariable == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1':\r
587             EdkLogger.quiet("Checking naming covention of single character variable name ...")\r
588             for IdentifierTable in EccGlobalData.gIdentifierTableList:\r
589                 SqlCommand = """select ID, Name from %s where Model = %s""" %(IdentifierTable, MODEL_IDENTIFIER_VARIABLE)\r
590                 RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
591                 for Record in RecordSet:\r
592                     if len(Record[1]) == 1:\r
593                         EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE, OtherMsg = "The variable name '%s' does not follow the rules" % (Record[1]), BelongsToTable = IdentifierTable, BelongsToItem = Record[0])\r
594 \r
595 ##\r
596 #\r
597 # This acts like the main() function for the script, unless it is 'import'ed into another\r
598 # script.\r
599 #\r
600 if __name__ == '__main__':\r
601     Check = Check()\r
602     Check.Check()\r
603 \r