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