920936bfa1de66ea1f85757fcc971ee7ee877124
[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     \r
37     #\r
38     # Doxygen document checking\r
39     #\r
40     def DoxygenCheck(self):\r
41         self.DoxygenCheckFileHeader()\r
42         self.DoxygenCheckFunctionHeader()\r
43         self.DoxygenCheckCommentDescription()\r
44         self.DoxygenCheckCommentFormat()\r
45         self.DoxygenCheckCommand()\r
46     \r
47     #\r
48     # Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5\r
49     #\r
50     def DoxygenCheckFileHeader(self):\r
51         if EccGlobalData.gConfig.DoxygenCheckFileHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1':\r
52             pass\r
53     \r
54     #\r
55     # Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5\r
56     #\r
57     def DoxygenCheckFunctionHeader(self):\r
58         if EccGlobalData.gConfig.DoxygenCheckFunctionHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1':\r
59             Tuple = os.walk(EccGlobalData.gTarget)\r
60             IgnoredPattern = re.compile(r'.*[\\/](?:BUILD|CVS|\.SVN|INTELRESTRICTEDTOOLS|INTELRESTRICTEDPKG)[\\/].*')\r
61 #            ParseErrorFileList = []\r
62         \r
63             for Dirpath, Dirnames, Filenames in Tuple:\r
64                 if IgnoredPattern.match(Dirpath.upper()) or Dirpath.find('.svn') != -1:\r
65                     continue\r
66                 for F in Filenames:\r
67                     if os.path.splitext(F)[1] in ('.h', '.c'):\r
68                         FullName = os.path.join(Dirpath, F)\r
69                         MsgList = c.CheckFuncHeaderDoxygenComments(FullName)\r
70                         for Msg in MsgList:\r
71                             print Msg\r
72             print 'Done'                \r
73                             \r
74     #        \r
75     # Check whether the first line of text in a comment block is a brief description of the element being documented. \r
76     # The brief description must end with a period.\r
77     #\r
78     def DoxygenCheckCommentDescription(self):\r
79         if EccGlobalData.gConfig.DoxygenCheckCommentDescription == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1':\r
80             pass\r
81 \r
82     #\r
83     # Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.\r
84     #\r
85     def DoxygenCheckCommentFormat(self):\r
86         if EccGlobalData.gConfig.DoxygenCheckCommentFormat == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1':\r
87             pass\r
88         \r
89     #\r
90     # Check whether only Doxygen commands allowed to mark the code are @bug and @todo.\r
91     #\r
92     def DoxygenCheckCommand(self):\r
93         if EccGlobalData.gConfig.DoxygenCheckCommand == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1':\r
94             pass\r
95     \r
96     #\r
97     # Meta-Data File Processing Checking\r
98     #\r
99     def MetaDataFileCheck(self):\r
100         self.MetaDataFileCheckPathName()\r
101         self.MetaDataFileCheckGenerateFileList()\r
102         self.MetaDataFileCheckLibraryInstance()\r
103         self.MetaDataFileCheckLibraryInstanceDependent()\r
104         self.MetaDataFileCheckLibraryInstanceOrder()\r
105         self.MetaDataFileCheckLibraryNoUse()\r
106         self.MetaDataFileCheckBinaryInfInFdf()\r
107         self.MetaDataFileCheckPcdDuplicate()\r
108         self.MetaDataFileCheckPcdFlash()\r
109         self.MetaDataFileCheckPcdNoUse()\r
110         self.MetaDataFileCheckGuidDuplicate()\r
111 \r
112     #\r
113     # Check whether each file defined in meta-data exists\r
114     #\r
115     def MetaDataFileCheckPathName(self):\r
116         if EccGlobalData.gConfig.MetaDataFileCheckPathName == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
117             # This item is covered when parsing Inf/Dec/Dsc files\r
118             pass\r
119     \r
120     #\r
121     # Generate a list for all files defined in meta-data files\r
122     #\r
123     def MetaDataFileCheckGenerateFileList(self):\r
124         if EccGlobalData.gConfig.MetaDataFileCheckGenerateFileList == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
125             # This item is covered when parsing Inf/Dec/Dsc files\r
126             pass\r
127     \r
128     #\r
129     # Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.  \r
130     # Each Library Instance must specify the Supported Module Types in its Inf file, \r
131     # and any module specifying the library instance must be one of the supported types.\r
132     #\r
133     def MetaDataFileCheckLibraryInstance(self):\r
134         if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstance == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
135             pass\r
136 \r
137     #\r
138     # Check whether a Library Instance has been defined for all dependent library classes\r
139     #\r
140     def MetaDataFileCheckLibraryInstanceDependent(self):\r
141         if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceDependent == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
142             pass\r
143 \r
144     #\r
145     # Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies\r
146     #\r
147     def MetaDataFileCheckLibraryInstanceOrder(self):\r
148         if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceOrder == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
149             pass\r
150 \r
151     #\r
152     # Check whether the unnecessary inclusion of library classes in the Inf file\r
153     #\r
154     def MetaDataFileCheckLibraryNoUse(self):\r
155         if EccGlobalData.gConfig.MetaDataFileCheckLibraryNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
156             pass\r
157 \r
158     #\r
159     # 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
160     #\r
161     def MetaDataFileCheckBinaryInfInFdf(self):\r
162         if EccGlobalData.gConfig.MetaDataFileCheckBinaryInfInFdf == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
163             SqlCommand = """select A.ID, A.Value1 from Fdf as A\r
164                          where A.Model = %s\r
165                          and A.Enabled > -1\r
166                          and A.Value1 not in \r
167                          (select B.Value1 from Dsc as B\r
168                          where B.Model = %s\r
169                          and B.Enabled > -1)""" % (MODEL_META_DATA_COMPONENT, MODEL_META_DATA_COMPONENT)\r
170             RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)\r
171             for Record in RecordSet:\r
172                 FdfID = Record[0]\r
173                 FilePath = Record[1]\r
174                 FilePath = os.path.normpath(os.path.join(EccGlobalData.gWorkspace, FilePath))\r
175                 SqlCommand = """select * from Inf where BelongsToFile = (select ID from File where FullPath like '%s')""" % FilePath\r
176                 NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)\r
177 \r
178     #\r
179     # Check whether a PCD is set in a Dsc file or the FDF file, but not in both.\r
180     #\r
181     def MetaDataFileCheckPcdDuplicate(self):\r
182         if EccGlobalData.gConfig.MetaDataFileCheckPcdDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
183             EdkLogger.quiet("Checking duplicate pcd defined in both Dsc and Fdf files ...")\r
184             SqlCommand = """\r
185                          select A.ID, A.Value2, B.ID, B.Value2 from Dsc as A, Fdf as B \r
186                          where A.Model >= %s and A.Model < %s \r
187                          and B.Model >= %s and B.Model < %s \r
188                          and A.Value2 = B.Value2\r
189                          and A.Enabled > -1\r
190                          and B.Enabled > -1\r
191                          """% (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)\r
192             RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)\r
193             for Record in RecordSet:\r
194                 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
195                 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
196 \r
197     #\r
198     # Check whether PCD settings in the FDF file can only be related to flash.\r
199     #\r
200     def MetaDataFileCheckPcdFlash(self):\r
201         if EccGlobalData.gConfig.MetaDataFileCheckPcdFlash == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
202             EdkLogger.quiet("Checking only Flash related Pcd is used in FDF ...")\r
203             SqlCommand = """\r
204                          select ID, Value2, BelongsToFile from Fdf as A\r
205                          where A.Model >= %s and Model < %s\r
206                          and A.Enabled > -1\r
207                          and A.Value2 not like '%%Flash%%'\r
208                          """% (MODEL_PCD, MODEL_META_DATA_HEADER)\r
209             RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)\r
210             for Record in RecordSet:\r
211                 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
212         \r
213     #\r
214     # Check whether PCDs used in Inf files but not specified in Dsc or FDF files\r
215     #\r
216     def MetaDataFileCheckPcdNoUse(self):\r
217         if EccGlobalData.gConfig.MetaDataFileCheckPcdNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
218             EdkLogger.quiet("Checking no use pcds ...")\r
219             SqlCommand = """\r
220                          select ID, Value2, BelongsToFile from Inf as A \r
221                          where A.Model >= %s and Model < %s\r
222                          and A.Enabled > -1\r
223                          and A.Value2 not in \r
224                              (select Value2 from Dsc as B \r
225                               where B.Model >= %s and B.Model < %s\r
226                               and B.Enabled > -1)\r
227                          and A.Value2 not in\r
228                              (select Value2 from Fdf as C \r
229                               where C.Model >= %s and C.Model < %s\r
230                               and C.Enabled > -1)\r
231                          """% (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)\r
232             RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)\r
233             for Record in RecordSet:\r
234                 EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE, OtherMsg = "The pcd '%s' defined in Inf file is not referenced by any Dsc of Fdf files" % (Record[1]), BelongsToTable = 'Inf', BelongsToItem = Record[0])\r
235         \r
236     #\r
237     # Check whether having duplicate guids defined for Guid/Protocol/Ppi\r
238     #\r
239     def MetaDataFileCheckGuidDuplicate(self):\r
240         if EccGlobalData.gConfig.MetaDataFileCheckGuidDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1':\r
241             EdkLogger.quiet("Checking duplicate guid/ppi/protocol ...")\r
242             #\r
243             # Check Guid\r
244             #\r
245             self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDec)\r
246             self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDsc)\r
247             self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID)\r
248             #\r
249             # Check protocol\r
250             #\r
251             self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDec)\r
252             self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDsc)\r
253             self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL)\r
254             #\r
255             # Check ppi\r
256             #\r
257             self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDec)\r
258             self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDsc)\r
259             self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI)\r
260 \r
261             #EdkLogger.quiet("Checking duplicate guid/ppi/protocol done!")\r
262     \r
263     #\r
264     # Check whether these is duplicate Guid/Ppi/Protocol name\r
265     #\r
266     def CheckGuidProtocolPpi(self, ErrorID, Model, Table):\r
267         Name = ''\r
268         if Model == MODEL_EFI_GUID:\r
269             Name = 'guid'\r
270         if Model == MODEL_EFI_PROTOCOL:\r
271             Name = 'protocol'\r
272         if Model == MODEL_EFI_PPI:\r
273             Name = 'ppi'\r
274         SqlCommand = """\r
275                      select A.ID, A.Value1 from %s as A, %s as B \r
276                      where A.Model = %s and B.Model = %s \r
277                      and A.Value1 = B.Value1 and A.ID <> B.ID \r
278                      and A.Enabled > -1\r
279                      and B.Enabled > -1\r
280                      group by A.ID\r
281                      """ % (Table.Table, Table.Table, Model, Model)\r
282         RecordSet = Table.Exec(SqlCommand)\r
283         for Record in RecordSet:\r
284             EccGlobalData.gDb.TblReport.Insert(ErrorID, OtherMsg = "The %s name '%s' is defined more than one time" % (Name, Record[1]), BelongsToTable = Table.Table, BelongsToItem = Record[0])\r
285 \r
286     #\r
287     # Check whether these is duplicate Guid/Ppi/Protocol value\r
288     #\r
289     def CheckGuidProtocolPpiValue(self, ErrorID, Model):\r
290         Name = ''\r
291         Table = EccGlobalData.gDb.TblDec\r
292         if Model == MODEL_EFI_GUID:\r
293             Name = 'guid'\r
294         if Model == MODEL_EFI_PROTOCOL:\r
295             Name = 'protocol'\r
296         if Model == MODEL_EFI_PPI:\r
297             Name = 'ppi'\r
298         SqlCommand = """\r
299                      select A.ID, A.Value2 from %s as A, %s as B \r
300                      where A.Model = %s and B.Model = %s \r
301                      and A.Value2 = B.Value2 and A.ID <> B.ID \r
302                      group by A.ID\r
303                      """ % (Table.Table, Table.Table, Model, Model)\r
304         RecordSet = Table.Exec(SqlCommand)\r
305         for Record in RecordSet:\r
306             EccGlobalData.gDb.TblReport.Insert(ErrorID, OtherMsg = "The %s value '%s' is used more than one time" % (Name, Record[1]), BelongsToTable = Table.Table, BelongsToItem = Record[0])\r
307 \r
308 ##\r
309 #\r
310 # This acts like the main() function for the script, unless it is 'import'ed into another\r
311 # script.\r
312 #\r
313 if __name__ == '__main__':\r
314     Check = Check()\r
315     Check.Check()