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