]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Ecc/c.py
BaseTools: Various typo
[mirror_edk2.git] / BaseTools / Source / Python / Ecc / c.py
CommitLineData
52302d4d
LG
1## @file\r
2# This file is used to be the c coding style checking of ECC tool\r
3#\r
ce3bfbec 4# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>\r
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
855698fb 20from Ecc import CodeFragmentCollector\r
21from Ecc import FileProfile\r
30fdf114 22from CommonDataClass import DataClass\r
855698fb 23from Ecc import Database\r
30fdf114 24from Common import EdkLogger\r
855698fb 25from Ecc.EccToolError import *\r
26from Ecc import EccGlobalData\r
27from Ecc 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
c60377d7 38 DirString = '|'.join(skipList)\r
30fdf114
LG
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
fb0b35e0 736 # maybe type-cast at the beginning, skip it.\r
30fdf114
LG
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
fb0b35e0 837 # remove array suffix\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
c60377d7 966 elif ListFromStr[Index] == '/' and ListFromStr[Index + 1] == '/':\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
fb0b35e0 1022 # For the condition that the field in struct is an array with [] suffixes...\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
c60377d7 1300 Index = Result0.find(TypeStart)\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
ce3bfbec 1514 SqlStatement = """ select BodyStartColumn, EndColumn, ID, Name\r
30fdf114
LG
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
ce3bfbec
HC
1523 if not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, Result[3]):\r
1524 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY,\r
1525 'The open brace should be at the very beginning of a line for the function [%s].' % Result[3],\r
1526 'Function', Result[2])\r
30fdf114 1527 if Result[1] != 0:\r
ce3bfbec
HC
1528 if not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, Result[3]):\r
1529 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY,\r
1530 'The close brace should be at the very beginning of a line for the function [%s].' % Result[3],\r
1531 'Function', Result[2])\r
30fdf114
LG
1532\r
1533def CheckFuncLayoutLocalVariable(FullFileName):\r
1534 ErrorMsgList = []\r
52302d4d 1535\r
30fdf114
LG
1536 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1537 if FileID < 0:\r
1538 return ErrorMsgList\r
52302d4d 1539\r
30fdf114
LG
1540 Db = GetDB()\r
1541 FileTable = 'Identifier' + str(FileID)\r
1542 SqlStatement = """ select ID\r
1543 from Function\r
1544 where BelongsToFile = %d\r
1545 """ % (FileID)\r
1546 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1547 if len(ResultSet) == 0:\r
1548 return ErrorMsgList\r
1549 FL = []\r
1550 for Result in ResultSet:\r
1551 FL.append(Result)\r
52302d4d 1552\r
30fdf114 1553 for F in FL:\r
79b74a03 1554 SqlStatement = """ select Name, Value, ID, Modifier\r
30fdf114
LG
1555 from %s\r
1556 where Model = %d and BelongsToFunction = %d\r
1557 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, F[0])\r
1558 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1559 if len(ResultSet) == 0:\r
1560 continue\r
52302d4d 1561\r
30fdf114 1562 for Result in ResultSet:\r
79b74a03 1563 if len(Result[1]) > 0 and 'CONST' not in Result[3]:\r
30fdf114 1564 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE, 'Variable Name: %s' % Result[0], FileTable, Result[2])\r
52302d4d 1565\r
30fdf114
LG
1566def CheckMemberVariableFormat(Name, Value, FileTable, TdId, ModelId):\r
1567 ErrMsgList = []\r
1568 # Member variable format pattern.\r
1569 Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')\r
52302d4d 1570\r
30fdf114
LG
1571 LBPos = Value.find('{')\r
1572 RBPos = Value.rfind('}')\r
1573 if LBPos == -1 or RBPos == -1:\r
1574 return ErrMsgList\r
52302d4d 1575\r
30fdf114
LG
1576 Fields = Value[LBPos + 1 : RBPos]\r
1577 Fields = StripComments(Fields).strip()\r
1578 NestPos = Fields.find ('struct')\r
f8895c2a 1579 if NestPos != -1 and (NestPos + len('struct') < len(Fields)) and ModelId != DataClass.MODEL_IDENTIFIER_UNION:\r
30fdf114
LG
1580 if not Fields[NestPos + len('struct') + 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 struct in [%s].' % (Name), FileTable, TdId)\r
1583 return ErrMsgList\r
1584 NestPos = Fields.find ('union')\r
1585 if NestPos != -1 and (NestPos + len('union') < len(Fields)):\r
1586 if not Fields[NestPos + len('union') + 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 union in [%s].' % (Name), FileTable, TdId)\r
1589 return ErrMsgList\r
1590 NestPos = Fields.find ('enum')\r
1591 if NestPos != -1 and (NestPos + len('enum') < len(Fields)):\r
1592 if not Fields[NestPos + len('enum') + 1].isalnum():\r
1593 if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name):\r
1594 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested enum in [%s].' % (Name), FileTable, TdId)\r
1595 return ErrMsgList\r
52302d4d 1596\r
30fdf114
LG
1597 if ModelId == DataClass.MODEL_IDENTIFIER_ENUMERATE:\r
1598 FieldsList = Fields.split(',')\r
1599 # deal with enum is pre-assigned a value by function call ( , , , ...)\r
1600 QuoteCount = 0\r
1601 Index = 0\r
1602 RemoveCurrentElement = False\r
1603 while Index < len(FieldsList):\r
1604 Field = FieldsList[Index]\r
52302d4d 1605\r
30fdf114
LG
1606 if Field.find('(') != -1:\r
1607 QuoteCount += 1\r
1608 RemoveCurrentElement = True\r
1609 Index += 1\r
1610 continue\r
52302d4d 1611\r
30fdf114
LG
1612 if Field.find(')') != -1 and QuoteCount > 0:\r
1613 QuoteCount -= 1\r
1614\r
52302d4d 1615 if RemoveCurrentElement:\r
30fdf114
LG
1616 FieldsList.remove(Field)\r
1617 if QuoteCount == 0:\r
1618 RemoveCurrentElement = False\r
1619 continue\r
52302d4d 1620\r
30fdf114
LG
1621 if QuoteCount == 0:\r
1622 RemoveCurrentElement = False\r
52302d4d 1623\r
30fdf114
LG
1624 Index += 1\r
1625 else:\r
1626 FieldsList = Fields.split(';')\r
52302d4d 1627\r
30fdf114
LG
1628 for Field in FieldsList:\r
1629 Field = Field.strip()\r
1630 if Field == '':\r
1631 continue\r
fb0b35e0 1632 # For the condition that the field in struct is an array with [] suffixes...\r
30fdf114
LG
1633 if Field[-1] == ']':\r
1634 LBPos = Field.find('[')\r
1635 Field = Field[0:LBPos]\r
1636 # For the condition that bit field ": Number"\r
1637 if Field.find(':') != -1:\r
1638 ColonPos = Field.find(':')\r
1639 Field = Field[0:ColonPos]\r
52302d4d 1640\r
30fdf114
LG
1641 Field = Field.strip()\r
1642 if Field == '':\r
1643 continue\r
00261e1d
HC
1644 if Field.startswith("#"):\r
1645 continue\r
30fdf114
LG
1646 # Enum could directly assign value to variable\r
1647 Field = Field.split('=')[0].strip()\r
52302d4d 1648 TokenList = Field.split()\r
30fdf114 1649 # Remove pointers before variable\r
fa3a2156
HC
1650 Token = TokenList[-1]\r
1651 if Token in ['OPTIONAL']:\r
1652 Token = TokenList[-2]\r
1653 if not Pattern.match(Token.lstrip('*')):\r
1654 ErrMsgList.append(Token.lstrip('*'))\r
52302d4d 1655\r
30fdf114
LG
1656 return ErrMsgList\r
1657\r
1658def CheckDeclTypedefFormat(FullFileName, ModelId):\r
1659 ErrorMsgList = []\r
52302d4d 1660\r
30fdf114
LG
1661 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1662 if FileID < 0:\r
1663 return ErrorMsgList\r
52302d4d 1664\r
30fdf114
LG
1665 Db = GetDB()\r
1666 FileTable = 'Identifier' + str(FileID)\r
1667 SqlStatement = """ select Name, StartLine, EndLine, ID, Value\r
1668 from %s\r
1669 where Model = %d\r
1670 """ % (FileTable, ModelId)\r
1671 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1672 ResultList = []\r
1673 for Result in ResultSet:\r
1674 ResultList.append(Result)\r
52302d4d 1675\r
30fdf114
LG
1676 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_ALL\r
1677 if ModelId == DataClass.MODEL_IDENTIFIER_STRUCTURE:\r
1678 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_STRUCTURE_DECLARATION\r
1679 elif ModelId == DataClass.MODEL_IDENTIFIER_ENUMERATE:\r
1680 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_ENUMERATED_TYPE\r
1681 elif ModelId == DataClass.MODEL_IDENTIFIER_UNION:\r
1682 ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_UNION_TYPE\r
52302d4d 1683\r
30fdf114
LG
1684 SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID\r
1685 from %s\r
1686 where Model = %d\r
1687 """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
1688 TdSet = Db.TblFile.Exec(SqlStatement)\r
1689 TdList = []\r
1690 for Td in TdSet:\r
1691 TdList.append(Td)\r
1692 # Check member variable name format that from typedefs of ONLY this file.\r
1693 for Td in TdList:\r
1694 Name = Td[1].strip()\r
1695 Value = Td[2].strip()\r
1696 if Value.startswith('enum'):\r
1697 ValueModelId = DataClass.MODEL_IDENTIFIER_ENUMERATE\r
1698 elif Value.startswith('struct'):\r
1699 ValueModelId = DataClass.MODEL_IDENTIFIER_STRUCTURE\r
1700 elif Value.startswith('union'):\r
1701 ValueModelId = DataClass.MODEL_IDENTIFIER_UNION\r
1702 else:\r
1703 continue\r
52302d4d 1704\r
30fdf114
LG
1705 if ValueModelId != ModelId:\r
1706 continue\r
1707 # Check member variable format.\r
1708 ErrMsgList = CheckMemberVariableFormat(Name, Value, FileTable, Td[5], ModelId)\r
1709 for ErrMsg in ErrMsgList:\r
79b74a03 1710 if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Name + '.' + ErrMsg):\r
30fdf114 1711 continue\r
79b74a03 1712 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Name + '.' + ErrMsg), FileTable, Td[5])\r
52302d4d 1713\r
30fdf114
LG
1714 # First check in current file to see whether struct/union/enum is typedef-ed.\r
1715 UntypedefedList = []\r
1716 for Result in ResultList:\r
1717 # Check member variable format.\r
1718 Name = Result[0].strip()\r
1719 Value = Result[4].strip()\r
1720 if Value.startswith('enum'):\r
1721 ValueModelId = DataClass.MODEL_IDENTIFIER_ENUMERATE\r
1722 elif Value.startswith('struct'):\r
1723 ValueModelId = DataClass.MODEL_IDENTIFIER_STRUCTURE\r
1724 elif Value.startswith('union'):\r
1725 ValueModelId = DataClass.MODEL_IDENTIFIER_UNION\r
1726 else:\r
1727 continue\r
52302d4d 1728\r
30fdf114
LG
1729 if ValueModelId != ModelId:\r
1730 continue\r
1731 ErrMsgList = CheckMemberVariableFormat(Name, Value, FileTable, Result[3], ModelId)\r
1732 for ErrMsg in ErrMsgList:\r
79b74a03 1733 if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Result[0] + '.' + ErrMsg):\r
30fdf114 1734 continue\r
79b74a03 1735 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Result[0] + '.' + ErrMsg), FileTable, Result[3])\r
30fdf114
LG
1736 # Check whether it is typedefed.\r
1737 Found = False\r
1738 for Td in TdList:\r
1739 # skip function pointer\r
1740 if len(Td[0]) > 0:\r
1741 continue\r
1742 if Result[1] >= Td[3] and Td[4] >= Result[2]:\r
1743 Found = True\r
1744 if not Td[1].isupper():\r
1745 PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
1746 if Result[0] in Td[2].split():\r
1747 Found = True\r
1748 if not Td[1].isupper():\r
1749 PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
1750 if Found:\r
1751 break\r
52302d4d 1752\r
30fdf114
LG
1753 if not Found:\r
1754 UntypedefedList.append(Result)\r
1755 continue\r
52302d4d 1756\r
30fdf114
LG
1757 if len(UntypedefedList) == 0:\r
1758 return\r
52302d4d 1759\r
30fdf114
LG
1760 IncludeFileList = GetAllIncludeFiles(FullFileName)\r
1761 TdList = []\r
1762 for F in IncludeFileList:\r
1763 FileID = GetTableID(F, ErrorMsgList)\r
1764 if FileID < 0:\r
1765 continue\r
52302d4d 1766\r
30fdf114
LG
1767 IncludeFileTable = 'Identifier' + str(FileID)\r
1768 SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID\r
1769 from %s\r
1770 where Model = %d\r
1771 """ % (IncludeFileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF)\r
1772 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1773 TdList.extend(ResultSet)\r
52302d4d 1774\r
30fdf114 1775 for Result in UntypedefedList:\r
52302d4d 1776\r
30fdf114
LG
1777 # Check whether it is typedefed.\r
1778 Found = False\r
1779 for Td in TdList:\r
52302d4d 1780\r
30fdf114
LG
1781 if len(Td[0]) > 0:\r
1782 continue\r
1783 if Result[1] >= Td[3] and Td[4] >= Result[2]:\r
1784 Found = True\r
1785 if not Td[1].isupper():\r
1786 PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
1787 if Result[0] in Td[2].split():\r
1788 Found = True\r
1789 if not Td[1].isupper():\r
1790 PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5])\r
1791 if Found:\r
1792 break\r
52302d4d 1793\r
30fdf114
LG
1794 if not Found:\r
1795 PrintErrorMsg(ErrorType, 'No Typedef for %s' % Result[0], FileTable, Result[3])\r
1796 continue\r
52302d4d 1797\r
30fdf114
LG
1798def CheckDeclStructTypedef(FullFileName):\r
1799 CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_STRUCTURE)\r
1800\r
1801def CheckDeclEnumTypedef(FullFileName):\r
1802 CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_ENUMERATE)\r
52302d4d 1803\r
30fdf114
LG
1804def CheckDeclUnionTypedef(FullFileName):\r
1805 CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_UNION)\r
1806\r
1807def CheckDeclArgModifier(FullFileName):\r
1808 ErrorMsgList = []\r
52302d4d 1809\r
30fdf114
LG
1810 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1811 if FileID < 0:\r
1812 return ErrorMsgList\r
52302d4d 1813\r
30fdf114
LG
1814 Db = GetDB()\r
1815 FileTable = 'Identifier' + str(FileID)\r
1816 SqlStatement = """ select Modifier, Name, ID\r
1817 from %s\r
1818 where Model = %d\r
1819 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE)\r
1820 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1821 ModifierTuple = ('IN', 'OUT', 'OPTIONAL', 'UNALIGNED')\r
1822 MAX_MODIFIER_LENGTH = 100\r
1823 for Result in ResultSet:\r
1824 for Modifier in ModifierTuple:\r
1825 if PatternInModifier(Result[0], Modifier) and len(Result[0]) < MAX_MODIFIER_LENGTH:\r
1826 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Variable Modifier %s' % Result[0], FileTable, Result[2])\r
1827 break\r
52302d4d 1828\r
30fdf114
LG
1829 SqlStatement = """ select Modifier, Name, ID\r
1830 from %s\r
1831 where Model = %d\r
1832 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1833 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1834 for Result in ResultSet:\r
1835 for Modifier in ModifierTuple:\r
1836 if PatternInModifier(Result[0], Modifier):\r
1837 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Return Type Modifier %s' % Result[0], FileTable, Result[2])\r
1838 break\r
52302d4d 1839\r
30fdf114
LG
1840 SqlStatement = """ select Modifier, Header, ID\r
1841 from Function\r
1842 where BelongsToFile = %d\r
1843 """ % (FileID)\r
1844 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1845 for Result in ResultSet:\r
1846 for Modifier in ModifierTuple:\r
1847 if PatternInModifier(Result[0], Modifier):\r
1848 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Return Type Modifier %s' % Result[0], FileTable, Result[2])\r
1849 break\r
1850\r
1851def CheckDeclNoUseCType(FullFileName):\r
1852 ErrorMsgList = []\r
52302d4d 1853\r
30fdf114
LG
1854 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1855 if FileID < 0:\r
1856 return ErrorMsgList\r
52302d4d 1857\r
30fdf114
LG
1858 Db = GetDB()\r
1859 FileTable = 'Identifier' + str(FileID)\r
1860 SqlStatement = """ select Modifier, Name, ID\r
1861 from %s\r
1862 where Model = %d\r
1863 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE)\r
1864 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1865 CTypeTuple = ('int', 'unsigned', 'char', 'void', 'static', 'long')\r
1866 for Result in ResultSet:\r
1867 for Type in CTypeTuple:\r
1868 if PatternInModifier(Result[0], Type):\r
dbc85eb9
HC
1869 if EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE,\r
1870 Result[0] + ' ' + Result[1]):\r
1871 continue\r
1872 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE,\r
1873 'Invalid variable type (%s) in definition [%s]' % (Type, Result[0] + ' ' + Result[1]),\r
1874 FileTable,\r
1875 Result[2])\r
30fdf114 1876 break\r
52302d4d 1877\r
30fdf114
LG
1878 SqlStatement = """ select Modifier, Name, ID, Value\r
1879 from %s\r
1880 where Model = %d\r
1881 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
1882 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1883 for Result in ResultSet:\r
1884 ParamList = GetParamList(Result[1])\r
1885 FuncName = Result[3]\r
1886 if EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, FuncName):\r
1887 continue\r
1888 for Type in CTypeTuple:\r
1889 if PatternInModifier(Result[0], Type):\r
1890 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, '%s Return type %s' % (FuncName, Result[0]), FileTable, Result[2])\r
52302d4d 1891\r
30fdf114
LG
1892 for Param in ParamList:\r
1893 if PatternInModifier(Param.Modifier, Type):\r
1894 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Parameter %s' % Param.Name, FileTable, Result[2])\r
52302d4d 1895\r
30fdf114
LG
1896 SqlStatement = """ select Modifier, Header, ID, Name\r
1897 from Function\r
1898 where BelongsToFile = %d\r
1899 """ % (FileID)\r
1900 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1901 for Result in ResultSet:\r
1902 ParamList = GetParamList(Result[1])\r
1903 FuncName = Result[3]\r
1904 if EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, FuncName):\r
1905 continue\r
1906 for Type in CTypeTuple:\r
1907 if PatternInModifier(Result[0], Type):\r
1908 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, '[%s] Return type %s' % (FuncName, Result[0]), FileTable, Result[2])\r
52302d4d 1909\r
30fdf114
LG
1910 for Param in ParamList:\r
1911 if PatternInModifier(Param.Modifier, Type):\r
1912 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Parameter %s' % Param.Name, FileTable, Result[2])\r
52302d4d 1913\r
30fdf114
LG
1914\r
1915def CheckPointerNullComparison(FullFileName):\r
1916 ErrorMsgList = []\r
52302d4d 1917\r
30fdf114
LG
1918 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1919 if FileID < 0:\r
1920 return ErrorMsgList\r
52302d4d 1921\r
30fdf114
LG
1922 # cache the found function return type to accelerate later checking in this file.\r
1923 FuncReturnTypeDict = {}\r
52302d4d 1924\r
30fdf114
LG
1925 Db = GetDB()\r
1926 FileTable = 'Identifier' + str(FileID)\r
1927 SqlStatement = """ select Value, StartLine, ID\r
1928 from %s\r
1929 where Model = %d\r
1930 """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION)\r
1931 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1932 if len(ResultSet) == 0:\r
1933 return\r
1934 PSL = []\r
1935 for Result in ResultSet:\r
1936 PSL.append([Result[0], Result[1], Result[2]])\r
52302d4d 1937\r
30fdf114
LG
1938 SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID\r
1939 from Function\r
1940 where BelongsToFile = %d\r
1941 """ % (FileID)\r
1942 ResultSet = Db.TblFile.Exec(SqlStatement)\r
1943 FL = []\r
1944 for Result in ResultSet:\r
1945 FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
52302d4d 1946\r
30fdf114
LG
1947 p = GetFuncDeclPattern()\r
1948 for Str in PSL:\r
1949 FuncRecord = GetFuncContainsPE(Str[1], FL)\r
4231a819 1950 if FuncRecord is None:\r
30fdf114 1951 continue\r
52302d4d 1952\r
30fdf114
LG
1953 for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
1954 PredInfo = SplitPredicateStr(Exp)\r
4231a819 1955 if PredInfo[1] is None:\r
30fdf114
LG
1956 PredVarStr = PredInfo[0][0].strip()\r
1957 IsFuncCall = False\r
1958 SearchInCache = False\r
1959 # PredVarStr may contain '.' or '->'\r
1960 TmpStr = PredVarStr.replace('.', '').replace('->', '')\r
1961 if p.match(TmpStr):\r
1962 PredVarStr = PredVarStr[0:PredVarStr.find('(')]\r
1963 SearchInCache = True\r
1964 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.\r
52302d4d 1965 if TmpStr.startswith(PredVarStr):\r
30fdf114 1966 IsFuncCall = True\r
52302d4d 1967\r
30fdf114
LG
1968 if PredVarStr.strip() in IgnoredKeywordList:\r
1969 continue\r
1970 StarList = []\r
1971 PredVarList = GetCNameList(PredVarStr, StarList)\r
1972 # No variable found, maybe value first? like (0 == VarName)\r
1973 if len(PredVarList) == 0:\r
1974 continue\r
1975 if SearchInCache:\r
1976 Type = FuncReturnTypeDict.get(PredVarStr)\r
4231a819 1977 if Type is not None:\r
79b74a03 1978 if Type.find('*') != -1 and Type != 'BOOLEAN*':\r
30fdf114
LG
1979 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
1980 continue\r
52302d4d 1981\r
30fdf114
LG
1982 if PredVarStr in FuncReturnTypeDict:\r
1983 continue\r
52302d4d 1984\r
30fdf114
LG
1985 Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, None, StarList)\r
1986 if SearchInCache:\r
1987 FuncReturnTypeDict[PredVarStr] = Type\r
4231a819 1988 if Type is None:\r
30fdf114 1989 continue\r
52302d4d 1990 Type = GetTypeFromArray(Type, PredVarStr)\r
79b74a03 1991 if Type.find('*') != -1 and Type != 'BOOLEAN*':\r
30fdf114
LG
1992 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
1993\r
1994def CheckNonBooleanValueComparison(FullFileName):\r
1995 ErrorMsgList = []\r
52302d4d 1996\r
30fdf114
LG
1997 FileID = GetTableID(FullFileName, ErrorMsgList)\r
1998 if FileID < 0:\r
1999 return ErrorMsgList\r
52302d4d 2000\r
30fdf114
LG
2001 # cache the found function return type to accelerate later checking in this file.\r
2002 FuncReturnTypeDict = {}\r
52302d4d 2003\r
30fdf114
LG
2004 Db = GetDB()\r
2005 FileTable = 'Identifier' + str(FileID)\r
2006 SqlStatement = """ select Value, StartLine, ID\r
2007 from %s\r
2008 where Model = %d\r
2009 """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION)\r
2010 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2011 if len(ResultSet) == 0:\r
2012 return\r
2013 PSL = []\r
2014 for Result in ResultSet:\r
2015 PSL.append([Result[0], Result[1], Result[2]])\r
52302d4d 2016\r
30fdf114
LG
2017 SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID\r
2018 from Function\r
2019 where BelongsToFile = %d\r
2020 """ % (FileID)\r
2021 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2022 FL = []\r
2023 for Result in ResultSet:\r
2024 FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
52302d4d 2025\r
30fdf114
LG
2026 p = GetFuncDeclPattern()\r
2027 for Str in PSL:\r
2028 FuncRecord = GetFuncContainsPE(Str[1], FL)\r
4231a819 2029 if FuncRecord is None:\r
30fdf114 2030 continue\r
52302d4d 2031\r
30fdf114 2032 for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
30fdf114 2033 PredInfo = SplitPredicateStr(Exp)\r
4231a819 2034 if PredInfo[1] is None:\r
30fdf114
LG
2035 PredVarStr = PredInfo[0][0].strip()\r
2036 IsFuncCall = False\r
2037 SearchInCache = False\r
2038 # PredVarStr may contain '.' or '->'\r
2039 TmpStr = PredVarStr.replace('.', '').replace('->', '')\r
2040 if p.match(TmpStr):\r
2041 PredVarStr = PredVarStr[0:PredVarStr.find('(')]\r
2042 SearchInCache = True\r
2043 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.\r
52302d4d 2044 if TmpStr.startswith(PredVarStr):\r
30fdf114 2045 IsFuncCall = True\r
52302d4d 2046\r
30fdf114
LG
2047 if PredVarStr.strip() in IgnoredKeywordList:\r
2048 continue\r
2049 StarList = []\r
2050 PredVarList = GetCNameList(PredVarStr, StarList)\r
2051 # No variable found, maybe value first? like (0 == VarName)\r
2052 if len(PredVarList) == 0:\r
2053 continue\r
52302d4d 2054\r
30fdf114
LG
2055 if SearchInCache:\r
2056 Type = FuncReturnTypeDict.get(PredVarStr)\r
4231a819 2057 if Type is not None:\r
30fdf114
LG
2058 if Type.find('BOOLEAN') == -1:\r
2059 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
2060 continue\r
52302d4d 2061\r
30fdf114
LG
2062 if PredVarStr in FuncReturnTypeDict:\r
2063 continue\r
30fdf114
LG
2064 Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, 'BOOLEAN', StarList)\r
2065 if SearchInCache:\r
2066 FuncReturnTypeDict[PredVarStr] = Type\r
4231a819 2067 if Type is None:\r
30fdf114
LG
2068 continue\r
2069 if Type.find('BOOLEAN') == -1:\r
2070 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
52302d4d 2071\r
30fdf114
LG
2072\r
2073def CheckBooleanValueComparison(FullFileName):\r
2074 ErrorMsgList = []\r
52302d4d 2075\r
30fdf114
LG
2076 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2077 if FileID < 0:\r
2078 return ErrorMsgList\r
52302d4d 2079\r
30fdf114
LG
2080 # cache the found function return type to accelerate later checking in this file.\r
2081 FuncReturnTypeDict = {}\r
52302d4d 2082\r
30fdf114
LG
2083 Db = GetDB()\r
2084 FileTable = 'Identifier' + str(FileID)\r
2085 SqlStatement = """ select Value, StartLine, ID\r
2086 from %s\r
2087 where Model = %d\r
2088 """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION)\r
2089 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2090 if len(ResultSet) == 0:\r
2091 return\r
2092 PSL = []\r
2093 for Result in ResultSet:\r
2094 PSL.append([Result[0], Result[1], Result[2]])\r
52302d4d 2095\r
30fdf114
LG
2096 SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID\r
2097 from Function\r
2098 where BelongsToFile = %d\r
2099 """ % (FileID)\r
2100 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2101 FL = []\r
2102 for Result in ResultSet:\r
2103 FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]])\r
52302d4d 2104\r
30fdf114
LG
2105 p = GetFuncDeclPattern()\r
2106 for Str in PSL:\r
2107 FuncRecord = GetFuncContainsPE(Str[1], FL)\r
4231a819 2108 if FuncRecord is None:\r
30fdf114 2109 continue\r
52302d4d 2110\r
30fdf114
LG
2111 for Exp in GetPredicateListFromPredicateExpStr(Str[0]):\r
2112 PredInfo = SplitPredicateStr(Exp)\r
2113 if PredInfo[1] in ('==', '!=') and PredInfo[0][1] in ('TRUE', 'FALSE'):\r
2114 PredVarStr = PredInfo[0][0].strip()\r
2115 IsFuncCall = False\r
2116 SearchInCache = False\r
2117 # PredVarStr may contain '.' or '->'\r
2118 TmpStr = PredVarStr.replace('.', '').replace('->', '')\r
2119 if p.match(TmpStr):\r
2120 PredVarStr = PredVarStr[0:PredVarStr.find('(')]\r
2121 SearchInCache = True\r
2122 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.\r
52302d4d 2123 if TmpStr.startswith(PredVarStr):\r
30fdf114 2124 IsFuncCall = True\r
52302d4d 2125\r
30fdf114
LG
2126 if PredVarStr.strip() in IgnoredKeywordList:\r
2127 continue\r
2128 StarList = []\r
2129 PredVarList = GetCNameList(PredVarStr, StarList)\r
2130 # No variable found, maybe value first? like (0 == VarName)\r
2131 if len(PredVarList) == 0:\r
2132 continue\r
52302d4d 2133\r
30fdf114
LG
2134 if SearchInCache:\r
2135 Type = FuncReturnTypeDict.get(PredVarStr)\r
4231a819 2136 if Type is not None:\r
30fdf114
LG
2137 if Type.find('BOOLEAN') != -1:\r
2138 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
2139 continue\r
52302d4d 2140\r
30fdf114
LG
2141 if PredVarStr in FuncReturnTypeDict:\r
2142 continue\r
52302d4d 2143\r
30fdf114
LG
2144 Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, 'BOOLEAN', StarList)\r
2145 if SearchInCache:\r
2146 FuncReturnTypeDict[PredVarStr] = Type\r
4231a819 2147 if Type is None:\r
30fdf114
LG
2148 continue\r
2149 if Type.find('BOOLEAN') != -1:\r
2150 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2])\r
52302d4d 2151\r
30fdf114 2152\r
3a244b8d 2153def CheckHeaderFileData(FullFileName, AllTypedefFun=[]):\r
30fdf114 2154 ErrorMsgList = []\r
52302d4d 2155\r
30fdf114
LG
2156 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2157 if FileID < 0:\r
2158 return ErrorMsgList\r
52302d4d 2159\r
30fdf114
LG
2160 Db = GetDB()\r
2161 FileTable = 'Identifier' + str(FileID)\r
2162 SqlStatement = """ select ID, Modifier\r
2163 from %s\r
2164 where Model = %d\r
2165 """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE)\r
2166 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2167 for Result in ResultSet:\r
2168 if not Result[1].startswith('extern'):\r
3a244b8d
HC
2169 for Item in AllTypedefFun:\r
2170 if '(%s)' % Result[1] in Item:\r
2171 break\r
2172 else:\r
2173 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA, 'Variable definition appears in header file', FileTable, Result[0])\r
52302d4d 2174\r
30fdf114
LG
2175 SqlStatement = """ select ID\r
2176 from Function\r
2177 where BelongsToFile = %d\r
2178 """ % FileID\r
2179 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2180 for Result in ResultSet:\r
2181 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA, 'Function definition appears in header file', 'Function', Result[0])\r
2182\r
2183 return ErrorMsgList\r
2184\r
2185def CheckHeaderFileIfndef(FullFileName):\r
2186 ErrorMsgList = []\r
52302d4d 2187\r
30fdf114
LG
2188 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2189 if FileID < 0:\r
2190 return ErrorMsgList\r
52302d4d 2191\r
30fdf114
LG
2192 Db = GetDB()\r
2193 FileTable = 'Identifier' + str(FileID)\r
2194 SqlStatement = """ select Value, StartLine\r
2195 from %s\r
2196 where Model = %d order by StartLine\r
2197 """ % (FileTable, DataClass.MODEL_IDENTIFIER_MACRO_IFNDEF)\r
2198 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2199 if len(ResultSet) == 0:\r
2200 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_1, '', 'File', FileID)\r
2201 return ErrorMsgList\r
2202 for Result in ResultSet:\r
2203 SqlStatement = """ select Value, EndLine\r
2204 from %s\r
2205 where EndLine < %d\r
2206 """ % (FileTable, Result[1])\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_2, '', 'File', FileID)\r
2211 break\r
52302d4d 2212\r
30fdf114
LG
2213 SqlStatement = """ select Value\r
2214 from %s\r
2215 where StartLine > (select max(EndLine) from %s where Model = %d)\r
2216 """ % (FileTable, FileTable, DataClass.MODEL_IDENTIFIER_MACRO_ENDIF)\r
2217 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2218 for Result in ResultSet:\r
2219 if not Result[0].startswith('/*') and not Result[0].startswith('//'):\r
2220 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_3, '', 'File', FileID)\r
2221 return ErrorMsgList\r
2222\r
2223def CheckDoxygenCommand(FullFileName):\r
2224 ErrorMsgList = []\r
52302d4d 2225\r
30fdf114
LG
2226 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2227 if FileID < 0:\r
2228 return ErrorMsgList\r
52302d4d 2229\r
30fdf114
LG
2230 Db = GetDB()\r
2231 FileTable = 'Identifier' + str(FileID)\r
2232 SqlStatement = """ select Value, ID\r
2233 from %s\r
2234 where Model = %d or Model = %d\r
2235 """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER)\r
2236 ResultSet = Db.TblFile.Exec(SqlStatement)\r
f8895c2a
HC
2237 DoxygenCommandList = ['bug', 'todo', 'example', 'file', 'attention', 'param', 'post', 'pre', 'retval',\r
2238 'return', 'sa', 'since', 'test', 'note', 'par', 'endcode', 'code']\r
30fdf114
LG
2239 for Result in ResultSet:\r
2240 CommentStr = Result[0]\r
2241 CommentPartList = CommentStr.split()\r
2242 for Part in CommentPartList:\r
2243 if Part.upper() == 'BUGBUG':\r
2244 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Bug should be marked with doxygen tag @bug', FileTable, Result[1])\r
2245 if Part.upper() == 'TODO':\r
2246 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'ToDo should be marked with doxygen tag @todo', FileTable, Result[1])\r
2247 if Part.startswith('@'):\r
2248 if EccGlobalData.gException.IsException(ERROR_DOXYGEN_CHECK_COMMAND, Part):\r
2249 continue\r
f8895c2a
HC
2250 if not Part.replace('@', '').strip():\r
2251 continue\r
2252 if Part.lstrip('@') in ['{', '}']:\r
2253 continue\r
30fdf114
LG
2254 if Part.lstrip('@').isalpha():\r
2255 if Part.lstrip('@') not in DoxygenCommandList:\r
2256 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])\r
2257 else:\r
2258 Index = Part.find('[')\r
2259 if Index == -1:\r
2260 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])\r
2261 RealCmd = Part[1:Index]\r
2262 if RealCmd not in DoxygenCommandList:\r
2263 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1])\r
52302d4d
LG
2264\r
2265\r
30fdf114
LG
2266def CheckDoxygenTripleForwardSlash(FullFileName):\r
2267 ErrorMsgList = []\r
52302d4d 2268\r
30fdf114
LG
2269 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2270 if FileID < 0:\r
2271 return ErrorMsgList\r
52302d4d 2272\r
30fdf114 2273 Db = GetDB()\r
52302d4d 2274\r
30fdf114
LG
2275 SqlStatement = """ select ID, BodyStartLine, BodyStartColumn, EndLine, EndColumn\r
2276 from Function\r
2277 where BelongsToFile = %d\r
2278 """ % (FileID)\r
2279 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2280 if len(ResultSet) == 0:\r
2281 return\r
52302d4d
LG
2282\r
2283 FuncDefSet = []\r
30fdf114
LG
2284 for Result in ResultSet:\r
2285 FuncDefSet.append(Result)\r
52302d4d
LG
2286\r
2287\r
30fdf114
LG
2288 FileTable = 'Identifier' + str(FileID)\r
2289 SqlStatement = """ select Value, ID, StartLine, StartColumn, EndLine, EndColumn\r
2290 from %s\r
52302d4d
LG
2291 where Model = %d\r
2292\r
30fdf114
LG
2293 """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)\r
2294 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2295 CommentSet = []\r
2296 try:\r
2297 for Result in ResultSet:\r
2298 CommentSet.append(Result)\r
2299 except:\r
72443dd2 2300 print('Unrecognized chars in comment of file %s', FullFileName)\r
52302d4d
LG
2301\r
2302\r
30fdf114
LG
2303 for Result in CommentSet:\r
2304 CommentStr = Result[0]\r
2305 StartLine = Result[2]\r
2306 StartColumn = Result[3]\r
2307 EndLine = Result[4]\r
2308 EndColumn = Result[5]\r
2309 if not CommentStr.startswith('///<'):\r
2310 continue\r
52302d4d 2311\r
30fdf114
LG
2312 Found = False\r
2313 for FuncDef in FuncDefSet:\r
2314 if StartLine == FuncDef[1] and StartColumn > FuncDef[2] and EndLine == FuncDef[3] and EndColumn < FuncDef[4]:\r
2315 Found = True\r
2316 break\r
2317 if StartLine > FuncDef[1] and EndLine < FuncDef[3]:\r
2318 Found = True\r
2319 break\r
2320 if StartLine == FuncDef[1] and StartColumn > FuncDef[2] and EndLine < FuncDef[3]:\r
2321 Found = True\r
2322 break\r
2323 if StartLine > FuncDef[1] and EndLine == FuncDef[3] and EndColumn < FuncDef[4]:\r
2324 Found = True\r
2325 break\r
2326 if Found:\r
2327 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_FORMAT, '', FileTable, Result[1])\r
2328\r
2329\r
2330def CheckFileHeaderDoxygenComments(FullFileName):\r
2331 ErrorMsgList = []\r
52302d4d 2332\r
30fdf114
LG
2333 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2334 if FileID < 0:\r
2335 return ErrorMsgList\r
52302d4d 2336\r
30fdf114
LG
2337 Db = GetDB()\r
2338 FileTable = 'Identifier' + str(FileID)\r
2339 SqlStatement = """ select Value, ID\r
2340 from %s\r
e56468c0 2341 where Model = %d and (StartLine = 1 or StartLine = 7 or StartLine = 8) and StartColumn = 0\r
30fdf114
LG
2342 """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)\r
2343 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2344 if len(ResultSet) == 0:\r
d0acc87a 2345 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'No File License header appear at the very beginning of file.', 'File', FileID)\r
30fdf114 2346 return ErrorMsgList\r
52302d4d 2347\r
d0acc87a
LG
2348 NoHeaderCommentStartFlag = True\r
2349 NoHeaderCommentEndFlag = True\r
2350 NoHeaderCommentPeriodFlag = True\r
2351 NoCopyrightFlag = True\r
2352 NoLicenseFlag = True\r
2353 NoRevReferFlag = True\r
2354 NextLineIndex = 0\r
30fdf114 2355 for Result in ResultSet:\r
d0acc87a
LG
2356 FileStartFlag = False\r
2357 CommentStrList = []\r
e56468c0 2358 CommentStr = Result[0].strip()\r
d0acc87a
LG
2359 CommentStrListTemp = CommentStr.split('\n')\r
2360 if (len(CommentStrListTemp) <= 1):\r
2361 # For Mac\r
2362 CommentStrListTemp = CommentStr.split('\r')\r
f7496d71 2363 # Skip the content before the file header\r
d0acc87a
LG
2364 for CommentLine in CommentStrListTemp:\r
2365 if CommentLine.strip().startswith('/** @file'):\r
2366 FileStartFlag = True\r
2367 if FileStartFlag == True:\r
2368 CommentStrList.append(CommentLine)\r
f7496d71 2369\r
e56468c0 2370 ID = Result[1]\r
d0acc87a
LG
2371 Index = 0\r
2372 if CommentStrList and CommentStrList[0].strip().startswith('/** @file'):\r
2373 NoHeaderCommentStartFlag = False\r
2374 else:\r
2375 continue\r
2376 if CommentStrList and CommentStrList[-1].strip().endswith('**/'):\r
2377 NoHeaderCommentEndFlag = False\r
2378 else:\r
2379 continue\r
2380\r
2381 for CommentLine in CommentStrList:\r
2382 Index = Index + 1\r
2383 NextLineIndex = Index\r
2384 if CommentLine.startswith('/** @file'):\r
2385 continue\r
2386 if CommentLine.startswith('**/'):\r
2387 break\r
2388 # Check whether C File header Comment content start with two spaces.\r
2389 if EccGlobalData.gConfig.HeaderCheckCFileCommentStartSpacesNum == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
2390 if CommentLine.startswith('/** @file') == False and CommentLine.startswith('**/') == False and CommentLine.strip() and CommentLine.startswith(' ') == False:\r
2391 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment content should start with two spaces at each line', FileTable, ID)\r
f7496d71 2392\r
d0acc87a
LG
2393 CommentLine = CommentLine.strip()\r
2394 if CommentLine.startswith('Copyright'):\r
2395 NoCopyrightFlag = False\r
2396 if CommentLine.find('All rights reserved') == -1:\r
d77cc206
HC
2397 for Copyright in EccGlobalData.gConfig.Copyright:\r
2398 if CommentLine.find(Copyright) > -1:\r
2399 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, '""All rights reserved"" announcement should be following the ""Copyright"" at the same line', FileTable, ID)\r
2400 break\r
d0acc87a
LG
2401 if CommentLine.endswith('<BR>') == -1:\r
2402 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'The ""<BR>"" at the end of the Copyright line is required', FileTable, ID)\r
2403 if NextLineIndex < len(CommentStrList) and CommentStrList[NextLineIndex].strip().startswith('Copyright') == False and CommentStrList[NextLineIndex].strip():\r
2404 NoLicenseFlag = False\r
2405 if CommentLine.startswith('@par Revision Reference:'):\r
2406 NoRevReferFlag = False\r
2407 RefListFlag = False\r
2408 for RefLine in CommentStrList[NextLineIndex:]:\r
2409 if RefLine.strip() and (NextLineIndex + 1) < len(CommentStrList) and CommentStrList[NextLineIndex+1].strip() and CommentStrList[NextLineIndex+1].strip().startswith('**/') == False:\r
2410 RefListFlag = True\r
2411 if RefLine.strip() == False or RefLine.strip().startswith('**/'):\r
2412 RefListFlag = False\r
2413 break\r
2414 # Check whether C File header Comment's each reference at list should begin with a bullet character.\r
2415 if EccGlobalData.gConfig.HeaderCheckCFileCommentReferenceFormat == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
2416 if RefListFlag == True:\r
f7496d71
LG
2417 if RefLine.strip() and RefLine.strip().startswith('**/') == False and RefLine.startswith(' -') == False:\r
2418 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'Each reference on a separate line should begin with a bullet character ""-"" ', FileTable, ID)\r
2419\r
d0acc87a 2420 if NoHeaderCommentStartFlag:\r
e56468c0 2421 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FILE_HEADER, 'File header comment should begin with ""/** @file""', FileTable, ID)\r
d0acc87a
LG
2422 return\r
2423 if NoHeaderCommentEndFlag:\r
e56468c0 2424 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should end with ""**/""', FileTable, ID)\r
d0acc87a
LG
2425 return\r
2426 if NoCopyrightFlag:\r
2427 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment missing the ""Copyright""', FileTable, ID)\r
2428 #Check whether C File header Comment have the License immediately after the ""Copyright"" line.\r
2429 if EccGlobalData.gConfig.HeaderCheckCFileCommentLicenseFormat == '1' or EccGlobalData.gConfig.HeaderCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':\r
2430 if NoLicenseFlag:\r
2431 PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should have the License immediately after the ""Copyright"" line', FileTable, ID)\r
30fdf114
LG
2432\r
2433def CheckFuncHeaderDoxygenComments(FullFileName):\r
2434 ErrorMsgList = []\r
52302d4d 2435\r
30fdf114
LG
2436 FileID = GetTableID(FullFileName, ErrorMsgList)\r
2437 if FileID < 0:\r
2438 return ErrorMsgList\r
52302d4d 2439\r
30fdf114
LG
2440 Db = GetDB()\r
2441 FileTable = 'Identifier' + str(FileID)\r
2442 SqlStatement = """ select Value, StartLine, EndLine, ID\r
2443 from %s\r
2444 where Model = %d\r
2445 """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT)\r
52302d4d 2446\r
30fdf114
LG
2447 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2448 CommentSet = []\r
2449 try:\r
2450 for Result in ResultSet:\r
2451 CommentSet.append(Result)\r
2452 except:\r
72443dd2 2453 print('Unrecognized chars in comment of file %s', FullFileName)\r
52302d4d 2454\r
30fdf114
LG
2455 # Func Decl check\r
2456 SqlStatement = """ select Modifier, Name, StartLine, ID, Value\r
2457 from %s\r
2458 where Model = %d\r
2459 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION)\r
2460 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2461 for Result in ResultSet:\r
2462 FuncName = Result[4]\r
2463 FunctionHeaderComment = CheckCommentImmediatelyPrecedeFunctionHeader(Result[1], Result[2], CommentSet)\r
2464 if FunctionHeaderComment:\r
2465 CheckFunctionHeaderConsistentWithDoxygenComment(Result[0], Result[1], Result[2], FunctionHeaderComment[0], FunctionHeaderComment[1], ErrorMsgList, FunctionHeaderComment[3], FileTable)\r
2466 else:\r
2467 if EccGlobalData.gException.IsException(ERROR_HEADER_CHECK_FUNCTION, FuncName):\r
2468 continue\r
2469 ErrorMsgList.append('Line %d :Function %s has NO comment immediately preceding it.' % (Result[2], Result[1]))\r
2470 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'Function [%s] has NO comment immediately preceding it.' % (FuncName), FileTable, Result[3])\r
52302d4d 2471\r
30fdf114
LG
2472 # Func Def check\r
2473 SqlStatement = """ select Value, StartLine, EndLine, ID\r
2474 from %s\r
2475 where Model = %d\r
2476 """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER)\r
52302d4d 2477\r
30fdf114
LG
2478 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2479 CommentSet = []\r
2480 try:\r
2481 for Result in ResultSet:\r
2482 CommentSet.append(Result)\r
2483 except:\r
72443dd2 2484 print('Unrecognized chars in comment of file %s', FullFileName)\r
52302d4d 2485\r
30fdf114
LG
2486 SqlStatement = """ select Modifier, Header, StartLine, ID, Name\r
2487 from Function\r
2488 where BelongsToFile = %d\r
2489 """ % (FileID)\r
2490 ResultSet = Db.TblFile.Exec(SqlStatement)\r
2491 for Result in ResultSet:\r
2492 FuncName = Result[4]\r
2493 FunctionHeaderComment = CheckCommentImmediatelyPrecedeFunctionHeader(Result[1], Result[2], CommentSet)\r
2494 if FunctionHeaderComment:\r
2495 CheckFunctionHeaderConsistentWithDoxygenComment(Result[0], Result[1], Result[2], FunctionHeaderComment[0], FunctionHeaderComment[1], ErrorMsgList, FunctionHeaderComment[3], FileTable)\r
2496 else:\r
2497 if EccGlobalData.gException.IsException(ERROR_HEADER_CHECK_FUNCTION, FuncName):\r
2498 continue\r
2499 ErrorMsgList.append('Line %d :Function [%s] has NO comment immediately preceding it.' % (Result[2], Result[1]))\r
2500 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'Function [%s] has NO comment immediately preceding it.' % (FuncName), 'Function', Result[3])\r
2501 return ErrorMsgList\r
2502\r
2503def CheckCommentImmediatelyPrecedeFunctionHeader(FuncName, FuncStartLine, CommentSet):\r
2504\r
2505 for Comment in CommentSet:\r
2506 if Comment[2] == FuncStartLine - 1:\r
2507 return Comment\r
2508 return None\r
2509\r
2510def GetDoxygenStrFromComment(Str):\r
2511 DoxygenStrList = []\r
2512 ParamTagList = Str.split('@param')\r
2513 if len(ParamTagList) > 1:\r
2514 i = 1\r
2515 while i < len(ParamTagList):\r
2516 DoxygenStrList.append('@param' + ParamTagList[i])\r
2517 i += 1\r
52302d4d 2518\r
30fdf114 2519 Str = ParamTagList[0]\r
52302d4d 2520\r
30fdf114
LG
2521 RetvalTagList = ParamTagList[-1].split('@retval')\r
2522 if len(RetvalTagList) > 1:\r
2523 if len(ParamTagList) > 1:\r
2524 DoxygenStrList[-1] = '@param' + RetvalTagList[0]\r
2525 i = 1\r
2526 while i < len(RetvalTagList):\r
2527 DoxygenStrList.append('@retval' + RetvalTagList[i])\r
2528 i += 1\r
52302d4d 2529\r
30fdf114
LG
2530 ReturnTagList = RetvalTagList[-1].split('@return')\r
2531 if len(ReturnTagList) > 1:\r
2532 if len(RetvalTagList) > 1:\r
2533 DoxygenStrList[-1] = '@retval' + ReturnTagList[0]\r
2534 elif len(ParamTagList) > 1:\r
2535 DoxygenStrList[-1] = '@param' + ReturnTagList[0]\r
2536 i = 1\r
2537 while i < len(ReturnTagList):\r
2538 DoxygenStrList.append('@return' + ReturnTagList[i])\r
2539 i += 1\r
52302d4d 2540\r
30fdf114
LG
2541 if len(DoxygenStrList) > 0:\r
2542 DoxygenStrList[-1] = DoxygenStrList[-1].rstrip('--*/')\r
52302d4d 2543\r
30fdf114 2544 return DoxygenStrList\r
52302d4d 2545\r
79b74a03 2546def CheckGeneralDoxygenCommentLayout(Str, StartLine, ErrorMsgList, CommentId= -1, TableName=''):\r
30fdf114
LG
2547 #/** --*/ @retval after @param\r
2548 if not Str.startswith('/**'):\r
2549 ErrorMsgList.append('Line %d : Comment does NOT have prefix /** ' % StartLine)\r
2550 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Comment does NOT have prefix /** ', TableName, CommentId)\r
2551 if not Str.endswith('**/'):\r
2552 ErrorMsgList.append('Line %d : Comment does NOT have tail **/ ' % StartLine)\r
2553 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Comment does NOT have tail **/ ', TableName, CommentId)\r
2554 FirstRetvalIndex = Str.find('@retval')\r
2555 LastParamIndex = Str.rfind('@param')\r
2556 if (FirstRetvalIndex > 0) and (LastParamIndex > 0) and (FirstRetvalIndex < LastParamIndex):\r
2557 ErrorMsgList.append('Line %d : @retval appear before @param ' % StartLine)\r
2558 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, @retval appear before @param ', TableName, CommentId)\r
52302d4d 2559\r
79b74a03 2560def CheckFunctionHeaderConsistentWithDoxygenComment(FuncModifier, FuncHeader, FuncStartLine, CommentStr, CommentStartLine, ErrorMsgList, CommentId= -1, TableName=''):\r
52302d4d
LG
2561\r
2562 ParamList = GetParamList(FuncHeader)\r
30fdf114
LG
2563 CheckGeneralDoxygenCommentLayout(CommentStr, CommentStartLine, ErrorMsgList, CommentId, TableName)\r
2564 DescriptionStr = CommentStr\r
2565 DoxygenStrList = GetDoxygenStrFromComment(DescriptionStr)\r
2566 if DescriptionStr.find('.') == -1:\r
2567 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION, 'Comment description should end with period \'.\'', TableName, CommentId)\r
2568 DoxygenTagNumber = len(DoxygenStrList)\r
2569 ParamNumber = len(ParamList)\r
2570 for Param in ParamList:\r
2571 if Param.Name.upper() == 'VOID' and ParamNumber == 1:\r
2572 ParamNumber -= 1\r
2573 Index = 0\r
2574 if ParamNumber > 0 and DoxygenTagNumber > 0:\r
2575 while Index < ParamNumber and Index < DoxygenTagNumber:\r
2576 ParamModifier = ParamList[Index].Modifier\r
2577 ParamName = ParamList[Index].Name.strip()\r
2578 Tag = DoxygenStrList[Index].strip(' ')\r
2579 if (not Tag[-1] == ('\n')) and (not Tag[-1] == ('\r')):\r
79b74a03
LG
2580 ErrorMsgList.append('Line %d : in Comment, <%s> does NOT end with new line ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', '')))\r
2581 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'in Comment, <%s> does NOT end with new line ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId)\r
30fdf114
LG
2582 TagPartList = Tag.split()\r
2583 if len(TagPartList) < 2:\r
79b74a03
LG
2584 ErrorMsgList.append('Line %d : in Comment, <%s> does NOT contain doxygen contents ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', '')))\r
2585 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, <%s> does NOT contain doxygen contents ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId)\r
30fdf114
LG
2586 Index += 1\r
2587 continue\r
2588 LBPos = Tag.find('[')\r
2589 RBPos = Tag.find(']')\r
2590 ParamToLBContent = Tag[len('@param'):LBPos].strip()\r
79b74a03 2591 if LBPos > 0 and len(ParamToLBContent) == 0 and RBPos > LBPos:\r
30fdf114
LG
2592 InOutStr = ''\r
2593 ModifierPartList = ParamModifier.split()\r
2594 for Part in ModifierPartList:\r
2595 if Part.strip() == 'IN':\r
2596 InOutStr += 'in'\r
2597 if Part.strip() == 'OUT':\r
52302d4d 2598 if InOutStr != '':\r
30fdf114
LG
2599 InOutStr += ', out'\r
2600 else:\r
2601 InOutStr = 'out'\r
52302d4d 2602\r
30fdf114 2603 if InOutStr != '':\r
79b74a03
LG
2604 if Tag.find('[' + InOutStr + ']') == -1:\r
2605 if InOutStr != 'in, out':\r
2606 ErrorMsgList.append('Line %d : in Comment, <%s> does NOT have %s ' % (CommentStartLine, (TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'))\r
2607 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
2608 else:\r
2609 if Tag.find('[in,out]') == -1:\r
2610 ErrorMsgList.append('Line %d : in Comment, <%s> does NOT have %s ' % (CommentStartLine, (TagPartList[0] + ' ' + TagPartList[1]).replace('\n', '').replace('\r', ''), '[' + InOutStr + ']'))\r
2611 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
2612\r
2613\r
30fdf114 2614 if Tag.find(ParamName) == -1 and ParamName != 'VOID' and ParamName != 'void':\r
79b74a03
LG
2615 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
2616 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 2617 Index += 1\r
52302d4d 2618\r
30fdf114
LG
2619 if Index < ParamNumber:\r
2620 ErrorMsgList.append('Line %d : Number of doxygen tags in comment less than number of function parameters' % CommentStartLine)\r
2621 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Number of doxygen tags in comment less than number of function parameters ', TableName, CommentId)\r
2622 # VOID return type, NOT VOID*. VOID* should be matched with a doxygen tag.\r
2623 if (FuncModifier.find('VOID') != -1 or FuncModifier.find('void') != -1) and FuncModifier.find('*') == -1:\r
52302d4d 2624\r
30fdf114
LG
2625 # assume we allow a return description tag for void func. return. that's why 'DoxygenTagNumber - 1' is used instead of 'DoxygenTagNumber'\r
2626 if Index < DoxygenTagNumber - 1 or (Index < DoxygenTagNumber and DoxygenStrList[Index].startswith('@retval')):\r
2627 ErrorMsgList.append('Line %d : VOID return type need NO doxygen tags in comment' % CommentStartLine)\r
2628 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'VOID return type need no doxygen tags in comment ', TableName, CommentId)\r
2629 else:\r
52302d4d 2630 if Index < DoxygenTagNumber and not DoxygenStrList[Index].startswith('@retval') and not DoxygenStrList[Index].startswith('@return'):\r
30fdf114
LG
2631 ErrorMsgList.append('Line %d : Number of @param doxygen tags in comment does NOT match number of function parameters' % CommentStartLine)\r
2632 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Number of @param doxygen tags in comment does NOT match number of function parameters ', TableName, CommentId)\r
2633 else:\r
2634 if ParamNumber == 0 and DoxygenTagNumber != 0 and ((FuncModifier.find('VOID') != -1 or FuncModifier.find('void') != -1) and FuncModifier.find('*') == -1):\r
2635 ErrorMsgList.append('Line %d : VOID return type need NO doxygen tags in comment' % CommentStartLine)\r
2636 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'VOID return type need NO doxygen tags in comment ', TableName, CommentId)\r
2637 if ParamNumber != 0 and DoxygenTagNumber == 0:\r
2638 ErrorMsgList.append('Line %d : No doxygen tags in comment' % CommentStartLine)\r
2639 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'No doxygen tags in comment ', TableName, CommentId)\r
2640\r
2641if __name__ == '__main__':\r
2642\r
2643# EdkLogger.Initialize()\r
2644# EdkLogger.SetLevel(EdkLogger.QUIET)\r
52302d4d 2645# CollectSourceCodeDataIntoDB(sys.argv[1])\r
b36d134f
LG
2646 try:\r
2647 test_file = sys.argv[1]\r
5b0671c1 2648 except IndexError as v:\r
72443dd2 2649 print("Usage: %s filename" % sys.argv[0])\r
b36d134f
LG
2650 sys.exit(1)\r
2651 MsgList = CheckFuncHeaderDoxygenComments(test_file)\r
30fdf114 2652 for Msg in MsgList:\r
72443dd2
GL
2653 print(Msg)\r
2654 print('Done!')\r