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