blob: a3114adba74373d025ebf092de95c0d7b36c7fae [file] [log] [blame]
Jack Palevich609c9942009-06-25 11:49:43 -07001#
2# Test the acc compiler
3
4import unittest
5import subprocess
6import os
Jack Palevich59178c02009-07-13 14:15:18 -07007import sets
8
9gArmInitialized = False
Jack Palevich609c9942009-06-25 11:49:43 -070010
11def compile(args):
12 proc = subprocess.Popen(["acc"] + args, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
13 result = proc.communicate()
14 return result
15
16def runCmd(args):
17 proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
18 result = proc.communicate()
19 return result[0].strip()
20
21def which(item):
22 return runCmd(["which", item])
23
24def fileType(item):
25 return runCmd(["file", item])
26
27def outputCanRun():
28 ft = fileType(which("acc"))
29 return ft.find("ELF 32-bit LSB executable, Intel 80386") >= 0
30
31def adb(args):
32 return runCmd(["adb"] + args)
33
Jack Palevich609c9942009-06-25 11:49:43 -070034def setupArm():
Jack Palevich59178c02009-07-13 14:15:18 -070035 global gArmInitialized
Jack Palevich609c9942009-06-25 11:49:43 -070036 if gArmInitialized:
37 return
38 print "Setting up arm"
39 adb(["remount"])
40 adb(["shell", "rm", "/system/bin/acc"])
41 adb(["shell", "mkdir", "/system/bin/accdata"])
42 adb(["shell", "mkdir", "/system/bin/accdata/data"])
43 # Clear out old data TODO: handle recursion
44 adb(["shell", "rm", "/system/bin/accdata/data/*"])
45 # Copy over data
46 for root, dirs, files in os.walk("data"):
47 for d in dirs:
48 adb(["shell", "mkdir", os.path.join(root, d)])
49 for f in files:
50 adb(["push", os.path.join(root, f), os.path.join("/system/bin/accdata", root, f)])
51 # Copy over compiler
52 adb(["sync"])
Jack Palevich59178c02009-07-13 14:15:18 -070053 gArmInitialized = True
Jack Palevich609c9942009-06-25 11:49:43 -070054
55def compileArm(args):
56 setupArm()
57 proc = subprocess.Popen(["adb", "shell", "/system/bin/acc"] + args, stdout=subprocess.PIPE)
58 result = proc.communicate()
59 return result[0].replace("\r","")
60
61def compare(a, b):
62 if a != b:
Jack Palevich40600de2009-07-01 15:32:35 -070063 firstDiff = firstDifference(a, b)
Jack Palevichbab80642009-07-09 13:54:54 -070064 print "Strings differ at character %d. Common: %s. Difference '%s' != '%s'" % (
65 firstDiff, a[0:firstDiff], safeAccess(a, firstDiff), safeAccess(b, firstDiff))
Jack Palevich40600de2009-07-01 15:32:35 -070066
67def safeAccess(s, i):
68 if 0 <= i < len(s):
69 return s[i]
70 else:
71 return '?'
Jack Palevich609c9942009-06-25 11:49:43 -070072
73def firstDifference(a, b):
74 commonLen = min(len(a), len(b))
75 for i in xrange(0, commonLen):
76 if a[i] != b[i]:
77 return i
78 return commonLen
79
Jack Palevich45431bc2009-07-13 15:57:26 -070080# a1 and a2 are the expected stdout and stderr.
81# b1 and b2 are the actual stdout and stderr.
82# Compare the two, sets. Allow any individual line
83# to appear in either stdout or stderr. This is because
84# the way we obtain output on the ARM combines both
85# streams into one sequence.
86
87def compareOuput(a1,a2,b1,b2):
Jack Palevich59178c02009-07-13 14:15:18 -070088 while True:
89 totalLen = len(a1) + len(a2) + len(b1) + len(b2)
90 a1, b1 = matchCommon(a1, b1)
91 a1, b2 = matchCommon(a1, b2)
92 a2, b1 = matchCommon(a2, b1)
93 a2, b2 = matchCommon(a2, b2)
94 newTotalLen = len(a1) + len(a2) + len(b1) + len(b2)
95 if newTotalLen == 0:
96 return True
97 if newTotalLen == totalLen:
98 print "Failed at %d %d %d %d" % (len(a1), len(a2), len(b1), len(b2))
99 print "a1", a1
100 print "a2", a2
101 print "b1", b1
102 print "b2", b2
103 return False
104
105def matchCommon(a, b):
Jack Palevich45431bc2009-07-13 15:57:26 -0700106 """Remove common items from the beginning of a and b,
107 return just the tails that are different."""
Jack Palevich59178c02009-07-13 14:15:18 -0700108 while len(a) > 0 and len(b) > 0 and a[0] == b[0]:
109 a = a[1:]
110 b = b[1:]
111 return a, b
112
113def rewritePaths(args):
114 return [rewritePath(x) for x in args]
115
116def rewritePath(p):
Jack Palevich45431bc2009-07-13 15:57:26 -0700117 """Take a path that's correct on the x86 and convert to a path
118 that's correct on ARM."""
Jack Palevich59178c02009-07-13 14:15:18 -0700119 if p.startswith("data/"):
120 p = "/system/bin/accdata/" + p
121 return p
122
Jack Palevich609c9942009-06-25 11:49:43 -0700123class TestACC(unittest.TestCase):
Jack Palevich609c9942009-06-25 11:49:43 -0700124
Jack Palevich59178c02009-07-13 14:15:18 -0700125 def checkResult(self, out, err, stdErrResult, stdOutResult=""):
126 a1 = out.splitlines()
127 a2 = err.splitlines()
128 b2 = stdErrResult.splitlines()
129 b1 = stdOutResult.splitlines()
Jack Palevich45431bc2009-07-13 15:57:26 -0700130 self.assertEqual(True, compareOuput(a1,a2,b1,b2))
Jack Palevich89baa202009-07-23 11:45:15 -0700131
Jack Palevich59178c02009-07-13 14:15:18 -0700132 def compileCheck(self, args, stdErrResult, stdOutResult="",
133 targets=['arm', 'x86']):
134 targetSet = sets.ImmutableSet(targets)
Jack Palevich9f51a262009-07-29 16:22:26 -0700135 if False and 'x86' in targetSet:
Jack Palevich59178c02009-07-13 14:15:18 -0700136 out, err = compile(args)
137 self.checkResult(out, err, stdErrResult, stdOutResult)
138 if 'arm' in targetSet:
139 out = compileArm(rewritePaths(args))
140 self.checkResult(out, "", stdErrResult, stdOutResult)
141
Jack Palevich609c9942009-06-25 11:49:43 -0700142 def compileCheckArm(self, args, result):
143 self.assertEqual(compileArm(args), result)
144
145 def testCompileReturnVal(self):
Jack Palevich89baa202009-07-23 11:45:15 -0700146 self.compileCheck(["data/returnval-ansi.c"], "")
Jack Palevich609c9942009-06-25 11:49:43 -0700147
Jack Palevich59178c02009-07-13 14:15:18 -0700148 def testCompileOTCCANSII(self):
149 self.compileCheck(["data/otcc-ansi.c"], "", "", ['x86'])
Jack Palevich609c9942009-06-25 11:49:43 -0700150
151 def testRunReturnVal(self):
152 self.compileCheck(["-R", "data/returnval-ansi.c"],
Jack Palevich89baa202009-07-23 11:45:15 -0700153 "Executing compiled code:\nresult: 42\n")
Jack Palevich40600de2009-07-01 15:32:35 -0700154
Jack Palevichbab80642009-07-09 13:54:54 -0700155 def testStringLiteralConcatenation(self):
Jack Palevich40600de2009-07-01 15:32:35 -0700156 self.compileCheck(["-R", "data/testStringConcat.c"],
Jack Palevich89baa202009-07-23 11:45:15 -0700157 "Executing compiled code:\nresult: 13\n", "Hello, world\n")
Jack Palevich40600de2009-07-01 15:32:35 -0700158
Jack Palevich609c9942009-06-25 11:49:43 -0700159 def testRunOTCCANSI(self):
Jack Palevich89baa202009-07-23 11:45:15 -0700160 self.compileCheck(["-R", "data/otcc-ansi.c", "data/returnval.c"],
Jack Palevich59178c02009-07-13 14:15:18 -0700161 "Executing compiled code:\notcc-ansi.c: About to execute compiled code:\natcc-ansi.c: result: 42\nresult: 42\n", "",
162 ['x86'])
Jack Palevich609c9942009-06-25 11:49:43 -0700163
164 def testRunOTCCANSI2(self):
Jack Palevich89baa202009-07-23 11:45:15 -0700165 self.compileCheck(["-R", "data/otcc-ansi.c", "data/otcc.c", "data/returnval.c"],
Jack Palevich59178c02009-07-13 14:15:18 -0700166 "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", "",['x86'])
Jack Palevich609c9942009-06-25 11:49:43 -0700167
168 def testRunConstants(self):
169 self.compileCheck(["-R", "data/constants.c"],
170 "Executing compiled code:\nresult: 12\n",
171 "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" +
172 "'\\\"' = 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")
173
Jack Palevichbab80642009-07-09 13:54:54 -0700174 def testRunFloat(self):
175 self.compileCheck(["-R", "data/float.c"],
176 "Executing compiled code:\nresult: 0\n",
Jack Palevich2aaf21f2009-07-15 16:16:37 -0700177 """Constants: 0 0 0 0.01 0.01 0.1 10 10 0.1
178int: 1 float: 2.2 double: 3.3
179 ftoi(1.4f)=1
180 dtoi(2.4)=2
181 itof(3)=3
182 itod(4)=4
183globals: 1 2 3 4
184args: 1 2 3 4
185locals: 1 2 3 4
186cast rval: 2 4
187cast lval: 1.1 2 3.3 4
188""")
Jack Palevich89baa202009-07-23 11:45:15 -0700189
Jack Palevichbab80642009-07-09 13:54:54 -0700190 def testRunFlops(self):
191 self.compileCheck(["-R", "data/flops.c"],
Jack Palevich45431bc2009-07-13 15:57:26 -0700192 """Executing compiled code:
193result: 0""",
194"""-1.1 = -1.1
195!1.2 = 0
196!0 = 1
197double op double:
1981 + 2 = 3
1991 - 2 = -1
2001 * 2 = 2
2011 / 2 = 0.5
202float op float:
2031 + 2 = 3
2041 - 2 = -1
2051 * 2 = 2
2061 / 2 = 0.5
207double op float:
2081 + 2 = 3
2091 - 2 = -1
2101 * 2 = 2
2111 / 2 = 0.5
212double op int:
2131 + 2 = 3
2141 - 2 = -1
2151 * 2 = 2
2161 / 2 = 0.5
217int op double:
2181 + 2 = 3
2191 - 2 = -1
2201 * 2 = 2
2211 / 2 = 0.5
222double op double:
2231 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
2241 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2252 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
226double op float:
2271 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
2281 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2292 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
230float op float:
2311 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
2321 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2332 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
234int op double:
2351 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
2361 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2372 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
238double op int:
2391 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
2401 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2412 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
242branching: 1 0 1
Jack Palevichfd3db482009-07-14 19:39:36 -0700243testpassi: 1 2 3 4 5 6 7 8 9 10 11 12
244testpassf: 1 2 3 4 5 6 7 8 9 10 11 12
245testpassd: 1 2 3 4 5 6 7 8 9 10 11 12
246testpassi: 1 2 3 4 5 6 7 8 9 10 11 12
247testpassf: 1 2 3 4 5 6 7 8 9 10 11 12
248testpassd: 1 2 3 4 5 6 7 8 9 10 11 12
249testpassi: 1 2 3 4 5 6 7 8 9 10 11 12
250testpassf: 1 2 3 4 5 6 7 8 9 10 11 12
251testpassd: 1 2 3 4 5 6 7 8 9 10 11 12
Jack Palevich45431bc2009-07-13 15:57:26 -0700252testpassidf: 1 2 3
253""")
254 def testCasts(self):
255 self.compileCheck(["-R", "data/casts.c"],
256 """Executing compiled code:
257result: 0""", """Reading from a pointer: 3 3
258Writing to a pointer: 4
259Testing casts: 3 3 4.5 4
260Testing reading (int*): 4
261Testing writing (int*): 8 9
262Testing reading (char*): 0x78 0x56 0x34 0x12
263Testing writing (char*): 0x87654321
264f(10)
265Function pointer result: 70
266Testing read/write (float*): 8.8 9.9
267Testing read/write (double*): 8.8 9.9
268""")
Jack Palevich609c9942009-06-25 11:49:43 -0700269
Jack Palevich25c0cca2009-07-13 16:56:28 -0700270 def testChar(self):
271 self.compileCheck(["-R", "data/char.c"], """Executing compiled code:
272result: 0""", """a = 99, b = 41
273ga = 100, gb = 44""")
274
Jack Palevicha8f427f2009-07-13 18:40:08 -0700275 def testPointerArithmetic(self):
276 self.compileCheck(["-R", "data/pointers.c"], """Executing compiled code:
277result: 0""", """Pointer difference: 1 4
278Pointer addition: 2
279Pointer comparison to zero: 0 0 1
280Pointer comparison: 1 0 0 0 1
281""")
Jack Palevich37c54bd2009-07-14 18:35:36 -0700282 def testRollo3(self):
283 self.compileCheck(["-R", "data/rollo3.c"], """Executing compiled code:
284result: 10""", """""")
285
Jack Palevich8148c5b2009-07-16 18:24:47 -0700286 def testFloatDouble(self):
287 self.compileCheck(["-R", "data/floatdouble.c"], """Executing compiled code:
288result: 0""", """0.002 0.1 10""")
Jack Palevicha8f427f2009-07-13 18:40:08 -0700289
Jack Palevichddf7c9c2009-07-29 10:28:18 -0700290 def testIncDec(self):
291 self.compileCheck(["-R", "data/inc.c"], """Executing compiled code:
2920
2931
2942
2951
Jack Palevichaaac9282009-07-31 14:34:34 -07002961
2972
2981
2990
Jack Palevichddf7c9c2009-07-29 10:28:18 -0700300result: 0
301""","""""")
302
Jack Palevich89baa202009-07-23 11:45:15 -0700303 def testIops(self):
304 self.compileCheck(["-R", "data/iops.c"], """Executing compiled code:
305result: 0""", """Literals: 1 -1
306++
3070
3081
3092
3103
3114
3125
3136
3147
3158
3169
317--
31810
3199
3208
3217
3226
3235
3244
3253
3262
3271
3280
329""")
Jack Palevich25c0cca2009-07-13 16:56:28 -0700330
Jack Palevichbeb4fe92009-07-31 11:27:29 -0700331 def testFilm(self):
Jack Palevich8f361fa2009-07-30 16:19:43 -0700332 self.compileCheck(["-R", "data/film.c"], """Executing compiled code:
333result: 0""", """testing...
334Total bad: 0
335""")
Jack Palevichbeb4fe92009-07-31 11:27:29 -0700336
337 def testpointers2(self):
338 self.compileCheck(["-R", "data/pointers2.c"], """Executing compiled code:
339result: 0""", """a = 0, *pa = 0
340a = 2, *pa = 2
341a = 0, *pa = 0 **ppa = 0
342a = 2, *pa = 2 **ppa = 2
343a = 0, *pa = 0 **ppa = 0
344a = 2, *pa = 2 **ppa = 2
345""")
346
Jack Palevich0c017742009-07-31 12:00:39 -0700347 def testassignmentop(self):
348 self.compileCheck(["-R", "data/assignmentop.c"], """Executing compiled code:
349result: 0""", """2 *= 5 10
35020 /= 5 4
35117 %= 5 2
35217 += 5 22
35317 -= 5 12
35417<<= 1 34
35517>>= 1 8
35617&= 1 1
35717^= 1 16
35816|= 1 17
Jack Palevich96138992009-07-31 15:58:19 -0700359*f() = *f() + 10;
360f()
361f()
362a = 10
363*f() += 10;
364f()
365a = 10
Jack Palevich0c017742009-07-31 12:00:39 -0700366""")
367
Jack Palevich43aaee32009-07-31 14:01:37 -0700368 def testcomma(self):
369 self.compileCheck(["-R", "data/comma.c"], """Executing compiled code:
370result: 0""", """statement: 10
371if: a = 0
372while: b = 11
373for: b = 22
374return: 30
375arg: 12
376""")
377
Jack Palevich47cbea92009-07-31 15:25:53 -0700378 def testBrackets(self):
379 self.compileCheck(["-R", "data/brackets.c"], """Executing compiled code:
380Errors: 0
3812D Errors: 0
382result: 0
383""","""""")
384
Jack Palevichc9b8ffc2009-08-03 14:42:57 -0700385 def testShort(self):
386 self.compileCheck(["-R", "data/short.c"], """Executing compiled code:
387result: -2
388""","""""")
389
Jack Palevich609c9942009-06-25 11:49:43 -0700390if __name__ == '__main__':
391 if not outputCanRun():
392 print "Many tests are expected to fail, because acc is not a 32-bit x86 Linux executable."
393 unittest.main()
394