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