5 import CodeFragmentCollector
7 from CommonDataClass
import DataClass
9 from Common
import EdkLogger
10 from EccToolError
import *
14 IncludeFileListDict
= {}
15 AllIncludeFileListDict
= {}
16 IncludePathListDict
= {}
19 IgnoredKeywordList
= ['EFI_ERROR']
21 def GetIgnoredDirListPattern():
22 skipList
= list(EccGlobalData
.gConfig
.SkipDirList
) + ['.svn']
23 DirString
= string
.join(skipList
, '|')
24 p
= re
.compile(r
'.*[\\/](?:%s)[\\/]?.*' % DirString
)
27 def GetFuncDeclPattern():
28 p
= re
.compile(r
'(?:EFIAPI|EFI_BOOT_SERVICE|EFI_RUNTIME_SERVICE)?\s*[_\w]+\s*\(.*\)$', re
.DOTALL
)
31 def GetArrayPattern():
32 p
= re
.compile(r
'[_\w]*\s*[\[.*\]]+')
35 def GetTypedefFuncPointerPattern():
36 p
= re
.compile('[_\w\s]*\([\w\s]*\*+\s*[_\w]+\s*\)\s*\(.*\)', re
.DOTALL
)
40 return EccGlobalData
.gDb
43 return EccGlobalData
.gConfig
45 def PrintErrorMsg(ErrorType
, Msg
, TableName
, ItemId
):
46 Msg
= Msg
.replace('\n', '').replace('\r', '')
47 MsgPartList
= Msg
.split()
49 for Part
in MsgPartList
:
52 GetDB().TblReport
.Insert(ErrorType
, OtherMsg
= Msg
, BelongsToTable
= TableName
, BelongsToItem
= ItemId
)
55 Type
= DataClass
.MODEL_UNKNOWN
56 Str
= Str
.replace('#', '# ')
58 if List
[1] == 'include':
59 Type
= DataClass
.MODEL_IDENTIFIER_INCLUDE
60 elif List
[1] == 'define':
61 Type
= DataClass
.MODEL_IDENTIFIER_MACRO_DEFINE
62 elif List
[1] == 'ifdef':
63 Type
= DataClass
.MODEL_IDENTIFIER_MACRO_IFDEF
64 elif List
[1] == 'ifndef':
65 Type
= DataClass
.MODEL_IDENTIFIER_MACRO_IFNDEF
66 elif List
[1] == 'endif':
67 Type
= DataClass
.MODEL_IDENTIFIER_MACRO_ENDIF
68 elif List
[1] == 'pragma':
69 Type
= DataClass
.MODEL_IDENTIFIER_MACRO_PROGMA
71 Type
= DataClass
.MODEL_UNKNOWN
74 def SuOccurInTypedef (Su
, TdList
):
76 if Su
.StartPos
[0] == Td
.StartPos
[0] and Su
.EndPos
[0] == Td
.EndPos
[0]:
80 def GetIdentifierList():
82 for comment
in FileProfile
.CommentList
:
83 IdComment
= DataClass
.IdentifierClass(-1, '', '', '', comment
.Content
, DataClass
.MODEL_IDENTIFIER_COMMENT
, -1, -1, comment
.StartPos
[0],comment
.StartPos
[1],comment
.EndPos
[0],comment
.EndPos
[1])
84 IdList
.append(IdComment
)
86 for pp
in FileProfile
.PPDirectiveList
:
87 Type
= GetIdType(pp
.Content
)
88 IdPP
= DataClass
.IdentifierClass(-1, '', '', '', pp
.Content
, Type
, -1, -1, pp
.StartPos
[0],pp
.StartPos
[1],pp
.EndPos
[0],pp
.EndPos
[1])
91 for pe
in FileProfile
.PredicateExpressionList
:
92 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])
95 FuncDeclPattern
= GetFuncDeclPattern()
96 ArrayPattern
= GetArrayPattern()
97 for var
in FileProfile
.VariableDeclarationList
:
98 DeclText
= var
.Declarator
.lstrip()
99 FuncPointerPattern
= GetTypedefFuncPointerPattern()
100 if FuncPointerPattern
.match(DeclText
):
102 VarNameStartLine
= var
.NameStartPos
[0]
103 VarNameStartColumn
= var
.NameStartPos
[1]
104 FirstChar
= DeclText
[0]
105 while not FirstChar
.isalpha() and FirstChar
!= '_':
108 VarNameStartColumn
+= 1
109 DeclText
= DeclText
.lstrip('*')
110 elif FirstChar
== '\r':
111 DeclText
= DeclText
.lstrip('\r\n').lstrip('\r')
112 VarNameStartLine
+= 1
113 VarNameStartColumn
= 0
114 elif FirstChar
== '\n':
115 DeclText
= DeclText
.lstrip('\n')
116 VarNameStartLine
+= 1
117 VarNameStartColumn
= 0
118 elif FirstChar
== ' ':
119 DeclText
= DeclText
.lstrip(' ')
120 VarNameStartColumn
+= 1
121 elif FirstChar
== '\t':
122 DeclText
= DeclText
.lstrip('\t')
123 VarNameStartColumn
+= 8
125 DeclText
= DeclText
[1:]
126 VarNameStartColumn
+= 1
127 FirstChar
= DeclText
[0]
129 var
.Declarator
= DeclText
130 if FuncDeclPattern
.match(var
.Declarator
):
131 DeclSplitList
= var
.Declarator
.split('(')
132 FuncName
= DeclSplitList
[0].strip()
133 FuncNamePartList
= FuncName
.split()
134 if len(FuncNamePartList
) > 1:
135 FuncName
= FuncNamePartList
[-1].strip()
136 NameStart
= DeclSplitList
[0].rfind(FuncName
)
137 var
.Declarator
= var
.Declarator
[NameStart
:]
139 var
.Modifier
+= ' ' + DeclSplitList
[0][0:NameStart
]
142 while Index
< NameStart
:
143 FirstChar
= DeclSplitList
[0][Index
]
144 if DeclSplitList
[0][Index
:].startswith('EFIAPI'):
146 VarNameStartColumn
+= 6
149 elif FirstChar
== '\r':
151 VarNameStartLine
+= 1
152 VarNameStartColumn
= 0
153 elif FirstChar
== '\n':
156 VarNameStartLine
+= 1
157 VarNameStartColumn
= 0
158 elif FirstChar
== ' ':
160 VarNameStartColumn
+= 1
161 elif FirstChar
== '\t':
163 VarNameStartColumn
+= 8
166 VarNameStartColumn
+= 1
168 IdVar
= DataClass
.IdentifierClass(-1, var
.Modifier
, '', var
.Declarator
, FuncName
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
, -1, -1, var
.StartPos
[0], var
.StartPos
[1], VarNameStartLine
, VarNameStartColumn
)
172 if var
.Declarator
.find('{') == -1:
173 for decl
in var
.Declarator
.split(','):
174 DeclList
= decl
.split('=')
175 Name
= DeclList
[0].strip()
176 if ArrayPattern
.match(Name
):
177 LSBPos
= var
.Declarator
.find('[')
178 var
.Modifier
+= ' ' + Name
[LSBPos
:]
179 Name
= Name
[0:LSBPos
]
181 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
)
184 DeclList
= var
.Declarator
.split('=')
185 Name
= DeclList
[0].strip()
186 if ArrayPattern
.match(Name
):
187 LSBPos
= var
.Declarator
.find('[')
188 var
.Modifier
+= ' ' + Name
[LSBPos
:]
189 Name
= Name
[0:LSBPos
]
190 IdVar
= DataClass
.IdentifierClass(-1, var
.Modifier
, '', Name
, (len(DeclList
) > 1 and [DeclList
[1]]or [''])[0], DataClass
.MODEL_IDENTIFIER_VARIABLE
, -1, -1, var
.StartPos
[0],var
.StartPos
[1], VarNameStartLine
, VarNameStartColumn
)
193 for enum
in FileProfile
.EnumerationDefinitionList
:
194 LBPos
= enum
.Content
.find('{')
195 RBPos
= enum
.Content
.find('}')
196 Name
= enum
.Content
[4:LBPos
].strip()
197 Value
= enum
.Content
[LBPos
+1:RBPos
]
198 IdEnum
= DataClass
.IdentifierClass(-1, '', '', Name
, Value
, DataClass
.MODEL_IDENTIFIER_ENUMERATE
, -1, -1, enum
.StartPos
[0],enum
.StartPos
[1],enum
.EndPos
[0],enum
.EndPos
[1])
199 IdList
.append(IdEnum
)
201 for su
in FileProfile
.StructUnionDefinitionList
:
202 if SuOccurInTypedef(su
, FileProfile
.TypedefDefinitionList
):
204 Type
= DataClass
.MODEL_IDENTIFIER_STRUCTURE
206 if su
.Content
.startswith('union'):
207 Type
= DataClass
.MODEL_IDENTIFIER_UNION
209 LBPos
= su
.Content
.find('{')
210 RBPos
= su
.Content
.find('}')
211 if LBPos
== -1 or RBPos
== -1:
212 Name
= su
.Content
[SkipLen
:].strip()
215 Name
= su
.Content
[SkipLen
:LBPos
].strip()
216 Value
= su
.Content
[LBPos
:RBPos
+1]
217 IdPE
= DataClass
.IdentifierClass(-1, '', '', Name
, Value
, Type
, -1, -1, su
.StartPos
[0],su
.StartPos
[1],su
.EndPos
[0],su
.EndPos
[1])
220 TdFuncPointerPattern
= GetTypedefFuncPointerPattern()
221 for td
in FileProfile
.TypedefDefinitionList
:
225 if TdFuncPointerPattern
.match(td
.ToType
):
226 Modifier
= td
.FromType
227 LBPos
= td
.ToType
.find('(')
228 TmpStr
= td
.ToType
[LBPos
+1:].strip()
229 StarPos
= TmpStr
.find('*')
231 Modifier
+= ' ' + TmpStr
[0:StarPos
]
232 while TmpStr
[StarPos
] == '*':
233 # Modifier += ' ' + '*'
235 TmpStr
= TmpStr
[StarPos
:].strip()
236 RBPos
= TmpStr
.find(')')
237 Name
= TmpStr
[0:RBPos
]
238 Value
= 'FP' + TmpStr
[RBPos
+ 1:]
240 while Name
.startswith('*'):
242 Name
= Name
.lstrip('*').strip()
244 if Name
.find('[') != -1:
245 LBPos
= Name
.find('[')
246 RBPos
= Name
.rfind(']')
247 Value
+= Name
[LBPos
: RBPos
+ 1]
248 Name
= Name
[0 : LBPos
]
250 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])
253 for funcCall
in FileProfile
.FunctionCallingList
:
254 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])
258 def StripNonAlnumChars(Str
):
265 def GetParamList(FuncDeclarator
, FuncNameLine
= 0, FuncNameOffset
= 0):
266 FuncDeclarator
= StripComments(FuncDeclarator
)
268 #DeclSplitList = FuncDeclarator.split('(')
269 LBPos
= FuncDeclarator
.find('(')
270 #if len(DeclSplitList) < 2:
273 #FuncName = DeclSplitList[0]
274 FuncName
= FuncDeclarator
[0:LBPos
]
275 #ParamStr = DeclSplitList[1].rstrip(')')
276 ParamStr
= FuncDeclarator
[LBPos
+ 1:].rstrip(')')
279 TailChar
= FuncName
[-1]
280 while not TailChar
.isalpha() and TailChar
!= '_':
283 FuncName
= FuncName
.rstrip('\r\n').rstrip('\n')
286 elif TailChar
== '\r':
287 FuncName
= FuncName
.rstrip('\r')
290 elif TailChar
== ' ':
291 FuncName
= FuncName
.rstrip(' ')
293 elif TailChar
== '\t':
294 FuncName
= FuncName
.rstrip('\t')
297 FuncName
= FuncName
[:-1]
298 TailChar
= FuncName
[-1]
300 OffsetSkipped
+= 1 #skip '('
302 for p
in ParamStr
.split(','):
306 ParamName
= ListP
[-1]
307 DeclText
= ParamName
.strip()
308 RightSpacePos
= p
.rfind(ParamName
)
309 ParamModifier
= p
[0:RightSpacePos
]
310 if ParamName
== 'OPTIONAL':
311 if ParamModifier
== '':
312 ParamModifier
+= ' ' + 'OPTIONAL'
315 ParamName
= ListP
[-2]
316 DeclText
= ParamName
.strip()
317 RightSpacePos
= p
.rfind(ParamName
)
318 ParamModifier
= p
[0:RightSpacePos
]
319 ParamModifier
+= 'OPTIONAL'
320 while DeclText
.startswith('*'):
321 ParamModifier
+= ' ' + '*'
322 DeclText
= DeclText
.lstrip('*').strip()
324 # ignore array length if exists.
325 LBIndex
= ParamName
.find('[')
327 ParamName
= ParamName
[0:LBIndex
]
329 Start
= RightSpacePos
335 if FirstChar
== '\r':
339 elif FirstChar
== '\n':
344 elif FirstChar
== ' ':
347 elif FirstChar
== '\t':
355 ParamBeginLine
= FuncNameLine
+ LineSkipped
356 ParamBeginOffset
= FuncNameOffset
+ OffsetSkipped
358 Index
= Start
+ len(ParamName
)
360 while Index
< len(p
):
363 if FirstChar
== '\r':
367 elif FirstChar
== '\n':
372 elif FirstChar
== ' ':
375 elif FirstChar
== '\t':
383 ParamEndLine
= FuncNameLine
+ LineSkipped
384 ParamEndOffset
= FuncNameOffset
+ OffsetSkipped
385 if ParamName
!= '...':
386 ParamName
= StripNonAlnumChars(ParamName
)
387 IdParam
= DataClass
.IdentifierClass(-1, ParamModifier
, '', ParamName
, '', DataClass
.MODEL_IDENTIFIER_PARAMETER
, -1, -1, ParamBeginLine
, ParamBeginOffset
, ParamEndLine
, ParamEndOffset
)
388 ParamIdList
.append(IdParam
)
390 OffsetSkipped
+= 1 #skip ','
394 def GetFunctionList():
396 for FuncDef
in FileProfile
.FunctionDefinitionList
:
398 DeclText
= FuncDef
.Declarator
.lstrip()
399 FuncNameStartLine
= FuncDef
.NamePos
[0]
400 FuncNameStartColumn
= FuncDef
.NamePos
[1]
401 FirstChar
= DeclText
[0]
402 while not FirstChar
.isalpha() and FirstChar
!= '_':
404 FuncDef
.Modifier
+= '*'
405 FuncNameStartColumn
+= 1
406 DeclText
= DeclText
.lstrip('*')
407 elif FirstChar
== '\r':
408 DeclText
= DeclText
.lstrip('\r\n').lstrip('\r')
409 FuncNameStartLine
+= 1
410 FuncNameStartColumn
= 0
411 elif FirstChar
== '\n':
412 DeclText
= DeclText
.lstrip('\n')
413 FuncNameStartLine
+= 1
414 FuncNameStartColumn
= 0
415 elif FirstChar
== ' ':
416 DeclText
= DeclText
.lstrip(' ')
417 FuncNameStartColumn
+= 1
418 elif FirstChar
== '\t':
419 DeclText
= DeclText
.lstrip('\t')
420 FuncNameStartColumn
+= 8
422 DeclText
= DeclText
[1:]
423 FuncNameStartColumn
+= 1
424 FirstChar
= DeclText
[0]
426 FuncDef
.Declarator
= DeclText
427 DeclSplitList
= FuncDef
.Declarator
.split('(')
428 if len(DeclSplitList
) < 2:
431 FuncName
= DeclSplitList
[0]
432 FuncNamePartList
= FuncName
.split()
433 if len(FuncNamePartList
) > 1:
434 FuncName
= FuncNamePartList
[-1]
435 NameStart
= DeclSplitList
[0].rfind(FuncName
)
437 FuncDef
.Modifier
+= ' ' + DeclSplitList
[0][0:NameStart
]
440 while Index
< NameStart
:
441 FirstChar
= DeclSplitList
[0][Index
]
442 if DeclSplitList
[0][Index
:].startswith('EFIAPI'):
444 FuncNameStartColumn
+= 6
447 elif FirstChar
== '\r':
449 FuncNameStartLine
+= 1
450 FuncNameStartColumn
= 0
451 elif FirstChar
== '\n':
454 FuncNameStartLine
+= 1
455 FuncNameStartColumn
= 0
456 elif FirstChar
== ' ':
458 FuncNameStartColumn
+= 1
459 elif FirstChar
== '\t':
461 FuncNameStartColumn
+= 8
464 FuncNameStartColumn
+= 1
467 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
)
468 FuncObjList
.append(FuncObj
)
472 def GetFileModificationTimeFromDB(FullFileName
):
475 SqlStatement
= """ select TimeStamp
477 where FullPath = \'%s\'
479 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
480 for Result
in ResultSet
:
481 TimeValue
= Result
[0]
484 def CollectSourceCodeDataIntoDB(RootDir
):
486 tuple = os
.walk(RootDir
)
487 IgnoredPattern
= GetIgnoredDirListPattern()
488 ParseErrorFileList
= []
490 for dirpath
, dirnames
, filenames
in tuple:
491 if IgnoredPattern
.match(dirpath
.upper()):
495 Dirname
= os
.path
.join(dirpath
, Dir
)
496 if os
.path
.islink(Dirname
):
497 Dirname
= os
.path
.realpath(Dirname
)
498 if os
.path
.isdir(Dirname
):
499 # symlinks to directories are treated as directories
501 dirnames
.append(Dirname
)
504 FullName
= os
.path
.normpath(os
.path
.join(dirpath
, f
))
505 if os
.path
.splitext(f
)[1] in ('.h', '.c'):
506 EdkLogger
.info("Parsing " + FullName
)
507 model
= f
.endswith('c') and DataClass
.MODEL_FILE_C
or DataClass
.MODEL_FILE_H
508 collector
= CodeFragmentCollector
.CodeFragmentCollector(FullName
)
510 collector
.ParseFile()
512 ParseErrorFileList
.append(FullName
)
513 collector
.CleanFileProfileBuffer()
514 collector
.ParseFileWithClearedPPDirective()
515 # collector.PrintFragments()
516 BaseName
= os
.path
.basename(f
)
517 DirName
= os
.path
.dirname(FullName
)
518 Ext
= os
.path
.splitext(f
)[1].lstrip('.')
519 ModifiedTime
= os
.path
.getmtime(FullName
)
520 FileObj
= DataClass
.FileClass(-1, BaseName
, Ext
, DirName
, FullName
, model
, ModifiedTime
, GetFunctionList(), GetIdentifierList(), [])
521 FileObjList
.append(FileObj
)
522 collector
.CleanFileProfileBuffer()
524 if len(ParseErrorFileList
) > 0:
525 EdkLogger
.info("Found unrecoverable error during parsing:\n\t%s\n" % "\n\t".join(ParseErrorFileList
))
528 for file in FileObjList
:
529 Db
.InsertOneFile(file)
531 Db
.UpdateIdentifierBelongsToFunction()
533 def GetTableID(FullFileName
, ErrorMsgList
= None):
534 if ErrorMsgList
== None:
538 SqlStatement
= """ select ID
540 where FullPath like '%s'
543 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
546 for Result
in ResultSet
:
548 ErrorMsgList
.append('Duplicate file ID found in DB for file %s' % FullFileName
)
552 ErrorMsgList
.append('NO file ID found in DB for file %s' % FullFileName
)
556 def GetIncludeFileList(FullFileName
):
557 IFList
= IncludeFileListDict
.get(FullFileName
)
561 FileID
= GetTableID(FullFileName
)
566 FileTable
= 'Identifier' + str(FileID
)
567 SqlStatement
= """ select Value
570 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_INCLUDE
)
571 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
572 IncludeFileListDict
[FullFileName
] = ResultSet
575 def GetFullPathOfIncludeFile(Str
, IncludePathList
):
576 for IncludePath
in IncludePathList
:
577 FullPath
= os
.path
.join(IncludePath
, Str
)
578 FullPath
= os
.path
.normpath(FullPath
)
579 if os
.path
.exists(FullPath
):
583 def GetAllIncludeFiles(FullFileName
):
584 if AllIncludeFileListDict
.get(FullFileName
) != None:
585 return AllIncludeFileListDict
.get(FullFileName
)
587 FileDirName
= os
.path
.dirname(FullFileName
)
588 IncludePathList
= IncludePathListDict
.get(FileDirName
)
589 if IncludePathList
== None:
590 IncludePathList
= MetaDataParser
.GetIncludeListOfFile(EccGlobalData
.gWorkspace
, FullFileName
, GetDB())
591 if FileDirName
not in IncludePathList
:
592 IncludePathList
.insert(0, FileDirName
)
593 IncludePathListDict
[FileDirName
] = IncludePathList
594 IncludeFileQueue
= []
595 for IncludeFile
in GetIncludeFileList(FullFileName
):
596 FileName
= IncludeFile
[0].lstrip('#').strip()
597 FileName
= FileName
.lstrip('include').strip()
598 FileName
= FileName
.strip('\"')
599 FileName
= FileName
.lstrip('<').rstrip('>').strip()
600 FullPath
= GetFullPathOfIncludeFile(FileName
, IncludePathList
)
602 IncludeFileQueue
.append(FullPath
)
605 while i
< len(IncludeFileQueue
):
606 for IncludeFile
in GetIncludeFileList(IncludeFileQueue
[i
]):
607 FileName
= IncludeFile
[0].lstrip('#').strip()
608 FileName
= FileName
.lstrip('include').strip()
609 FileName
= FileName
.strip('\"')
610 FileName
= FileName
.lstrip('<').rstrip('>').strip()
611 FullPath
= GetFullPathOfIncludeFile(FileName
, IncludePathList
)
612 if FullPath
!= None and FullPath
not in IncludeFileQueue
:
613 IncludeFileQueue
.insert(i
+ 1, FullPath
)
616 AllIncludeFileListDict
[FullFileName
] = IncludeFileQueue
617 return IncludeFileQueue
619 def GetPredicateListFromPredicateExpStr(PES
):
626 p
= GetFuncDeclPattern()
627 while i
< len(PES
) - 1:
628 if (PES
[i
].isalnum() or PES
[i
] == '_' or PES
[i
] == '*') and LogicOpPos
> PredicateBegin
:
630 if (PES
[i
] == '&' and PES
[i
+1] == '&') or (PES
[i
] == '|' and PES
[i
+1] == '|'):
632 Exp
= PES
[PredicateBegin
:i
].strip()
633 # Exp may contain '.' or '->'
634 TmpExp
= Exp
.replace('.', '').replace('->', '')
636 PredicateList
.append(Exp
)
638 PredicateList
.append(Exp
.rstrip(';').rstrip(')').strip())
641 if PredicateBegin
> LogicOpPos
:
642 while PredicateBegin
< len(PES
):
643 if PES
[PredicateBegin
].isalnum() or PES
[PredicateBegin
] == '_' or PES
[PredicateBegin
] == '*':
646 Exp
= PES
[PredicateBegin
:len(PES
)].strip()
647 # Exp may contain '.' or '->'
648 TmpExp
= Exp
.replace('.', '').replace('->', '')
650 PredicateList
.append(Exp
)
652 PredicateList
.append(Exp
.rstrip(';').rstrip(')').strip())
655 def GetCNameList(Lvalue
, StarList
= []):
663 while SearchBegin
< len(Lvalue
):
664 while i
< len(Lvalue
):
665 if Lvalue
[i
].isalnum() or Lvalue
[i
] == '_':
671 VarList
.append(Lvalue
[VarStart
:VarEnd
+1])
675 if VarStart
== -1 and Lvalue
[i
] == '*':
682 DotIndex
= Lvalue
[VarEnd
:].find('.')
683 ArrowIndex
= Lvalue
[VarEnd
:].find('->')
684 if DotIndex
== -1 and ArrowIndex
== -1:
686 elif DotIndex
== -1 and ArrowIndex
!= -1:
687 SearchBegin
= VarEnd
+ ArrowIndex
688 elif ArrowIndex
== -1 and DotIndex
!= -1:
689 SearchBegin
= VarEnd
+ DotIndex
691 SearchBegin
= VarEnd
+ ((DotIndex
< ArrowIndex
) and DotIndex
or ArrowIndex
)
699 def SplitPredicateByOp(Str
, Op
, IsFuncCalling
= False):
708 while Index
< len(Str
):
709 while not LBFound
and Str
[Index
] != '_' and not Str
[Index
].isalnum():
712 while not LBFound
and (Str
[Index
].isalnum() or Str
[Index
] == '_'):
714 # maybe type-cast at the begining, skip it.
715 RemainingStr
= Str
[Index
:].lstrip()
716 if RemainingStr
.startswith(')') and not LBFound
:
720 if RemainingStr
.startswith('(') and not LBFound
:
723 if Str
[Index
] == '(':
724 UnmatchedLBCount
+= 1
728 if Str
[Index
] == ')':
729 UnmatchedLBCount
-= 1
731 if UnmatchedLBCount
== 0:
737 if UnmatchedLBCount
> 0:
740 IndexInRemainingStr
= Str
[Index
:].find(Op
)
741 if IndexInRemainingStr
== -1:
744 Name
= Str
[0:Index
+ IndexInRemainingStr
].strip()
745 Value
= Str
[Index
+IndexInRemainingStr
+len(Op
):].strip()
748 TmpStr
= Str
.rstrip(';').rstrip(')')
750 Index
= TmpStr
.rfind(Op
)
754 if Str
[Index
- 1].isalnum() or Str
[Index
- 1].isspace() or Str
[Index
- 1] == ')':
755 Name
= Str
[0:Index
].strip()
756 Value
= Str
[Index
+ len(Op
):].strip()
759 TmpStr
= Str
[0:Index
- 1]
761 def SplitPredicateStr(Str
):
762 IsFuncCalling
= False
763 p
= GetFuncDeclPattern()
764 TmpStr
= Str
.replace('.', '').replace('->', '')
768 PredPartList
= SplitPredicateByOp(Str
, '==', IsFuncCalling
)
769 if len(PredPartList
) > 1:
770 return [PredPartList
, '==']
772 PredPartList
= SplitPredicateByOp(Str
, '!=', IsFuncCalling
)
773 if len(PredPartList
) > 1:
774 return [PredPartList
, '!=']
776 PredPartList
= SplitPredicateByOp(Str
, '>=', IsFuncCalling
)
777 if len(PredPartList
) > 1:
778 return [PredPartList
, '>=']
780 PredPartList
= SplitPredicateByOp(Str
, '<=', IsFuncCalling
)
781 if len(PredPartList
) > 1:
782 return [PredPartList
, '<=']
784 PredPartList
= SplitPredicateByOp(Str
, '>', IsFuncCalling
)
785 if len(PredPartList
) > 1:
786 return [PredPartList
, '>']
788 PredPartList
= SplitPredicateByOp(Str
, '<', IsFuncCalling
)
789 if len(PredPartList
) > 1:
790 return [PredPartList
, '<']
792 return [[Str
, None], None]
794 def GetFuncContainsPE(ExpLine
, ResultSet
):
795 for Result
in ResultSet
:
796 if Result
[0] < ExpLine
and Result
[1] > ExpLine
:
800 def PatternInModifier(Modifier
, SubStr
):
801 PartList
= Modifier
.split()
802 for Part
in PartList
:
807 def GetDataTypeFromModifier(ModifierStr
):
808 MList
= ModifierStr
.split()
810 if M
in EccGlobalData
.gConfig
.ModifierList
:
813 if M
.startswith('['):
818 ReturnType
+= M
+ ' '
820 ReturnType
= ReturnType
.strip()
821 if len(ReturnType
) == 0:
825 def DiffModifier(Str1
, Str2
):
826 PartList1
= Str1
.split()
827 PartList2
= Str2
.split()
828 if PartList1
== PartList2
:
833 def GetTypedefDict(FullFileName
):
835 Dict
= ComplexTypeDict
.get(FullFileName
)
839 FileID
= GetTableID(FullFileName
)
840 FileTable
= 'Identifier' + str(FileID
)
842 SqlStatement
= """ select Modifier, Name, Value, ID
845 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_TYPEDEF
)
846 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
849 for Result
in ResultSet
:
850 if len(Result
[0]) == 0:
851 Dict
[Result
[1]] = Result
[2]
853 IncludeFileList
= GetAllIncludeFiles(FullFileName
)
854 for F
in IncludeFileList
:
855 FileID
= GetTableID(F
)
859 FileTable
= 'Identifier' + str(FileID
)
860 SqlStatement
= """ select Modifier, Name, Value, ID
863 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_TYPEDEF
)
864 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
866 for Result
in ResultSet
:
867 if not Result
[2].startswith('FP ('):
868 Dict
[Result
[1]] = Result
[2]
870 if len(Result
[0]) == 0:
871 Dict
[Result
[1]] = 'VOID'
873 Dict
[Result
[1]] = GetDataTypeFromModifier(Result
[0])
875 ComplexTypeDict
[FullFileName
] = Dict
878 def GetSUDict(FullFileName
):
880 Dict
= SUDict
.get(FullFileName
)
884 FileID
= GetTableID(FullFileName
)
885 FileTable
= 'Identifier' + str(FileID
)
887 SqlStatement
= """ select Name, Value, ID
889 where Model = %d or Model = %d
890 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_STRUCTURE
, DataClass
.MODEL_IDENTIFIER_UNION
)
891 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
894 for Result
in ResultSet
:
895 if len(Result
[1]) > 0:
896 Dict
[Result
[0]] = Result
[1]
898 IncludeFileList
= GetAllIncludeFiles(FullFileName
)
899 for F
in IncludeFileList
:
900 FileID
= GetTableID(F
)
904 FileTable
= 'Identifier' + str(FileID
)
905 SqlStatement
= """ select Name, Value, ID
907 where Model = %d or Model = %d
908 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_STRUCTURE
, DataClass
.MODEL_IDENTIFIER_UNION
)
909 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
911 for Result
in ResultSet
:
912 if len(Result
[1]) > 0:
913 Dict
[Result
[0]] = Result
[1]
915 SUDict
[FullFileName
] = Dict
918 def StripComments(Str
):
920 ListFromStr
= list(Str
)
923 DoubleSlashComment
= False
925 while Index
< len(ListFromStr
):
926 # meet new line, then no longer in a comment for //
927 if ListFromStr
[Index
] == '\n':
928 if InComment
and DoubleSlashComment
:
930 DoubleSlashComment
= False
932 # check for */ comment end
933 elif InComment
and not DoubleSlashComment
and ListFromStr
[Index
] == '*' and ListFromStr
[Index
+1] == '/':
934 ListFromStr
[Index
] = ' '
936 ListFromStr
[Index
] = ' '
939 # set comments to spaces
941 ListFromStr
[Index
] = ' '
943 # check for // comment
944 elif ListFromStr
[Index
] == '/' and ListFromStr
[Index
+1] == '/' and ListFromStr
[Index
+2] != '\n':
946 DoubleSlashComment
= True
948 # check for /* comment start
949 elif ListFromStr
[Index
] == '/' and ListFromStr
[Index
+1] == '*':
950 ListFromStr
[Index
] = ' '
952 ListFromStr
[Index
] = ' '
958 # restore from List to String
959 Str
= "".join(ListFromStr
)
960 Str
= Str
.rstrip(' ')
964 def GetFinalTypeValue(Type
, FieldName
, TypedefDict
, SUDict
):
965 Value
= TypedefDict
.get(Type
)
967 Value
= SUDict
.get(Type
)
971 LBPos
= Value
.find('{')
973 FTList
= Value
.split()
975 if FT
not in ('struct', 'union'):
976 Value
= TypedefDict
.get(FT
)
978 Value
= SUDict
.get(FT
)
984 LBPos
= Value
.find('{')
986 # RBPos = Value.find('}')
987 Fields
= Value
[LBPos
+ 1:]
988 Fields
= StripComments(Fields
)
989 FieldsList
= Fields
.split(';')
990 for Field
in FieldsList
:
991 Field
= Field
.strip()
992 Index
= Field
.rfind(FieldName
)
995 if not Field
[Index
- 1].isalnum():
996 if Index
+ len(FieldName
) == len(Field
):
997 Type
= GetDataTypeFromModifier(Field
[0:Index
])
1000 # For the condition that the field in struct is an array with [] sufixes...
1001 if not Field
[Index
+ len(FieldName
)].isalnum():
1002 Type
= GetDataTypeFromModifier(Field
[0:Index
])
1007 def GetRealType(Type
, TypedefDict
, TargetType
= None):
1008 if TargetType
!= None and Type
== TargetType
:
1010 while TypedefDict
.get(Type
):
1011 Type
= TypedefDict
.get(Type
)
1012 if TargetType
!= None and Type
== TargetType
:
1016 def GetTypeInfo(RefList
, Modifier
, FullFileName
, TargetType
= None):
1017 TypedefDict
= GetTypedefDict(FullFileName
)
1018 SUDict
= GetSUDict(FullFileName
)
1019 Type
= GetDataTypeFromModifier(Modifier
).replace('*', '').strip()
1021 Type
= Type
.split()[-1]
1023 while Index
< len(RefList
):
1024 FieldName
= RefList
[Index
]
1025 FromType
= GetFinalTypeValue(Type
, FieldName
, TypedefDict
, SUDict
)
1026 if FromType
== None:
1028 # we want to determine the exact type.
1029 if TargetType
!= None:
1030 Type
= FromType
.split()[0]
1031 # we only want to check if it is a pointer
1034 if Type
.find('*') != -1 and Index
== len(RefList
)-1:
1036 Type
= FromType
.split()[0]
1040 Type
= GetRealType(Type
, TypedefDict
, TargetType
)
1044 def GetVarInfo(PredVarList
, FuncRecord
, FullFileName
, IsFuncCall
= False, TargetType
= None, StarList
= None):
1046 PredVar
= PredVarList
[0]
1047 FileID
= GetTableID(FullFileName
)
1050 FileTable
= 'Identifier' + str(FileID
)
1051 # search variable in include files
1053 # it is a function call, search function declarations and definitions
1055 SqlStatement
= """ select Modifier, ID
1057 where Model = %d and Value = \'%s\'
1058 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
, PredVar
)
1059 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1061 for Result
in ResultSet
:
1062 Type
= GetDataTypeFromModifier(Result
[0]).split()[-1]
1063 TypedefDict
= GetTypedefDict(FullFileName
)
1064 Type
= GetRealType(Type
, TypedefDict
, TargetType
)
1067 IncludeFileList
= GetAllIncludeFiles(FullFileName
)
1068 for F
in IncludeFileList
:
1069 FileID
= GetTableID(F
)
1073 FileTable
= 'Identifier' + str(FileID
)
1074 SqlStatement
= """ select Modifier, ID
1076 where Model = %d and Value = \'%s\'
1077 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
, PredVar
)
1078 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1080 for Result
in ResultSet
:
1081 Type
= GetDataTypeFromModifier(Result
[0]).split()[-1]
1082 TypedefDict
= GetTypedefDict(FullFileName
)
1083 Type
= GetRealType(Type
, TypedefDict
, TargetType
)
1086 FileID
= GetTableID(FullFileName
)
1087 SqlStatement
= """ select Modifier, ID
1089 where BelongsToFile = %d and Name = \'%s\'
1090 """ % (FileID
, PredVar
)
1091 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1093 for Result
in ResultSet
:
1094 Type
= GetDataTypeFromModifier(Result
[0]).split()[-1]
1095 TypedefDict
= GetTypedefDict(FullFileName
)
1096 Type
= GetRealType(Type
, TypedefDict
, TargetType
)
1099 for F
in IncludeFileList
:
1100 FileID
= GetTableID(F
)
1104 FileTable
= 'Identifier' + str(FileID
)
1105 SqlStatement
= """ select Modifier, ID
1107 where BelongsToFile = %d and Name = \'%s\'
1108 """ % (FileID
, PredVar
)
1109 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1111 for Result
in ResultSet
:
1112 Type
= GetDataTypeFromModifier(Result
[0]).split()[-1]
1113 TypedefDict
= GetTypedefDict(FullFileName
)
1114 Type
= GetRealType(Type
, TypedefDict
, TargetType
)
1119 # really variable, search local variable first
1120 SqlStatement
= """ select Modifier, ID
1122 where Model = %d and Name = \'%s\' and StartLine >= %d and StartLine <= %d
1123 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_VARIABLE
, PredVar
, FuncRecord
[0], FuncRecord
[1])
1124 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1126 for Result
in ResultSet
:
1127 if len(PredVarList
) > 1:
1128 Type
= GetTypeInfo(PredVarList
[1:], Result
[0], FullFileName
, TargetType
)
1131 # Type = GetDataTypeFromModifier(Result[0]).split()[-1]
1132 TypeList
= GetDataTypeFromModifier(Result
[0]).split()
1134 if len(TypeList
) > 1 and StarList
!= None:
1135 for Star
in StarList
:
1137 Type
= Type
.rstrip(Star
)
1138 # Get real type after de-reference pointers.
1139 if len(Type
.strip()) == 0:
1141 TypedefDict
= GetTypedefDict(FullFileName
)
1142 Type
= GetRealType(Type
, TypedefDict
, TargetType
)
1145 # search function parameters second
1146 ParamList
= GetParamList(FuncRecord
[2])
1147 for Param
in ParamList
:
1148 if Param
.Name
.strip() == PredVar
:
1149 if len(PredVarList
) > 1:
1150 Type
= GetTypeInfo(PredVarList
[1:], Param
.Modifier
, FullFileName
, TargetType
)
1153 TypeList
= GetDataTypeFromModifier(Param
.Modifier
).split()
1155 if len(TypeList
) > 1 and StarList
!= None:
1156 for Star
in StarList
:
1158 Type
= Type
.rstrip(Star
)
1159 # Get real type after de-reference pointers.
1160 if len(Type
.strip()) == 0:
1162 TypedefDict
= GetTypedefDict(FullFileName
)
1163 Type
= GetRealType(Type
, TypedefDict
, TargetType
)
1166 # search global variable next
1167 SqlStatement
= """ select Modifier, ID
1169 where Model = %d and Name = \'%s\' and BelongsToFunction = -1
1170 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_VARIABLE
, PredVar
)
1171 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1173 for Result
in ResultSet
:
1174 if len(PredVarList
) > 1:
1175 Type
= GetTypeInfo(PredVarList
[1:], Result
[0], FullFileName
, TargetType
)
1178 TypeList
= GetDataTypeFromModifier(Result
[0]).split()
1180 if len(TypeList
) > 1 and StarList
!= None:
1181 for Star
in StarList
:
1183 Type
= Type
.rstrip(Star
)
1184 # Get real type after de-reference pointers.
1185 if len(Type
.strip()) == 0:
1187 TypedefDict
= GetTypedefDict(FullFileName
)
1188 Type
= GetRealType(Type
, TypedefDict
, TargetType
)
1191 IncludeFileList
= GetAllIncludeFiles(FullFileName
)
1192 for F
in IncludeFileList
:
1193 FileID
= GetTableID(F
)
1197 FileTable
= 'Identifier' + str(FileID
)
1198 SqlStatement
= """ select Modifier, ID
1200 where Model = %d and BelongsToFunction = -1 and Name = \'%s\'
1201 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_VARIABLE
, PredVar
)
1202 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1204 for Result
in ResultSet
:
1205 if len(PredVarList
) > 1:
1206 Type
= GetTypeInfo(PredVarList
[1:], Result
[0], FullFileName
, TargetType
)
1209 TypeList
= GetDataTypeFromModifier(Result
[0]).split()
1211 if len(TypeList
) > 1 and StarList
!= None:
1212 for Star
in StarList
:
1214 Type
= Type
.rstrip(Star
)
1215 # Get real type after de-reference pointers.
1216 if len(Type
.strip()) == 0:
1218 TypedefDict
= GetTypedefDict(FullFileName
)
1219 Type
= GetRealType(Type
, TypedefDict
, TargetType
)
1222 def CheckFuncLayoutReturnType(FullFileName
):
1225 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1230 FileTable
= 'Identifier' + str(FileID
)
1231 SqlStatement
= """ select Modifier, ID, StartLine, StartColumn, EndLine, Value
1234 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
)
1235 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1236 for Result
in ResultSet
:
1237 ReturnType
= GetDataTypeFromModifier(Result
[0])
1238 TypeStart
= ReturnType
.split()[0]
1239 FuncName
= Result
[5]
1240 if EccGlobalData
.gException
.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE
, FuncName
):
1242 Index
= Result
[0].find(TypeStart
)
1243 if Index
!= 0 or Result
[3] != 0:
1244 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE
, '[%s] Return Type should appear at the start of line' % FuncName
, FileTable
, Result
[1])
1246 if Result
[2] == Result
[4]:
1247 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE
, '[%s] Return Type should appear on its own line' % FuncName
, FileTable
, Result
[1])
1249 SqlStatement
= """ select Modifier, ID, StartLine, StartColumn, FunNameStartLine, Name
1251 where BelongsToFile = %d
1253 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1254 for Result
in ResultSet
:
1255 ReturnType
= GetDataTypeFromModifier(Result
[0])
1256 TypeStart
= ReturnType
.split()[0]
1257 FuncName
= Result
[5]
1258 if EccGlobalData
.gException
.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE
, FuncName
):
1260 Index
= Result
[0].find(ReturnType
)
1261 if Index
!= 0 or Result
[3] != 0:
1262 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE
, '[%s] Return Type should appear at the start of line' % FuncName
, 'Function', Result
[1])
1264 if Result
[2] == Result
[4]:
1265 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE
, '[%s] Return Type should appear on its own line' % FuncName
, 'Function', Result
[1])
1267 def CheckFuncLayoutModifier(FullFileName
):
1270 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1275 FileTable
= 'Identifier' + str(FileID
)
1276 SqlStatement
= """ select Modifier, ID
1279 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
)
1280 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1281 for Result
in ResultSet
:
1282 ReturnType
= GetDataTypeFromModifier(Result
[0])
1283 TypeStart
= ReturnType
.split()[0]
1284 # if len(ReturnType) == 0:
1286 Index
= Result
[0].find(TypeStart
)
1288 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER
, '', FileTable
, Result
[1])
1290 SqlStatement
= """ select Modifier, ID
1292 where BelongsToFile = %d
1294 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1295 for Result
in ResultSet
:
1296 ReturnType
= GetDataTypeFromModifier(Result
[0])
1297 TypeStart
= ReturnType
.split()[0]
1298 # if len(ReturnType) == 0:
1300 Index
= Result
[0].find(TypeStart
)
1302 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER
, '', 'Function', Result
[1])
1304 def CheckFuncLayoutName(FullFileName
):
1306 # Parameter variable format pattern.
1307 Pattern
= re
.compile(r
'^[A-Z]+\S*[a-z]\S*$')
1308 ParamIgnoreList
= ('VOID', '...')
1309 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1314 FileTable
= 'Identifier' + str(FileID
)
1315 SqlStatement
= """ select Name, ID, EndColumn, Value
1318 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
)
1319 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1320 for Result
in ResultSet
:
1321 FuncName
= Result
[3]
1322 if EccGlobalData
.gException
.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, FuncName
):
1325 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, 'Function name [%s] should appear at the start of a line' % FuncName
, FileTable
, Result
[1])
1326 ParamList
= GetParamList(Result
[0])
1327 if len(ParamList
) == 0:
1330 for Param
in ParamList
:
1331 if Param
.StartLine
<= StartLine
:
1332 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, 'Parameter %s should be in its own line.' % Param
.Name
, FileTable
, Result
[1])
1333 if Param
.StartLine
- StartLine
> 1:
1334 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, 'Empty line appears before Parameter %s.' % Param
.Name
, FileTable
, Result
[1])
1335 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
):
1336 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME
, 'Parameter [%s] NOT follow naming convention.' % Param
.Name
, FileTable
, Result
[1])
1337 StartLine
= Param
.StartLine
1339 if not Result
[0].endswith('\n )') and not Result
[0].endswith('\r )'):
1340 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, '\')\' should be on a new line and indented two spaces', FileTable
, Result
[1])
1342 SqlStatement
= """ select Modifier, ID, FunNameStartColumn, Name
1344 where BelongsToFile = %d
1346 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1347 for Result
in ResultSet
:
1348 FuncName
= Result
[3]
1349 if EccGlobalData
.gException
.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, FuncName
):
1352 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, 'Function name [%s] should appear at the start of a line' % FuncName
, 'Function', Result
[1])
1353 ParamList
= GetParamList(Result
[0])
1354 if len(ParamList
) == 0:
1357 for Param
in ParamList
:
1358 if Param
.StartLine
<= StartLine
:
1359 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, 'Parameter %s should be in its own line.' % Param
.Name
, 'Function', Result
[1])
1360 if Param
.StartLine
- StartLine
> 1:
1361 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, 'Empty line appears before Parameter %s.' % Param
.Name
, 'Function', Result
[1])
1362 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
):
1363 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME
, 'Parameter [%s] NOT follow naming convention.' % Param
.Name
, FileTable
, Result
[1])
1364 StartLine
= Param
.StartLine
1365 if not Result
[0].endswith('\n )') and not Result
[0].endswith('\r )'):
1366 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME
, '\')\' should be on a new line and indented two spaces', 'Function', Result
[1])
1368 def CheckFuncLayoutPrototype(FullFileName
):
1371 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1375 FileTable
= 'Identifier' + str(FileID
)
1377 SqlStatement
= """ select Modifier, Header, Name, ID
1379 where BelongsToFile = %d
1381 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1382 if len(ResultSet
) == 0:
1386 for Result
in ResultSet
:
1387 FuncDefList
.append(Result
)
1389 SqlStatement
= """ select Modifier, Name, ID
1392 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
)
1393 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1395 for Result
in ResultSet
:
1396 FuncDeclList
.append(Result
)
1399 for FuncDef
in FuncDefList
:
1400 FuncName
= FuncDef
[2].strip()
1401 FuncModifier
= FuncDef
[0]
1402 FuncDefHeader
= FuncDef
[1]
1403 for FuncDecl
in FuncDeclList
:
1404 LBPos
= FuncDecl
[1].find('(')
1405 DeclName
= FuncDecl
[1][0:LBPos
].strip()
1406 DeclModifier
= FuncDecl
[0]
1407 if DeclName
== FuncName
:
1408 if DiffModifier(FuncModifier
, DeclModifier
) and not EccGlobalData
.gException
.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE
, FuncName
):
1409 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE
, 'Function [%s] modifier different with prototype.' % FuncName
, 'Function', FuncDef
[3])
1410 ParamListOfDef
= GetParamList(FuncDefHeader
)
1411 ParamListOfDecl
= GetParamList(FuncDecl
[1])
1412 if len(ParamListOfDef
) != len(ParamListOfDecl
):
1413 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE
, 'Parameter number different.', 'Function', FuncDef
[3])
1417 while Index
< len(ParamListOfDef
):
1418 if DiffModifier(ParamListOfDef
[Index
].Modifier
, ParamListOfDecl
[Index
].Modifier
):
1419 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE
, 'Parameter %s has different modifier with prototype.' % ParamListOfDef
[Index
].Name
, 'Function', FuncDef
[3])
1423 UndeclFuncList
.append(FuncDef
)
1425 IncludeFileList
= GetAllIncludeFiles(FullFileName
)
1427 for F
in IncludeFileList
:
1428 FileID
= GetTableID(F
, ErrorMsgList
)
1432 FileTable
= 'Identifier' + str(FileID
)
1433 SqlStatement
= """ select Modifier, Name, ID
1436 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
)
1437 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1439 for Result
in ResultSet
:
1440 FuncDeclList
.append(Result
)
1442 for FuncDef
in UndeclFuncList
:
1443 FuncName
= FuncDef
[2].strip()
1444 FuncModifier
= FuncDef
[0]
1445 FuncDefHeader
= FuncDef
[1]
1446 for FuncDecl
in FuncDeclList
:
1447 LBPos
= FuncDecl
[1].find('(')
1448 DeclName
= FuncDecl
[1][0:LBPos
].strip()
1449 DeclModifier
= FuncDecl
[0]
1450 if DeclName
== FuncName
:
1451 if DiffModifier(FuncModifier
, DeclModifier
) and not EccGlobalData
.gException
.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE
, FuncName
):
1452 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE
, 'Function [%s] modifier different with prototype.' % FuncName
, 'Function', FuncDef
[3])
1453 ParamListOfDef
= GetParamList(FuncDefHeader
)
1454 ParamListOfDecl
= GetParamList(FuncDecl
[1])
1455 if len(ParamListOfDef
) != len(ParamListOfDecl
):
1456 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE
, 'Parameter number different.', 'Function', FuncDef
[3])
1460 while Index
< len(ParamListOfDef
):
1461 if DiffModifier(ParamListOfDef
[Index
].Modifier
, ParamListOfDecl
[Index
].Modifier
):
1462 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE
, 'Parameter %s has different modifier with prototype.' % ParamListOfDef
[Index
].Name
, 'Function', FuncDef
[3])
1466 def CheckFuncLayoutBody(FullFileName
):
1469 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1473 FileTable
= 'Identifier' + str(FileID
)
1475 SqlStatement
= """ select BodyStartColumn, EndColumn, ID
1477 where BelongsToFile = %d
1479 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1480 if len(ResultSet
) == 0:
1482 for Result
in ResultSet
:
1484 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY
, 'open brace should be at the very beginning of a line.', 'Function', Result
[2])
1486 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY
, 'close brace should be at the very beginning of a line.', 'Function', Result
[2])
1488 def CheckFuncLayoutLocalVariable(FullFileName
):
1491 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1496 FileTable
= 'Identifier' + str(FileID
)
1497 SqlStatement
= """ select ID
1499 where BelongsToFile = %d
1501 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1502 if len(ResultSet
) == 0:
1505 for Result
in ResultSet
:
1509 SqlStatement
= """ select Name, Value, ID
1511 where Model = %d and BelongsToFunction = %d
1512 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_VARIABLE
, F
[0])
1513 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1514 if len(ResultSet
) == 0:
1517 for Result
in ResultSet
:
1518 if len(Result
[1]) > 0:
1519 PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE
, 'Variable Name: %s' % Result
[0], FileTable
, Result
[2])
1521 def CheckMemberVariableFormat(Name
, Value
, FileTable
, TdId
, ModelId
):
1523 # Member variable format pattern.
1524 Pattern
= re
.compile(r
'^[A-Z]+\S*[a-z]\S*$')
1526 LBPos
= Value
.find('{')
1527 RBPos
= Value
.rfind('}')
1528 if LBPos
== -1 or RBPos
== -1:
1531 Fields
= Value
[LBPos
+ 1 : RBPos
]
1532 Fields
= StripComments(Fields
).strip()
1533 NestPos
= Fields
.find ('struct')
1534 if NestPos
!= -1 and (NestPos
+ len('struct') < len(Fields
)):
1535 if not Fields
[NestPos
+ len('struct') + 1].isalnum():
1536 if not EccGlobalData
.gException
.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE
, Name
):
1537 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE
, 'Nested struct in [%s].' % (Name
), FileTable
, TdId
)
1539 NestPos
= Fields
.find ('union')
1540 if NestPos
!= -1 and (NestPos
+ len('union') < len(Fields
)):
1541 if not Fields
[NestPos
+ len('union') + 1].isalnum():
1542 if not EccGlobalData
.gException
.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE
, Name
):
1543 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE
, 'Nested union in [%s].' % (Name
), FileTable
, TdId
)
1545 NestPos
= Fields
.find ('enum')
1546 if NestPos
!= -1 and (NestPos
+ len('enum') < len(Fields
)):
1547 if not Fields
[NestPos
+ len('enum') + 1].isalnum():
1548 if not EccGlobalData
.gException
.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE
, Name
):
1549 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE
, 'Nested enum in [%s].' % (Name
), FileTable
, TdId
)
1552 if ModelId
== DataClass
.MODEL_IDENTIFIER_ENUMERATE
:
1553 FieldsList
= Fields
.split(',')
1554 # deal with enum is pre-assigned a value by function call ( , , , ...)
1557 RemoveCurrentElement
= False
1558 while Index
< len(FieldsList
):
1559 Field
= FieldsList
[Index
]
1561 if Field
.find('(') != -1:
1563 RemoveCurrentElement
= True
1567 if Field
.find(')') != -1 and QuoteCount
> 0:
1570 if RemoveCurrentElement
:
1571 FieldsList
.remove(Field
)
1573 RemoveCurrentElement
= False
1577 RemoveCurrentElement
= False
1581 FieldsList
= Fields
.split(';')
1583 for Field
in FieldsList
:
1584 Field
= Field
.strip()
1587 # For the condition that the field in struct is an array with [] sufixes...
1588 if Field
[-1] == ']':
1589 LBPos
= Field
.find('[')
1590 Field
= Field
[0:LBPos
]
1591 # For the condition that bit field ": Number"
1592 if Field
.find(':') != -1:
1593 ColonPos
= Field
.find(':')
1594 Field
= Field
[0:ColonPos
]
1596 Field
= Field
.strip()
1599 # Enum could directly assign value to variable
1600 Field
= Field
.split('=')[0].strip()
1601 TokenList
= Field
.split()
1602 # Remove pointers before variable
1603 if not Pattern
.match(TokenList
[-1].lstrip('*')):
1604 ErrMsgList
.append(TokenList
[-1].lstrip('*'))
1608 def CheckDeclTypedefFormat(FullFileName
, ModelId
):
1611 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1616 FileTable
= 'Identifier' + str(FileID
)
1617 SqlStatement
= """ select Name, StartLine, EndLine, ID, Value
1620 """ % (FileTable
, ModelId
)
1621 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1623 for Result
in ResultSet
:
1624 ResultList
.append(Result
)
1626 ErrorType
= ERROR_DECLARATION_DATA_TYPE_CHECK_ALL
1627 if ModelId
== DataClass
.MODEL_IDENTIFIER_STRUCTURE
:
1628 ErrorType
= ERROR_DECLARATION_DATA_TYPE_CHECK_STRUCTURE_DECLARATION
1629 elif ModelId
== DataClass
.MODEL_IDENTIFIER_ENUMERATE
:
1630 ErrorType
= ERROR_DECLARATION_DATA_TYPE_CHECK_ENUMERATED_TYPE
1631 elif ModelId
== DataClass
.MODEL_IDENTIFIER_UNION
:
1632 ErrorType
= ERROR_DECLARATION_DATA_TYPE_CHECK_UNION_TYPE
1634 SqlStatement
= """ select Modifier, Name, Value, StartLine, EndLine, ID
1637 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_TYPEDEF
)
1638 TdSet
= Db
.TblFile
.Exec(SqlStatement
)
1642 # Check member variable name format that from typedefs of ONLY this file.
1644 Name
= Td
[1].strip()
1645 Value
= Td
[2].strip()
1646 if Value
.startswith('enum'):
1647 ValueModelId
= DataClass
.MODEL_IDENTIFIER_ENUMERATE
1648 elif Value
.startswith('struct'):
1649 ValueModelId
= DataClass
.MODEL_IDENTIFIER_STRUCTURE
1650 elif Value
.startswith('union'):
1651 ValueModelId
= DataClass
.MODEL_IDENTIFIER_UNION
1655 if ValueModelId
!= ModelId
:
1657 # Check member variable format.
1658 ErrMsgList
= CheckMemberVariableFormat(Name
, Value
, FileTable
, Td
[5], ModelId
)
1659 for ErrMsg
in ErrMsgList
:
1660 if EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME
, Name
+'.'+ErrMsg
):
1662 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME
, 'Member variable [%s] NOT follow naming convention.' % (Name
+'.'+ErrMsg
), FileTable
, Td
[5])
1664 # First check in current file to see whether struct/union/enum is typedef-ed.
1665 UntypedefedList
= []
1666 for Result
in ResultList
:
1667 # Check member variable format.
1668 Name
= Result
[0].strip()
1669 Value
= Result
[4].strip()
1670 if Value
.startswith('enum'):
1671 ValueModelId
= DataClass
.MODEL_IDENTIFIER_ENUMERATE
1672 elif Value
.startswith('struct'):
1673 ValueModelId
= DataClass
.MODEL_IDENTIFIER_STRUCTURE
1674 elif Value
.startswith('union'):
1675 ValueModelId
= DataClass
.MODEL_IDENTIFIER_UNION
1679 if ValueModelId
!= ModelId
:
1681 ErrMsgList
= CheckMemberVariableFormat(Name
, Value
, FileTable
, Result
[3], ModelId
)
1682 for ErrMsg
in ErrMsgList
:
1683 if EccGlobalData
.gException
.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME
, Result
[0]+'.'+ErrMsg
):
1685 PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME
, 'Member variable [%s] NOT follow naming convention.' % (Result
[0]+'.'+ErrMsg
), FileTable
, Result
[3])
1686 # Check whether it is typedefed.
1689 # skip function pointer
1692 if Result
[1] >= Td
[3] and Td
[4] >= Result
[2]:
1694 if not Td
[1].isupper():
1695 PrintErrorMsg(ErrorType
, 'Typedef should be UPPER case', FileTable
, Td
[5])
1696 if Result
[0] in Td
[2].split():
1698 if not Td
[1].isupper():
1699 PrintErrorMsg(ErrorType
, 'Typedef should be UPPER case', FileTable
, Td
[5])
1704 UntypedefedList
.append(Result
)
1707 if len(UntypedefedList
) == 0:
1710 IncludeFileList
= GetAllIncludeFiles(FullFileName
)
1712 for F
in IncludeFileList
:
1713 FileID
= GetTableID(F
, ErrorMsgList
)
1717 IncludeFileTable
= 'Identifier' + str(FileID
)
1718 SqlStatement
= """ select Modifier, Name, Value, StartLine, EndLine, ID
1721 """ % (IncludeFileTable
, DataClass
.MODEL_IDENTIFIER_TYPEDEF
)
1722 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1723 TdList
.extend(ResultSet
)
1725 for Result
in UntypedefedList
:
1727 # Check whether it is typedefed.
1733 if Result
[1] >= Td
[3] and Td
[4] >= Result
[2]:
1735 if not Td
[1].isupper():
1736 PrintErrorMsg(ErrorType
, 'Typedef should be UPPER case', FileTable
, Td
[5])
1737 if Result
[0] in Td
[2].split():
1739 if not Td
[1].isupper():
1740 PrintErrorMsg(ErrorType
, 'Typedef should be UPPER case', FileTable
, Td
[5])
1745 PrintErrorMsg(ErrorType
, 'No Typedef for %s' % Result
[0], FileTable
, Result
[3])
1748 def CheckDeclStructTypedef(FullFileName
):
1749 CheckDeclTypedefFormat(FullFileName
, DataClass
.MODEL_IDENTIFIER_STRUCTURE
)
1751 def CheckDeclEnumTypedef(FullFileName
):
1752 CheckDeclTypedefFormat(FullFileName
, DataClass
.MODEL_IDENTIFIER_ENUMERATE
)
1754 def CheckDeclUnionTypedef(FullFileName
):
1755 CheckDeclTypedefFormat(FullFileName
, DataClass
.MODEL_IDENTIFIER_UNION
)
1757 def CheckDeclArgModifier(FullFileName
):
1760 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1765 FileTable
= 'Identifier' + str(FileID
)
1766 SqlStatement
= """ select Modifier, Name, ID
1769 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_VARIABLE
)
1770 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1771 ModifierTuple
= ('IN', 'OUT', 'OPTIONAL', 'UNALIGNED')
1772 MAX_MODIFIER_LENGTH
= 100
1773 for Result
in ResultSet
:
1774 for Modifier
in ModifierTuple
:
1775 if PatternInModifier(Result
[0], Modifier
) and len(Result
[0]) < MAX_MODIFIER_LENGTH
:
1776 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER
, 'Variable Modifier %s' % Result
[0], FileTable
, Result
[2])
1779 SqlStatement
= """ select Modifier, Name, ID
1782 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
)
1783 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1784 for Result
in ResultSet
:
1785 for Modifier
in ModifierTuple
:
1786 if PatternInModifier(Result
[0], Modifier
):
1787 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER
, 'Return Type Modifier %s' % Result
[0], FileTable
, Result
[2])
1790 SqlStatement
= """ select Modifier, Header, ID
1792 where BelongsToFile = %d
1794 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1795 for Result
in ResultSet
:
1796 for Modifier
in ModifierTuple
:
1797 if PatternInModifier(Result
[0], Modifier
):
1798 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER
, 'Return Type Modifier %s' % Result
[0], FileTable
, Result
[2])
1801 def CheckDeclNoUseCType(FullFileName
):
1804 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1809 FileTable
= 'Identifier' + str(FileID
)
1810 SqlStatement
= """ select Modifier, Name, ID
1813 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_VARIABLE
)
1814 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1815 CTypeTuple
= ('int', 'unsigned', 'char', 'void', 'static', 'long')
1816 for Result
in ResultSet
:
1817 for Type
in CTypeTuple
:
1818 if PatternInModifier(Result
[0], Type
):
1819 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE
, 'Variable type %s' % Type
, FileTable
, Result
[2])
1822 SqlStatement
= """ select Modifier, Name, ID, Value
1825 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
)
1826 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1827 for Result
in ResultSet
:
1828 ParamList
= GetParamList(Result
[1])
1829 FuncName
= Result
[3]
1830 if EccGlobalData
.gException
.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE
, FuncName
):
1832 for Type
in CTypeTuple
:
1833 if PatternInModifier(Result
[0], Type
):
1834 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE
, '%s Return type %s' % (FuncName
, Result
[0]), FileTable
, Result
[2])
1836 for Param
in ParamList
:
1837 if PatternInModifier(Param
.Modifier
, Type
):
1838 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE
, 'Parameter %s' % Param
.Name
, FileTable
, Result
[2])
1840 SqlStatement
= """ select Modifier, Header, ID, Name
1842 where BelongsToFile = %d
1844 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1845 for Result
in ResultSet
:
1846 ParamList
= GetParamList(Result
[1])
1847 FuncName
= Result
[3]
1848 if EccGlobalData
.gException
.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE
, FuncName
):
1850 for Type
in CTypeTuple
:
1851 if PatternInModifier(Result
[0], Type
):
1852 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE
, '[%s] Return type %s' % (FuncName
, Result
[0]), FileTable
, Result
[2])
1854 for Param
in ParamList
:
1855 if PatternInModifier(Param
.Modifier
, Type
):
1856 PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE
, 'Parameter %s' % Param
.Name
, FileTable
, Result
[2])
1859 def CheckPointerNullComparison(FullFileName
):
1862 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1866 # cache the found function return type to accelerate later checking in this file.
1867 FuncReturnTypeDict
= {}
1870 FileTable
= 'Identifier' + str(FileID
)
1871 SqlStatement
= """ select Value, StartLine, ID
1874 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_PREDICATE_EXPRESSION
)
1875 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1876 if len(ResultSet
) == 0:
1879 for Result
in ResultSet
:
1880 PSL
.append([Result
[0], Result
[1], Result
[2]])
1882 SqlStatement
= """ select BodyStartLine, EndLine, Header, Modifier, ID
1884 where BelongsToFile = %d
1886 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1888 for Result
in ResultSet
:
1889 FL
.append([Result
[0], Result
[1], Result
[2], Result
[3], Result
[4]])
1891 p
= GetFuncDeclPattern()
1893 FuncRecord
= GetFuncContainsPE(Str
[1], FL
)
1894 if FuncRecord
== None:
1897 for Exp
in GetPredicateListFromPredicateExpStr(Str
[0]):
1898 PredInfo
= SplitPredicateStr(Exp
)
1899 if PredInfo
[1] == None:
1900 PredVarStr
= PredInfo
[0][0].strip()
1902 SearchInCache
= False
1903 # PredVarStr may contain '.' or '->'
1904 TmpStr
= PredVarStr
.replace('.', '').replace('->', '')
1906 PredVarStr
= PredVarStr
[0:PredVarStr
.find('(')]
1907 SearchInCache
= True
1908 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.
1909 if TmpStr
.startswith(PredVarStr
):
1912 if PredVarStr
.strip() in IgnoredKeywordList
:
1915 PredVarList
= GetCNameList(PredVarStr
, StarList
)
1916 # No variable found, maybe value first? like (0 == VarName)
1917 if len(PredVarList
) == 0:
1920 Type
= FuncReturnTypeDict
.get(PredVarStr
)
1922 if Type
.find('*') != -1:
1923 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE
, 'Predicate Expression: %s' % Exp
, FileTable
, Str
[2])
1926 if PredVarStr
in FuncReturnTypeDict
:
1929 Type
= GetVarInfo(PredVarList
, FuncRecord
, FullFileName
, IsFuncCall
, None, StarList
)
1931 FuncReturnTypeDict
[PredVarStr
] = Type
1934 if Type
.find('*') != -1:
1935 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE
, 'Predicate Expression: %s' % Exp
, FileTable
, Str
[2])
1937 def CheckNonBooleanValueComparison(FullFileName
):
1940 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
1944 # cache the found function return type to accelerate later checking in this file.
1945 FuncReturnTypeDict
= {}
1948 FileTable
= 'Identifier' + str(FileID
)
1949 SqlStatement
= """ select Value, StartLine, ID
1952 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_PREDICATE_EXPRESSION
)
1953 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1954 if len(ResultSet
) == 0:
1957 for Result
in ResultSet
:
1958 PSL
.append([Result
[0], Result
[1], Result
[2]])
1960 SqlStatement
= """ select BodyStartLine, EndLine, Header, Modifier, ID
1962 where BelongsToFile = %d
1964 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
1966 for Result
in ResultSet
:
1967 FL
.append([Result
[0], Result
[1], Result
[2], Result
[3], Result
[4]])
1969 p
= GetFuncDeclPattern()
1971 FuncRecord
= GetFuncContainsPE(Str
[1], FL
)
1972 if FuncRecord
== None:
1975 for Exp
in GetPredicateListFromPredicateExpStr(Str
[0]):
1978 PredInfo
= SplitPredicateStr(Exp
)
1979 if PredInfo
[1] == None:
1980 PredVarStr
= PredInfo
[0][0].strip()
1982 SearchInCache
= False
1983 # PredVarStr may contain '.' or '->'
1984 TmpStr
= PredVarStr
.replace('.', '').replace('->', '')
1986 PredVarStr
= PredVarStr
[0:PredVarStr
.find('(')]
1987 SearchInCache
= True
1988 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.
1989 if TmpStr
.startswith(PredVarStr
):
1992 if PredVarStr
.strip() in IgnoredKeywordList
:
1995 PredVarList
= GetCNameList(PredVarStr
, StarList
)
1996 # No variable found, maybe value first? like (0 == VarName)
1997 if len(PredVarList
) == 0:
2001 Type
= FuncReturnTypeDict
.get(PredVarStr
)
2003 if Type
.find('BOOLEAN') == -1:
2004 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR
, 'Predicate Expression: %s' % Exp
, FileTable
, Str
[2])
2007 if PredVarStr
in FuncReturnTypeDict
:
2010 Type
= GetVarInfo(PredVarList
, FuncRecord
, FullFileName
, IsFuncCall
, 'BOOLEAN', StarList
)
2012 FuncReturnTypeDict
[PredVarStr
] = Type
2015 if Type
.find('BOOLEAN') == -1:
2016 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR
, 'Predicate Expression: %s' % Exp
, FileTable
, Str
[2])
2019 def CheckBooleanValueComparison(FullFileName
):
2022 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
2026 # cache the found function return type to accelerate later checking in this file.
2027 FuncReturnTypeDict
= {}
2030 FileTable
= 'Identifier' + str(FileID
)
2031 SqlStatement
= """ select Value, StartLine, ID
2034 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_PREDICATE_EXPRESSION
)
2035 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2036 if len(ResultSet
) == 0:
2039 for Result
in ResultSet
:
2040 PSL
.append([Result
[0], Result
[1], Result
[2]])
2042 SqlStatement
= """ select BodyStartLine, EndLine, Header, Modifier, ID
2044 where BelongsToFile = %d
2046 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2048 for Result
in ResultSet
:
2049 FL
.append([Result
[0], Result
[1], Result
[2], Result
[3], Result
[4]])
2051 p
= GetFuncDeclPattern()
2053 FuncRecord
= GetFuncContainsPE(Str
[1], FL
)
2054 if FuncRecord
== None:
2057 for Exp
in GetPredicateListFromPredicateExpStr(Str
[0]):
2058 PredInfo
= SplitPredicateStr(Exp
)
2059 if PredInfo
[1] in ('==', '!=') and PredInfo
[0][1] in ('TRUE', 'FALSE'):
2060 PredVarStr
= PredInfo
[0][0].strip()
2062 SearchInCache
= False
2063 # PredVarStr may contain '.' or '->'
2064 TmpStr
= PredVarStr
.replace('.', '').replace('->', '')
2066 PredVarStr
= PredVarStr
[0:PredVarStr
.find('(')]
2067 SearchInCache
= True
2068 # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable.
2069 if TmpStr
.startswith(PredVarStr
):
2072 if PredVarStr
.strip() in IgnoredKeywordList
:
2075 PredVarList
= GetCNameList(PredVarStr
, StarList
)
2076 # No variable found, maybe value first? like (0 == VarName)
2077 if len(PredVarList
) == 0:
2081 Type
= FuncReturnTypeDict
.get(PredVarStr
)
2083 if Type
.find('BOOLEAN') != -1:
2084 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE
, 'Predicate Expression: %s' % Exp
, FileTable
, Str
[2])
2087 if PredVarStr
in FuncReturnTypeDict
:
2090 Type
= GetVarInfo(PredVarList
, FuncRecord
, FullFileName
, IsFuncCall
, 'BOOLEAN', StarList
)
2092 FuncReturnTypeDict
[PredVarStr
] = Type
2095 if Type
.find('BOOLEAN') != -1:
2096 PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE
, 'Predicate Expression: %s' % Exp
, FileTable
, Str
[2])
2099 def CheckHeaderFileData(FullFileName
):
2102 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
2107 FileTable
= 'Identifier' + str(FileID
)
2108 SqlStatement
= """ select ID, Modifier
2111 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_VARIABLE
)
2112 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2113 for Result
in ResultSet
:
2114 if not Result
[1].startswith('extern'):
2115 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA
, 'Variable definition appears in header file', FileTable
, Result
[0])
2117 SqlStatement
= """ select ID
2119 where BelongsToFile = %d
2121 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2122 for Result
in ResultSet
:
2123 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA
, 'Function definition appears in header file', 'Function', Result
[0])
2127 def CheckHeaderFileIfndef(FullFileName
):
2130 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
2135 FileTable
= 'Identifier' + str(FileID
)
2136 SqlStatement
= """ select Value, StartLine
2138 where Model = %d order by StartLine
2139 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_MACRO_IFNDEF
)
2140 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2141 if len(ResultSet
) == 0:
2142 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_1
, '', 'File', FileID
)
2144 for Result
in ResultSet
:
2145 SqlStatement
= """ select Value, EndLine
2148 """ % (FileTable
, Result
[1])
2149 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2150 for Result
in ResultSet
:
2151 if not Result
[0].startswith('/*') and not Result
[0].startswith('//'):
2152 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_2
, '', 'File', FileID
)
2155 SqlStatement
= """ select Value
2157 where StartLine > (select max(EndLine) from %s where Model = %d)
2158 """ % (FileTable
, FileTable
, DataClass
.MODEL_IDENTIFIER_MACRO_ENDIF
)
2159 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2160 for Result
in ResultSet
:
2161 if not Result
[0].startswith('/*') and not Result
[0].startswith('//'):
2162 PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_3
, '', 'File', FileID
)
2165 def CheckDoxygenCommand(FullFileName
):
2168 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
2173 FileTable
= 'Identifier' + str(FileID
)
2174 SqlStatement
= """ select Value, ID
2176 where Model = %d or Model = %d
2177 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_COMMENT
, DataClass
.MODEL_IDENTIFIER_FUNCTION_HEADER
)
2178 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2179 DoxygenCommandList
= ['bug', 'todo', 'example', 'file', 'attention', 'param', 'post', 'pre', 'retval', 'return', 'sa', 'since', 'test', 'note', 'par']
2180 for Result
in ResultSet
:
2181 CommentStr
= Result
[0]
2182 CommentPartList
= CommentStr
.split()
2183 for Part
in CommentPartList
:
2184 if Part
.upper() == 'BUGBUG':
2185 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND
, 'Bug should be marked with doxygen tag @bug', FileTable
, Result
[1])
2186 if Part
.upper() == 'TODO':
2187 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND
, 'ToDo should be marked with doxygen tag @todo', FileTable
, Result
[1])
2188 if Part
.startswith('@'):
2189 if EccGlobalData
.gException
.IsException(ERROR_DOXYGEN_CHECK_COMMAND
, Part
):
2191 if Part
.lstrip('@').isalpha():
2192 if Part
.lstrip('@') not in DoxygenCommandList
:
2193 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND
, 'Unknown doxygen command %s' % Part
, FileTable
, Result
[1])
2195 Index
= Part
.find('[')
2197 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND
, 'Unknown doxygen command %s' % Part
, FileTable
, Result
[1])
2198 RealCmd
= Part
[1:Index
]
2199 if RealCmd
not in DoxygenCommandList
:
2200 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND
, 'Unknown doxygen command %s' % Part
, FileTable
, Result
[1])
2203 def CheckDoxygenTripleForwardSlash(FullFileName
):
2206 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
2212 SqlStatement
= """ select ID, BodyStartLine, BodyStartColumn, EndLine, EndColumn
2214 where BelongsToFile = %d
2216 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2217 if len(ResultSet
) == 0:
2221 for Result
in ResultSet
:
2222 FuncDefSet
.append(Result
)
2225 FileTable
= 'Identifier' + str(FileID
)
2226 SqlStatement
= """ select Value, ID, StartLine, StartColumn, EndLine, EndColumn
2230 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_COMMENT
)
2231 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2234 for Result
in ResultSet
:
2235 CommentSet
.append(Result
)
2237 print 'Unrecognized chars in comment of file %s', FullFileName
2240 for Result
in CommentSet
:
2241 CommentStr
= Result
[0]
2242 StartLine
= Result
[2]
2243 StartColumn
= Result
[3]
2245 EndColumn
= Result
[5]
2246 if not CommentStr
.startswith('///<'):
2250 for FuncDef
in FuncDefSet
:
2251 if StartLine
== FuncDef
[1] and StartColumn
> FuncDef
[2] and EndLine
== FuncDef
[3] and EndColumn
< FuncDef
[4]:
2254 if StartLine
> FuncDef
[1] and EndLine
< FuncDef
[3]:
2257 if StartLine
== FuncDef
[1] and StartColumn
> FuncDef
[2] and EndLine
< FuncDef
[3]:
2260 if StartLine
> FuncDef
[1] and EndLine
== FuncDef
[3] and EndColumn
< FuncDef
[4]:
2264 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_FORMAT
, '', FileTable
, Result
[1])
2267 def CheckFileHeaderDoxygenComments(FullFileName
):
2270 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
2275 FileTable
= 'Identifier' + str(FileID
)
2276 SqlStatement
= """ select Value, ID
2278 where Model = %d and StartLine = 1 and StartColumn = 0
2279 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_COMMENT
)
2280 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2281 if len(ResultSet
) == 0:
2282 PrintErrorMsg(ERROR_HEADER_CHECK_FILE
, 'No Comment appear at the very beginning of file.', 'File', FileID
)
2285 for Result
in ResultSet
:
2286 CommentStr
= Result
[0]
2287 if not CommentStr
.startswith('/** @file'):
2288 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FILE_HEADER
, 'File header comment should begin with ""/** @file""', FileTable
, Result
[1])
2289 if not CommentStr
.endswith('**/'):
2290 PrintErrorMsg(ERROR_HEADER_CHECK_FILE
, 'File header comment should end with **/', FileTable
, Result
[1])
2291 if CommentStr
.find('.') == -1:
2292 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION
, 'Comment description should end with period \'.\'', FileTable
, Result
[1])
2294 def CheckFuncHeaderDoxygenComments(FullFileName
):
2297 FileID
= GetTableID(FullFileName
, ErrorMsgList
)
2302 FileTable
= 'Identifier' + str(FileID
)
2303 SqlStatement
= """ select Value, StartLine, EndLine, ID
2306 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_COMMENT
)
2308 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2311 for Result
in ResultSet
:
2312 CommentSet
.append(Result
)
2314 print 'Unrecognized chars in comment of file %s', FullFileName
2317 SqlStatement
= """ select Modifier, Name, StartLine, ID, Value
2320 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_DECLARATION
)
2321 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2322 for Result
in ResultSet
:
2323 FuncName
= Result
[4]
2324 FunctionHeaderComment
= CheckCommentImmediatelyPrecedeFunctionHeader(Result
[1], Result
[2], CommentSet
)
2325 if FunctionHeaderComment
:
2326 CheckFunctionHeaderConsistentWithDoxygenComment(Result
[0], Result
[1], Result
[2], FunctionHeaderComment
[0], FunctionHeaderComment
[1], ErrorMsgList
, FunctionHeaderComment
[3], FileTable
)
2328 if EccGlobalData
.gException
.IsException(ERROR_HEADER_CHECK_FUNCTION
, FuncName
):
2330 ErrorMsgList
.append('Line %d :Function %s has NO comment immediately preceding it.' % (Result
[2], Result
[1]))
2331 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION
, 'Function [%s] has NO comment immediately preceding it.' % (FuncName
), FileTable
, Result
[3])
2334 SqlStatement
= """ select Value, StartLine, EndLine, ID
2337 """ % (FileTable
, DataClass
.MODEL_IDENTIFIER_FUNCTION_HEADER
)
2339 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2342 for Result
in ResultSet
:
2343 CommentSet
.append(Result
)
2345 print 'Unrecognized chars in comment of file %s', FullFileName
2347 SqlStatement
= """ select Modifier, Header, StartLine, ID, Name
2349 where BelongsToFile = %d
2351 ResultSet
= Db
.TblFile
.Exec(SqlStatement
)
2352 for Result
in ResultSet
:
2353 FuncName
= Result
[4]
2354 FunctionHeaderComment
= CheckCommentImmediatelyPrecedeFunctionHeader(Result
[1], Result
[2], CommentSet
)
2355 if FunctionHeaderComment
:
2356 CheckFunctionHeaderConsistentWithDoxygenComment(Result
[0], Result
[1], Result
[2], FunctionHeaderComment
[0], FunctionHeaderComment
[1], ErrorMsgList
, FunctionHeaderComment
[3], FileTable
)
2358 if EccGlobalData
.gException
.IsException(ERROR_HEADER_CHECK_FUNCTION
, FuncName
):
2360 ErrorMsgList
.append('Line %d :Function [%s] has NO comment immediately preceding it.' % (Result
[2], Result
[1]))
2361 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION
, 'Function [%s] has NO comment immediately preceding it.' % (FuncName
), 'Function', Result
[3])
2364 def CheckCommentImmediatelyPrecedeFunctionHeader(FuncName
, FuncStartLine
, CommentSet
):
2366 for Comment
in CommentSet
:
2367 if Comment
[2] == FuncStartLine
- 1:
2371 def GetDoxygenStrFromComment(Str
):
2373 ParamTagList
= Str
.split('@param')
2374 if len(ParamTagList
) > 1:
2376 while i
< len(ParamTagList
):
2377 DoxygenStrList
.append('@param' + ParamTagList
[i
])
2380 Str
= ParamTagList
[0]
2382 RetvalTagList
= ParamTagList
[-1].split('@retval')
2383 if len(RetvalTagList
) > 1:
2384 if len(ParamTagList
) > 1:
2385 DoxygenStrList
[-1] = '@param' + RetvalTagList
[0]
2387 while i
< len(RetvalTagList
):
2388 DoxygenStrList
.append('@retval' + RetvalTagList
[i
])
2391 ReturnTagList
= RetvalTagList
[-1].split('@return')
2392 if len(ReturnTagList
) > 1:
2393 if len(RetvalTagList
) > 1:
2394 DoxygenStrList
[-1] = '@retval' + ReturnTagList
[0]
2395 elif len(ParamTagList
) > 1:
2396 DoxygenStrList
[-1] = '@param' + ReturnTagList
[0]
2398 while i
< len(ReturnTagList
):
2399 DoxygenStrList
.append('@return' + ReturnTagList
[i
])
2402 if len(DoxygenStrList
) > 0:
2403 DoxygenStrList
[-1] = DoxygenStrList
[-1].rstrip('--*/')
2405 return DoxygenStrList
2407 def CheckGeneralDoxygenCommentLayout(Str
, StartLine
, ErrorMsgList
, CommentId
= -1, TableName
= ''):
2408 #/** --*/ @retval after @param
2409 if not Str
.startswith('/**'):
2410 ErrorMsgList
.append('Line %d : Comment does NOT have prefix /** ' % StartLine
)
2411 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'Comment does NOT have prefix /** ', TableName
, CommentId
)
2412 if not Str
.endswith('**/'):
2413 ErrorMsgList
.append('Line %d : Comment does NOT have tail **/ ' % StartLine
)
2414 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'Comment does NOT have tail **/ ', TableName
, CommentId
)
2415 FirstRetvalIndex
= Str
.find('@retval')
2416 LastParamIndex
= Str
.rfind('@param')
2417 if (FirstRetvalIndex
> 0) and (LastParamIndex
> 0) and (FirstRetvalIndex
< LastParamIndex
):
2418 ErrorMsgList
.append('Line %d : @retval appear before @param ' % StartLine
)
2419 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'in Comment, @retval appear before @param ', TableName
, CommentId
)
2421 def CheckFunctionHeaderConsistentWithDoxygenComment(FuncModifier
, FuncHeader
, FuncStartLine
, CommentStr
, CommentStartLine
, ErrorMsgList
, CommentId
= -1, TableName
= ''):
2423 ParamList
= GetParamList(FuncHeader
)
2424 CheckGeneralDoxygenCommentLayout(CommentStr
, CommentStartLine
, ErrorMsgList
, CommentId
, TableName
)
2425 DescriptionStr
= CommentStr
2426 DoxygenStrList
= GetDoxygenStrFromComment(DescriptionStr
)
2427 if DescriptionStr
.find('.') == -1:
2428 PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION
, 'Comment description should end with period \'.\'', TableName
, CommentId
)
2429 DoxygenTagNumber
= len(DoxygenStrList
)
2430 ParamNumber
= len(ParamList
)
2431 for Param
in ParamList
:
2432 if Param
.Name
.upper() == 'VOID' and ParamNumber
== 1:
2435 if ParamNumber
> 0 and DoxygenTagNumber
> 0:
2436 while Index
< ParamNumber
and Index
< DoxygenTagNumber
:
2437 ParamModifier
= ParamList
[Index
].Modifier
2438 ParamName
= ParamList
[Index
].Name
.strip()
2439 Tag
= DoxygenStrList
[Index
].strip(' ')
2440 if (not Tag
[-1] == ('\n')) and (not Tag
[-1] == ('\r')):
2441 ErrorMsgList
.append('Line %d : in Comment, \"%s\" does NOT end with new line ' % (CommentStartLine
, Tag
.replace('\n', '').replace('\r', '')))
2442 PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION
, 'in Comment, \"%s\" does NOT end with new line ' % (Tag
.replace('\n', '').replace('\r', '')), TableName
, CommentId
)
2443 TagPartList
= Tag
.split()
2444 if len(TagPartList
) < 2:
2445 ErrorMsgList
.append('Line %d : in Comment, \"%s\" does NOT contain doxygen contents ' % (CommentStartLine
, Tag
.replace('\n', '').replace('\r', '')))
2446 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'in Comment, \"%s\" does NOT contain doxygen contents ' % (Tag
.replace('\n', '').replace('\r', '')), TableName
, CommentId
)
2449 LBPos
= Tag
.find('[')
2450 RBPos
= Tag
.find(']')
2451 ParamToLBContent
= Tag
[len('@param'):LBPos
].strip()
2452 if LBPos
> 0 and len(ParamToLBContent
)==0 and RBPos
> LBPos
:
2454 ModifierPartList
= ParamModifier
.split()
2455 for Part
in ModifierPartList
:
2456 if Part
.strip() == 'IN':
2458 if Part
.strip() == 'OUT':
2465 if Tag
.find('['+InOutStr
+']') == -1:
2466 ErrorMsgList
.append('Line %d : in Comment, \"%s\" does NOT have %s ' % (CommentStartLine
, (TagPartList
[0] + ' ' +TagPartList
[1]).replace('\n', '').replace('\r', ''), '['+InOutStr
+']'))
2467 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'in Comment, \"%s\" does NOT have %s ' % ((TagPartList
[0] + ' ' +TagPartList
[1]).replace('\n', '').replace('\r', ''), '['+InOutStr
+']'), TableName
, CommentId
)
2468 if Tag
.find(ParamName
) == -1 and ParamName
!= 'VOID' and ParamName
!= 'void':
2469 ErrorMsgList
.append('Line %d : in Comment, \"%s\" does NOT consistent with parameter name %s ' % (CommentStartLine
, (TagPartList
[0] + ' ' +TagPartList
[1]).replace('\n', '').replace('\r', ''), ParamName
))
2470 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
)
2473 if Index
< ParamNumber
:
2474 ErrorMsgList
.append('Line %d : Number of doxygen tags in comment less than number of function parameters' % CommentStartLine
)
2475 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'Number of doxygen tags in comment less than number of function parameters ', TableName
, CommentId
)
2476 # VOID return type, NOT VOID*. VOID* should be matched with a doxygen tag.
2477 if (FuncModifier
.find('VOID') != -1 or FuncModifier
.find('void') != -1) and FuncModifier
.find('*') == -1:
2479 # assume we allow a return description tag for void func. return. that's why 'DoxygenTagNumber - 1' is used instead of 'DoxygenTagNumber'
2480 if Index
< DoxygenTagNumber
- 1 or (Index
< DoxygenTagNumber
and DoxygenStrList
[Index
].startswith('@retval')):
2481 ErrorMsgList
.append('Line %d : VOID return type need NO doxygen tags in comment' % CommentStartLine
)
2482 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'VOID return type need no doxygen tags in comment ', TableName
, CommentId
)
2484 if Index
< DoxygenTagNumber
and not DoxygenStrList
[Index
].startswith('@retval') and not DoxygenStrList
[Index
].startswith('@return'):
2485 ErrorMsgList
.append('Line %d : Number of @param doxygen tags in comment does NOT match number of function parameters' % CommentStartLine
)
2486 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'Number of @param doxygen tags in comment does NOT match number of function parameters ', TableName
, CommentId
)
2488 if ParamNumber
== 0 and DoxygenTagNumber
!= 0 and ((FuncModifier
.find('VOID') != -1 or FuncModifier
.find('void') != -1) and FuncModifier
.find('*') == -1):
2489 ErrorMsgList
.append('Line %d : VOID return type need NO doxygen tags in comment' % CommentStartLine
)
2490 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'VOID return type need NO doxygen tags in comment ', TableName
, CommentId
)
2491 if ParamNumber
!= 0 and DoxygenTagNumber
== 0:
2492 ErrorMsgList
.append('Line %d : No doxygen tags in comment' % CommentStartLine
)
2493 PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER
, 'No doxygen tags in comment ', TableName
, CommentId
)
2495 if __name__
== '__main__':
2497 # EdkLogger.Initialize()
2498 # EdkLogger.SetLevel(EdkLogger.QUIET)
2499 # CollectSourceCodeDataIntoDB(sys.argv[1])
2500 MsgList
= CheckFuncHeaderDoxygenComments('C:\\Combo\\R9\\LakeportX64Dev\\FlashDevicePkg\\Library\\SpiFlashChipM25P64\\SpiFlashChipM25P64.c')