]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Ecc/c.py
BaseTools:ECC report errors on account of analyze special characters
[mirror_edk2.git] / BaseTools / Source / Python / Ecc / c.py
CommitLineData
52302d4d
LG
1## @file\r
2# This file is used to be the c coding style checking of ECC tool\r
3#\r
ce3bfbec 4# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>\r
2e351cbe 5# SPDX-License-Identifier: BSD-2-Clause-Patent\r
52302d4d
LG
6#\r
7\r
72443dd2 8from __future__ import print_function\r
b6f6b636 9from __future__ import absolute_import\r
30fdf114 10import sys\r
1be2ed90 11import Common.LongFilePathOs as os\r
30fdf114
LG
12import re\r
13import string\r
855698fb 14from Ecc import CodeFragmentCollector\r
15from Ecc import FileProfile\r
30fdf114 16from CommonDataClass import DataClass\r
855698fb 17from Ecc import Database\r
30fdf114 18from Common import EdkLogger\r
855698fb 19from Ecc.EccToolError import *\r
20from Ecc import EccGlobalData\r
21from Ecc import MetaDataParser\r
30fdf114
LG
22\r
23IncludeFileListDict = {}\r
24AllIncludeFileListDict = {}\r
25IncludePathListDict = {}\r
26ComplexTypeDict = {}\r
27SUDict = {}\r
28IgnoredKeywordList = ['EFI_ERROR']\r
29\r
30def GetIgnoredDirListPattern():\r
31 skipList = list(EccGlobalData.gConfig.SkipDirList) + ['.svn']\r
c60377d7 32 DirString = '|'.join(skipList)\r
30fdf114
LG
33 p = re.compile(r'.*[\\/](?:%s)[\\/]?.*' % DirString)\r
34 return p\r
35\r
36def GetFuncDeclPattern():\r
37 p = re.compile(r'(?:EFIAPI|EFI_BOOT_SERVICE|EFI_RUNTIME_SERVICE)?\s*[_\w]+\s*\(.*\)$', re.DOTALL)\r
38 return p\r
39\r
40def GetArrayPattern():\r
41 p = re.compile(r'[_\w]*\s*[\[.*\]]+')\r
42 return p\r
43\r
44def GetTypedefFuncPointerPattern():\r
45 p = re.compile('[_\w\s]*\([\w\s]*\*+\s*[_\w]+\s*\)\s*\(.*\)', re.DOTALL)\r
46 return p\r
47\r
48def GetDB():\r
49 return EccGlobalData.gDb\r
50\r
51def GetConfig():\r
52 return EccGlobalData.gConfig\r
53\r
54def PrintErrorMsg(ErrorType, Msg, TableName, ItemId):\r
55 Msg = Msg.replace('\n', '').replace('\r', '')\r
56 MsgPartList = Msg.split()\r
57 Msg = ''\r
58 for Part in MsgPartList:\r
59 Msg += Part\r
60 Msg += ' '\r
79b74a03 61 GetDB().TblReport.Insert(ErrorType, OtherMsg=Msg, BelongsToTable=TableName, BelongsToItem=ItemId)\r
30fdf114
LG
62\r
63def GetIdType(Str):\r
64 Type = DataClass.MODEL_UNKNOWN\r
65 Str = Str.replace('#', '# ')\r
66 List = Str.split()\r
67 if List[1] == 'include':\r
68 Type = DataClass.MODEL_IDENTIFIER_INCLUDE\r
69 elif List[1] == 'define':\r
70 Type = DataClass.MODEL_IDENTIFIER_MACRO_DEFINE\r
71 elif List[1] == 'ifdef':\r
72 Type = DataClass.MODEL_IDENTIFIER_MACRO_IFDEF\r
73 elif List[1] == 'ifndef':\r
74 Type = DataClass.MODEL_IDENTIFIER_MACRO_IFNDEF\r
75 elif List[1] == 'endif':\r
76 Type = DataClass.MODEL_IDENTIFIER_MACRO_ENDIF\r
77 elif List[1] == 'pragma':\r
78 Type = DataClass.MODEL_IDENTIFIER_MACRO_PROGMA\r
79 else:\r
80 Type = DataClass.MODEL_UNKNOWN\r
81 return Type\r
82\r
83def SuOccurInTypedef (Su, TdList):\r
84 for Td in TdList:\r
85 if Su.StartPos[0] == Td.StartPos[0] and Su.EndPos[0] == Td.EndPos[0]:\r
86 return True\r
87 return False\r
88\r
89def GetIdentifierList():\r
90 IdList = []\r
91 for comment in FileProfile.CommentList:\r
79b74a03 92 IdComment = DataClass.IdentifierClass(-1, '', '', '', comment.Content, DataClass.MODEL_IDENTIFIER_COMMENT, -1, -1, comment.StartPos[0], comment.StartPos[1], comment.EndPos[0], comment.EndPos[1])\r
30fdf114 93 IdList.append(IdComment)\r
52302d4d 94\r
30fdf114
LG
95 for pp in FileProfile.PPDirectiveList:\r
96 Type = GetIdType(pp.Content)\r
79b74a03 97 IdPP = DataClass.IdentifierClass(-1, '', '', '', pp.Content, Type, -1, -1, pp.StartPos[0], pp.StartPos[1], pp.EndPos[0], pp.EndPos[1])\r
30fdf114 98 IdList.append(IdPP)\r
52302d4d 99\r
30fdf114 100 for pe in FileProfile.PredicateExpressionList:\r
79b74a03 101 IdPE = DataClass.IdentifierClass(-1, '', '', '', pe.Content, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION, -1, -1, pe.StartPos[0], pe.StartPos[1], pe.EndPos[0], pe.EndPos[1])\r
30fdf114 102 IdList.append(IdPE)\r
52302d4d 103\r
30fdf114
LG
104 FuncDeclPattern = GetFuncDeclPattern()\r
105 ArrayPattern = GetArrayPattern()\r
106 for var in FileProfile.VariableDeclarationList:\r
107 DeclText = var.Declarator.lstrip()\r
108 FuncPointerPattern = GetTypedefFuncPointerPattern()\r
109 if FuncPointerPattern.match(DeclText):\r
110 continue\r
111 VarNameStartLine = var.NameStartPos[0]\r
112 VarNameStartColumn = var.NameStartPos[1]\r
113 FirstChar = DeclText[0]\r
114 while not FirstChar.isalpha() and FirstChar != '_':\r
115 if FirstChar == '*':\r
116 var.Modifier += '*'\r
117 VarNameStartColumn += 1\r
118 DeclText = DeclText.lstrip('*')\r
119 elif FirstChar == '\r':\r
120 DeclText = DeclText.lstrip('\r\n').lstrip('\r')\r
121 VarNameStartLine += 1\r
122 VarNameStartColumn = 0\r
123 elif FirstChar == '\n':\r
124 DeclText = DeclText.lstrip('\n')\r
125 VarNameStartLine += 1\r
126 VarNameStartColumn = 0\r
127 elif FirstChar == ' ':\r
128 DeclText = DeclText.lstrip(' ')\r
129 VarNameStartColumn += 1\r
130 elif FirstChar == '\t':\r
131 DeclText = DeclText.lstrip('\t')\r
132 VarNameStartColumn += 8\r
133 else:\r
134 DeclText = DeclText[1:]\r
135 VarNameStartColumn += 1\r
136 FirstChar = DeclText[0]\r
52302d4d 137\r
30fdf114
LG
138 var.Declarator = DeclText\r
139 if FuncDeclPattern.match(var.Declarator):\r
52302d4d 140 DeclSplitList = var.Declarator.split('(')\r
30fdf114
LG
141 FuncName = DeclSplitList[0].strip()\r
142 FuncNamePartList = FuncName.split()\r
143 if len(FuncNamePartList) > 1:\r
144 FuncName = FuncNamePartList[-1].strip()\r
145 NameStart = DeclSplitList[0].rfind(FuncName)\r
146 var.Declarator = var.Declarator[NameStart:]\r
147 if NameStart > 0:\r
148 var.Modifier += ' ' + DeclSplitList[0][0:NameStart]\r
149 Index = 0\r
150 PreChar = ''\r
151 while Index < NameStart:\r
152 FirstChar = DeclSplitList[0][Index]\r
153 if DeclSplitList[0][Index:].startswith('EFIAPI'):\r
154 Index += 6\r
155 VarNameStartColumn += 6\r
156 PreChar = ''\r
157 continue\r
158 elif FirstChar == '\r':\r
159 Index += 1\r
160 VarNameStartLine += 1\r
161 VarNameStartColumn = 0\r
162 elif FirstChar == '\n':\r
163 Index += 1\r
164 if PreChar != '\r':\r
165 VarNameStartLine += 1\r
166 VarNameStartColumn = 0\r
167 elif FirstChar == ' ':\r
168 Index += 1\r
169 VarNameStartColumn += 1\r
170 elif FirstChar == '\t':\r
171 Index += 1\r
172 VarNameStartColumn += 8\r
173 else:\r
174 Index += 1\r
175 VarNameStartColumn += 1\r
176 PreChar = FirstChar\r
177 IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', var.Declarator, FuncName, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, -1, -1, var.StartPos[0], var.StartPos[1], VarNameStartLine, VarNameStartColumn)\r
178 IdList.append(IdVar)\r
179 continue\r
52302d4d
LG
180\r
181 if var.Declarator.find('{') == -1:\r
30fdf114
LG
182 for decl in var.Declarator.split(','):\r
183 DeclList = decl.split('=')\r
184 Name = DeclList[0].strip()\r
185 if ArrayPattern.match(Name):\r
186 LSBPos = var.Declarator.find('[')\r
187 var.Modifier += ' ' + Name[LSBPos:]\r
188 Name = Name[0:LSBPos]\r
52302d4d 189\r
79b74a03 190 IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', Name, (len(DeclList) > 1 and [DeclList[1]]or [''])[0], DataClass.MODEL_IDENTIFIER_VARIABLE, -1, -1, var.StartPos[0], var.StartPos[1], VarNameStartLine, VarNameStartColumn)\r
30fdf114
LG
191 IdList.append(IdVar)\r
192 else:\r
193 DeclList = var.Declarator.split('=')\r
194 Name = DeclList[0].strip()\r
195 if ArrayPattern.match(Name):\r
196 LSBPos = var.Declarator.find('[')\r
197 var.Modifier += ' ' + Name[LSBPos:]\r
198 Name = Name[0:LSBPos]\r
79b74a03 199 IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', Name, (len(DeclList) > 1 and [DeclList[1]]or [''])[0], DataClass.MODEL_IDENTIFIER_VARIABLE, -1, -1, var.StartPos[0], var.StartPos[1], VarNameStartLine, VarNameStartColumn)\r
30fdf114 200 IdList.append(IdVar)\r
52302d4d 201\r
30fdf114
LG
202 for enum in FileProfile.EnumerationDefinitionList:\r
203 LBPos = enum.Content.find('{')\r
204 RBPos = enum.Content.find('}')\r
205 Name = enum.Content[4:LBPos].strip()\r
79b74a03
LG
206 Value = enum.Content[LBPos + 1:RBPos]\r
207 IdEnum = DataClass.IdentifierClass(-1, '', '', Name, Value, DataClass.MODEL_IDENTIFIER_ENUMERATE, -1, -1, enum.StartPos[0], enum.StartPos[1], enum.EndPos[0], enum.EndPos[1])\r
30fdf114 208 IdList.append(IdEnum)\r
52302d4d 209\r
30fdf114
LG
210 for su in FileProfile.StructUnionDefinitionList:\r
211 if SuOccurInTypedef(su, FileProfile.TypedefDefinitionList):\r
212 continue\r
213 Type = DataClass.MODEL_IDENTIFIER_STRUCTURE\r
214 SkipLen = 6\r
215 if su.Content.startswith('union'):\r
216 Type = DataClass.MODEL_IDENTIFIER_UNION\r
217 SkipLen = 5\r
218 LBPos = su.Content.find('{')\r
219 RBPos = su.Content.find('}')\r
220 if LBPos == -1 or RBPos == -1:\r
221 Name = su.Content[SkipLen:].strip()\r
222 Value = ''\r
223 else:\r
224 Name = su.Content[SkipLen:LBPos].strip()\r
79b74a03
LG
225 Value = su.Content[LBPos:RBPos + 1]\r
226 IdPE = DataClass.IdentifierClass(-1, '', '', Name, Value, Type, -1, -1, su.StartPos[0], su.StartPos[1], su.EndPos[0], su.EndPos[1])\r
30fdf114 227 IdList.append(IdPE)\r
52302d4d
LG
228\r
229 TdFuncPointerPattern = GetTypedefFuncPointerPattern()\r
30fdf114
LG
230 for td in FileProfile.TypedefDefinitionList:\r
231 Modifier = ''\r
232 Name = td.ToType\r
233 Value = td.FromType\r
234 if TdFuncPointerPattern.match(td.ToType):\r
235 Modifier = td.FromType\r
236 LBPos = td.ToType.find('(')\r
79b74a03 237 TmpStr = td.ToType[LBPos + 1:].strip()\r
30fdf114
LG
238 StarPos = TmpStr.find('*')\r
239 if StarPos != -1:\r
240 Modifier += ' ' + TmpStr[0:StarPos]\r
241 while TmpStr[StarPos] == '*':\r
242# Modifier += ' ' + '*'\r
243 StarPos += 1\r
244 TmpStr = TmpStr[StarPos:].strip()\r
245 RBPos = TmpStr.find(')')\r
246 Name = TmpStr[0:RBPos]\r
247 Value = 'FP' + TmpStr[RBPos + 1:]\r
248 else:\r
249 while Name.startswith('*'):\r
250 Value += ' ' + '*'\r
251 Name = Name.lstrip('*').strip()\r
52302d4d 252\r
30fdf114
LG
253 if Name.find('[') != -1:\r
254 LBPos = Name.find('[')\r
255 RBPos = Name.rfind(']')\r
256 Value += Name[LBPos : RBPos + 1]\r
257 Name = Name[0 : LBPos]\r
52302d4d 258\r
79b74a03 259 IdTd = DataClass.IdentifierClass(-1, Modifier, '', Name, Value, DataClass.MODEL_IDENTIFIER_TYPEDEF, -1, -1, td.StartPos[0], td.StartPos[1], td.EndPos[0], td.EndPos[1])\r
30fdf114 260 IdList.append(IdTd)\r
52302d4d 261\r
30fdf114 262 for funcCall in FileProfile.FunctionCallingList:\r
79b74a03 263 IdFC = DataClass.IdentifierClass(-1, '', '', funcCall.FuncName, funcCall.ParamList, DataClass.MODEL_IDENTIFIER_FUNCTION_CALLING, -1, -1, funcCall.StartPos[0], funcCall.StartPos[1], funcCall.EndPos[0], funcCall.EndPos[1])\r
30fdf114
LG
264 IdList.append(IdFC)\r
265 return IdList\r
266\r
267def StripNonAlnumChars(Str):\r
268 StrippedStr = ''\r
269 for Char in Str:\r
b7f63a5a 270 if Char.isalnum() or Char == '_':\r
30fdf114
LG
271 StrippedStr += Char\r
272 return StrippedStr\r
273\r
79b74a03 274def GetParamList(FuncDeclarator, FuncNameLine=0, FuncNameOffset=0):\r
30fdf114
LG
275 FuncDeclarator = StripComments(FuncDeclarator)\r
276 ParamIdList = []\r
277 #DeclSplitList = FuncDeclarator.split('(')\r
278 LBPos = FuncDeclarator.find('(')\r
279 #if len(DeclSplitList) < 2:\r
280 if LBPos == -1:\r
281 return ParamIdList\r
282 #FuncName = DeclSplitList[0]\r
283 FuncName = FuncDeclarator[0:LBPos]\r
284 #ParamStr = DeclSplitList[1].rstrip(')')\r
285 ParamStr = FuncDeclarator[LBPos + 1:].rstrip(')')\r
286 LineSkipped = 0\r
287 OffsetSkipped = 0\r
288 TailChar = FuncName[-1]\r
289 while not TailChar.isalpha() and TailChar != '_':\r
52302d4d 290\r
30fdf114
LG
291 if TailChar == '\n':\r
292 FuncName = FuncName.rstrip('\r\n').rstrip('\n')\r
293 LineSkipped += 1\r
294 OffsetSkipped = 0\r
295 elif TailChar == '\r':\r
296 FuncName = FuncName.rstrip('\r')\r
297 LineSkipped += 1\r
298 OffsetSkipped = 0\r
299 elif TailChar == ' ':\r
300 FuncName = FuncName.rstrip(' ')\r
301 OffsetSkipped += 1\r
302 elif TailChar == '\t':\r
303 FuncName = FuncName.rstrip('\t')\r
304 OffsetSkipped += 8\r
305 else:\r
306 FuncName = FuncName[:-1]\r
307 TailChar = FuncName[-1]\r
52302d4d 308\r
30fdf114 309 OffsetSkipped += 1 #skip '('\r
52302d4d 310\r
30fdf114
LG
311 for p in ParamStr.split(','):\r
312 ListP = p.split()\r
313 if len(ListP) == 0:\r
314 continue\r
315 ParamName = ListP[-1]\r
316 DeclText = ParamName.strip()\r
317 RightSpacePos = p.rfind(ParamName)\r
318 ParamModifier = p[0:RightSpacePos]\r
319 if ParamName == 'OPTIONAL':\r
320 if ParamModifier == '':\r
321 ParamModifier += ' ' + 'OPTIONAL'\r
322 DeclText = ''\r
323 else:\r
324 ParamName = ListP[-2]\r
325 DeclText = ParamName.strip()\r
326 RightSpacePos = p.rfind(ParamName)\r
327 ParamModifier = p[0:RightSpacePos]\r
328 ParamModifier += 'OPTIONAL'\r
329 while DeclText.startswith('*'):\r
330 ParamModifier += ' ' + '*'\r
331 DeclText = DeclText.lstrip('*').strip()\r
332 ParamName = DeclText\r
333 # ignore array length if exists.\r
334 LBIndex = ParamName.find('[')\r
335 if LBIndex != -1:\r
336 ParamName = ParamName[0:LBIndex]\r
52302d4d 337\r
30fdf114
LG
338 Start = RightSpacePos\r
339 Index = 0\r
340 PreChar = ''\r
341 while Index < Start:\r
342 FirstChar = p[Index]\r
52302d4d 343\r
30fdf114
LG
344 if FirstChar == '\r':\r
345 Index += 1\r
346 LineSkipped += 1\r
347 OffsetSkipped = 0\r
348 elif FirstChar == '\n':\r
349 Index += 1\r
350 if PreChar != '\r':\r
351 LineSkipped += 1\r
352 OffsetSkipped = 0\r
353 elif FirstChar == ' ':\r
354 Index += 1\r
355 OffsetSkipped += 1\r
356 elif FirstChar == '\t':\r
357 Index += 1\r
358 OffsetSkipped += 8\r
359 else:\r
360 Index += 1\r
361 OffsetSkipped += 1\r
362 PreChar = FirstChar\r
52302d4d 363\r
30fdf114
LG
364 ParamBeginLine = FuncNameLine + LineSkipped\r
365 ParamBeginOffset = FuncNameOffset + OffsetSkipped\r
52302d4d 366\r
30fdf114
LG
367 Index = Start + len(ParamName)\r
368 PreChar = ''\r
369 while Index < len(p):\r
370 FirstChar = p[Index]\r
52302d4d 371\r
30fdf114
LG
372 if FirstChar == '\r':\r
373 Index += 1\r
374 LineSkipped += 1\r
375 OffsetSkipped = 0\r
376 elif FirstChar == '\n':\r
377 Index += 1\r
378 if PreChar != '\r':\r
379 LineSkipped += 1\r
380 OffsetSkipped = 0\r
381 elif FirstChar == ' ':\r
382 Index += 1\r
383 OffsetSkipped += 1\r
384 elif FirstChar == '\t':\r
385 Index += 1\r
386 OffsetSkipped += 8\r
387 else:\r
388 Index += 1\r
389 OffsetSkipped += 1\r
390 PreChar = FirstChar\r
52302d4d 391\r
30fdf114
LG
392 ParamEndLine = FuncNameLine + LineSkipped\r
393 ParamEndOffset = FuncNameOffset + OffsetSkipped\r
394 if ParamName != '...':\r
395 ParamName = StripNonAlnumChars(ParamName)\r
396 IdParam = DataClass.IdentifierClass(-1, ParamModifier, '', ParamName, '', DataClass.MODEL_IDENTIFIER_PARAMETER, -1, -1, ParamBeginLine, ParamBeginOffset, ParamEndLine, ParamEndOffset)\r
397 ParamIdList.append(IdParam)\r
52302d4d 398\r
30fdf114 399 OffsetSkipped += 1 #skip ','\r
52302d4d 400\r
30fdf114 401 return ParamIdList\r
52302d4d 402\r
30fdf114
LG
403def GetFunctionList():\r
404 FuncObjList = []\r
405 for FuncDef in FileProfile.FunctionDefinitionList:\r
406 ParamIdList = []\r
407 DeclText = FuncDef.Declarator.lstrip()\r
408 FuncNameStartLine = FuncDef.NamePos[0]\r
409 FuncNameStartColumn = FuncDef.NamePos[1]\r
410 FirstChar = DeclText[0]\r
411 while not FirstChar.isalpha() and FirstChar != '_':\r
412 if FirstChar == '*':\r
413 FuncDef.Modifier += '*'\r
414 FuncNameStartColumn += 1\r
415 DeclText = DeclText.lstrip('*')\r
416 elif FirstChar == '\r':\r
417 DeclText = DeclText.lstrip('\r\n').lstrip('\r')\r
418 FuncNameStartLine += 1\r
419 FuncNameStartColumn = 0\r
420 elif FirstChar == '\n':\r
421 DeclText = DeclText.lstrip('\n')\r
422 FuncNameStartLine += 1\r
423 FuncNameStartColumn = 0\r
424 elif FirstChar == ' ':\r
425 DeclText = DeclText.lstrip(' ')\r
426 FuncNameStartColumn += 1\r
427 elif FirstChar == '\t':\r
428 DeclText = DeclText.lstrip('\t')\r
429 FuncNameStartColumn += 8\r
430 else:\r
431 DeclText = DeclText[1:]\r
432 FuncNameStartColumn += 1\r
433 FirstChar = DeclText[0]\r
52302d4d 434\r
30fdf114
LG
435 FuncDef.Declarator = DeclText\r
436 DeclSplitList = FuncDef.Declarator.split('(')\r
437 if len(DeclSplitList) < 2:\r
438 continue\r
52302d4d 439\r
30fdf114
LG
440 FuncName = DeclSplitList[0]\r
441 FuncNamePartList = FuncName.split()\r
442 if len(FuncNamePartList) > 1:\r
443 FuncName = FuncNamePartList[-1]\r
444 NameStart = DeclSplitList[0].rfind(FuncName)\r
445 if NameStart > 0:\r
446 FuncDef.Modifier += ' ' + DeclSplitList[0][0:NameStart]\r
447 Index = 0\r
448 PreChar = ''\r
449 while Index < NameStart:\r
450 FirstChar = DeclSplitList[0][Index]\r
451 if DeclSplitList[0][Index:].startswith('EFIAPI'):\r
452 Index += 6\r
453 FuncNameStartColumn += 6\r
454 PreChar = ''\r
455 continue\r
456 elif FirstChar == '\r':\r
457 Index += 1\r
458 FuncNameStartLine += 1\r
459 FuncNameStartColumn = 0\r
460 elif FirstChar == '\n':\r
461 Index += 1\r
462 if PreChar != '\r':\r
463 FuncNameStartLine += 1\r
464 FuncNameStartColumn = 0\r
465 elif FirstChar == ' ':\r
466 Index += 1\r
467 FuncNameStartColumn += 1\r
468 elif FirstChar == '\t':\r
469 Index += 1\r
470 FuncNameStartColumn += 8\r
471 else:\r
472 Index += 1\r
473 FuncNameStartColumn += 1\r
474 PreChar = FirstChar\r
52302d4d 475\r
79b74a03 476 FuncObj = DataClass.FunctionClass(-1, FuncDef.Declarator, FuncDef.Modifier, FuncName.strip(), '', FuncDef.StartPos[0], FuncDef.StartPos[1], FuncDef.EndPos[0], FuncDef.EndPos[1], FuncDef.LeftBracePos[0], FuncDef.LeftBracePos[1], -1, ParamIdList, [], FuncNameStartLine, FuncNameStartColumn)\r
30fdf114 477 FuncObjList.append(FuncObj)\r
52302d4d 478\r
30fdf114
LG
479 return FuncObjList\r
480\r
481def GetFileModificationTimeFromDB(FullFileName):\r
482 TimeValue = 0.0\r
483 Db = GetDB()\r
484 SqlStatement = """ select TimeStamp\r
485 from File\r
486 where FullPath = \'%s\'\r
487 """ % (FullFileName)\r
488 ResultSet = Db.TblFile.Exec(SqlStatement)\r
489 for Result in ResultSet:\r
490 TimeValue = Result[0]\r
491 return TimeValue\r
492\r
493def CollectSourceCodeDataIntoDB(RootDir):\r
494 FileObjList = []\r
495 tuple = os.walk(RootDir)\r
496 IgnoredPattern = GetIgnoredDirListPattern()\r
497 ParseErrorFileList = []\r
0cb3f771
FZ
498 TokenReleaceList = EccGlobalData.gConfig.TokenReleaceList\r
499 TokenReleaceList.extend(['L",\\\""'])\r
30fdf114
LG
500\r
501 for dirpath, dirnames, filenames in tuple:\r
502 if IgnoredPattern.match(dirpath.upper()):\r
503 continue\r
504\r
505 for Dir in dirnames:\r
506 Dirname = os.path.join(dirpath, Dir)\r
507 if os.path.islink(Dirname):\r
508 Dirname = os.path.realpath(Dirname)\r
509 if os.path.isdir(Dirname):\r
510 # symlinks to directories are treated as directories\r
511 dirnames.remove(Dir)\r
512 dirnames.append(Dirname)\r
513\r
514 for f in filenames:\r
8c3f9b4e
HC
515 if f.lower() in EccGlobalData.gConfig.SkipFileList:\r
516 continue\r
e56468c0 517 collector = None\r
30fdf114 518 FullName = os.path.normpath(os.path.join(dirpath, f))\r
e56468c0 519 model = DataClass.MODEL_FILE_OTHERS\r
30fdf114
LG
520 if os.path.splitext(f)[1] in ('.h', '.c'):\r
521 EdkLogger.info("Parsing " + FullName)\r
522 model = f.endswith('c') and DataClass.MODEL_FILE_C or DataClass.MODEL_FILE_H\r
523 collector = CodeFragmentCollector.CodeFragmentCollector(FullName)\r
0cb3f771 524 collector.TokenReleaceList = TokenReleaceList\r
30fdf114
LG
525 try:\r
526 collector.ParseFile()\r
527 except UnicodeError:\r
528 ParseErrorFileList.append(FullName)\r
529 collector.CleanFileProfileBuffer()\r
530 collector.ParseFileWithClearedPPDirective()\r
531# collector.PrintFragments()\r
e56468c0 532 BaseName = os.path.basename(f)\r
533 DirName = os.path.dirname(FullName)\r
534 Ext = os.path.splitext(f)[1].lstrip('.')\r
535 ModifiedTime = os.path.getmtime(FullName)\r
536 FileObj = DataClass.FileClass(-1, BaseName, Ext, DirName, FullName, model, ModifiedTime, GetFunctionList(), GetIdentifierList(), [])\r
537 FileObjList.append(FileObj)\r
538 if collector:\r
52302d4d
LG
539 collector.CleanFileProfileBuffer()\r
540\r
30fdf114
LG
541 if len(ParseErrorFileList) > 0:\r
542 EdkLogger.info("Found unrecoverable error during parsing:\n\t%s\n" % "\n\t".join(ParseErrorFileList))\r
52302d4d
LG
543\r
544 Db = GetDB()\r
545 for file in FileObjList:\r
e56468c0 546 if file.ExtName.upper() not in ['INF', 'DEC', 'DSC', 'FDF']:\r
547 Db.InsertOneFile(file)\r
30fdf114
LG
548\r
549 Db.UpdateIdentifierBelongsToFunction()\r
550\r
79b74a03 551def GetTableID(FullFileName, ErrorMsgList=None):\r
4231a819 552 if ErrorMsgList is None:\r
30fdf114 553 ErrorMsgList = []\r
52302d4d 554\r
30fdf114
LG
555 Db = GetDB()\r
556 SqlStatement = """ select ID\r
557 from File\r
558 where FullPath like '%s'\r
559 """ % FullFileName\r
30fdf114
LG
560 ResultSet = Db.TblFile.Exec(SqlStatement)\r
561\r
562 FileID = -1\r
563 for Result in ResultSet:\r
564 if FileID != -1:\r
565 ErrorMsgList.append('Duplicate file ID found in DB for file %s' % FullFileName)\r
79b74a03 566 return - 2\r
30fdf114
LG
567 FileID = Result[0]\r
568 if FileID == -1:\r
569 ErrorMsgList.append('NO file ID found in DB for file %s' % FullFileName)\r
79b74a03 570 return - 1\r
30fdf114
LG
571 return FileID\r
572\r
573def GetIncludeFileList(FullFileName):\r
e56468c0 574 if os.path.splitext(FullFileName)[1].upper() not in ('.H'):\r
575 return []\r
30fdf114 576 IFList = IncludeFileListDict.get(FullFileName)\r
4231a819 577 if IFList is not None:\r
30fdf114 578 return IFList\r
52302d4d 579\r
30fdf114
LG
580 FileID = GetTableID(FullFileName)\r
581 if FileID < 0:\r
582 return []\r
52302d4d 583\r
30fdf114
LG
584 Db = GetDB()\r
585 FileTable = 'Identifier' + str(FileID)\r
586 SqlStatement = """ select Value\r
587 from %s\r
588 where Model = %d\r
589 """ % (FileTable, DataClass.MODEL_IDENTIFIER_INCLUDE)\r
590 ResultSet = Db.TblFile.Exec(SqlStatement)\r
591 IncludeFileListDict[FullFileName] = ResultSet\r
592 return ResultSet\r
593\r
594def GetFullPathOfIncludeFile(Str, IncludePathList):\r
595 for IncludePath in IncludePathList:\r
596 FullPath = os.path.join(IncludePath, Str)\r
597 FullPath = os.path.normpath(FullPath)\r
598 if os.path.exists(FullPath):\r
599 return FullPath\r
600 return None\r
601\r
602def GetAllIncludeFiles(FullFileName):\r
4231a819 603 if AllIncludeFileListDict.get(FullFileName) is not None:\r
30fdf114 604 return AllIncludeFileListDict.get(FullFileName)\r
52302d4d 605\r
30fdf114
LG
606 FileDirName = os.path.dirname(FullFileName)\r
607 IncludePathList = IncludePathListDict.get(FileDirName)\r
4231a819 608 if IncludePathList is None:\r
30fdf114
LG
609 IncludePathList = MetaDataParser.GetIncludeListOfFile(EccGlobalData.gWorkspace, FullFileName, GetDB())\r
610 if FileDirName not in IncludePathList:\r
611 IncludePathList.insert(0, FileDirName)\r
612 IncludePathListDict[FileDirName] = IncludePathList\r
613 IncludeFileQueue = []\r
614 for IncludeFile in GetIncludeFileList(FullFileName):\r
615 FileName = IncludeFile[0].lstrip('#').strip()\r
616 FileName = FileName.lstrip('include').strip()\r
617 FileName = FileName.strip('\"')\r
618 FileName = FileName.lstrip('<').rstrip('>').strip()\r
619 FullPath = GetFullPathOfIncludeFile(FileName, IncludePathList)\r
4231a819 620 if FullPath is not None:\r
30fdf114 621 IncludeFileQueue.append(FullPath)\r
52302d4d 622\r
30fdf114
LG
623 i = 0\r
624 while i < len(IncludeFileQueue):\r
625 for IncludeFile in GetIncludeFileList(IncludeFileQueue[i]):\r
626 FileName = IncludeFile[0].lstrip('#').strip()\r
627 FileName = FileName.lstrip('include').strip()\r
628 FileName = FileName.strip('\"')\r
629 FileName = FileName.lstrip('<').rstrip('>').strip()\r
630 FullPath = GetFullPathOfIncludeFile(FileName, IncludePathList)\r
4231a819 631 if FullPath is not None and FullPath not in IncludeFileQueue:\r
30fdf114
LG
632 IncludeFileQueue.insert(i + 1, FullPath)\r
633 i += 1\r
52302d4d 634\r
30fdf114
LG
635 AllIncludeFileListDict[FullFileName] = IncludeFileQueue\r
636 return IncludeFileQueue\r
637\r
638def GetPredicateListFromPredicateExpStr(PES):\r
639\r
640 PredicateList = []\r
641 i = 0\r
642 PredicateBegin = 0\r
643 #PredicateEnd = 0\r
644 LogicOpPos = -1\r
645 p = GetFuncDeclPattern()\r
646 while i < len(PES) - 1:\r
647 if (PES[i].isalnum() or PES[i] == '_' or PES[i] == '*') and LogicOpPos > PredicateBegin:\r
648 PredicateBegin = i\r
79b74a03 649 if (PES[i] == '&' and PES[i + 1] == '&') or (PES[i] == '|' and PES[i + 1] == '|'):\r
30fdf114
LG
650 LogicOpPos = i\r
651 Exp = PES[PredicateBegin:i].strip()\r
652 # Exp may contain '.' or '->'\r
653 TmpExp = Exp.replace('.', '').replace('->', '')\r
654 if p.match(TmpExp):\r
655 PredicateList.append(Exp)\r
656 else:\r
657 PredicateList.append(Exp.rstrip(';').rstrip(')').strip())\r
658 i += 1\r
52302d4d 659\r
30fdf114
LG
660 if PredicateBegin > LogicOpPos:\r
661 while PredicateBegin < len(PES):\r
662 if PES[PredicateBegin].isalnum() or PES[PredicateBegin] == '_' or PES[PredicateBegin] == '*':\r
663 break\r
664 PredicateBegin += 1\r
665 Exp = PES[PredicateBegin:len(PES)].strip()\r
666 # Exp may contain '.' or '->'\r
667 TmpExp = Exp.replace('.', '').replace('->', '')\r
668 if p.match(TmpExp):\r
669 PredicateList.append(Exp)\r
670 else:\r
671 PredicateList.append(Exp.rstrip(';').rstrip(')').strip())\r
672 return PredicateList\r
52302d4d 673\r
79b74a03 674def GetCNameList(Lvalue, StarList=[]):\r
30fdf114
LG
675 Lvalue += ' '\r
676 i = 0\r
677 SearchBegin = 0\r
678 VarStart = -1\r
679 VarEnd = -1\r
680 VarList = []\r
52302d4d 681\r
30fdf114
LG
682 while SearchBegin < len(Lvalue):\r
683 while i < len(Lvalue):\r
684 if Lvalue[i].isalnum() or Lvalue[i] == '_':\r
685 if VarStart == -1:\r
686 VarStart = i\r
687 VarEnd = i\r
688 i += 1\r
689 elif VarEnd != -1:\r
79b74a03 690 VarList.append(Lvalue[VarStart:VarEnd + 1])\r
30fdf114
LG
691 i += 1\r
692 break\r
693 else:\r
694 if VarStart == -1 and Lvalue[i] == '*':\r
695 StarList.append('*')\r
696 i += 1\r
697 if VarEnd == -1:\r
698 break\r
52302d4d
LG
699\r
700\r
30fdf114
LG
701 DotIndex = Lvalue[VarEnd:].find('.')\r
702 ArrowIndex = Lvalue[VarEnd:].find('->')\r
703 if DotIndex == -1 and ArrowIndex == -1:\r
704 break\r
705 elif DotIndex == -1 and ArrowIndex != -1:\r
706 SearchBegin = VarEnd + ArrowIndex\r
707 elif ArrowIndex == -1 and DotIndex != -1:\r
708 SearchBegin = VarEnd + DotIndex\r
709 else:\r
52302d4d
LG
710 SearchBegin = VarEnd + ((DotIndex < ArrowIndex) and DotIndex or ArrowIndex)\r
711\r
30fdf114
LG
712 i = SearchBegin\r
713 VarStart = -1\r
714 VarEnd = -1\r
52302d4d
LG
715\r
716 return VarList\r
30fdf114 717\r
79b74a03 718def SplitPredicateByOp(Str, Op, IsFuncCalling=False):\r
30fdf114
LG
719\r
720 Name = Str.strip()\r
721 Value = None\r
52302d4d 722\r
30fdf114
LG
723 if IsFuncCalling:\r
724 Index = 0\r
725 LBFound = False\r
726 UnmatchedLBCount = 0\r
727 while Index < len(Str):\r
728 while not LBFound and Str[Index] != '_' and not Str[Index].isalnum():\r
729 Index += 1\r
52302d4d 730\r
30fdf114
LG
731 while not LBFound and (Str[Index].isalnum() or Str[Index] == '_'):\r
732 Index += 1\r
fb0b35e0 733 # maybe type-cast at the beginning, skip it.\r
30fdf114
LG
734 RemainingStr = Str[Index:].lstrip()\r
735 if RemainingStr.startswith(')') and not LBFound:\r
736 Index += 1\r
737 continue\r
52302d4d 738\r
30fdf114
LG
739 if RemainingStr.startswith('(') and not LBFound:\r
740 LBFound = True\r
52302d4d 741\r
30fdf114
LG
742 if Str[Index] == '(':\r
743 UnmatchedLBCount += 1\r
744 Index += 1\r
745 continue\r
52302d4d 746\r
30fdf114
LG
747 if Str[Index] == ')':\r
748 UnmatchedLBCount -= 1\r
749 Index += 1\r
750 if UnmatchedLBCount == 0:\r
751 break\r
752 continue\r
52302d4d 753\r
30fdf114 754 Index += 1\r
52302d4d 755\r
30fdf114
LG
756 if UnmatchedLBCount > 0:\r
757 return [Name]\r
52302d4d 758\r
30fdf114
LG
759 IndexInRemainingStr = Str[Index:].find(Op)\r
760 if IndexInRemainingStr == -1:\r
761 return [Name]\r
52302d4d 762\r
30fdf114 763 Name = Str[0:Index + IndexInRemainingStr].strip()\r
79b74a03 764 Value = Str[Index + IndexInRemainingStr + len(Op):].strip().strip(')')\r
30fdf114 765 return [Name, Value]\r
52302d4d 766\r
30fdf114
LG
767 TmpStr = Str.rstrip(';').rstrip(')')\r
768 while True:\r
769 Index = TmpStr.rfind(Op)\r
770 if Index == -1:\r
771 return [Name]\r
52302d4d 772\r
79b74a03 773 if Str[Index - 1].isalnum() or Str[Index - 1].isspace() or Str[Index - 1] == ')' or Str[Index - 1] == ']':\r
30fdf114
LG
774 Name = Str[0:Index].strip()\r
775 Value = Str[Index + len(Op):].strip()\r
52302d4d
LG
776 return [Name, Value]\r
777\r
30fdf114
LG
778 TmpStr = Str[0:Index - 1]\r
779\r
780def SplitPredicateStr(Str):\r
52302d4d
LG
781\r
782 Str = Str.lstrip('(')\r
30fdf114
LG
783 IsFuncCalling = False\r
784 p = GetFuncDeclPattern()\r
785 TmpStr = Str.replace('.', '').replace('->', '')\r
786 if p.match(TmpStr):\r
787 IsFuncCalling = True\r
52302d4d 788\r
30fdf114
LG
789 PredPartList = SplitPredicateByOp(Str, '==', IsFuncCalling)\r
790 if len(PredPartList) > 1:\r
791 return [PredPartList, '==']\r
52302d4d 792\r
30fdf114
LG
793 PredPartList = SplitPredicateByOp(Str, '!=', IsFuncCalling)\r
794 if len(PredPartList) > 1:\r
795 return [PredPartList, '!=']\r
52302d4d 796\r
30fdf114
LG
797 PredPartList = SplitPredicateByOp(Str, '>=', IsFuncCalling)\r
798 if len(PredPartList) > 1:\r
799 return [PredPartList, '>=']\r
52302d4d 800\r
30fdf114
LG
801 PredPartList = SplitPredicateByOp(Str, '<=', IsFuncCalling)\r
802 if len(PredPartList) > 1:\r
803 return [PredPartList, '<=']\r
52302d4d 804\r
30fdf114
LG
805 PredPartList = SplitPredicateByOp(Str, '>', IsFuncCalling)\r
806 if len(PredPartList) > 1:\r
807 return [PredPartList, '>']\r
52302d4d 808\r
30fdf114
LG
809 PredPartList = SplitPredicateByOp(Str, '<', IsFuncCalling)\r
810 if len(PredPartList) > 1:\r
811 return [PredPartList, '<']\r
52302d4d 812\r
30fdf114
LG
813 return [[Str, None], None]\r
814\r
815def GetFuncContainsPE(ExpLine, ResultSet):\r
816 for Result in ResultSet:\r
817 if Result[0] < ExpLine and Result[1] > ExpLine:\r
818 return Result\r
819 return None\r
820\r
821def PatternInModifier(Modifier, SubStr):\r
822 PartList = Modifier.split()\r
823 for Part in PartList:\r
824 if Part == SubStr:\r
825 return True\r
826 return False\r
827\r
828def GetDataTypeFromModifier(ModifierStr):\r
829 MList = ModifierStr.split()\r
79b74a03 830 ReturnType = ''\r
30fdf114 831 for M in MList:\r
eece4292 832 if M in EccGlobalData.gConfig.ModifierSet:\r
79b74a03 833 continue\r
fb0b35e0 834 # remove array suffix\r
79b74a03
LG
835 if M.startswith('[') or M.endswith(']'):\r
836 continue\r
30fdf114 837 ReturnType += M + ' '\r
52302d4d 838\r
30fdf114
LG
839 ReturnType = ReturnType.strip()\r
840 if len(ReturnType) == 0:\r
841 ReturnType = 'VOID'\r
842 return ReturnType\r
843\r
844def DiffModifier(Str1, Str2):\r
845 PartList1 = Str1.split()\r
846 PartList2 = Str2.split()\r
847 if PartList1 == PartList2:\r
848 return False\r
849 else:\r
850 return True\r
52302d4d 851\r
30fdf114 852def GetTypedefDict(FullFileName):\r
52302d4d 853\r
30fdf114 854 Dict = ComplexTypeDict.get(FullFileName)\r
4231a819 855 if Dict is not None:\r
30fdf114 856 return Dict\r
52302d4d 857\r
30fdf114
LG
858 FileID = GetTableID(FullFileName)\r
859 FileTable = 'Identifier' + str(FileID)\r
860 Db = GetDB()\r
861 SqlStatement = """ select Modifier, Name, Value, ID\r
862 from %s\r
863 where Model = %d\r
864 """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
865 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 866\r
30fdf114
LG
867 Dict = {}\r
868 for Result in ResultSet:\r
869 if len(Result[0]) == 0:\r
870 Dict[Result[1]] = Result[2]\r
52302d4d 871\r
30fdf114
LG
872 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
873 for F in IncludeFileList:\r
874 FileID = GetTableID(F)\r
875 if FileID < 0:\r
876 continue\r
52302d4d 877\r
30fdf114
LG
878 FileTable = 'Identifier' + str(FileID)\r
879 SqlStatement = """ select Modifier, Name, Value, ID\r
880 from %s\r
881 where Model = %d\r
882 """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
883 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 884\r
30fdf114
LG
885 for Result in ResultSet:\r
886 if not Result[2].startswith('FP ('):\r
887 Dict[Result[1]] = Result[2]\r
888 else:\r
889 if len(Result[0]) == 0:\r
890 Dict[Result[1]] = 'VOID'\r
891 else:\r
892 Dict[Result[1]] = GetDataTypeFromModifier(Result[0])\r
52302d4d 893\r
30fdf114
LG
894 ComplexTypeDict[FullFileName] = Dict\r
895 return Dict\r
896\r
897def GetSUDict(FullFileName):\r
52302d4d 898\r
30fdf114 899 Dict = SUDict.get(FullFileName)\r
4231a819 900 if Dict is not None:\r
30fdf114 901 return Dict\r
52302d4d 902\r
30fdf114
LG
903 FileID = GetTableID(FullFileName)\r
904 FileTable = 'Identifier' + str(FileID)\r
905 Db = GetDB()\r
906 SqlStatement = """ select Name, Value, ID\r
907 from %s\r
908 where Model = %d or Model = %d\r
909 """ % (FileTable, DataClass.MODEL_IDENTIFIER_STRUCTURE, DataClass.MODEL_IDENTIFIER_UNION)\r
910 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 911\r
30fdf114
LG
912 Dict = {}\r
913 for Result in ResultSet:\r
914 if len(Result[1]) > 0:\r
915 Dict[Result[0]] = Result[1]\r
52302d4d 916\r
30fdf114
LG
917 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
918 for F in IncludeFileList:\r
919 FileID = GetTableID(F)\r
920 if FileID < 0:\r
921 continue\r
52302d4d 922\r
30fdf114
LG
923 FileTable = 'Identifier' + str(FileID)\r
924 SqlStatement = """ select Name, Value, ID\r
925 from %s\r
926 where Model = %d or Model = %d\r
927 """ % (FileTable, DataClass.MODEL_IDENTIFIER_STRUCTURE, DataClass.MODEL_IDENTIFIER_UNION)\r
928 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 929\r
30fdf114
LG
930 for Result in ResultSet:\r
931 if len(Result[1]) > 0:\r
932 Dict[Result[0]] = Result[1]\r
52302d4d 933\r
30fdf114
LG
934 SUDict[FullFileName] = Dict\r
935 return Dict\r
936\r
937def StripComments(Str):\r
938 Str += ' '\r
939 ListFromStr = list(Str)\r
52302d4d 940\r
30fdf114
LG
941 InComment = False\r
942 DoubleSlashComment = False\r
943 Index = 0\r
944 while Index < len(ListFromStr):\r
945 # meet new line, then no longer in a comment for //\r
946 if ListFromStr[Index] == '\n':\r
947 if InComment and DoubleSlashComment:\r
948 InComment = False\r
949 DoubleSlashComment = False\r
950 Index += 1\r
951 # check for */ comment end\r
79b74a03 952 elif InComment and not DoubleSlashComment and ListFromStr[Index] == '*' and ListFromStr[Index + 1] == '/':\r
30fdf114
LG
953 ListFromStr[Index] = ' '\r
954 Index += 1\r
955 ListFromStr[Index] = ' '\r
956 Index += 1\r
957 InComment = False\r
958 # set comments to spaces\r
959 elif InComment:\r
960 ListFromStr[Index] = ' '\r
961 Index += 1\r
962 # check for // comment\r
c60377d7 963 elif ListFromStr[Index] == '/' and ListFromStr[Index + 1] == '/':\r
30fdf114
LG
964 InComment = True\r
965 DoubleSlashComment = True\r
52302d4d 966\r
30fdf114 967 # check for /* comment start\r
79b74a03 968 elif ListFromStr[Index] == '/' and ListFromStr[Index + 1] == '*':\r
30fdf114
LG
969 ListFromStr[Index] = ' '\r
970 Index += 1\r
971 ListFromStr[Index] = ' '\r
972 Index += 1\r
973 InComment = True\r
974 else:\r
975 Index += 1\r
976\r
977 # restore from List to String\r
978 Str = "".join(ListFromStr)\r
979 Str = Str.rstrip(' ')\r
52302d4d 980\r
30fdf114
LG
981 return Str\r
982\r
983def GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict):\r
984 Value = TypedefDict.get(Type)\r
4231a819 985 if Value is None:\r
30fdf114 986 Value = SUDict.get(Type)\r
4231a819 987 if Value is None:\r
30fdf114 988 return None\r
52302d4d 989\r
30fdf114
LG
990 LBPos = Value.find('{')\r
991 while LBPos == -1:\r
992 FTList = Value.split()\r
993 for FT in FTList:\r
994 if FT not in ('struct', 'union'):\r
995 Value = TypedefDict.get(FT)\r
4231a819 996 if Value is None:\r
30fdf114
LG
997 Value = SUDict.get(FT)\r
998 break\r
52302d4d 999\r
4231a819 1000 if Value is None:\r
30fdf114 1001 return None\r
52302d4d 1002\r
30fdf114 1003 LBPos = Value.find('{')\r
52302d4d 1004\r
30fdf114
LG
1005# RBPos = Value.find('}')\r
1006 Fields = Value[LBPos + 1:]\r
1007 Fields = StripComments(Fields)\r
1008 FieldsList = Fields.split(';')\r
1009 for Field in FieldsList:\r
1010 Field = Field.strip()\r
1011 Index = Field.rfind(FieldName)\r
1012 if Index < 1:\r
1013 continue\r
1014 if not Field[Index - 1].isalnum():\r
1015 if Index + len(FieldName) == len(Field):\r
1016 Type = GetDataTypeFromModifier(Field[0:Index])\r
1017 return Type.strip()\r
1018 else:\r
fb0b35e0 1019 # For the condition that the field in struct is an array with [] suffixes...\r
30fdf114
LG
1020 if not Field[Index + len(FieldName)].isalnum():\r
1021 Type = GetDataTypeFromModifier(Field[0:Index])\r
1022 return Type.strip()\r
52302d4d 1023\r
30fdf114 1024 return None\r
52302d4d 1025\r
79b74a03 1026def GetRealType(Type, TypedefDict, TargetType=None):\r
4231a819 1027 if TargetType is not None and Type == TargetType:\r
30fdf114
LG
1028 return Type\r
1029 while TypedefDict.get(Type):\r
1030 Type = TypedefDict.get(Type)\r
4231a819 1031 if TargetType is not None and Type == TargetType:\r
30fdf114
LG
1032 return Type\r
1033 return Type\r
1034\r
79b74a03 1035def GetTypeInfo(RefList, Modifier, FullFileName, TargetType=None):\r
30fdf114
LG
1036 TypedefDict = GetTypedefDict(FullFileName)\r
1037 SUDict = GetSUDict(FullFileName)\r
1038 Type = GetDataTypeFromModifier(Modifier).replace('*', '').strip()\r
52302d4d 1039\r
30fdf114
LG
1040 Type = Type.split()[-1]\r
1041 Index = 0\r
1042 while Index < len(RefList):\r
1043 FieldName = RefList[Index]\r
1044 FromType = GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict)\r
4231a819 1045 if FromType is None:\r
30fdf114
LG
1046 return None\r
1047 # we want to determine the exact type.\r
4231a819 1048 if TargetType is not None:\r
30fdf114
LG
1049 Type = FromType.split()[0]\r
1050 # we only want to check if it is a pointer\r
1051 else:\r
1052 Type = FromType\r
79b74a03 1053 if Type.find('*') != -1 and Index == len(RefList) - 1:\r
30fdf114
LG
1054 return Type\r
1055 Type = FromType.split()[0]\r
52302d4d 1056\r
30fdf114
LG
1057 Index += 1\r
1058\r
1059 Type = GetRealType(Type, TypedefDict, TargetType)\r
1060\r
1061 return Type\r
1062\r
79b74a03 1063def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall=False, TargetType=None, StarList=None):\r
52302d4d 1064\r
30fdf114
LG
1065 PredVar = PredVarList[0]\r
1066 FileID = GetTableID(FullFileName)\r
52302d4d 1067\r
30fdf114
LG
1068 Db = GetDB()\r
1069 FileTable = 'Identifier' + str(FileID)\r
1070 # search variable in include files\r
52302d4d 1071\r
30fdf114
LG
1072 # it is a function call, search function declarations and definitions\r
1073 if IsFuncCall:\r
1074 SqlStatement = """ select Modifier, ID\r
1075 from %s\r
1076 where Model = %d and Value = \'%s\'\r
1077 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, PredVar)\r
1078 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d
LG
1079\r
1080 for Result in ResultSet:\r
30fdf114
LG
1081 Type = GetDataTypeFromModifier(Result[0]).split()[-1]\r
1082 TypedefDict = GetTypedefDict(FullFileName)\r
1083 Type = GetRealType(Type, TypedefDict, TargetType)\r
1084 return Type\r
52302d4d 1085\r
30fdf114
LG
1086 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
1087 for F in IncludeFileList:\r
1088 FileID = GetTableID(F)\r
1089 if FileID < 0:\r
1090 continue\r
52302d4d 1091\r
30fdf114
LG
1092 FileTable = 'Identifier' + str(FileID)\r
1093 SqlStatement = """ select Modifier, ID\r
1094 from %s\r
1095 where Model = %d and Value = \'%s\'\r
1096 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, PredVar)\r
1097 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 1098\r
30fdf114
LG
1099 for Result in ResultSet:\r
1100 Type = GetDataTypeFromModifier(Result[0]).split()[-1]\r
1101 TypedefDict = GetTypedefDict(FullFileName)\r
1102 Type = GetRealType(Type, TypedefDict, TargetType)\r
1103 return Type\r
52302d4d 1104\r
30fdf114
LG
1105 FileID = GetTableID(FullFileName)\r
1106 SqlStatement = """ select Modifier, ID\r
1107 from Function\r
1108 where BelongsToFile = %d and Name = \'%s\'\r
1109 """ % (FileID, PredVar)\r
1110 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d
LG
1111\r
1112 for Result in ResultSet:\r
30fdf114
LG
1113 Type = GetDataTypeFromModifier(Result[0]).split()[-1]\r
1114 TypedefDict = GetTypedefDict(FullFileName)\r
1115 Type = GetRealType(Type, TypedefDict, TargetType)\r
1116 return Type\r
52302d4d 1117\r
30fdf114
LG
1118 for F in IncludeFileList:\r
1119 FileID = GetTableID(F)\r
1120 if FileID < 0:\r
1121 continue\r
52302d4d 1122\r
30fdf114
LG
1123 FileTable = 'Identifier' + str(FileID)\r
1124 SqlStatement = """ select Modifier, ID\r
1125 from Function\r
1126 where BelongsToFile = %d and Name = \'%s\'\r
1127 """ % (FileID, PredVar)\r
1128 ResultSet = Db.TblFile.Exec(SqlStatement)\r
52302d4d 1129\r
30fdf114
LG
1130 for Result in ResultSet:\r
1131 Type = GetDataTypeFromModifier(Result[0]).split()[-1]\r
1132 TypedefDict = GetTypedefDict(FullFileName)\r
1133 Type = GetRealType(Type, TypedefDict, TargetType)\r
1134 return Type\r
52302d4d 1135\r
30fdf114 1136 return None\r
52302d4d 1137\r
30fdf114
LG
1138 # really variable, search local variable first\r
1139 SqlStatement = """ select Modifier, ID\r
1140 from %s\r
1141 where Model = %d and Name = \'%s\' and StartLine >= %d and StartLine <= %d\r
1142 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, PredVar, FuncRecord[0], FuncRecord[1])\r
1143 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1144 VarFound = False\r
1145 for Result in ResultSet:\r
1146 if len(PredVarList) > 1:\r
1147 Type = GetTypeInfo(PredVarList[1:], Result[0], FullFileName, TargetType)\r
1148 return Type\r
1149 else:\r
1150# Type = GetDataTypeFromModifier(Result[0]).split()[-1]\r
1151 TypeList = GetDataTypeFromModifier(Result[0]).split()\r
1152 Type = TypeList[-1]\r
4231a819 1153 if len(TypeList) > 1 and StarList is not None:\r
30fdf114
LG
1154 for Star in StarList:\r
1155 Type = Type.strip()\r
1156 Type = Type.rstrip(Star)\r
1157 # Get real type after de-reference pointers.\r
1158 if len(Type.strip()) == 0:\r
1159 Type = TypeList[-2]\r
1160 TypedefDict = GetTypedefDict(FullFileName)\r
1161 Type = GetRealType(Type, TypedefDict, TargetType)\r
1162 return Type\r
52302d4d 1163\r
30fdf114
LG
1164 # search function parameters second\r
1165 ParamList = GetParamList(FuncRecord[2])\r
1166 for Param in ParamList:\r
1167 if Param.Name.strip() == PredVar:\r
1168 if len(PredVarList) > 1:\r
1169 Type = GetTypeInfo(PredVarList[1:], Param.Modifier, FullFileName, TargetType)\r
1170 return Type\r
1171 else:\r
1172 TypeList = GetDataTypeFromModifier(Param.Modifier).split()\r
1173 Type = TypeList[-1]\r
83461d2c
HC
1174 if Type == '*' and len(TypeList) >= 2:\r
1175 Type = TypeList[-2]\r
4231a819 1176 if len(TypeList) > 1 and StarList is not None:\r
30fdf114
LG
1177 for Star in StarList:\r
1178 Type = Type.strip()\r
1179 Type = Type.rstrip(Star)\r
1180 # Get real type after de-reference pointers.\r
1181 if len(Type.strip()) == 0:\r
1182 Type = TypeList[-2]\r
1183 TypedefDict = GetTypedefDict(FullFileName)\r
1184 Type = GetRealType(Type, TypedefDict, TargetType)\r
1185 return Type\r
52302d4d 1186\r
30fdf114
LG
1187 # search global variable next\r
1188 SqlStatement = """ select Modifier, ID\r
1189 from %s\r
1190 where Model = %d and Name = \'%s\' and BelongsToFunction = -1\r
1191 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, PredVar)\r
1192 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1193\r
1194 for Result in ResultSet:\r
1195 if len(PredVarList) > 1:\r
1196 Type = GetTypeInfo(PredVarList[1:], Result[0], FullFileName, TargetType)\r
1197 return Type\r
1198 else:\r
1199 TypeList = GetDataTypeFromModifier(Result[0]).split()\r
1200 Type = TypeList[-1]\r
4231a819 1201 if len(TypeList) > 1 and StarList is not None:\r
30fdf114
LG
1202 for Star in StarList:\r
1203 Type = Type.strip()\r
1204 Type = Type.rstrip(Star)\r
1205 # Get real type after de-reference pointers.\r
1206 if len(Type.strip()) == 0:\r
1207 Type = TypeList[-2]\r
1208 TypedefDict = GetTypedefDict(FullFileName)\r
1209 Type = GetRealType(Type, TypedefDict, TargetType)\r
1210 return Type\r
52302d4d 1211\r
30fdf114
LG
1212 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
1213 for F in IncludeFileList:\r
1214 FileID = GetTableID(F)\r
1215 if FileID < 0:\r
1216 continue\r
52302d4d 1217\r
30fdf114
LG
1218 FileTable = 'Identifier' + str(FileID)\r
1219 SqlStatement = """ select Modifier, ID\r
1220 from %s\r
1221 where Model = %d and BelongsToFunction = -1 and Name = \'%s\'\r
1222 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, PredVar)\r
1223 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1224\r
1225 for Result in ResultSet:\r
1226 if len(PredVarList) > 1:\r
1227 Type = GetTypeInfo(PredVarList[1:], Result[0], FullFileName, TargetType)\r
1228 return Type\r
1229 else:\r
1230 TypeList = GetDataTypeFromModifier(Result[0]).split()\r
1231 Type = TypeList[-1]\r
4231a819 1232 if len(TypeList) > 1 and StarList is not None:\r
30fdf114
LG
1233 for Star in StarList:\r
1234 Type = Type.strip()\r
1235 Type = Type.rstrip(Star)\r
1236 # Get real type after de-reference pointers.\r
1237 if len(Type.strip()) == 0:\r
1238 Type = TypeList[-2]\r
1239 TypedefDict = GetTypedefDict(FullFileName)\r
1240 Type = GetRealType(Type, TypedefDict, TargetType)\r
1241 return Type\r
1242\r
52302d4d
LG
1243def GetTypeFromArray(Type, Var):\r
1244 Count = Var.count('[')\r
1245\r
1246 while Count > 0:\r
1247 Type = Type.strip()\r
1248 Type = Type.rstrip('*')\r
1249 Count = Count - 1\r
1250\r
1251 return Type\r
1252\r
30fdf114
LG
1253def CheckFuncLayoutReturnType(FullFileName):\r
1254 ErrorMsgList = []\r
52302d4d 1255\r
30fdf114
LG
1256 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1257 if FileID < 0:\r
1258 return ErrorMsgList\r
52302d4d 1259\r
30fdf114
LG
1260 Db = GetDB()\r
1261 FileTable = 'Identifier' + str(FileID)\r
52302d4d 1262 SqlStatement = """ select Modifier, ID, StartLine, StartColumn, EndLine, Value\r
30fdf114
LG
1263 from %s\r
1264 where Model = %d\r
1265 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1266 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1267 for Result in ResultSet:\r
1268 ReturnType = GetDataTypeFromModifier(Result[0])\r
1269 TypeStart = ReturnType.split()[0]\r
1270 FuncName = Result[5]\r
1271 if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, FuncName):\r
1272 continue\r
00261e1d
HC
1273 Result0 = Result[0]\r
1274 if Result0.upper().startswith('STATIC'):\r
1275 Result0 = Result0[6:].strip()\r
1276 Index = Result0.find(TypeStart)\r
30fdf114
LG
1277 if Index != 0 or Result[3] != 0:\r
1278 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear at the start of line' % FuncName, FileTable, Result[1])\r
52302d4d 1279\r
30fdf114
LG
1280 if Result[2] == Result[4]:\r
1281 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear on its own line' % FuncName, FileTable, Result[1])\r
52302d4d 1282\r
30fdf114
LG
1283 SqlStatement = """ select Modifier, ID, StartLine, StartColumn, FunNameStartLine, Name\r
1284 from Function\r
1285 where BelongsToFile = %d\r
1286 """ % (FileID)\r
1287 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1288 for Result in ResultSet:\r
1289 ReturnType = GetDataTypeFromModifier(Result[0])\r
1290 TypeStart = ReturnType.split()[0]\r
1291 FuncName = Result[5]\r
1292 if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, FuncName):\r
1293 continue\r
72358997
HC
1294 Result0 = Result[0]\r
1295 if Result0.upper().startswith('STATIC'):\r
1296 Result0 = Result0[6:].strip()\r
c60377d7 1297 Index = Result0.find(TypeStart)\r
30fdf114
LG
1298 if Index != 0 or Result[3] != 0:\r
1299 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear at the start of line' % FuncName, 'Function', Result[1])\r
52302d4d 1300\r
30fdf114
LG
1301def CheckFuncLayoutModifier(FullFileName):\r
1302 ErrorMsgList = []\r
52302d4d 1303\r
30fdf114
LG
1304 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1305 if FileID < 0:\r
1306 return ErrorMsgList\r
52302d4d 1307\r
30fdf114
LG
1308 Db = GetDB()\r
1309 FileTable = 'Identifier' + str(FileID)\r
1310 SqlStatement = """ select Modifier, ID\r
1311 from %s\r
1312 where Model = %d\r
1313 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1314 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1315 for Result in ResultSet:\r
1316 ReturnType = GetDataTypeFromModifier(Result[0])\r
1317 TypeStart = ReturnType.split()[0]\r
00261e1d
HC
1318 Result0 = Result[0]\r
1319 if Result0.upper().startswith('STATIC'):\r
1320 Result0 = Result0[6:].strip()\r
1321 Index = Result0.find(TypeStart)\r
30fdf114
LG
1322 if Index != 0:\r
1323 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER, '', FileTable, Result[1])\r
52302d4d 1324\r
30fdf114
LG
1325 SqlStatement = """ select Modifier, ID\r
1326 from Function\r
1327 where BelongsToFile = %d\r
1328 """ % (FileID)\r
1329 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1330 for Result in ResultSet:\r
1331 ReturnType = GetDataTypeFromModifier(Result[0])\r
1332 TypeStart = ReturnType.split()[0]\r
72358997
HC
1333 Result0 = Result[0]\r
1334 if Result0.upper().startswith('STATIC'):\r
1335 Result0 = Result0[6:].strip()\r
1336 Index = Result0.find(TypeStart)\r
30fdf114
LG
1337 if Index != 0:\r
1338 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER, '', 'Function', Result[1])\r
1339\r
1340def CheckFuncLayoutName(FullFileName):\r
1341 ErrorMsgList = []\r
1342 # Parameter variable format pattern.\r
1343 Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')\r
1344 ParamIgnoreList = ('VOID', '...')\r
1345 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1346 if FileID < 0:\r
1347 return ErrorMsgList\r
52302d4d 1348\r
30fdf114
LG
1349 Db = GetDB()\r
1350 FileTable = 'Identifier' + str(FileID)\r
1351 SqlStatement = """ select Name, ID, EndColumn, Value\r
1352 from %s\r
1353 where Model = %d\r
1354 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1355 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1356 for Result in ResultSet:\r
1357 FuncName = Result[3]\r
1358 if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, FuncName):\r
1359 continue\r
1360 if Result[2] != 0:\r
1361 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Function name [%s] should appear at the start of a line' % FuncName, FileTable, Result[1])\r
1362 ParamList = GetParamList(Result[0])\r
1363 if len(ParamList) == 0:\r
1364 continue\r
1365 StartLine = 0\r
1366 for Param in ParamList:\r
1367 if Param.StartLine <= StartLine:\r
1368 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Parameter %s should be in its own line.' % Param.Name, FileTable, Result[1])\r
1369 if Param.StartLine - StartLine > 1:\r
52302d4d 1370 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Empty line appears before Parameter %s.' % Param.Name, FileTable, Result[1])\r
30fdf114
LG
1371 if not Pattern.match(Param.Name) and not Param.Name in ParamIgnoreList and not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Param.Name):\r
1372 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Parameter [%s] NOT follow naming convention.' % Param.Name, FileTable, Result[1])\r
1373 StartLine = Param.StartLine\r
52302d4d 1374\r
30fdf114
LG
1375 if not Result[0].endswith('\n )') and not Result[0].endswith('\r )'):\r
1376 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, '\')\' should be on a new line and indented two spaces', FileTable, Result[1])\r
52302d4d 1377\r
30fdf114
LG
1378 SqlStatement = """ select Modifier, ID, FunNameStartColumn, Name\r
1379 from Function\r
1380 where BelongsToFile = %d\r
1381 """ % (FileID)\r
1382 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1383 for Result in ResultSet:\r
1384 FuncName = Result[3]\r
1385 if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, FuncName):\r
1386 continue\r
1387 if Result[2] != 0:\r
1388 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Function name [%s] should appear at the start of a line' % FuncName, 'Function', Result[1])\r
1389 ParamList = GetParamList(Result[0])\r
1390 if len(ParamList) == 0:\r
1391 continue\r
1392 StartLine = 0\r
1393 for Param in ParamList:\r
1394 if Param.StartLine <= StartLine:\r
1395 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Parameter %s should be in its own line.' % Param.Name, 'Function', Result[1])\r
1396 if Param.StartLine - StartLine > 1:\r
1397 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Empty line appears before Parameter %s.' % Param.Name, 'Function', Result[1])\r
1398 if not Pattern.match(Param.Name) and not Param.Name in ParamIgnoreList and not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Param.Name):\r
1399 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Parameter [%s] NOT follow naming convention.' % Param.Name, FileTable, Result[1])\r
1400 StartLine = Param.StartLine\r
1401 if not Result[0].endswith('\n )') and not Result[0].endswith('\r )'):\r
1402 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, '\')\' should be on a new line and indented two spaces', 'Function', Result[1])\r
1403\r
1404def CheckFuncLayoutPrototype(FullFileName):\r
1405 ErrorMsgList = []\r
52302d4d 1406\r
30fdf114
LG
1407 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1408 if FileID < 0:\r
1409 return ErrorMsgList\r
52302d4d 1410\r
30fdf114
LG
1411 FileTable = 'Identifier' + str(FileID)\r
1412 Db = GetDB()\r
1413 SqlStatement = """ select Modifier, Header, Name, ID\r
1414 from Function\r
1415 where BelongsToFile = %d\r
1416 """ % (FileID)\r
1417 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1418 if len(ResultSet) == 0:\r
1419 return ErrorMsgList\r
52302d4d 1420\r
30fdf114
LG
1421 FuncDefList = []\r
1422 for Result in ResultSet:\r
1423 FuncDefList.append(Result)\r
52302d4d 1424\r
30fdf114
LG
1425 SqlStatement = """ select Modifier, Name, ID\r
1426 from %s\r
1427 where Model = %d\r
1428 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1429 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1430 FuncDeclList = []\r
1431 for Result in ResultSet:\r
1432 FuncDeclList.append(Result)\r
52302d4d 1433\r
30fdf114
LG
1434 UndeclFuncList = []\r
1435 for FuncDef in FuncDefList:\r
1436 FuncName = FuncDef[2].strip()\r
1437 FuncModifier = FuncDef[0]\r
1438 FuncDefHeader = FuncDef[1]\r
1439 for FuncDecl in FuncDeclList:\r
1440 LBPos = FuncDecl[1].find('(')\r
1441 DeclName = FuncDecl[1][0:LBPos].strip()\r
1442 DeclModifier = FuncDecl[0]\r
1443 if DeclName == FuncName:\r
1444 if DiffModifier(FuncModifier, DeclModifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, FuncName):\r
1445 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Function [%s] modifier different with prototype.' % FuncName, 'Function', FuncDef[3])\r
1446 ParamListOfDef = GetParamList(FuncDefHeader)\r
1447 ParamListOfDecl = GetParamList(FuncDecl[1])\r
52302d4d
LG
1448 if len(ParamListOfDef) != len(ParamListOfDecl) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, FuncName):\r
1449 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, 'Parameter number different in function [%s].' % FuncName, 'Function', FuncDef[3])\r
30fdf114
LG
1450 break\r
1451\r
1452 Index = 0\r
1453 while Index < len(ParamListOfDef):\r
52302d4d
LG
1454 if DiffModifier(ParamListOfDef[Index].Modifier, ParamListOfDecl[Index].Modifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, FuncName):\r
1455 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, 'Parameter %s has different modifier with prototype in function [%s].' % (ParamListOfDef[Index].Name, FuncName), 'Function', FuncDef[3])\r
30fdf114
LG
1456 Index += 1\r
1457 break\r
1458 else:\r
1459 UndeclFuncList.append(FuncDef)\r
52302d4d 1460\r
30fdf114
LG
1461 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
1462 FuncDeclList = []\r
1463 for F in IncludeFileList:\r
1464 FileID = GetTableID(F, ErrorMsgList)\r
1465 if FileID < 0:\r
1466 continue\r
52302d4d 1467\r
30fdf114
LG
1468 FileTable = 'Identifier' + str(FileID)\r
1469 SqlStatement = """ select Modifier, Name, ID\r
1470 from %s\r
1471 where Model = %d\r
1472 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1473 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1474\r
1475 for Result in ResultSet:\r
1476 FuncDeclList.append(Result)\r
52302d4d 1477\r
30fdf114
LG
1478 for FuncDef in UndeclFuncList:\r
1479 FuncName = FuncDef[2].strip()\r
1480 FuncModifier = FuncDef[0]\r
1481 FuncDefHeader = FuncDef[1]\r
1482 for FuncDecl in FuncDeclList:\r
1483 LBPos = FuncDecl[1].find('(')\r
1484 DeclName = FuncDecl[1][0:LBPos].strip()\r
1485 DeclModifier = FuncDecl[0]\r
1486 if DeclName == FuncName:\r
1487 if DiffModifier(FuncModifier, DeclModifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, FuncName):\r
1488 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Function [%s] modifier different with prototype.' % FuncName, 'Function', FuncDef[3])\r
1489 ParamListOfDef = GetParamList(FuncDefHeader)\r
1490 ParamListOfDecl = GetParamList(FuncDecl[1])\r
52302d4d
LG
1491 if len(ParamListOfDef) != len(ParamListOfDecl) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, FuncName):\r
1492 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_2, 'Parameter number different in function [%s].' % FuncName, 'Function', FuncDef[3])\r
30fdf114
LG
1493 break\r
1494\r
1495 Index = 0\r
1496 while Index < len(ParamListOfDef):\r
52302d4d
LG
1497 if DiffModifier(ParamListOfDef[Index].Modifier, ParamListOfDecl[Index].Modifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, FuncName):\r
1498 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE_3, 'Parameter %s has different modifier with prototype in function [%s].' % (ParamListOfDef[Index].Name, FuncName), 'Function', FuncDef[3])\r
30fdf114
LG
1499 Index += 1\r
1500 break\r
52302d4d 1501\r
30fdf114
LG
1502def CheckFuncLayoutBody(FullFileName):\r
1503 ErrorMsgList = []\r
52302d4d 1504\r
30fdf114
LG
1505 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1506 if FileID < 0:\r
1507 return ErrorMsgList\r
52302d4d 1508\r
30fdf114
LG
1509 FileTable = 'Identifier' + str(FileID)\r
1510 Db = GetDB()\r
ce3bfbec 1511 SqlStatement = """ select BodyStartColumn, EndColumn, ID, Name\r
30fdf114
LG
1512 from Function\r
1513 where BelongsToFile = %d\r
1514 """ % (FileID)\r
1515 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1516 if len(ResultSet) == 0:\r
1517 return ErrorMsgList\r
1518 for Result in ResultSet:\r
1519 if Result[0] != 0:\r
ce3bfbec
HC
1520 if not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, Result[3]):\r
1521 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY,\r
1522 'The open brace should be at the very beginning of a line for the function [%s].' % Result[3],\r
1523 'Function', Result[2])\r
30fdf114 1524 if Result[1] != 0:\r
ce3bfbec
HC
1525 if not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, Result[3]):\r
1526 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY,\r
1527 'The close brace should be at the very beginning of a line for the function [%s].' % Result[3],\r
1528 'Function', Result[2])\r
30fdf114
LG
1529\r
1530def CheckFuncLayoutLocalVariable(FullFileName):\r
1531 ErrorMsgList = []\r
52302d4d 1532\r
30fdf114
LG
1533 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1534 if FileID < 0:\r
1535 return ErrorMsgList\r
52302d4d 1536\r
30fdf114
LG
1537 Db = GetDB()\r
1538 FileTable = 'Identifier' + str(FileID)\r
1539 SqlStatement = """ select ID\r
1540 from Function\r
1541 where BelongsToFile = %d\r
1542 """ % (FileID)\r
1543 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1544 if len(ResultSet) == 0:\r
1545 return ErrorMsgList\r
1546 FL = []\r
1547 for Result in ResultSet:\r
1548 FL.append(Result)\r
52302d4d 1549\r
30fdf114 1550 for F in FL:\r
79b74a03 1551 SqlStatement = """ select Name, Value, ID, Modifier\r
30fdf114
LG
1552 from %s\r
1553 where Model = %d and BelongsToFunction = %d\r
1554 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, F[0])\r
1555 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1556 if len(ResultSet) == 0:\r
1557 continue\r
52302d4d 1558\r
30fdf114 1559 for Result in ResultSet:\r
79b74a03 1560 if len(Result[1]) > 0 and 'CONST' not in Result[3]:\r
30fdf114 1561 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE, 'Variable Name: %s' % Result[0], FileTable, Result[2])\r
52302d4d 1562\r
30fdf114
LG
1563def CheckMemberVariableFormat(Name, Value, FileTable, TdId, ModelId):\r
1564 ErrMsgList = []\r
1565 # Member variable format pattern.\r
1566 Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')\r
52302d4d 1567\r
30fdf114
LG
1568 LBPos = Value.find('{')\r
1569 RBPos = Value.rfind('}')\r
1570 if LBPos == -1 or RBPos == -1:\r
1571 return ErrMsgList\r
52302d4d 1572\r
30fdf114
LG
1573 Fields = Value[LBPos + 1 : RBPos]\r
1574 Fields = StripComments(Fields).strip()\r
1575 NestPos = Fields.find ('struct')\r
f8895c2a 1576 if NestPos != -1 and (NestPos + len('struct') < len(Fields)) and ModelId != DataClass.MODEL_IDENTIFIER_UNION:\r
30fdf114
LG
1577 if not Fields[NestPos + len('struct') + 1].isalnum():\r
1578 if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name):\r
1579 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested struct in [%s].' % (Name), FileTable, TdId)\r
1580 return ErrMsgList\r
1581 NestPos = Fields.find ('union')\r
1582 if NestPos != -1 and (NestPos + len('union') < len(Fields)):\r
1583 if not Fields[NestPos + len('union') + 1].isalnum():\r
1584 if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name):\r
1585 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested union in [%s].' % (Name), FileTable, TdId)\r
1586 return ErrMsgList\r
1587 NestPos = Fields.find ('enum')\r
1588 if NestPos != -1 and (NestPos + len('enum') < len(Fields)):\r
1589 if not Fields[NestPos + len('enum') + 1].isalnum():\r
1590 if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name):\r
1591 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested enum in [%s].' % (Name), FileTable, TdId)\r
1592 return ErrMsgList\r
52302d4d 1593\r
30fdf114
LG
1594 if ModelId == DataClass.MODEL_IDENTIFIER_ENUMERATE:\r
1595 FieldsList = Fields.split(',')\r
1596 # deal with enum is pre-assigned a value by function call ( , , , ...)\r
1597 QuoteCount = 0\r
1598 Index = 0\r
1599 RemoveCurrentElement = False\r
1600 while Index < len(FieldsList):\r
1601 Field = FieldsList[Index]\r
52302d4d 1602\r
30fdf114
LG
1603 if Field.find('(') != -1:\r
1604 QuoteCount += 1\r
1605 RemoveCurrentElement = True\r
1606 Index += 1\r
1607 continue\r
52302d4d 1608\r
30fdf114
LG
1609 if Field.find(')') != -1 and QuoteCount > 0:\r
1610 QuoteCount -= 1\r
1611\r
52302d4d 1612 if RemoveCurrentElement:\r
30fdf114
LG
1613 FieldsList.remove(Field)\r
1614 if QuoteCount == 0:\r
1615 RemoveCurrentElement = False\r
1616 continue\r
52302d4d 1617\r
30fdf114
LG
1618 if QuoteCount == 0:\r
1619 RemoveCurrentElement = False\r
52302d4d 1620\r
30fdf114
LG
1621 Index += 1\r
1622 else:\r
1623 FieldsList = Fields.split(';')\r
52302d4d 1624\r
30fdf114
LG
1625 for Field in FieldsList:\r
1626 Field = Field.strip()\r
1627 if Field == '':\r
1628 continue\r
fb0b35e0 1629 # For the condition that the field in struct is an array with [] suffixes...\r
30fdf114
LG
1630 if Field[-1] == ']':\r
1631 LBPos = Field.find('[')\r
1632 Field = Field[0:LBPos]\r
1633 # For the condition that bit field ": Number"\r
1634 if Field.find(':') != -1:\r
1635 ColonPos = Field.find(':')\r
1636 Field = Field[0:ColonPos]\r
52302d4d 1637\r
30fdf114
LG
1638 Field = Field.strip()\r
1639 if Field == '':\r
1640 continue\r
00261e1d
HC
1641 if Field.startswith("#"):\r
1642 continue\r
30fdf114
LG
1643 # Enum could directly assign value to variable\r
1644 Field = Field.split('=')[0].strip()\r
52302d4d 1645 TokenList = Field.split()\r
30fdf114 1646 # Remove pointers before variable\r
fa3a2156
HC
1647 Token = TokenList[-1]\r
1648 if Token in ['OPTIONAL']:\r
1649 Token = TokenList[-2]\r
1650 if not Pattern.match(Token.lstrip('*')):\r
1651 ErrMsgList.append(Token.lstrip('*'))\r
52302d4d 1652\r
30fdf114
LG
1653 return ErrMsgList\r
1654\r
1655def CheckDeclTypedefFormat(FullFileName, ModelId):\r
1656 ErrorMsgList = []\r
52302d4d 1657\r
30fdf114
LG
1658 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1659 if FileID < 0:\r
1660 return ErrorMsgList\r
52302d4d 1661\r
30fdf114
LG
1662 Db = GetDB()\r
1663 FileTable = 'Identifier' + str(FileID)\r
1664 SqlStatement = """ select Name, StartLine, EndLine, ID, Value\r
1665 from %s\r
1666 where Model = %d\r
1667 """ % (FileTable, ModelId)\r
1668 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1669 ResultList = []\r
1670 for Result in ResultSet:\r
1671 ResultList.append(Result)\r
52302d4d 1672\r
30fdf114
LG
1673 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_ALL\r
1674 if ModelId == DataClass.MODEL_IDENTIFIER_STRUCTURE:\r
1675 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_STRUCTURE_DECLARATION\r
1676 elif ModelId == DataClass.MODEL_IDENTIFIER_ENUMERATE:\r
1677 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_ENUMERATED_TYPE\r
1678 elif ModelId == DataClass.MODEL_IDENTIFIER_UNION:\r
1679 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_UNION_TYPE\r
52302d4d 1680\r
30fdf114
LG
1681 SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID\r
1682 from %s\r
1683 where Model = %d\r
1684 """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
1685 TdSet = Db.TblFile.Exec(SqlStatement)\r
1686 TdList = []\r
1687 for Td in TdSet:\r
1688 TdList.append(Td)\r
1689 # Check member variable name format that from typedefs of ONLY this file.\r
1690 for Td in TdList:\r
1691 Name = Td[1].strip()\r
1692 Value = Td[2].strip()\r
1693 if Value.startswith('enum'):\r
1694 ValueModelId = DataClass.MODEL_IDENTIFIER_ENUMERATE\r
1695 elif Value.startswith('struct'):\r
1696 ValueModelId = DataClass.MODEL_IDENTIFIER_STRUCTURE\r
1697 elif Value.startswith('union'):\r
1698 ValueModelId = DataClass.MODEL_IDENTIFIER_UNION\r
1699 else:\r
1700 continue\r
52302d4d 1701\r
30fdf114
LG
1702 if ValueModelId != ModelId:\r
1703 continue\r
1704 # Check member variable format.\r
1705 ErrMsgList = CheckMemberVariableFormat(Name, Value, FileTable, Td[5], ModelId)\r
1706 for ErrMsg in ErrMsgList:\r
79b74a03 1707 if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Name + '.' + ErrMsg):\r
30fdf114 1708 continue\r
79b74a03 1709 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Name + '.' + ErrMsg), FileTable, Td[5])\r
52302d4d 1710\r
30fdf114
LG
1711 # First check in current file to see whether struct/union/enum is typedef-ed.\r
1712 UntypedefedList = []\r
1713 for Result in ResultList:\r
1714 # Check member variable format.\r
1715 Name = Result[0].strip()\r
1716 Value = Result[4].strip()\r
1717 if Value.startswith('enum'):\r
1718 ValueModelId = DataClass.MODEL_IDENTIFIER_ENUMERATE\r
1719 elif Value.startswith('struct'):\r
1720 ValueModelId = DataClass.MODEL_IDENTIFIER_STRUCTURE\r
1721 elif Value.startswith('union'):\r
1722 ValueModelId = DataClass.MODEL_IDENTIFIER_UNION\r
1723 else:\r
1724 continue\r
52302d4d 1725\r
30fdf114
LG
1726 if ValueModelId != ModelId:\r
1727 continue\r
1728 ErrMsgList = CheckMemberVariableFormat(Name, Value, FileTable, Result[3], ModelId)\r
1729 for ErrMsg in ErrMsgList:\r
79b74a03 1730 if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Result[0] + '.' + ErrMsg):\r
30fdf114 1731 continue\r
79b74a03 1732 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Result[0] + '.' + ErrMsg), FileTable, Result[3])\r
30fdf114
LG
1733 # Check whether it is typedefed.\r
1734 Found = False\r
1735 for Td in TdList:\r
1736 # skip function pointer\r
1737 if len(Td[0]) > 0:\r
1738 continue\r
1739 if Result[1] >= Td[3] and Td[4] >= Result[2]:\r
1740 Found = True\r
1741 if not Td[1].isupper():\r
1742 PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
1743 if Result[0] in Td[2].split():\r
1744 Found = True\r
1745 if not Td[1].isupper():\r
1746 PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
1747 if Found:\r
1748 break\r
52302d4d 1749\r
30fdf114
LG
1750 if not Found:\r
1751 UntypedefedList.append(Result)\r
1752 continue\r
52302d4d 1753\r
30fdf114
LG
1754 if len(UntypedefedList) == 0:\r
1755 return\r
52302d4d 1756\r
30fdf114
LG
1757 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
1758 TdList = []\r
1759 for F in IncludeFileList:\r
1760 FileID = GetTableID(F, ErrorMsgList)\r
1761 if FileID < 0:\r
1762 continue\r
52302d4d 1763\r
30fdf114
LG
1764 IncludeFileTable = 'Identifier' + str(FileID)\r
1765 SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID\r
1766 from %s\r
1767 where Model = %d\r
1768 """ % (IncludeFileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
1769 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1770 TdList.extend(ResultSet)\r
52302d4d 1771\r
30fdf114 1772 for Result in UntypedefedList:\r
52302d4d 1773\r
30fdf114
LG
1774 # Check whether it is typedefed.\r
1775 Found = False\r
1776 for Td in TdList:\r
52302d4d 1777\r
30fdf114
LG
1778 if len(Td[0]) > 0:\r
1779 continue\r
1780 if Result[1] >= Td[3] and Td[4] >= Result[2]:\r
1781 Found = True\r
1782 if not Td[1].isupper():\r
1783 PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
1784 if Result[0] in Td[2].split():\r
1785 Found = True\r
1786 if not Td[1].isupper():\r
1787 PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
1788 if Found:\r
1789 break\r
52302d4d 1790\r
30fdf114
LG
1791 if not Found:\r
1792 PrintErrorMsg(ErrorType, 'No Typedef for %s' % Result[0], FileTable, Result[3])\r
1793 continue\r
52302d4d 1794\r
30fdf114
LG
1795def CheckDeclStructTypedef(FullFileName):\r
1796 CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_STRUCTURE)\r
1797\r
1798def CheckDeclEnumTypedef(FullFileName):\r
1799 CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_ENUMERATE)\r
52302d4d 1800\r
30fdf114
LG
1801def CheckDeclUnionTypedef(FullFileName):\r
1802 CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_UNION)\r
1803\r
1804def CheckDeclArgModifier(FullFileName):\r
1805 ErrorMsgList = []\r
52302d4d 1806\r
30fdf114
LG
1807 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1808 if FileID < 0:\r
1809 return ErrorMsgList\r
52302d4d 1810\r
30fdf114
LG
1811 Db = GetDB()\r
1812 FileTable = 'Identifier' + str(FileID)\r
1813 SqlStatement = """ select Modifier, Name, ID\r
1814 from %s\r
1815 where Model = %d\r
1816 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE)\r
1817 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1818 ModifierTuple = ('IN', 'OUT', 'OPTIONAL', 'UNALIGNED')\r
1819 MAX_MODIFIER_LENGTH = 100\r
1820 for Result in ResultSet:\r
1821 for Modifier in ModifierTuple:\r
1822 if PatternInModifier(Result[0], Modifier) and len(Result[0]) < MAX_MODIFIER_LENGTH:\r
1823 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Variable Modifier %s' % Result[0], FileTable, Result[2])\r
1824 break\r
52302d4d 1825\r
30fdf114
LG
1826 SqlStatement = """ select Modifier, Name, ID\r
1827 from %s\r
1828 where Model = %d\r
1829 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1830 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1831 for Result in ResultSet:\r
1832 for Modifier in ModifierTuple:\r
1833 if PatternInModifier(Result[0], Modifier):\r
1834 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Return Type Modifier %s' % Result[0], FileTable, Result[2])\r
1835 break\r
52302d4d 1836\r
30fdf114
LG
1837 SqlStatement = """ select Modifier, Header, ID\r
1838 from Function\r
1839 where BelongsToFile = %d\r
1840 """ % (FileID)\r
1841 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1842 for Result in ResultSet:\r
1843 for Modifier in ModifierTuple:\r
1844 if PatternInModifier(Result[0], Modifier):\r
1845 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Return Type Modifier %s' % Result[0], FileTable, Result[2])\r
1846 break\r
1847\r
1848def CheckDeclNoUseCType(FullFileName):\r
1849 ErrorMsgList = []\r
52302d4d 1850\r
30fdf114
LG
1851 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1852 if FileID < 0:\r
1853 return ErrorMsgList\r
52302d4d 1854\r
30fdf114
LG
1855 Db = GetDB()\r
1856 FileTable = 'Identifier' + str(FileID)\r
1857 SqlStatement = """ select Modifier, Name, ID\r
1858 from %s\r
1859 where Model = %d\r
1860 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE)\r
1861 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1862 CTypeTuple = ('int', 'unsigned', 'char', 'void', 'static', 'long')\r
1863 for Result in ResultSet:\r
1864 for Type in CTypeTuple:\r
1865 if PatternInModifier(Result[0], Type):\r
dbc85eb9
HC
1866 if EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE,\r
1867 Result[0] + ' ' + Result[1]):\r
1868 continue\r
1869 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE,\r
1870 'Invalid variable type (%s) in definition [%s]' % (Type, Result[0] + ' ' + Result[1]),\r
1871 FileTable,\r
1872 Result[2])\r
30fdf114 1873 break\r
52302d4d 1874\r
30fdf114
LG
1875 SqlStatement = """ select Modifier, Name, ID, Value\r
1876 from %s\r
1877 where Model = %d\r
1878 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1879 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1880 for Result in ResultSet:\r
1881 ParamList = GetParamList(Result[1])\r
1882 FuncName = Result[3]\r
1883 if EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, FuncName):\r
1884 continue\r
1885 for Type in CTypeTuple:\r
1886 if PatternInModifier(Result[0], Type):\r
1887 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, '%s Return type %s' % (FuncName, Result[0]), FileTable, Result[2])\r
52302d4d 1888\r
30fdf114
LG
1889 for Param in ParamList:\r
1890 if PatternInModifier(Param.Modifier, Type):\r
1891 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Parameter %s' % Param.Name, FileTable, Result[2])\r
52302d4d 1892\r
30fdf114
LG
1893 SqlStatement = """ select Modifier, Header, ID, Name\r
1894 from Function\r
1895 where BelongsToFile = %d\r
1896 """ % (FileID)\r
1897 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1898 for Result in ResultSet:\r
1899 ParamList = GetParamList(Result[1])\r
1900 FuncName = Result[3]\r
1901 if EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, FuncName):\r
1902 continue\r
1903 for Type in CTypeTuple:\r
1904 if PatternInModifier(Result[0], Type):\r
1905 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, '[%s] Return type %s' % (FuncName, Result[0]), FileTable, Result[2])\r
52302d4d 1906\r
30fdf114
LG
1907 for Param in ParamList:\r
1908 if PatternInModifier(Param.Modifier, Type):\r
1909 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Parameter %s' % Param.Name, FileTable, Result[2])\r
52302d4d 1910\r
30fdf114
LG
1911\r
1912def CheckPointerNullComparison(FullFileName):\r
1913 ErrorMsgList = []\r
52302d4d 1914\r
30fdf114
LG
1915 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1916 if FileID < 0:\r
1917 return ErrorMsgList\r
52302d4d 1918\r
30fdf114
LG
1919 # cache the found function return type to accelerate later checking in this file.\r
1920 FuncReturnTypeDict = {}\r
52302d4d 1921\r
30fdf114
LG
1922 Db = GetDB()\r
1923 FileTable = 'Identifier' + str(FileID)\r
1924 SqlStatement = """ select Value, StartLine, ID\r
1925 from %s\r
1926 where Model = %d\r
1927 """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION)\r
1928 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1929 if len(ResultSet) == 0:\r
1930 return\r
1931 PSL = []\r
1932 for Result in ResultSet:\r
1933 PSL.append([Result[0], Result[1], Result[2]])\r
52302d4d 1934\r
30fdf114
LG
1935 SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID\r
1936 from Function\r
1937 where BelongsToFile = %d\r
1938 """ % (FileID)\r
1939 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1940 FL = []\r
1941 for Result in ResultSet:\r
1942 FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
52302d4d 1943\r
30fdf114
LG
1944 p = GetFuncDeclPattern()\r
1945 for Str in PSL:\r
1946 FuncRecord = GetFuncContainsPE(Str[1], FL)\r
4231a819 1947 if FuncRecord is None:\r
30fdf114 1948 continue\r
52302d4d 1949\r
30fdf114
LG
1950 for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
1951 PredInfo = SplitPredicateStr(Exp)\r
4231a819 1952 if PredInfo[1] is None:\r
30fdf114
LG
1953 PredVarStr = PredInfo[0][0].strip()\r
1954 IsFuncCall = False\r
1955 SearchInCache = False\r
1956 # PredVarStr may contain '.' or '->'\r
1957 TmpStr = PredVarStr.replace('.', '').replace('->', '')\r
1958 if p.match(TmpStr):\r
1959 PredVarStr = PredVarStr[0:PredVarStr.find('(')]\r
1960 SearchInCache = True\r
1961 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.\r
52302d4d 1962 if TmpStr.startswith(PredVarStr):\r
30fdf114 1963 IsFuncCall = True\r
52302d4d 1964\r
30fdf114
LG
1965 if PredVarStr.strip() in IgnoredKeywordList:\r
1966 continue\r
1967 StarList = []\r
1968 PredVarList = GetCNameList(PredVarStr, StarList)\r
1969 # No variable found, maybe value first? like (0 == VarName)\r
1970 if len(PredVarList) == 0:\r
1971 continue\r
1972 if SearchInCache:\r
1973 Type = FuncReturnTypeDict.get(PredVarStr)\r
4231a819 1974 if Type is not None:\r
79b74a03 1975 if Type.find('*') != -1 and Type != 'BOOLEAN*':\r
30fdf114
LG
1976 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
1977 continue\r
52302d4d 1978\r
30fdf114
LG
1979 if PredVarStr in FuncReturnTypeDict:\r
1980 continue\r
52302d4d 1981\r
30fdf114
LG
1982 Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, None, StarList)\r
1983 if SearchInCache:\r
1984 FuncReturnTypeDict[PredVarStr] = Type\r
4231a819 1985 if Type is None:\r
30fdf114 1986 continue\r
52302d4d 1987 Type = GetTypeFromArray(Type, PredVarStr)\r
79b74a03 1988 if Type.find('*') != -1 and Type != 'BOOLEAN*':\r
30fdf114
LG
1989 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
1990\r
1991def CheckNonBooleanValueComparison(FullFileName):\r
1992 ErrorMsgList = []\r
52302d4d 1993\r
30fdf114
LG
1994 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1995 if FileID < 0:\r
1996 return ErrorMsgList\r
52302d4d 1997\r
30fdf114
LG
1998 # cache the found function return type to accelerate later checking in this file.\r
1999 FuncReturnTypeDict = {}\r
52302d4d 2000\r
30fdf114
LG
2001 Db = GetDB()\r
2002 FileTable = 'Identifier' + str(FileID)\r
2003 SqlStatement = """ select Value, StartLine, ID\r
2004 from %s\r
2005 where Model = %d\r
2006 """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION)\r
2007 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2008 if len(ResultSet) == 0:\r
2009 return\r
2010 PSL = []\r
2011 for Result in ResultSet:\r
2012 PSL.append([Result[0], Result[1], Result[2]])\r
52302d4d 2013\r
30fdf114
LG
2014 SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID\r
2015 from Function\r
2016 where BelongsToFile = %d\r
2017 """ % (FileID)\r
2018 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2019 FL = []\r
2020 for Result in ResultSet:\r
2021 FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
52302d4d 2022\r
30fdf114
LG
2023 p = GetFuncDeclPattern()\r
2024 for Str in PSL:\r
2025 FuncRecord = GetFuncContainsPE(Str[1], FL)\r
4231a819 2026 if FuncRecord is None:\r
30fdf114 2027 continue\r
52302d4d 2028\r
30fdf114 2029 for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
30fdf114 2030 PredInfo = SplitPredicateStr(Exp)\r
4231a819 2031 if PredInfo[1] is None:\r
30fdf114
LG
2032 PredVarStr = PredInfo[0][0].strip()\r
2033 IsFuncCall = False\r
2034 SearchInCache = False\r
2035 # PredVarStr may contain '.' or '->'\r
2036 TmpStr = PredVarStr.replace('.', '').replace('->', '')\r
2037 if p.match(TmpStr):\r
2038 PredVarStr = PredVarStr[0:PredVarStr.find('(')]\r
2039 SearchInCache = True\r
2040 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.\r
52302d4d 2041 if TmpStr.startswith(PredVarStr):\r
30fdf114 2042 IsFuncCall = True\r
52302d4d 2043\r
30fdf114
LG
2044 if PredVarStr.strip() in IgnoredKeywordList:\r
2045 continue\r
2046 StarList = []\r
2047 PredVarList = GetCNameList(PredVarStr, StarList)\r
2048 # No variable found, maybe value first? like (0 == VarName)\r
2049 if len(PredVarList) == 0:\r
2050 continue\r
52302d4d 2051\r
30fdf114
LG
2052 if SearchInCache:\r
2053 Type = FuncReturnTypeDict.get(PredVarStr)\r
4231a819 2054 if Type is not None:\r
30fdf114
LG
2055 if Type.find('BOOLEAN') == -1:\r
2056 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
2057 continue\r
52302d4d 2058\r
30fdf114
LG
2059 if PredVarStr in FuncReturnTypeDict:\r
2060 continue\r
30fdf114
LG
2061 Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, 'BOOLEAN', StarList)\r
2062 if SearchInCache:\r
2063 FuncReturnTypeDict[PredVarStr] = Type\r
4231a819 2064 if Type is None:\r
30fdf114
LG
2065 continue\r
2066 if Type.find('BOOLEAN') == -1:\r
2067 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
52302d4d 2068\r
30fdf114
LG
2069\r
2070def CheckBooleanValueComparison(FullFileName):\r
2071 ErrorMsgList = []\r
52302d4d 2072\r
30fdf114
LG
2073 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2074 if FileID < 0:\r
2075 return ErrorMsgList\r
52302d4d 2076\r
30fdf114
LG
2077 # cache the found function return type to accelerate later checking in this file.\r
2078 FuncReturnTypeDict = {}\r
52302d4d 2079\r
30fdf114
LG
2080 Db = GetDB()\r
2081 FileTable = 'Identifier' + str(FileID)\r
2082 SqlStatement = """ select Value, StartLine, ID\r
2083 from %s\r
2084 where Model = %d\r
2085 """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION)\r
2086 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2087 if len(ResultSet) == 0:\r
2088 return\r
2089 PSL = []\r
2090 for Result in ResultSet:\r
2091 PSL.append([Result[0], Result[1], Result[2]])\r
52302d4d 2092\r
30fdf114
LG
2093 SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID\r
2094 from Function\r
2095 where BelongsToFile = %d\r
2096 """ % (FileID)\r
2097 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2098 FL = []\r
2099 for Result in ResultSet:\r
2100 FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
52302d4d 2101\r
30fdf114
LG
2102 p = GetFuncDeclPattern()\r
2103 for Str in PSL:\r
2104 FuncRecord = GetFuncContainsPE(Str[1], FL)\r
4231a819 2105 if FuncRecord is None:\r
30fdf114 2106 continue\r
52302d4d 2107\r
30fdf114
LG
2108 for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
2109 PredInfo = SplitPredicateStr(Exp)\r
2110 if PredInfo[1] in ('==', '!=') and PredInfo[0][1] in ('TRUE', 'FALSE'):\r
2111 PredVarStr = PredInfo[0][0].strip()\r
2112 IsFuncCall = False\r
2113 SearchInCache = False\r
2114 # PredVarStr may contain '.' or '->'\r
2115 TmpStr = PredVarStr.replace('.', '').replace('->', '')\r
2116 if p.match(TmpStr):\r
2117 PredVarStr = PredVarStr[0:PredVarStr.find('(')]\r
2118 SearchInCache = True\r
2119 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.\r
52302d4d 2120 if TmpStr.startswith(PredVarStr):\r
30fdf114 2121 IsFuncCall = True\r
52302d4d 2122\r
30fdf114
LG
2123 if PredVarStr.strip() in IgnoredKeywordList:\r
2124 continue\r
2125 StarList = []\r
2126 PredVarList = GetCNameList(PredVarStr, StarList)\r
2127 # No variable found, maybe value first? like (0 == VarName)\r
2128 if len(PredVarList) == 0:\r
2129 continue\r
52302d4d 2130\r
30fdf114
LG
2131 if SearchInCache:\r
2132 Type = FuncReturnTypeDict.get(PredVarStr)\r
4231a819 2133 if Type is not None:\r
30fdf114
LG
2134 if Type.find('BOOLEAN') != -1:\r
2135 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
2136 continue\r
52302d4d 2137\r
30fdf114
LG
2138 if PredVarStr in FuncReturnTypeDict:\r
2139 continue\r
52302d4d 2140\r
30fdf114
LG
2141 Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, 'BOOLEAN', StarList)\r
2142 if SearchInCache:\r
2143 FuncReturnTypeDict[PredVarStr] = Type\r
4231a819 2144 if Type is None:\r
30fdf114
LG
2145 continue\r
2146 if Type.find('BOOLEAN') != -1:\r
2147 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
52302d4d 2148\r
30fdf114 2149\r
3a244b8d 2150def CheckHeaderFileData(FullFileName, AllTypedefFun=[]):\r
30fdf114 2151 ErrorMsgList = []\r
52302d4d 2152\r
30fdf114
LG
2153 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2154 if FileID < 0:\r
2155 return ErrorMsgList\r
52302d4d 2156\r
30fdf114
LG
2157 Db = GetDB()\r
2158 FileTable = 'Identifier' + str(FileID)\r
2159 SqlStatement = """ select ID, Modifier\r
2160 from %s\r
2161 where Model = %d\r
2162 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE)\r
2163 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2164 for Result in ResultSet:\r
2165 if not Result[1].startswith('extern'):\r
3a244b8d
HC
2166 for Item in AllTypedefFun:\r
2167 if '(%s)' % Result[1] in Item:\r
2168 break\r
2169 else:\r
2170 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA, 'Variable definition appears in header file', FileTable, Result[0])\r
52302d4d 2171\r
30fdf114
LG
2172 SqlStatement = """ select ID\r
2173 from Function\r
2174 where BelongsToFile = %d\r
2175 """ % FileID\r
2176 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2177 for Result in ResultSet:\r
2178 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA, 'Function definition appears in header file', 'Function', Result[0])\r
2179\r
2180 return ErrorMsgList\r
2181\r
2182def CheckHeaderFileIfndef(FullFileName):\r
2183 ErrorMsgList = []\r
52302d4d 2184\r
30fdf114
LG
2185 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2186 if FileID < 0:\r
2187 return ErrorMsgList\r
52302d4d 2188\r
30fdf114
LG
2189 Db = GetDB()\r
2190 FileTable = 'Identifier' + str(FileID)\r
2191 SqlStatement = """ select Value, StartLine\r
2192 from %s\r
2193 where Model = %d order by StartLine\r
2194 """ % (FileTable, DataClass.MODEL_IDENTIFIER_MACRO_IFNDEF)\r
2195 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2196 if len(ResultSet) == 0:\r
2197 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_1, '', 'File', FileID)\r
2198 return ErrorMsgList\r
2199 for Result in ResultSet:\r
2200 SqlStatement = """ select Value, EndLine\r
2201 from %s\r
2202 where EndLine < %d\r
2203 """ % (FileTable, Result[1])\r
2204 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2205 for Result in ResultSet:\r
2206 if not Result[0].startswith('/*') and not Result[0].startswith('//'):\r
2207 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_2, '', 'File', FileID)\r
2208 break\r
52302d4d 2209\r
30fdf114
LG
2210 SqlStatement = """ select Value\r
2211 from %s\r
2212 where StartLine > (select max(EndLine) from %s where Model = %d)\r
2213 """ % (FileTable, FileTable, DataClass.MODEL_IDENTIFIER_MACRO_ENDIF)\r
2214 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2215 for Result in ResultSet:\r
2216 if not Result[0].startswith('/*') and not Result[0].startswith('//'):\r
2217 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_3, '', 'File', FileID)\r
2218 return ErrorMsgList\r
2219\r
2220def CheckDoxygenCommand(FullFileName):\r
2221 ErrorMsgList = []\r
52302d4d 2222\r
30fdf114
LG
2223 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2224 if FileID < 0:\r
2225 return ErrorMsgList\r
52302d4d 2226\r
30fdf114
LG
2227 Db = GetDB()\r
2228 FileTable = 'Identifier' + str(FileID)\r
2229 SqlStatement = """ select Value, ID\r
2230 from %s\r
2231 where Model = %d or Model = %d\r
2232 """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER)\r
2233 ResultSet = Db.TblFile.Exec(SqlStatement)\r
f8895c2a
HC
2234 DoxygenCommandList = ['bug', 'todo', 'example', 'file', 'attention', 'param', 'post', 'pre', 'retval',\r
2235 'return', 'sa', 'since', 'test', 'note', 'par', 'endcode', 'code']\r
30fdf114
LG
2236 for Result in ResultSet:\r
2237 CommentStr = Result[0]\r
2238 CommentPartList = CommentStr.split()\r
2239 for Part in CommentPartList:\r
2240 if Part.upper() == 'BUGBUG':\r
2241 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Bug should be marked with doxygen tag @bug', FileTable, Result[1])\r
2242 if Part.upper() == 'TODO':\r
2243 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'ToDo should be marked with doxygen tag @todo', FileTable, Result[1])\r
2244 if Part.startswith('@'):\r
2245 if EccGlobalData.gException.IsException(ERROR_DOXYGEN_CHECK_COMMAND, Part):\r
2246 continue\r
f8895c2a
HC
2247 if not Part.replace('@', '').strip():\r
2248 continue\r
2249 if Part.lstrip('@') in ['{', '}']:\r
2250 continue\r
30fdf114
LG
2251 if Part.lstrip('@').isalpha():\r
2252 if Part.lstrip('@') not in DoxygenCommandList:\r
2253 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])\r
2254 else:\r
2255 Index = Part.find('[')\r
2256 if Index == -1:\r
2257 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])\r
2258 RealCmd = Part[1:Index]\r
2259 if RealCmd not in DoxygenCommandList:\r
2260 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])\r
52302d4d
LG
2261\r
2262\r
30fdf114
LG
2263def CheckDoxygenTripleForwardSlash(FullFileName):\r
2264 ErrorMsgList = []\r
52302d4d 2265\r
30fdf114
LG
2266 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2267 if FileID < 0:\r
2268 return ErrorMsgList\r
52302d4d 2269\r
30fdf114 2270 Db = GetDB()\r
52302d4d 2271\r
30fdf114
LG
2272 SqlStatement = """ select ID, BodyStartLine, BodyStartColumn, EndLine, EndColumn\r
2273 from Function\r
2274 where BelongsToFile = %d\r
2275 """ % (FileID)\r
2276 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2277 if len(ResultSet) == 0:\r
2278 return\r
52302d4d
LG
2279\r
2280 FuncDefSet = []\r
30fdf114
LG
2281 for Result in ResultSet:\r
2282 FuncDefSet.append(Result)\r
52302d4d
LG
2283\r
2284\r
30fdf114
LG
2285 FileTable = 'Identifier' + str(FileID)\r
2286 SqlStatement = """ select Value, ID, StartLine, StartColumn, EndLine, EndColumn\r
2287 from %s\r
52302d4d
LG
2288 where Model = %d\r
2289\r
30fdf114
LG
2290 """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)\r
2291 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2292 CommentSet = []\r
2293 try:\r
2294 for Result in ResultSet:\r
2295 CommentSet.append(Result)\r
2296 except:\r
72443dd2 2297 print('Unrecognized chars in comment of file %s', FullFileName)\r
52302d4d
LG
2298\r
2299\r
30fdf114
LG
2300 for Result in CommentSet:\r
2301 CommentStr = Result[0]\r
2302 StartLine = Result[2]\r
2303 StartColumn = Result[3]\r
2304 EndLine = Result[4]\r
2305 EndColumn = Result[5]\r
2306 if not CommentStr.startswith('///<'):\r
2307 continue\r
52302d4d 2308\r
30fdf114
LG
2309 Found = False\r
2310 for FuncDef in FuncDefSet:\r
2311 if StartLine == FuncDef[1] and StartColumn > FuncDef[2] and EndLine == FuncDef[3] and EndColumn < FuncDef[4]:\r
2312 Found = True\r
2313 break\r
2314 if StartLine > FuncDef[1] and EndLine < FuncDef[3]:\r
2315 Found = True\r
2316 break\r
2317 if StartLine == FuncDef[1] and StartColumn > FuncDef[2] and EndLine < FuncDef[3]:\r
2318 Found = True\r
2319 break\r
2320 if StartLine > FuncDef[1] and EndLine == FuncDef[3] and EndColumn < FuncDef[4]:\r
2321 Found = True\r
2322 break\r
2323 if Found:\r
2324 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_FORMAT, '', FileTable, Result[1])\r
2325\r
2326\r
2327def CheckFileHeaderDoxygenComments(FullFileName):\r
2328 ErrorMsgList = []\r
52302d4d 2329\r
30fdf114
LG
2330 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2331 if FileID < 0:\r
2332 return ErrorMsgList\r
52302d4d 2333\r
30fdf114
LG
2334 Db = GetDB()\r
2335 FileTable = 'Identifier' + str(FileID)\r
2336 SqlStatement = """ select Value, ID\r
2337 from %s\r
e56468c0 2338 where Model = %d and (StartLine = 1 or StartLine = 7 or StartLine = 8) and StartColumn = 0\r
30fdf114
LG
2339 """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)\r
2340 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2341 if len(ResultSet) == 0:\r
d0acc87a 2342 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'No File License header appear at the very beginning of file.', 'File', FileID)\r
30fdf114 2343 return ErrorMsgList\r
52302d4d 2344\r
d0acc87a
LG
2345 NoHeaderCommentStartFlag = True\r
2346 NoHeaderCommentEndFlag = True\r
2347 NoHeaderCommentPeriodFlag = True\r
2348 NoCopyrightFlag = True\r
2349 NoLicenseFlag = True\r
2350 NoRevReferFlag = True\r
2351 NextLineIndex = 0\r
30fdf114 2352 for Result in ResultSet:\r
d0acc87a
LG
2353 FileStartFlag = False\r
2354 CommentStrList = []\r
e56468c0 2355 CommentStr = Result[0].strip()\r
d0acc87a
LG
2356 CommentStrListTemp = CommentStr.split('\n')\r
2357 if (len(CommentStrListTemp) <= 1):\r
2358 # For Mac\r
2359 CommentStrListTemp = CommentStr.split('\r')\r
f7496d71 2360 # Skip the content before the file header\r
d0acc87a
LG
2361 for CommentLine in CommentStrListTemp:\r
2362 if CommentLine.strip().startswith('/** @file'):\r
2363 FileStartFlag = True\r
2364 if FileStartFlag == True:\r
2365 CommentStrList.append(CommentLine)\r
f7496d71 2366\r
e56468c0 2367 ID = Result[1]\r
d0acc87a
LG
2368 Index = 0\r
2369 if CommentStrList and CommentStrList[0].strip().startswith('/** @file'):\r
2370 NoHeaderCommentStartFlag = False\r
2371 else:\r
2372 continue\r
2373 if CommentStrList and CommentStrList[-1].strip().endswith('**/'):\r
2374 NoHeaderCommentEndFlag = False\r
2375 else:\r
2376 continue\r
2377\r
2378 for CommentLine in CommentStrList:\r
2379 Index = Index + 1\r
2380 NextLineIndex = Index\r
2381 if CommentLine.startswith('/** @file'):\r
2382 continue\r
2383 if CommentLine.startswith('**/'):\r
2384 break\r
2385 # Check whether C File header Comment content start with two spaces.\r
2386 if EccGlobalData.gConfig.HeaderCheckCFileCommentStartSpacesNum == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
2387 if CommentLine.startswith('/** @file') == False and CommentLine.startswith('**/') == False and CommentLine.strip() and CommentLine.startswith(' ') == False:\r
2388 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment content should start with two spaces at each line', FileTable, ID)\r
f7496d71 2389\r
d0acc87a
LG
2390 CommentLine = CommentLine.strip()\r
2391 if CommentLine.startswith('Copyright'):\r
2392 NoCopyrightFlag = False\r
2393 if CommentLine.find('All rights reserved') == -1:\r
d77cc206
HC
2394 for Copyright in EccGlobalData.gConfig.Copyright:\r
2395 if CommentLine.find(Copyright) > -1:\r
2396 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, '""All rights reserved"" announcement should be following the ""Copyright"" at the same line', FileTable, ID)\r
2397 break\r
d0acc87a
LG
2398 if CommentLine.endswith('<BR>') == -1:\r
2399 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'The ""<BR>"" at the end of the Copyright line is required', FileTable, ID)\r
2400 if NextLineIndex < len(CommentStrList) and CommentStrList[NextLineIndex].strip().startswith('Copyright') == False and CommentStrList[NextLineIndex].strip():\r
2401 NoLicenseFlag = False\r
2402 if CommentLine.startswith('@par Revision Reference:'):\r
2403 NoRevReferFlag = False\r
2404 RefListFlag = False\r
2405 for RefLine in CommentStrList[NextLineIndex:]:\r
2406 if RefLine.strip() and (NextLineIndex + 1) < len(CommentStrList) and CommentStrList[NextLineIndex+1].strip() and CommentStrList[NextLineIndex+1].strip().startswith('**/') == False:\r
2407 RefListFlag = True\r
2408 if RefLine.strip() == False or RefLine.strip().startswith('**/'):\r
2409 RefListFlag = False\r
2410 break\r
2411 # Check whether C File header Comment's each reference at list should begin with a bullet character.\r
2412 if EccGlobalData.gConfig.HeaderCheckCFileCommentReferenceFormat == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
2413 if RefListFlag == True:\r
f7496d71
LG
2414 if RefLine.strip() and RefLine.strip().startswith('**/') == False and RefLine.startswith(' -') == False:\r
2415 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'Each reference on a separate line should begin with a bullet character ""-"" ', FileTable, ID)\r
2416\r
d0acc87a 2417 if NoHeaderCommentStartFlag:\r
e56468c0 2418 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FILE_HEADER, 'File header comment should begin with ""/** @file""', FileTable, ID)\r
d0acc87a
LG
2419 return\r
2420 if NoHeaderCommentEndFlag:\r
e56468c0 2421 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should end with ""**/""', FileTable, ID)\r
d0acc87a
LG
2422 return\r
2423 if NoCopyrightFlag:\r
2424 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment missing the ""Copyright""', FileTable, ID)\r
2425 #Check whether C File header Comment have the License immediately after the ""Copyright"" line.\r
2426 if EccGlobalData.gConfig.HeaderCheckCFileCommentLicenseFormat == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
2427 if NoLicenseFlag:\r
2428 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should have the License immediately after the ""Copyright"" line', FileTable, ID)\r
30fdf114
LG
2429\r
2430def CheckFuncHeaderDoxygenComments(FullFileName):\r
2431 ErrorMsgList = []\r
52302d4d 2432\r
30fdf114
LG
2433 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2434 if FileID < 0:\r
2435 return ErrorMsgList\r
52302d4d 2436\r
30fdf114
LG
2437 Db = GetDB()\r
2438 FileTable = 'Identifier' + str(FileID)\r
2439 SqlStatement = """ select Value, StartLine, EndLine, ID\r
2440 from %s\r
2441 where Model = %d\r
2442 """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)\r
52302d4d 2443\r
30fdf114
LG
2444 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2445 CommentSet = []\r
2446 try:\r
2447 for Result in ResultSet:\r
2448 CommentSet.append(Result)\r
2449 except:\r
72443dd2 2450 print('Unrecognized chars in comment of file %s', FullFileName)\r
52302d4d 2451\r
30fdf114
LG
2452 # Func Decl check\r
2453 SqlStatement = """ select Modifier, Name, StartLine, ID, Value\r
2454 from %s\r
2455 where Model = %d\r
2456 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
2457 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2458 for Result in ResultSet:\r
2459 FuncName = Result[4]\r
2460 FunctionHeaderComment = CheckCommentImmediatelyPrecedeFunctionHeader(Result[1], Result[2], CommentSet)\r
2461 if FunctionHeaderComment:\r
2462 CheckFunctionHeaderConsistentWithDoxygenComment(Result[0], Result[1], Result[2], FunctionHeaderComment[0], FunctionHeaderComment[1], ErrorMsgList, FunctionHeaderComment[3], FileTable)\r
2463 else:\r
2464 if EccGlobalData.gException.IsException(ERROR_HEADER_CHECK_FUNCTION, FuncName):\r
2465 continue\r
2466 ErrorMsgList.append('Line %d :Function %s has NO comment immediately preceding it.' % (Result[2], Result[1]))\r
2467 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'Function [%s] has NO comment immediately preceding it.' % (FuncName), FileTable, Result[3])\r
52302d4d 2468\r
30fdf114
LG
2469 # Func Def check\r
2470 SqlStatement = """ select Value, StartLine, EndLine, ID\r
2471 from %s\r
2472 where Model = %d\r
2473 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER)\r
52302d4d 2474\r
30fdf114
LG
2475 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2476 CommentSet = []\r
2477 try:\r
2478 for Result in ResultSet:\r
2479 CommentSet.append(Result)\r
2480 except:\r
72443dd2 2481 print('Unrecognized chars in comment of file %s', FullFileName)\r
52302d4d 2482\r
30fdf114
LG
2483 SqlStatement = """ select Modifier, Header, StartLine, ID, Name\r
2484 from Function\r
2485 where BelongsToFile = %d\r
2486 """ % (FileID)\r
2487 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2488 for Result in ResultSet:\r
2489 FuncName = Result[4]\r
2490 FunctionHeaderComment = CheckCommentImmediatelyPrecedeFunctionHeader(Result[1], Result[2], CommentSet)\r
2491 if FunctionHeaderComment:\r
2492 CheckFunctionHeaderConsistentWithDoxygenComment(Result[0], Result[1], Result[2], FunctionHeaderComment[0], FunctionHeaderComment[1], ErrorMsgList, FunctionHeaderComment[3], FileTable)\r
2493 else:\r
2494 if EccGlobalData.gException.IsException(ERROR_HEADER_CHECK_FUNCTION, FuncName):\r
2495 continue\r
2496 ErrorMsgList.append('Line %d :Function [%s] has NO comment immediately preceding it.' % (Result[2], Result[1]))\r
2497 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'Function [%s] has NO comment immediately preceding it.' % (FuncName), 'Function', Result[3])\r
2498 return ErrorMsgList\r
2499\r
2500def CheckCommentImmediatelyPrecedeFunctionHeader(FuncName, FuncStartLine, CommentSet):\r
2501\r
2502 for Comment in CommentSet:\r
2503 if Comment[2] == FuncStartLine - 1:\r
2504 return Comment\r
2505 return None\r
2506\r
2507def GetDoxygenStrFromComment(Str):\r
2508 DoxygenStrList = []\r
2509 ParamTagList = Str.split('@param')\r
2510 if len(ParamTagList) > 1:\r
2511 i = 1\r
2512 while i < len(ParamTagList):\r
2513 DoxygenStrList.append('@param' + ParamTagList[i])\r
2514 i += 1\r
52302d4d 2515\r
30fdf114 2516 Str = ParamTagList[0]\r
52302d4d 2517\r
30fdf114
LG
2518 RetvalTagList = ParamTagList[-1].split('@retval')\r
2519 if len(RetvalTagList) > 1:\r
2520 if len(ParamTagList) > 1:\r
2521 DoxygenStrList[-1] = '@param' + RetvalTagList[0]\r
2522 i = 1\r
2523 while i < len(RetvalTagList):\r
2524 DoxygenStrList.append('@retval' + RetvalTagList[i])\r
2525 i += 1\r
52302d4d 2526\r
30fdf114
LG
2527 ReturnTagList = RetvalTagList[-1].split('@return')\r
2528 if len(ReturnTagList) > 1:\r
2529 if len(RetvalTagList) > 1:\r
2530 DoxygenStrList[-1] = '@retval' + ReturnTagList[0]\r
2531 elif len(ParamTagList) > 1:\r
2532 DoxygenStrList[-1] = '@param' + ReturnTagList[0]\r
2533 i = 1\r
2534 while i < len(ReturnTagList):\r
2535 DoxygenStrList.append('@return' + ReturnTagList[i])\r
2536 i += 1\r
52302d4d 2537\r
30fdf114
LG
2538 if len(DoxygenStrList) > 0:\r
2539 DoxygenStrList[-1] = DoxygenStrList[-1].rstrip('--*/')\r
52302d4d 2540\r
30fdf114 2541 return DoxygenStrList\r
52302d4d 2542\r
79b74a03 2543def CheckGeneralDoxygenCommentLayout(Str, StartLine, ErrorMsgList, CommentId= -1, TableName=''):\r
30fdf114
LG
2544 #/** --*/ @retval after @param\r
2545 if not Str.startswith('/**'):\r
2546 ErrorMsgList.append('Line %d : Comment does NOT have prefix /** ' % StartLine)\r
2547 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Comment does NOT have prefix /** ', TableName, CommentId)\r
2548 if not Str.endswith('**/'):\r
2549 ErrorMsgList.append('Line %d : Comment does NOT have tail **/ ' % StartLine)\r
2550 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Comment does NOT have tail **/ ', TableName, CommentId)\r
2551 FirstRetvalIndex = Str.find('@retval')\r
2552 LastParamIndex = Str.rfind('@param')\r
2553 if (FirstRetvalIndex > 0) and (LastParamIndex > 0) and (FirstRetvalIndex < LastParamIndex):\r
2554 ErrorMsgList.append('Line %d : @retval appear before @param ' % StartLine)\r
2555 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, @retval appear before @param ', TableName, CommentId)\r
52302d4d 2556\r
79b74a03 2557def CheckFunctionHeaderConsistentWithDoxygenComment(FuncModifier, FuncHeader, FuncStartLine, CommentStr, CommentStartLine, ErrorMsgList, CommentId= -1, TableName=''):\r
52302d4d
LG
2558\r
2559 ParamList = GetParamList(FuncHeader)\r
30fdf114
LG
2560 CheckGeneralDoxygenCommentLayout(CommentStr, CommentStartLine, ErrorMsgList, CommentId, TableName)\r
2561 DescriptionStr = CommentStr\r
2562 DoxygenStrList = GetDoxygenStrFromComment(DescriptionStr)\r
2563 if DescriptionStr.find('.') == -1:\r
2564 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION, 'Comment description should end with period \'.\'', TableName, CommentId)\r
2565 DoxygenTagNumber = len(DoxygenStrList)\r
2566 ParamNumber = len(ParamList)\r
2567 for Param in ParamList:\r
2568 if Param.Name.upper() == 'VOID' and ParamNumber == 1:\r
2569 ParamNumber -= 1\r
2570 Index = 0\r
2571 if ParamNumber > 0 and DoxygenTagNumber > 0:\r
2572 while Index < ParamNumber and Index < DoxygenTagNumber:\r
2573 ParamModifier = ParamList[Index].Modifier\r
2574 ParamName = ParamList[Index].Name.strip()\r
2575 Tag = DoxygenStrList[Index].strip(' ')\r
2576 if (not Tag[-1] == ('\n')) and (not Tag[-1] == ('\r')):\r
79b74a03
LG
2577 ErrorMsgList.append('Line %d : in Comment, <%s> does NOT end with new line ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', '')))\r
2578 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'in Comment, <%s> does NOT end with new line ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId)\r
30fdf114
LG
2579 TagPartList = Tag.split()\r
2580 if len(TagPartList) < 2:\r
79b74a03
LG
2581 ErrorMsgList.append('Line %d : in Comment, <%s> does NOT contain doxygen contents ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', '')))\r
2582 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT contain doxygen contents ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId)\r
30fdf114
LG
2583 Index += 1\r
2584 continue\r
2585 LBPos = Tag.find('[')\r
2586 RBPos = Tag.find(']')\r
2587 ParamToLBContent = Tag[len('@param'):LBPos].strip()\r
79b74a03 2588 if LBPos > 0 and len(ParamToLBContent) == 0 and RBPos > LBPos:\r
30fdf114
LG
2589 InOutStr = ''\r
2590 ModifierPartList = ParamModifier.split()\r
2591 for Part in ModifierPartList:\r
2592 if Part.strip() == 'IN':\r
2593 InOutStr += 'in'\r
2594 if Part.strip() == 'OUT':\r
52302d4d 2595 if InOutStr != '':\r
30fdf114
LG
2596 InOutStr += ', out'\r
2597 else:\r
2598 InOutStr = 'out'\r
52302d4d 2599\r
30fdf114 2600 if InOutStr != '':\r
79b74a03
LG
2601 if Tag.find('[' + InOutStr + ']') == -1:\r
2602 if InOutStr != 'in, out':\r
2603 ErrorMsgList.append('Line %d : in Comment, <%s> does NOT have %s ' % (CommentStartLine, (TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'))\r
2604 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT have %s ' % ((TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'), TableName, CommentId)\r
2605 else:\r
2606 if Tag.find('[in,out]') == -1:\r
2607 ErrorMsgList.append('Line %d : in Comment, <%s> does NOT have %s ' % (CommentStartLine, (TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'))\r
2608 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT have %s ' % ((TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'), TableName, CommentId)\r
2609\r
2610\r
30fdf114 2611 if Tag.find(ParamName) == -1 and ParamName != 'VOID' and ParamName != 'void':\r
79b74a03
LG
2612 ErrorMsgList.append('Line %d : in Comment, <%s> does NOT consistent with parameter name %s ' % (CommentStartLine, (TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), ParamName))\r
2613 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT consistent with parameter name %s ' % ((TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), ParamName), TableName, CommentId)\r
30fdf114 2614 Index += 1\r
52302d4d 2615\r
30fdf114
LG
2616 if Index < ParamNumber:\r
2617 ErrorMsgList.append('Line %d : Number of doxygen tags in comment less than number of function parameters' % CommentStartLine)\r
2618 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Number of doxygen tags in comment less than number of function parameters ', TableName, CommentId)\r
2619 # VOID return type, NOT VOID*. VOID* should be matched with a doxygen tag.\r
2620 if (FuncModifier.find('VOID') != -1 or FuncModifier.find('void') != -1) and FuncModifier.find('*') == -1:\r
52302d4d 2621\r
30fdf114
LG
2622 # assume we allow a return description tag for void func. return. that's why 'DoxygenTagNumber - 1' is used instead of 'DoxygenTagNumber'\r
2623 if Index < DoxygenTagNumber - 1 or (Index < DoxygenTagNumber and DoxygenStrList[Index].startswith('@retval')):\r
2624 ErrorMsgList.append('Line %d : VOID return type need NO doxygen tags in comment' % CommentStartLine)\r
2625 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'VOID return type need no doxygen tags in comment ', TableName, CommentId)\r
2626 else:\r
52302d4d 2627 if Index < DoxygenTagNumber and not DoxygenStrList[Index].startswith('@retval') and not DoxygenStrList[Index].startswith('@return'):\r
30fdf114
LG
2628 ErrorMsgList.append('Line %d : Number of @param doxygen tags in comment does NOT match number of function parameters' % CommentStartLine)\r
2629 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Number of @param doxygen tags in comment does NOT match number of function parameters ', TableName, CommentId)\r
2630 else:\r
2631 if ParamNumber == 0 and DoxygenTagNumber != 0 and ((FuncModifier.find('VOID') != -1 or FuncModifier.find('void') != -1) and FuncModifier.find('*') == -1):\r
2632 ErrorMsgList.append('Line %d : VOID return type need NO doxygen tags in comment' % CommentStartLine)\r
2633 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'VOID return type need NO doxygen tags in comment ', TableName, CommentId)\r
2634 if ParamNumber != 0 and DoxygenTagNumber == 0:\r
2635 ErrorMsgList.append('Line %d : No doxygen tags in comment' % CommentStartLine)\r
2636 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'No doxygen tags in comment ', TableName, CommentId)\r
2637\r
2638if __name__ == '__main__':\r
2639\r
2640# EdkLogger.Initialize()\r
2641# EdkLogger.SetLevel(EdkLogger.QUIET)\r
52302d4d 2642# CollectSourceCodeDataIntoDB(sys.argv[1])\r
b36d134f
LG
2643 try:\r
2644 test_file = sys.argv[1]\r
5b0671c1 2645 except IndexError as v:\r
72443dd2 2646 print("Usage: %s filename" % sys.argv[0])\r
b36d134f
LG
2647 sys.exit(1)\r
2648 MsgList = CheckFuncHeaderDoxygenComments(test_file)\r
30fdf114 2649 for Msg in MsgList:\r
72443dd2
GL
2650 print(Msg)\r
2651 print('Done!')\r