cppcheck/addons/misra.py

88 lines
2.3 KiB
Python
Raw Normal View History

2017-04-08 16:08:54 +02:00
#/usr/bin/python
#
2017-04-11 14:45:38 +02:00
# MISRA C 2012 checkers
2017-04-08 16:08:54 +02:00
#
# Example usage of this addon (scan a sourcefile main.cpp)
# cppcheck --dump main.cpp
# python misra.py main.cpp.dump
#
# Limitations: This addon is released as open source. Rule texts can't be freely
# distributed. https://www.misra.org.uk/forum/viewtopic.php?f=56&t=1189
#
#
2017-04-08 16:08:54 +02:00
import cppcheckdata
import sys
import re
def reportError(token, num):
2017-04-08 16:08:54 +02:00
sys.stderr.write(
'[' + token.file + ':' + str(token.linenr) + '] misra ' + str(num) + ' violation\n')
2017-04-08 16:08:54 +02:00
def hasSideEffects(expr):
if not expr:
return False
2017-04-08 19:00:50 +02:00
if expr.str in ['++', '--', '=']:
2017-04-08 16:08:54 +02:00
return True
# Todo: Check function calls
return hasSideEffects(expr.astOperand1) or hasSideEffects(expr.astOperand2)
2017-04-11 14:45:38 +02:00
def isBoolExpression(expr):
return expr and expr.str in ['!', '==', '!=', '<', '<=', '>', '>=', '&&', '||']
def misra_5_1(data):
2017-04-08 16:08:54 +02:00
for token in data.tokenlist:
if token.isName and len(token.str) > 31:
2017-04-11 14:45:38 +02:00
reportError(token, 51)
2017-04-08 16:08:54 +02:00
2017-04-11 14:45:38 +02:00
def misra_7_1(rawTokens):
2017-04-09 10:11:54 +02:00
for tok in rawTokens:
2017-04-11 14:45:38 +02:00
if re.match(r'^0[0-7]+$', tok.str):
reportError(tok, 71)
2017-04-08 16:08:54 +02:00
def misra_7_3(rawTokens):
for tok in rawTokens:
if re.match(r'^[0-9]+l+$', tok.str):
reportError(tok, 73)
2017-04-11 14:45:38 +02:00
def misra_13_5(data):
2017-04-08 16:08:54 +02:00
for token in data.tokenlist:
if token.isLogicalOp and hasSideEffects(token.astOperand2):
2017-04-11 14:45:38 +02:00
reportError(token, 135)
2017-04-08 16:08:54 +02:00
2017-04-11 14:45:38 +02:00
def misra_14_4(data):
2017-04-08 16:08:54 +02:00
for token in data.tokenlist:
2017-04-11 14:45:38 +02:00
if token.str != '(':
2017-04-08 19:00:50 +02:00
continue
2017-04-11 14:45:38 +02:00
if not token.astOperand1 or not (token.astOperand1.str in ['if', 'while']):
continue
if not isBoolExpression(token.astOperand2):
reportError(token, 144)
2017-04-08 16:08:54 +02:00
2017-04-11 14:45:38 +02:00
def misra_15_1(data):
2017-04-08 16:08:54 +02:00
for token in data.tokenlist:
2017-04-08 19:00:50 +02:00
if token.str == "goto":
2017-04-11 14:45:38 +02:00
reportError(token, 151)
2017-04-08 16:08:54 +02:00
for arg in sys.argv[1:]:
print('Checking ' + arg + '...')
data = cppcheckdata.parsedump(arg)
2017-04-09 10:11:54 +02:00
cfgNumber = 0
2017-04-08 16:08:54 +02:00
for cfg in data.configurations:
2017-04-09 10:11:54 +02:00
cfgNumber = cfgNumber + 1
2017-04-08 16:08:54 +02:00
if len(data.configurations) > 1:
print('Checking ' + arg + ', config "' + cfg.name + '"...')
2017-04-11 14:45:38 +02:00
misra_5_1(cfg)
if cfgNumber == 1:
misra_7_1(data.rawTokens)
misra_7_3(data.rawTokens)
2017-04-11 14:45:38 +02:00
misra_13_5(cfg)
misra_14_4(cfg)
misra_15_1(cfg)