blob: ab85f10be433f3e2faabb5ad1cec74f5745663af [file] [log] [blame]
Jack Palevich609c9942009-06-25 11:49:43 -07001#
2# Test the acc compiler
3
4import unittest
5import subprocess
6import os
Jack Palevich0b2de0d2009-08-18 16:04:03 -07007import sys
Jack Palevich59178c02009-07-13 14:15:18 -07008
9gArmInitialized = False
Jack Palevich0b2de0d2009-08-18 16:04:03 -070010gUseArm = True
11gUseX86 = True
12gRunOTCCOutput = True
13
14
15def parseArgv():
16 global gUseArm
Jack Palevichd3abe3c2009-08-19 11:12:56 -070017 global gUseX86
Jack Palevich0b2de0d2009-08-18 16:04:03 -070018 global gRunOTCCOutput
19 for arg in sys.argv[1:]:
20 if arg == "--noarm":
Jack Palevichd3abe3c2009-08-19 11:12:56 -070021 print "--noarm: not testing ARM"
Jack Palevich0b2de0d2009-08-18 16:04:03 -070022 gUseArm = False
Jack Palevichd3abe3c2009-08-19 11:12:56 -070023 elif arg == "--nox86":
24 print "--nox86: not testing x86"
25 gUseX86 = False
Jack Palevich0b2de0d2009-08-18 16:04:03 -070026 elif arg == "--norunotcc":
27 print "--norunotcc detected, not running OTCC output"
28 gRunOTCCOutput = False
29 else:
30 print "Unknown parameter: ", arg
31 raise "Unknown parameter"
32 sys.argv = sys.argv[0:1]
Jack Palevich609c9942009-06-25 11:49:43 -070033
34def compile(args):
35 proc = subprocess.Popen(["acc"] + args, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
36 result = proc.communicate()
37 return result
38
39def runCmd(args):
40 proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
41 result = proc.communicate()
42 return result[0].strip()
43
44def which(item):
45 return runCmd(["which", item])
46
47def fileType(item):
48 return runCmd(["file", item])
49
50def outputCanRun():
51 ft = fileType(which("acc"))
52 return ft.find("ELF 32-bit LSB executable, Intel 80386") >= 0
53
54def adb(args):
55 return runCmd(["adb"] + args)
56
Jack Palevich609c9942009-06-25 11:49:43 -070057def setupArm():
Jack Palevich59178c02009-07-13 14:15:18 -070058 global gArmInitialized
Jack Palevich609c9942009-06-25 11:49:43 -070059 if gArmInitialized:
60 return
61 print "Setting up arm"
62 adb(["remount"])
63 adb(["shell", "rm", "/system/bin/acc"])
64 adb(["shell", "mkdir", "/system/bin/accdata"])
65 adb(["shell", "mkdir", "/system/bin/accdata/data"])
66 # Clear out old data TODO: handle recursion
67 adb(["shell", "rm", "/system/bin/accdata/data/*"])
68 # Copy over data
69 for root, dirs, files in os.walk("data"):
70 for d in dirs:
71 adb(["shell", "mkdir", os.path.join(root, d)])
72 for f in files:
73 adb(["push", os.path.join(root, f), os.path.join("/system/bin/accdata", root, f)])
74 # Copy over compiler
75 adb(["sync"])
Jack Palevich59178c02009-07-13 14:15:18 -070076 gArmInitialized = True
Jack Palevich609c9942009-06-25 11:49:43 -070077
78def compileArm(args):
79 setupArm()
80 proc = subprocess.Popen(["adb", "shell", "/system/bin/acc"] + args, stdout=subprocess.PIPE)
81 result = proc.communicate()
82 return result[0].replace("\r","")
83
84def compare(a, b):
85 if a != b:
Jack Palevich40600de2009-07-01 15:32:35 -070086 firstDiff = firstDifference(a, b)
Jack Palevichbab80642009-07-09 13:54:54 -070087 print "Strings differ at character %d. Common: %s. Difference '%s' != '%s'" % (
88 firstDiff, a[0:firstDiff], safeAccess(a, firstDiff), safeAccess(b, firstDiff))
Jack Palevich40600de2009-07-01 15:32:35 -070089
90def safeAccess(s, i):
91 if 0 <= i < len(s):
92 return s[i]
93 else:
94 return '?'
Jack Palevich609c9942009-06-25 11:49:43 -070095
96def firstDifference(a, b):
97 commonLen = min(len(a), len(b))
98 for i in xrange(0, commonLen):
99 if a[i] != b[i]:
100 return i
101 return commonLen
102
Jack Palevich45431bc2009-07-13 15:57:26 -0700103# a1 and a2 are the expected stdout and stderr.
104# b1 and b2 are the actual stdout and stderr.
105# Compare the two, sets. Allow any individual line
106# to appear in either stdout or stderr. This is because
107# the way we obtain output on the ARM combines both
108# streams into one sequence.
109
110def compareOuput(a1,a2,b1,b2):
Jack Palevich59178c02009-07-13 14:15:18 -0700111 while True:
112 totalLen = len(a1) + len(a2) + len(b1) + len(b2)
113 a1, b1 = matchCommon(a1, b1)
114 a1, b2 = matchCommon(a1, b2)
115 a2, b1 = matchCommon(a2, b1)
116 a2, b2 = matchCommon(a2, b2)
117 newTotalLen = len(a1) + len(a2) + len(b1) + len(b2)
118 if newTotalLen == 0:
119 return True
120 if newTotalLen == totalLen:
121 print "Failed at %d %d %d %d" % (len(a1), len(a2), len(b1), len(b2))
122 print "a1", a1
123 print "a2", a2
124 print "b1", b1
125 print "b2", b2
126 return False
127
128def matchCommon(a, b):
Jack Palevich45431bc2009-07-13 15:57:26 -0700129 """Remove common items from the beginning of a and b,
130 return just the tails that are different."""
Jack Palevich59178c02009-07-13 14:15:18 -0700131 while len(a) > 0 and len(b) > 0 and a[0] == b[0]:
132 a = a[1:]
133 b = b[1:]
134 return a, b
135
136def rewritePaths(args):
137 return [rewritePath(x) for x in args]
138
139def rewritePath(p):
Jack Palevich45431bc2009-07-13 15:57:26 -0700140 """Take a path that's correct on the x86 and convert to a path
141 that's correct on ARM."""
Jack Palevich59178c02009-07-13 14:15:18 -0700142 if p.startswith("data/"):
143 p = "/system/bin/accdata/" + p
144 return p
145
Jack Palevich609c9942009-06-25 11:49:43 -0700146class TestACC(unittest.TestCase):
Jack Palevich609c9942009-06-25 11:49:43 -0700147
Jack Palevich59178c02009-07-13 14:15:18 -0700148 def checkResult(self, out, err, stdErrResult, stdOutResult=""):
149 a1 = out.splitlines()
150 a2 = err.splitlines()
151 b2 = stdErrResult.splitlines()
152 b1 = stdOutResult.splitlines()
Jack Palevich45431bc2009-07-13 15:57:26 -0700153 self.assertEqual(True, compareOuput(a1,a2,b1,b2))
Jack Palevich89baa202009-07-23 11:45:15 -0700154
Jack Palevich59178c02009-07-13 14:15:18 -0700155 def compileCheck(self, args, stdErrResult, stdOutResult="",
156 targets=['arm', 'x86']):
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700157 global gUseArm
158 global gUseX86
159 targetSet = frozenset(targets)
160 if gUseX86 and 'x86' in targetSet:
Jack Palevich59178c02009-07-13 14:15:18 -0700161 out, err = compile(args)
162 self.checkResult(out, err, stdErrResult, stdOutResult)
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700163 if gUseArm and 'arm' in targetSet:
Jack Palevich59178c02009-07-13 14:15:18 -0700164 out = compileArm(rewritePaths(args))
165 self.checkResult(out, "", stdErrResult, stdOutResult)
166
Jack Palevich609c9942009-06-25 11:49:43 -0700167 def compileCheckArm(self, args, result):
168 self.assertEqual(compileArm(args), result)
169
170 def testCompileReturnVal(self):
Jack Palevich89baa202009-07-23 11:45:15 -0700171 self.compileCheck(["data/returnval-ansi.c"], "")
Jack Palevich609c9942009-06-25 11:49:43 -0700172
Jack Palevich59178c02009-07-13 14:15:18 -0700173 def testCompileOTCCANSII(self):
174 self.compileCheck(["data/otcc-ansi.c"], "", "", ['x86'])
Jack Palevich609c9942009-06-25 11:49:43 -0700175
176 def testRunReturnVal(self):
177 self.compileCheck(["-R", "data/returnval-ansi.c"],
Jack Palevich89baa202009-07-23 11:45:15 -0700178 "Executing compiled code:\nresult: 42\n")
Jack Palevich40600de2009-07-01 15:32:35 -0700179
Jack Palevichbab80642009-07-09 13:54:54 -0700180 def testStringLiteralConcatenation(self):
Jack Palevich40600de2009-07-01 15:32:35 -0700181 self.compileCheck(["-R", "data/testStringConcat.c"],
Jack Palevich89baa202009-07-23 11:45:15 -0700182 "Executing compiled code:\nresult: 13\n", "Hello, world\n")
Jack Palevich40600de2009-07-01 15:32:35 -0700183
Jack Palevich609c9942009-06-25 11:49:43 -0700184 def testRunOTCCANSI(self):
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700185 global gRunOTCCOutput
186 if gRunOTCCOutput:
187 self.compileCheck(["-R", "data/otcc-ansi.c", "data/returnval.c"],
188 "Executing compiled code:\notcc-ansi.c: About to execute compiled code:\natcc-ansi.c: result: 42\nresult: 42\n", "",
189 ['x86'])
Jack Palevich609c9942009-06-25 11:49:43 -0700190
191 def testRunOTCCANSI2(self):
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700192 global gRunOTCCOutput
193 if gRunOTCCOutput:
194 self.compileCheck(["-R", "data/otcc-ansi.c", "data/otcc.c", "data/returnval.c"],
195 "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 -0700196
197 def testRunConstants(self):
198 self.compileCheck(["-R", "data/constants.c"],
199 "Executing compiled code:\nresult: 12\n",
200 "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" +
201 "'\\\"' = 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")
202
Jack Palevichbab80642009-07-09 13:54:54 -0700203 def testRunFloat(self):
204 self.compileCheck(["-R", "data/float.c"],
205 "Executing compiled code:\nresult: 0\n",
Jack Palevich2aaf21f2009-07-15 16:16:37 -0700206 """Constants: 0 0 0 0.01 0.01 0.1 10 10 0.1
207int: 1 float: 2.2 double: 3.3
208 ftoi(1.4f)=1
209 dtoi(2.4)=2
210 itof(3)=3
211 itod(4)=4
212globals: 1 2 3 4
213args: 1 2 3 4
214locals: 1 2 3 4
215cast rval: 2 4
216cast lval: 1.1 2 3.3 4
217""")
Jack Palevich89baa202009-07-23 11:45:15 -0700218
Jack Palevichbab80642009-07-09 13:54:54 -0700219 def testRunFlops(self):
220 self.compileCheck(["-R", "data/flops.c"],
Jack Palevich45431bc2009-07-13 15:57:26 -0700221 """Executing compiled code:
222result: 0""",
223"""-1.1 = -1.1
224!1.2 = 0
225!0 = 1
226double op double:
2271 + 2 = 3
2281 - 2 = -1
2291 * 2 = 2
2301 / 2 = 0.5
231float op float:
2321 + 2 = 3
2331 - 2 = -1
2341 * 2 = 2
2351 / 2 = 0.5
236double op float:
2371 + 2 = 3
2381 - 2 = -1
2391 * 2 = 2
2401 / 2 = 0.5
241double op int:
2421 + 2 = 3
2431 - 2 = -1
2441 * 2 = 2
2451 / 2 = 0.5
246int op double:
2471 + 2 = 3
2481 - 2 = -1
2491 * 2 = 2
2501 / 2 = 0.5
251double op double:
2521 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
2531 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2542 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
255double op float:
2561 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
2571 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2582 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
259float op float:
2601 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
2611 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2622 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
263int op double:
2641 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
2651 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2662 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
267double op int:
2681 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
2691 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2702 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
271branching: 1 0 1
Jack Palevichfd3db482009-07-14 19:39:36 -0700272testpassi: 1 2 3 4 5 6 7 8 9 10 11 12
273testpassf: 1 2 3 4 5 6 7 8 9 10 11 12
274testpassd: 1 2 3 4 5 6 7 8 9 10 11 12
275testpassi: 1 2 3 4 5 6 7 8 9 10 11 12
276testpassf: 1 2 3 4 5 6 7 8 9 10 11 12
277testpassd: 1 2 3 4 5 6 7 8 9 10 11 12
278testpassi: 1 2 3 4 5 6 7 8 9 10 11 12
279testpassf: 1 2 3 4 5 6 7 8 9 10 11 12
280testpassd: 1 2 3 4 5 6 7 8 9 10 11 12
Jack Palevich45431bc2009-07-13 15:57:26 -0700281testpassidf: 1 2 3
282""")
283 def testCasts(self):
284 self.compileCheck(["-R", "data/casts.c"],
285 """Executing compiled code:
286result: 0""", """Reading from a pointer: 3 3
287Writing to a pointer: 4
288Testing casts: 3 3 4.5 4
289Testing reading (int*): 4
290Testing writing (int*): 8 9
291Testing reading (char*): 0x78 0x56 0x34 0x12
292Testing writing (char*): 0x87654321
293f(10)
294Function pointer result: 70
295Testing read/write (float*): 8.8 9.9
296Testing read/write (double*): 8.8 9.9
297""")
Jack Palevich609c9942009-06-25 11:49:43 -0700298
Jack Palevich25c0cca2009-07-13 16:56:28 -0700299 def testChar(self):
300 self.compileCheck(["-R", "data/char.c"], """Executing compiled code:
301result: 0""", """a = 99, b = 41
302ga = 100, gb = 44""")
303
Jack Palevicha8f427f2009-07-13 18:40:08 -0700304 def testPointerArithmetic(self):
305 self.compileCheck(["-R", "data/pointers.c"], """Executing compiled code:
306result: 0""", """Pointer difference: 1 4
307Pointer addition: 2
308Pointer comparison to zero: 0 0 1
309Pointer comparison: 1 0 0 0 1
310""")
Jack Palevich37c54bd2009-07-14 18:35:36 -0700311 def testRollo3(self):
312 self.compileCheck(["-R", "data/rollo3.c"], """Executing compiled code:
313result: 10""", """""")
314
Jack Palevich8148c5b2009-07-16 18:24:47 -0700315 def testFloatDouble(self):
316 self.compileCheck(["-R", "data/floatdouble.c"], """Executing compiled code:
317result: 0""", """0.002 0.1 10""")
Jack Palevicha8f427f2009-07-13 18:40:08 -0700318
Jack Palevichddf7c9c2009-07-29 10:28:18 -0700319 def testIncDec(self):
320 self.compileCheck(["-R", "data/inc.c"], """Executing compiled code:
3210
3221
3232
3241
Jack Palevichaaac9282009-07-31 14:34:34 -07003251
3262
3271
3280
Jack Palevichddf7c9c2009-07-29 10:28:18 -0700329result: 0
330""","""""")
331
Jack Palevich89baa202009-07-23 11:45:15 -0700332 def testIops(self):
333 self.compileCheck(["-R", "data/iops.c"], """Executing compiled code:
334result: 0""", """Literals: 1 -1
335++
3360
3371
3382
3393
3404
3415
3426
3437
3448
3459
346--
34710
3489
3498
3507
3516
3525
3534
3543
3552
3561
3570
358""")
Jack Palevich25c0cca2009-07-13 16:56:28 -0700359
Jack Palevichbeb4fe92009-07-31 11:27:29 -0700360 def testFilm(self):
Jack Palevich8f361fa2009-07-30 16:19:43 -0700361 self.compileCheck(["-R", "data/film.c"], """Executing compiled code:
362result: 0""", """testing...
363Total bad: 0
364""")
Jack Palevichbeb4fe92009-07-31 11:27:29 -0700365
366 def testpointers2(self):
367 self.compileCheck(["-R", "data/pointers2.c"], """Executing compiled code:
368result: 0""", """a = 0, *pa = 0
369a = 2, *pa = 2
370a = 0, *pa = 0 **ppa = 0
371a = 2, *pa = 2 **ppa = 2
372a = 0, *pa = 0 **ppa = 0
373a = 2, *pa = 2 **ppa = 2
374""")
375
Jack Palevich0c017742009-07-31 12:00:39 -0700376 def testassignmentop(self):
377 self.compileCheck(["-R", "data/assignmentop.c"], """Executing compiled code:
378result: 0""", """2 *= 5 10
37920 /= 5 4
38017 %= 5 2
38117 += 5 22
38217 -= 5 12
38317<<= 1 34
38417>>= 1 8
38517&= 1 1
38617^= 1 16
38716|= 1 17
Jack Palevich96138992009-07-31 15:58:19 -0700388*f() = *f() + 10;
389f()
390f()
391a = 10
392*f() += 10;
393f()
394a = 10
Jack Palevich0c017742009-07-31 12:00:39 -0700395""")
396
Jack Palevich43aaee32009-07-31 14:01:37 -0700397 def testcomma(self):
398 self.compileCheck(["-R", "data/comma.c"], """Executing compiled code:
399result: 0""", """statement: 10
400if: a = 0
401while: b = 11
402for: b = 22
403return: 30
404arg: 12
405""")
406
Jack Palevich47cbea92009-07-31 15:25:53 -0700407 def testBrackets(self):
408 self.compileCheck(["-R", "data/brackets.c"], """Executing compiled code:
409Errors: 0
4102D Errors: 0
411result: 0
412""","""""")
413
Jack Palevichc9b8ffc2009-08-03 14:42:57 -0700414 def testShort(self):
415 self.compileCheck(["-R", "data/short.c"], """Executing compiled code:
416result: -2
417""","""""")
418
Jack Palevichb6154502009-08-04 14:56:09 -0700419 def testArray(self):
420 self.compileCheck(["-R", "data/array.c"], """Executing compiled code:
421localInt: 3
422localDouble: 3 3
423globalChar: 3
424globalDouble: 3
425testArgs: 0 2 4
Jack Palevich80e49722009-08-04 15:39:49 -0700426testDecay: Hi!
427test2D:
428abcdefghijdefghijklm
429defghijklmghijklmnop
430ghijklmnopjklmnopabc
431jklmnopabcmnopabcdef
432mnopabcdefpabcdefghi
433pabcdefghicdefghijkl
434cdefghijklfghijklmno
435fghijklmnoijklmnopab
436ijklmnopablmnopabcde
437lmnopabcdefghijklmno
Jack Palevichb6154502009-08-04 14:56:09 -0700438result: 0
439""","""""")
440
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700441 def testDefines(self):
442 self.compileCheck(["-R", "data/defines.c"], """Executing compiled code:
443result: 3
444""","""""")
445
Jack Palevich0a01a5d2009-08-19 10:53:43 -0700446 def testFuncArgs(self):
447 self.compileCheck(["-R", "data/funcargs.c"], """Executing compiled code:
448result: 4
449""","""""")
450
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700451def main():
452 parseArgv()
Jack Palevich609c9942009-06-25 11:49:43 -0700453 if not outputCanRun():
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700454 print "Can't run output of acc compiler."
Jack Palevich609c9942009-06-25 11:49:43 -0700455 unittest.main()
456
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700457if __name__ == '__main__':
458 main()
459