Added script reduce.py that reduces code. It can complement the reduce tool. It can also be used with other tools and not just cppcheck.
This commit is contained in:
parent
b7efc7793a
commit
49ff511324
|
@ -0,0 +1,233 @@
|
|||
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
|
||||
CMD = None
|
||||
EXPECTED = None
|
||||
SEGFAULT = False
|
||||
FILE = None
|
||||
BACKUPFILE = None
|
||||
for arg in sys.argv[1:]:
|
||||
if arg.startswith('--cmd='):
|
||||
CMD = arg[arg.find('=')+1:]
|
||||
elif arg.startswith('--expected='):
|
||||
EXPECTED = arg[arg.find('=')+1:]
|
||||
elif arg.startswith('--file='):
|
||||
FILE = arg[arg.find('=')+1:]
|
||||
BACKUPFILE = FILE + '.bak'
|
||||
elif arg == '--segfault':
|
||||
SEGFAULT = True
|
||||
|
||||
if CMD is None:
|
||||
print('Abort: No --cmd')
|
||||
sys.exit(1)
|
||||
|
||||
if SEGFAULT == False and EXPECTED is None:
|
||||
print('Abort: No --expected')
|
||||
sys.exit(1)
|
||||
|
||||
if FILE is None:
|
||||
print('Abort: No --file')
|
||||
sys.exit(1)
|
||||
|
||||
print('CMD='+CMD)
|
||||
if SEGFAULT:
|
||||
print('EXPECTED=SEGFAULT')
|
||||
else:
|
||||
print('EXPECTED='+EXPECTED)
|
||||
print('FILE='+FILE)
|
||||
|
||||
def runtool():
|
||||
p = subprocess.Popen(CMD.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
comm = p.communicate()
|
||||
if SEGFAULT:
|
||||
if p.returncode != 0:
|
||||
return True
|
||||
elif p.returncode == 0:
|
||||
out = comm[0] + '\n' + comm[1]
|
||||
if (out.find('error:') < 0) and (out.find(EXPECTED) > 0):
|
||||
return True
|
||||
return False
|
||||
|
||||
def writefile(filename, filedata):
|
||||
f = open(filename, 'wt')
|
||||
for line in filedata:
|
||||
f.write(line)
|
||||
f.close()
|
||||
|
||||
def replaceandrun(what, filedata, i, line):
|
||||
print(what + ' ' + str(i+1) + '/' + str(len(filedata)) + '..')
|
||||
bak = filedata[i]
|
||||
filedata[i] = line
|
||||
writefile(FILE, filedata)
|
||||
if runtool() == True:
|
||||
print('pass')
|
||||
writefile(BACKUPFILE, filedata)
|
||||
return True
|
||||
print('fail')
|
||||
filedata[i] = bak
|
||||
return False
|
||||
|
||||
def replaceandrun2(what, filedata, i, line1, line2):
|
||||
print(what + ' ' + str(i+1) + '/' + str(len(filedata)) + '..')
|
||||
bak1 = filedata[i]
|
||||
bak2 = filedata[i+1]
|
||||
filedata[i] = line1
|
||||
filedata[i+1] = line2
|
||||
writefile(FILE, filedata)
|
||||
if runtool() == True:
|
||||
print('pass')
|
||||
writefile(BACKUPFILE, filedata)
|
||||
else:
|
||||
print('fail')
|
||||
filedata[i] = bak1
|
||||
filedata[i+1] = bak2
|
||||
|
||||
def removecomments(filedata):
|
||||
for i in range(len(filedata)):
|
||||
line = filedata[i]
|
||||
if line.find('//') >= 0:
|
||||
replaceandrun('remove comment', filedata, i, line[:line.find('//')].rstrip())
|
||||
|
||||
def checkpar(line):
|
||||
par = 0
|
||||
for c in line:
|
||||
if c=='(' or c=='[':
|
||||
par = par + 1
|
||||
elif c==')' or c==']':
|
||||
par = par - 1
|
||||
if par<0:
|
||||
return False
|
||||
return par == 0
|
||||
|
||||
def combinelines(filedata):
|
||||
if len(filedata) < 3:
|
||||
return
|
||||
for i in range(len(filedata)-1):
|
||||
fd1 = filedata[i].rstrip()
|
||||
if fd1.endswith(','):
|
||||
fd2 = filedata[i+1].lstrip()
|
||||
replaceandrun2('combine lines', filedata, i, fd1+fd2, '')
|
||||
|
||||
def removeline(filedata):
|
||||
stmt = True
|
||||
for i in range(len(filedata)):
|
||||
line = filedata[i]
|
||||
strippedline = line.strip()
|
||||
|
||||
if len(strippedline) == 0:
|
||||
continue
|
||||
|
||||
if stmt and strippedline[-1]==';' and checkpar(line) and line.find('{')<0 and line.find('}')<0:
|
||||
replaceandrun('remove line', filedata, i, '')
|
||||
|
||||
elif stmt and strippedline.find('{') > 0 and strippedline.find('}') == len(strippedline) - 1:
|
||||
replaceandrun('remove line', filedata, i, '')
|
||||
|
||||
if ';{}'.find(strippedline[-1]) >= 0:
|
||||
stmt = True
|
||||
else:
|
||||
stmt = False
|
||||
|
||||
|
||||
def removeincludes(filedata):
|
||||
for i in range(len(filedata)):
|
||||
if filedata[i].startswith('#include '):
|
||||
replaceandrun('remove #include', filedata, i, '')
|
||||
|
||||
def removeemptyblocks(filedata):
|
||||
if len(filedata) < 3:
|
||||
return
|
||||
|
||||
i = 0
|
||||
while i < len(filedata):
|
||||
if filedata[i].strip() == '':
|
||||
filedata.pop(i)
|
||||
else:
|
||||
i = i + 1
|
||||
|
||||
for i in range(len(filedata)-1):
|
||||
fd1 = filedata[i].rstrip()
|
||||
fd2 = filedata[i+1].strip()
|
||||
if checkpar(fd1) and fd1.endswith('{') and fd2 == '}':
|
||||
replaceandrun2('remove block', filedata, i, '', '')
|
||||
|
||||
def removenamespaces(filedata):
|
||||
if len(filedata) < 3:
|
||||
return filedata
|
||||
|
||||
stmt = True
|
||||
|
||||
for i in range(len(filedata)):
|
||||
line = filedata[i]
|
||||
strippedline = line.strip()
|
||||
|
||||
if len(strippedline) == 0:
|
||||
continue
|
||||
|
||||
stmt1 = stmt
|
||||
if ';{}'.find(strippedline[-1]) >= 0:
|
||||
stmt = True
|
||||
else:
|
||||
stmt = False
|
||||
|
||||
if stmt1 == False:
|
||||
continue
|
||||
|
||||
if strippedline.find('}') < 0 and strippedline.find('{') == len(strippedline)-1:
|
||||
i2 = i + 1
|
||||
level = 1
|
||||
while i2 < len(filedata) and level > 0:
|
||||
#print(str(i2)+':'+str(level)+':'+filedata[i2])
|
||||
for c in filedata[i2]:
|
||||
if c == '}':
|
||||
level = level - 1
|
||||
if level <= 0:
|
||||
break
|
||||
elif c == '{':
|
||||
level = level + 1
|
||||
i2 = i2 + 1
|
||||
if level == 0 and (filedata[i2-1].strip().endswith('}') or filedata[i2-1].strip().endswith('};')):
|
||||
#print(str(i)+';'+str(i2))
|
||||
filedata2 = list(filedata)
|
||||
ii = i
|
||||
while ii < i2:
|
||||
filedata2[ii] = ''
|
||||
ii = ii + 1
|
||||
if replaceandrun('remove codeblock', filedata2, i, ''):
|
||||
filedata = filedata2
|
||||
return filedata
|
||||
|
||||
# reduce..
|
||||
print('Make sure error can be reproduced...')
|
||||
if runtool() == False:
|
||||
print("Cannot reproduce")
|
||||
sys.exit(1)
|
||||
|
||||
f = open(FILE, 'rt')
|
||||
filedata = f.readlines()
|
||||
f.close()
|
||||
|
||||
writefile(BACKUPFILE, filedata)
|
||||
|
||||
print('remove comments...')
|
||||
removecomments(filedata)
|
||||
print('combine lines..')
|
||||
combinelines(filedata)
|
||||
print('remove namespaces...')
|
||||
filedata = removenamespaces(filedata)
|
||||
print('remove includes...')
|
||||
removeincludes(filedata)
|
||||
print('remove line...')
|
||||
removeline(filedata)
|
||||
print('remove includes...')
|
||||
removeincludes(filedata)
|
||||
print('remove empty blocks...')
|
||||
removeemptyblocks(filedata)
|
||||
print('remove namespaces...')
|
||||
filedata = removenamespaces(filedata)
|
||||
|
||||
|
||||
|
||||
writefile(FILE, filedata)
|
Loading…
Reference in New Issue