MISRA - support for per file/line error suppression (#1275)
* cppcheckdata.py: fixed Suppression.isMatch method * cppcheckdata.py: fixed parsing <suppressions> tag * misra.py: now uses cppcheckdata.reportError and supports suppressions
This commit is contained in:
parent
74b18d7fd9
commit
0c6d60d202
|
@ -483,14 +483,14 @@ class Suppression:
|
||||||
self.lineNumber = element.get('lineNumber')
|
self.lineNumber = element.get('lineNumber')
|
||||||
self.symbolName = element.get('symbolName')
|
self.symbolName = element.get('symbolName')
|
||||||
|
|
||||||
def isMatch(file, line, message, errorId):
|
def isMatch(self, file, line, message, errorId):
|
||||||
if (fnmatch(file, self.fileName)
|
if (fnmatch(file, self.fileName)
|
||||||
and (self.lineNumber is None or line == self.lineNumber)
|
and (self.lineNumber is None or line == self.lineNumber)
|
||||||
and fnmatch(message, '*'+self.symbolName+'*')
|
and (self.symbolName is None or fnmatch(message, '*'+self.symbolName+'*'))
|
||||||
and fnmatch(errorId, self.errorId)):
|
and fnmatch(errorId, self.errorId)):
|
||||||
return true
|
return True
|
||||||
else:
|
else:
|
||||||
return false
|
return False
|
||||||
|
|
||||||
class Configuration:
|
class Configuration:
|
||||||
"""
|
"""
|
||||||
|
@ -506,7 +506,6 @@ class Configuration:
|
||||||
functions List of Function items
|
functions List of Function items
|
||||||
variables List of Variable items
|
variables List of Variable items
|
||||||
valueflow List of ValueFlow values
|
valueflow List of ValueFlow values
|
||||||
suppressions List of warning suppressions
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name = ''
|
name = ''
|
||||||
|
@ -516,7 +515,6 @@ class Configuration:
|
||||||
functions = []
|
functions = []
|
||||||
variables = []
|
variables = []
|
||||||
valueflow = []
|
valueflow = []
|
||||||
suppressions = []
|
|
||||||
|
|
||||||
def __init__(self, confignode):
|
def __init__(self, confignode):
|
||||||
self.name = confignode.get('cfg')
|
self.name = confignode.get('cfg')
|
||||||
|
@ -526,7 +524,6 @@ class Configuration:
|
||||||
self.functions = []
|
self.functions = []
|
||||||
self.variables = []
|
self.variables = []
|
||||||
self.valueflow = []
|
self.valueflow = []
|
||||||
self.suppressions = []
|
|
||||||
arguments = []
|
arguments = []
|
||||||
|
|
||||||
for element in confignode:
|
for element in confignode:
|
||||||
|
@ -562,9 +559,6 @@ class Configuration:
|
||||||
if element.tag == 'valueflow':
|
if element.tag == 'valueflow':
|
||||||
for values in element:
|
for values in element:
|
||||||
self.valueflow.append(ValueFlow(values))
|
self.valueflow.append(ValueFlow(values))
|
||||||
if element.tag == "suppressions":
|
|
||||||
for suppression in element:
|
|
||||||
self.suppressions.append(Suppression(suppression))
|
|
||||||
|
|
||||||
IdMap = {None: None, '0': None, '00000000': None, '0000000000000000': None}
|
IdMap = {None: None, '0': None, '00000000': None, '0000000000000000': None}
|
||||||
for token in self.tokenlist:
|
for token in self.tokenlist:
|
||||||
|
@ -664,6 +658,7 @@ class CppcheckData:
|
||||||
rawTokens = []
|
rawTokens = []
|
||||||
platform = None
|
platform = None
|
||||||
configurations = []
|
configurations = []
|
||||||
|
suppressions = []
|
||||||
|
|
||||||
def __init__(self, filename):
|
def __init__(self, filename):
|
||||||
self.configurations = []
|
self.configurations = []
|
||||||
|
@ -689,6 +684,13 @@ class CppcheckData:
|
||||||
self.rawTokens[i + 1].previous = self.rawTokens[i]
|
self.rawTokens[i + 1].previous = self.rawTokens[i]
|
||||||
self.rawTokens[i].next = self.rawTokens[i + 1]
|
self.rawTokens[i].next = self.rawTokens[i + 1]
|
||||||
|
|
||||||
|
|
||||||
|
for suppressionsNode in data.getroot():
|
||||||
|
if suppressionsNode.tag == "suppressions":
|
||||||
|
for suppression in suppressionsNode:
|
||||||
|
self.suppressions.append(Suppression(suppression))
|
||||||
|
|
||||||
|
|
||||||
# root is 'dumps' node, each config has its own 'dump' subnode.
|
# root is 'dumps' node, each config has its own 'dump' subnode.
|
||||||
for cfgnode in data.getroot():
|
for cfgnode in data.getroot():
|
||||||
if cfgnode.tag == 'dump':
|
if cfgnode.tag == 'dump':
|
||||||
|
|
|
@ -23,6 +23,7 @@ import argparse
|
||||||
|
|
||||||
ruleTexts = {}
|
ruleTexts = {}
|
||||||
suppressRules = {}
|
suppressRules = {}
|
||||||
|
suppressions = None
|
||||||
typeBits = {
|
typeBits = {
|
||||||
'CHAR': None,
|
'CHAR': None,
|
||||||
'SHORT': None,
|
'SHORT': None,
|
||||||
|
@ -60,8 +61,13 @@ def reportError(location, num1, num2):
|
||||||
errmsg = 'misra violation (use --rule-texts=<file> to get proper output) [' + id + ']'
|
errmsg = 'misra violation (use --rule-texts=<file> to get proper output) [' + id + ']'
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
sys.stderr.write('[' + location.file + ':' + str(location.linenr) + '] (style): ' + errmsg + '\n')
|
if not cppcheckdata.reportError('[{file}:{line}] {severity}: {message}',
|
||||||
|
callstack=[(location.file, location.linenr)],
|
||||||
|
severity='style',
|
||||||
|
message = errmsg,
|
||||||
|
errorId = id,
|
||||||
|
suppressions = suppressions,
|
||||||
|
outputFunc = sys.stderr.write) is None:
|
||||||
VIOLATIONS.append(errmsg)
|
VIOLATIONS.append(errmsg)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1700,6 +1706,9 @@ def parseDump(dumpfile):
|
||||||
|
|
||||||
data = cppcheckdata.parsedump(dumpfile)
|
data = cppcheckdata.parsedump(dumpfile)
|
||||||
|
|
||||||
|
global suppressions
|
||||||
|
suppressions = data.suppressions
|
||||||
|
|
||||||
typeBits['CHAR'] = data.platform.char_bit
|
typeBits['CHAR'] = data.platform.char_bit
|
||||||
typeBits['SHORT'] = data.platform.short_bit
|
typeBits['SHORT'] = data.platform.short_bit
|
||||||
typeBits['INT'] = data.platform.int_bit
|
typeBits['INT'] = data.platform.int_bit
|
||||||
|
|
Loading…
Reference in New Issue