xref: /aosp_15_r20/external/capstone/suite/cstest/cstest_report.py (revision 9a0e4156d50a75a99ec4f1653a0e9602a5d45c18)
1#!/usr/bin/python
2
3import re
4import sys
5import getopt
6from subprocess import Popen, PIPE
7from pprint import pprint as ppr
8import os
9
10
11def Usage(s):
12	print 'Usage: {} -t <cstest_path> [-f <file_name.cs>] [-d <directory>]'.format(s)
13	sys.exit(-1)
14
15def get_report_file(toolpath, filepath, getDetails, cmt_out):
16	cmd = [toolpath, '-f', filepath]
17	process = Popen(cmd, stdout=PIPE, stderr=PIPE)
18	stdout, stderr = process.communicate()
19
20#	stdout
21	failed_tests = []
22#	print '---> stdout\n', stdout
23#	print '---> stderr\n', stderr
24	matches = re.finditer(r'\[\s+RUN\s+\]\s+(.*)\n\[\s+FAILED\s+\]', stdout)
25	for match in matches:
26		failed_tests.append(match.group(1))
27#	stderr
28	counter = 0
29	details = []
30	for line in stderr.split('\n'):
31		if '[  PASSED  ] 0 test(s).' in line:
32			break
33		elif 'LINE' in line:
34			continue
35		elif 'ERROR' in line and ' --- ' in line:
36			parts = line.split(' --- ')
37			try:
38				details.append((parts[1], failed_tests[counter], parts[2]))
39			except IndexError:
40				details.append(('', 'Unknown test', line.split(' --- ')[1]))
41			counter += 1
42		else:
43			continue
44	print '\n[-] There are/is {} failed test(s)'.format(len(details))
45	if len(details) > 0 and getDetails:
46		print '[-] Detailed report for {}:\n'.format(filepath)
47		for c, f, d in details:
48			print '\t[+] {}: {}\n\t\t{}\n'.format(f, c, d)
49		print '\n'
50		return 0
51	elif len(details) > 0:
52		for c, f, d in details:
53			if len(f) > 0 and cmt_out is True:
54				tmp_cmd = ['sed', '-E', '-i.bak', 's/({})(.*)/\/\/ \\1\\2/g'.format(c), filepath]
55				sed_proc = Popen(tmp_cmd, stdout=PIPE, stderr=PIPE)
56				sed_proc.communicate()
57				tmp_cmd2 = ['rm', '-f', filepath + '.bak']
58				rm_proc = Popen(tmp_cmd2, stdout=PIPE, stderr=PIPE)
59				rm_proc.communicate()
60
61		return 0;
62	return 1
63
64def get_report_folder(toolpath, folderpath, details, cmt_out):
65	result = 1
66	for root, dirs, files in os.walk(folderpath):
67		path = root.split(os.sep)
68		for f in files:
69			if f.split('.')[-1] == 'cs':
70				print '[-] Target:', f,
71				result *= get_report_file(toolpath, os.sep.join(x for x in path) + os.sep + f, details, cmt_out)
72
73	sys.exit(result ^ 1)
74
75if __name__ == '__main__':
76	Done = False
77	details = False
78	toolpath = ''
79	cmt_out = False
80	try:
81		opts, args = getopt.getopt(sys.argv[1:], "ct:f:d:D")
82		for opt, arg in opts:
83			if opt == '-f':
84				result = get_report_file(toolpath, arg, details, cmt_out)
85				if result == 0:
86					sys.exit(1)
87				Done = True
88			elif opt == '-d':
89				get_report_folder(toolpath, arg, details, cmt_out)
90				Done = True
91			elif opt == '-t':
92				toolpath = arg
93			elif opt == '-D':
94				details = True
95			elif opt == '-c':
96				cmt_out = True
97
98	except getopt.GetoptError:
99		Usage(sys.argv[0])
100
101	if Done is False:
102		Usage(sys.argv[0])
103