blob: 77c66093cfe386a84a4169b824c0943cf49a7e2a [file] [log] [blame]
Jack Palevich609c9942009-06-25 11:49:43 -07001#
2# Test the acc compiler
3
4import unittest
5import subprocess
6import os
7
8def compile(args):
9 proc = subprocess.Popen(["acc"] + args, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
10 result = proc.communicate()
11 return result
12
13def runCmd(args):
14 proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
15 result = proc.communicate()
16 return result[0].strip()
17
18def which(item):
19 return runCmd(["which", item])
20
21def fileType(item):
22 return runCmd(["file", item])
23
24def outputCanRun():
25 ft = fileType(which("acc"))
26 return ft.find("ELF 32-bit LSB executable, Intel 80386") >= 0
27
28def adb(args):
29 return runCmd(["adb"] + args)
30
31gArmInitialized = False
32
33def setupArm():
34 if gArmInitialized:
35 return
36 print "Setting up arm"
37 adb(["remount"])
38 adb(["shell", "rm", "/system/bin/acc"])
39 adb(["shell", "mkdir", "/system/bin/accdata"])
40 adb(["shell", "mkdir", "/system/bin/accdata/data"])
41 # Clear out old data TODO: handle recursion
42 adb(["shell", "rm", "/system/bin/accdata/data/*"])
43 # Copy over data
44 for root, dirs, files in os.walk("data"):
45 for d in dirs:
46 adb(["shell", "mkdir", os.path.join(root, d)])
47 for f in files:
48 adb(["push", os.path.join(root, f), os.path.join("/system/bin/accdata", root, f)])
49 # Copy over compiler
50 adb(["sync"])
51 gArmInitialied = True
52
53def compileArm(args):
54 setupArm()
55 proc = subprocess.Popen(["adb", "shell", "/system/bin/acc"] + args, stdout=subprocess.PIPE)
56 result = proc.communicate()
57 return result[0].replace("\r","")
58
59def compare(a, b):
60 if a != b:
Jack Palevich40600de2009-07-01 15:32:35 -070061 firstDiff = firstDifference(a, b)
Jack Palevichbab80642009-07-09 13:54:54 -070062 print "Strings differ at character %d. Common: %s. Difference '%s' != '%s'" % (
63 firstDiff, a[0:firstDiff], safeAccess(a, firstDiff), safeAccess(b, firstDiff))
Jack Palevich40600de2009-07-01 15:32:35 -070064
65def safeAccess(s, i):
66 if 0 <= i < len(s):
67 return s[i]
68 else:
69 return '?'
Jack Palevich609c9942009-06-25 11:49:43 -070070
71def firstDifference(a, b):
72 commonLen = min(len(a), len(b))
73 for i in xrange(0, commonLen):
74 if a[i] != b[i]:
75 return i
76 return commonLen
77
78class TestACC(unittest.TestCase):
79
80 def compileCheck(self, args, stdErrResult, stdOutResult=""):
81 out, err = compile(args)
82 compare(out, stdOutResult)
83 compare(err, stdErrResult)
84 self.assertEqual(out, stdOutResult)
85 self.assertEqual(err, stdErrResult)
86
87 def compileCheckArm(self, args, result):
88 self.assertEqual(compileArm(args), result)
89
90 def testCompileReturnVal(self):
91 self.compileCheck(["data/returnval-ansi.c"], "")
92
93 def testCompileReturnVal(self):
94 self.compileCheck(["data/otcc-ansi.c"], "")
95
96 def testRunReturnVal(self):
97 self.compileCheck(["-R", "data/returnval-ansi.c"],
98 "Executing compiled code:\nresult: 42\n")
Jack Palevich40600de2009-07-01 15:32:35 -070099
Jack Palevichbab80642009-07-09 13:54:54 -0700100 def testStringLiteralConcatenation(self):
Jack Palevich40600de2009-07-01 15:32:35 -0700101 self.compileCheck(["-R", "data/testStringConcat.c"],
102 "Executing compiled code:\nresult: 13\n", "Hello, world\n")
103
Jack Palevich609c9942009-06-25 11:49:43 -0700104 def testRunOTCCANSI(self):
105 self.compileCheck(["-R", "data/otcc-ansi.c", "data/returnval.c"],
106 "Executing compiled code:\notcc-ansi.c: About to execute compiled code:\natcc-ansi.c: result: 42\nresult: 42\n")
107
108 def testRunOTCCANSI2(self):
109 self.compileCheck(["-R", "data/otcc-ansi.c", "data/otcc.c", "data/returnval.c"],
110 "Executing compiled code:\notcc-ansi.c: About to execute compiled code:\notcc.c: about to execute compiled code.\natcc-ansi.c: result: 42\nresult: 42\n")
111
112 def testRunConstants(self):
113 self.compileCheck(["-R", "data/constants.c"],
114 "Executing compiled code:\nresult: 12\n",
115 "0 = 0\n010 = 8\n0x10 = 16\n'\\a' = 7\n'\\b' = 8\n'\\f' = 12\n'\\n' = 10\n'\\r' = 13\n'\\t' = 9\n'\\v' = 11\n'\\\\' = 92\n'\\'' = 39\n" +
116 "'\\\"' = 34\n'\\?' = 63\n'\\0' = 0\n'\\1' = 1\n'\\12' = 10\n'\\123' = 83\n'\\x0' = 0\n'\\x1' = 1\n'\\x12' = 18\n'\\x123' = 291\n'\\x1f' = 31\n'\\x1F' = 31\n")
117
Jack Palevichbab80642009-07-09 13:54:54 -0700118 def testRunFloat(self):
119 self.compileCheck(["-R", "data/float.c"],
120 "Executing compiled code:\nresult: 0\n",
121 "int: 1 float: 2.2 double: 3.3\n ftoi(1.4f)=1\n dtoi(2.4f)=2\n itof(3)=3\n itod(4)=4\nglobals: 1 2 3 4\nargs: 1 2 3 4\nlocals: 1 2 3 4\ncast rval: 2 4\ncast lval: 1.1 2 3.3 4\n")
122
123 def testRunFlops(self):
124 self.compileCheck(["-R", "data/flops.c"],
125 "Executing compiled code:\nresult: 0\n",
126 "-1.1 = -1.1\n" +
127 "!1.2 = 0\n" +
128 "!0 = 1\n" +
129 "double op double:\n" +
130 "1 + 2 = 3\n" +
131 "1 - 2 = -1\n" +
132 "1 * 2 = 2\n" +
133 "1 / 2 = 0.5\n" +
134 "float op float:\n" +
135 "1 + 2 = 3\n" +
136 "1 - 2 = -1\n" +
137 "1 * 2 = 2\n" +
138 "1 / 2 = 0.5\n" +
139 "double op float:\n" +
140 "1 + 2 = 3\n" +
141 "1 - 2 = -1\n" +
142 "1 * 2 = 2\n" +
143 "1 / 2 = 0.5\n" +
144 "double op int:\n" +
145 "1 + 2 = 3\n" +
146 "1 - 2 = -1\n" +
147 "1 * 2 = 2\n" +
148 "1 / 2 = 0.5\n" +
149 "int op double:\n" +
150 "1 + 2 = 3\n" +
151 "1 - 2 = -1\n" +
152 "1 * 2 = 2\n" +
153 "1 / 2 = 0.5\n" +
154 "double op double:\n" +
155 "1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1\n" +
156 "1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0\n" +
157 "2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1\n" +
158 "double op float:\n" +
159 "1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1\n" +
160 "1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0\n" +
161 "2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1\n" +
162 "float op float:\n" +
163 "1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1\n" +
164 "1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0\n" +
165 "2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1\n" +
166 "int op double:\n" +
167 "1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1\n" +
168 "1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0\n" +
169 "2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1\n" +
170 "double op int:\n" +
171 "1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1\n" +
172 "1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0\n" +
173 "2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1\n" +
174 "branching: 1 0 1\n")
175
Jack Palevich609c9942009-06-25 11:49:43 -0700176 def testArmRunReturnVal(self):
177 self.compileCheckArm(["-R", "/system/bin/accdata/data/returnval-ansi.c"],
178 "Executing compiled code:\nresult: 42\n")
179
180if __name__ == '__main__':
181 if not outputCanRun():
182 print "Many tests are expected to fail, because acc is not a 32-bit x86 Linux executable."
183 unittest.main()
184