blob: bef9fc64e7d9d2585c984dc0d4d1b256658657d7 [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
17 global gRunOTCCOutput
18 for arg in sys.argv[1:]:
19 if arg == "--noarm":
20 print "--noarm detected, not testing on ARM"
21 gUseArm = False
22 elif arg == "--norunotcc":
23 print "--norunotcc detected, not running OTCC output"
24 gRunOTCCOutput = False
25 else:
26 print "Unknown parameter: ", arg
27 raise "Unknown parameter"
28 sys.argv = sys.argv[0:1]
Jack Palevich609c9942009-06-25 11:49:43 -070029
30def compile(args):
31 proc = subprocess.Popen(["acc"] + args, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
32 result = proc.communicate()
33 return result
34
35def runCmd(args):
36 proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
37 result = proc.communicate()
38 return result[0].strip()
39
40def which(item):
41 return runCmd(["which", item])
42
43def fileType(item):
44 return runCmd(["file", item])
45
46def outputCanRun():
47 ft = fileType(which("acc"))
48 return ft.find("ELF 32-bit LSB executable, Intel 80386") >= 0
49
50def adb(args):
51 return runCmd(["adb"] + args)
52
Jack Palevich609c9942009-06-25 11:49:43 -070053def setupArm():
Jack Palevich59178c02009-07-13 14:15:18 -070054 global gArmInitialized
Jack Palevich609c9942009-06-25 11:49:43 -070055 if gArmInitialized:
56 return
57 print "Setting up arm"
58 adb(["remount"])
59 adb(["shell", "rm", "/system/bin/acc"])
60 adb(["shell", "mkdir", "/system/bin/accdata"])
61 adb(["shell", "mkdir", "/system/bin/accdata/data"])
62 # Clear out old data TODO: handle recursion
63 adb(["shell", "rm", "/system/bin/accdata/data/*"])
64 # Copy over data
65 for root, dirs, files in os.walk("data"):
66 for d in dirs:
67 adb(["shell", "mkdir", os.path.join(root, d)])
68 for f in files:
69 adb(["push", os.path.join(root, f), os.path.join("/system/bin/accdata", root, f)])
70 # Copy over compiler
71 adb(["sync"])
Jack Palevich59178c02009-07-13 14:15:18 -070072 gArmInitialized = True
Jack Palevich609c9942009-06-25 11:49:43 -070073
74def compileArm(args):
75 setupArm()
76 proc = subprocess.Popen(["adb", "shell", "/system/bin/acc"] + args, stdout=subprocess.PIPE)
77 result = proc.communicate()
78 return result[0].replace("\r","")
79
80def compare(a, b):
81 if a != b:
Jack Palevich40600de2009-07-01 15:32:35 -070082 firstDiff = firstDifference(a, b)
Jack Palevichbab80642009-07-09 13:54:54 -070083 print "Strings differ at character %d. Common: %s. Difference '%s' != '%s'" % (
84 firstDiff, a[0:firstDiff], safeAccess(a, firstDiff), safeAccess(b, firstDiff))
Jack Palevich40600de2009-07-01 15:32:35 -070085
86def safeAccess(s, i):
87 if 0 <= i < len(s):
88 return s[i]
89 else:
90 return '?'
Jack Palevich609c9942009-06-25 11:49:43 -070091
92def firstDifference(a, b):
93 commonLen = min(len(a), len(b))
94 for i in xrange(0, commonLen):
95 if a[i] != b[i]:
96 return i
97 return commonLen
98
Jack Palevich45431bc2009-07-13 15:57:26 -070099# a1 and a2 are the expected stdout and stderr.
100# b1 and b2 are the actual stdout and stderr.
101# Compare the two, sets. Allow any individual line
102# to appear in either stdout or stderr. This is because
103# the way we obtain output on the ARM combines both
104# streams into one sequence.
105
106def compareOuput(a1,a2,b1,b2):
Jack Palevich59178c02009-07-13 14:15:18 -0700107 while True:
108 totalLen = len(a1) + len(a2) + len(b1) + len(b2)
109 a1, b1 = matchCommon(a1, b1)
110 a1, b2 = matchCommon(a1, b2)
111 a2, b1 = matchCommon(a2, b1)
112 a2, b2 = matchCommon(a2, b2)
113 newTotalLen = len(a1) + len(a2) + len(b1) + len(b2)
114 if newTotalLen == 0:
115 return True
116 if newTotalLen == totalLen:
117 print "Failed at %d %d %d %d" % (len(a1), len(a2), len(b1), len(b2))
118 print "a1", a1
119 print "a2", a2
120 print "b1", b1
121 print "b2", b2
122 return False
123
124def matchCommon(a, b):
Jack Palevich45431bc2009-07-13 15:57:26 -0700125 """Remove common items from the beginning of a and b,
126 return just the tails that are different."""
Jack Palevich59178c02009-07-13 14:15:18 -0700127 while len(a) > 0 and len(b) > 0 and a[0] == b[0]:
128 a = a[1:]
129 b = b[1:]
130 return a, b
131
132def rewritePaths(args):
133 return [rewritePath(x) for x in args]
134
135def rewritePath(p):
Jack Palevich45431bc2009-07-13 15:57:26 -0700136 """Take a path that's correct on the x86 and convert to a path
137 that's correct on ARM."""
Jack Palevich59178c02009-07-13 14:15:18 -0700138 if p.startswith("data/"):
139 p = "/system/bin/accdata/" + p
140 return p
141
Jack Palevich609c9942009-06-25 11:49:43 -0700142class TestACC(unittest.TestCase):
Jack Palevich609c9942009-06-25 11:49:43 -0700143
Jack Palevich59178c02009-07-13 14:15:18 -0700144 def checkResult(self, out, err, stdErrResult, stdOutResult=""):
145 a1 = out.splitlines()
146 a2 = err.splitlines()
147 b2 = stdErrResult.splitlines()
148 b1 = stdOutResult.splitlines()
Jack Palevich45431bc2009-07-13 15:57:26 -0700149 self.assertEqual(True, compareOuput(a1,a2,b1,b2))
Jack Palevich89baa202009-07-23 11:45:15 -0700150
Jack Palevich59178c02009-07-13 14:15:18 -0700151 def compileCheck(self, args, stdErrResult, stdOutResult="",
152 targets=['arm', 'x86']):
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700153 global gUseArm
154 global gUseX86
155 targetSet = frozenset(targets)
156 if gUseX86 and 'x86' in targetSet:
Jack Palevich59178c02009-07-13 14:15:18 -0700157 out, err = compile(args)
158 self.checkResult(out, err, stdErrResult, stdOutResult)
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700159 if gUseArm and 'arm' in targetSet:
Jack Palevich59178c02009-07-13 14:15:18 -0700160 out = compileArm(rewritePaths(args))
161 self.checkResult(out, "", stdErrResult, stdOutResult)
162
Jack Palevich609c9942009-06-25 11:49:43 -0700163 def compileCheckArm(self, args, result):
164 self.assertEqual(compileArm(args), result)
165
166 def testCompileReturnVal(self):
Jack Palevich89baa202009-07-23 11:45:15 -0700167 self.compileCheck(["data/returnval-ansi.c"], "")
Jack Palevich609c9942009-06-25 11:49:43 -0700168
Jack Palevich59178c02009-07-13 14:15:18 -0700169 def testCompileOTCCANSII(self):
170 self.compileCheck(["data/otcc-ansi.c"], "", "", ['x86'])
Jack Palevich609c9942009-06-25 11:49:43 -0700171
172 def testRunReturnVal(self):
173 self.compileCheck(["-R", "data/returnval-ansi.c"],
Jack Palevich89baa202009-07-23 11:45:15 -0700174 "Executing compiled code:\nresult: 42\n")
Jack Palevich40600de2009-07-01 15:32:35 -0700175
Jack Palevichbab80642009-07-09 13:54:54 -0700176 def testStringLiteralConcatenation(self):
Jack Palevich40600de2009-07-01 15:32:35 -0700177 self.compileCheck(["-R", "data/testStringConcat.c"],
Jack Palevich89baa202009-07-23 11:45:15 -0700178 "Executing compiled code:\nresult: 13\n", "Hello, world\n")
Jack Palevich40600de2009-07-01 15:32:35 -0700179
Jack Palevich609c9942009-06-25 11:49:43 -0700180 def testRunOTCCANSI(self):
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700181 global gRunOTCCOutput
182 if gRunOTCCOutput:
183 self.compileCheck(["-R", "data/otcc-ansi.c", "data/returnval.c"],
184 "Executing compiled code:\notcc-ansi.c: About to execute compiled code:\natcc-ansi.c: result: 42\nresult: 42\n", "",
185 ['x86'])
Jack Palevich609c9942009-06-25 11:49:43 -0700186
187 def testRunOTCCANSI2(self):
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700188 global gRunOTCCOutput
189 if gRunOTCCOutput:
190 self.compileCheck(["-R", "data/otcc-ansi.c", "data/otcc.c", "data/returnval.c"],
191 "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 -0700192
193 def testRunConstants(self):
194 self.compileCheck(["-R", "data/constants.c"],
195 "Executing compiled code:\nresult: 12\n",
196 "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" +
197 "'\\\"' = 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")
198
Jack Palevichbab80642009-07-09 13:54:54 -0700199 def testRunFloat(self):
200 self.compileCheck(["-R", "data/float.c"],
201 "Executing compiled code:\nresult: 0\n",
Jack Palevich2aaf21f2009-07-15 16:16:37 -0700202 """Constants: 0 0 0 0.01 0.01 0.1 10 10 0.1
203int: 1 float: 2.2 double: 3.3
204 ftoi(1.4f)=1
205 dtoi(2.4)=2
206 itof(3)=3
207 itod(4)=4
208globals: 1 2 3 4
209args: 1 2 3 4
210locals: 1 2 3 4
211cast rval: 2 4
212cast lval: 1.1 2 3.3 4
213""")
Jack Palevich89baa202009-07-23 11:45:15 -0700214
Jack Palevichbab80642009-07-09 13:54:54 -0700215 def testRunFlops(self):
216 self.compileCheck(["-R", "data/flops.c"],
Jack Palevich45431bc2009-07-13 15:57:26 -0700217 """Executing compiled code:
218result: 0""",
219"""-1.1 = -1.1
220!1.2 = 0
221!0 = 1
222double op double:
2231 + 2 = 3
2241 - 2 = -1
2251 * 2 = 2
2261 / 2 = 0.5
227float op float:
2281 + 2 = 3
2291 - 2 = -1
2301 * 2 = 2
2311 / 2 = 0.5
232double op float:
2331 + 2 = 3
2341 - 2 = -1
2351 * 2 = 2
2361 / 2 = 0.5
237double op int:
2381 + 2 = 3
2391 - 2 = -1
2401 * 2 = 2
2411 / 2 = 0.5
242int op double:
2431 + 2 = 3
2441 - 2 = -1
2451 * 2 = 2
2461 / 2 = 0.5
247double op double:
2481 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
2491 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2502 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
251double op float:
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
255float 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
259int op double:
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
263double op int:
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
267branching: 1 0 1
Jack Palevichfd3db482009-07-14 19:39:36 -0700268testpassi: 1 2 3 4 5 6 7 8 9 10 11 12
269testpassf: 1 2 3 4 5 6 7 8 9 10 11 12
270testpassd: 1 2 3 4 5 6 7 8 9 10 11 12
271testpassi: 1 2 3 4 5 6 7 8 9 10 11 12
272testpassf: 1 2 3 4 5 6 7 8 9 10 11 12
273testpassd: 1 2 3 4 5 6 7 8 9 10 11 12
274testpassi: 1 2 3 4 5 6 7 8 9 10 11 12
275testpassf: 1 2 3 4 5 6 7 8 9 10 11 12
276testpassd: 1 2 3 4 5 6 7 8 9 10 11 12
Jack Palevich45431bc2009-07-13 15:57:26 -0700277testpassidf: 1 2 3
278""")
279 def testCasts(self):
280 self.compileCheck(["-R", "data/casts.c"],
281 """Executing compiled code:
282result: 0""", """Reading from a pointer: 3 3
283Writing to a pointer: 4
284Testing casts: 3 3 4.5 4
285Testing reading (int*): 4
286Testing writing (int*): 8 9
287Testing reading (char*): 0x78 0x56 0x34 0x12
288Testing writing (char*): 0x87654321
289f(10)
290Function pointer result: 70
291Testing read/write (float*): 8.8 9.9
292Testing read/write (double*): 8.8 9.9
293""")
Jack Palevich609c9942009-06-25 11:49:43 -0700294
Jack Palevich25c0cca2009-07-13 16:56:28 -0700295 def testChar(self):
296 self.compileCheck(["-R", "data/char.c"], """Executing compiled code:
297result: 0""", """a = 99, b = 41
298ga = 100, gb = 44""")
299
Jack Palevicha8f427f2009-07-13 18:40:08 -0700300 def testPointerArithmetic(self):
301 self.compileCheck(["-R", "data/pointers.c"], """Executing compiled code:
302result: 0""", """Pointer difference: 1 4
303Pointer addition: 2
304Pointer comparison to zero: 0 0 1
305Pointer comparison: 1 0 0 0 1
306""")
Jack Palevich37c54bd2009-07-14 18:35:36 -0700307 def testRollo3(self):
308 self.compileCheck(["-R", "data/rollo3.c"], """Executing compiled code:
309result: 10""", """""")
310
Jack Palevich8148c5b2009-07-16 18:24:47 -0700311 def testFloatDouble(self):
312 self.compileCheck(["-R", "data/floatdouble.c"], """Executing compiled code:
313result: 0""", """0.002 0.1 10""")
Jack Palevicha8f427f2009-07-13 18:40:08 -0700314
Jack Palevichddf7c9c2009-07-29 10:28:18 -0700315 def testIncDec(self):
316 self.compileCheck(["-R", "data/inc.c"], """Executing compiled code:
3170
3181
3192
3201
Jack Palevichaaac9282009-07-31 14:34:34 -07003211
3222
3231
3240
Jack Palevichddf7c9c2009-07-29 10:28:18 -0700325result: 0
326""","""""")
327
Jack Palevich89baa202009-07-23 11:45:15 -0700328 def testIops(self):
329 self.compileCheck(["-R", "data/iops.c"], """Executing compiled code:
330result: 0""", """Literals: 1 -1
331++
3320
3331
3342
3353
3364
3375
3386
3397
3408
3419
342--
34310
3449
3458
3467
3476
3485
3494
3503
3512
3521
3530
354""")
Jack Palevich25c0cca2009-07-13 16:56:28 -0700355
Jack Palevichbeb4fe92009-07-31 11:27:29 -0700356 def testFilm(self):
Jack Palevich8f361fa2009-07-30 16:19:43 -0700357 self.compileCheck(["-R", "data/film.c"], """Executing compiled code:
358result: 0""", """testing...
359Total bad: 0
360""")
Jack Palevichbeb4fe92009-07-31 11:27:29 -0700361
362 def testpointers2(self):
363 self.compileCheck(["-R", "data/pointers2.c"], """Executing compiled code:
364result: 0""", """a = 0, *pa = 0
365a = 2, *pa = 2
366a = 0, *pa = 0 **ppa = 0
367a = 2, *pa = 2 **ppa = 2
368a = 0, *pa = 0 **ppa = 0
369a = 2, *pa = 2 **ppa = 2
370""")
371
Jack Palevich0c017742009-07-31 12:00:39 -0700372 def testassignmentop(self):
373 self.compileCheck(["-R", "data/assignmentop.c"], """Executing compiled code:
374result: 0""", """2 *= 5 10
37520 /= 5 4
37617 %= 5 2
37717 += 5 22
37817 -= 5 12
37917<<= 1 34
38017>>= 1 8
38117&= 1 1
38217^= 1 16
38316|= 1 17
Jack Palevich96138992009-07-31 15:58:19 -0700384*f() = *f() + 10;
385f()
386f()
387a = 10
388*f() += 10;
389f()
390a = 10
Jack Palevich0c017742009-07-31 12:00:39 -0700391""")
392
Jack Palevich43aaee32009-07-31 14:01:37 -0700393 def testcomma(self):
394 self.compileCheck(["-R", "data/comma.c"], """Executing compiled code:
395result: 0""", """statement: 10
396if: a = 0
397while: b = 11
398for: b = 22
399return: 30
400arg: 12
401""")
402
Jack Palevich47cbea92009-07-31 15:25:53 -0700403 def testBrackets(self):
404 self.compileCheck(["-R", "data/brackets.c"], """Executing compiled code:
405Errors: 0
4062D Errors: 0
407result: 0
408""","""""")
409
Jack Palevichc9b8ffc2009-08-03 14:42:57 -0700410 def testShort(self):
411 self.compileCheck(["-R", "data/short.c"], """Executing compiled code:
412result: -2
413""","""""")
414
Jack Palevichb6154502009-08-04 14:56:09 -0700415 def testArray(self):
416 self.compileCheck(["-R", "data/array.c"], """Executing compiled code:
417localInt: 3
418localDouble: 3 3
419globalChar: 3
420globalDouble: 3
421testArgs: 0 2 4
Jack Palevich80e49722009-08-04 15:39:49 -0700422testDecay: Hi!
423test2D:
424abcdefghijdefghijklm
425defghijklmghijklmnop
426ghijklmnopjklmnopabc
427jklmnopabcmnopabcdef
428mnopabcdefpabcdefghi
429pabcdefghicdefghijkl
430cdefghijklfghijklmno
431fghijklmnoijklmnopab
432ijklmnopablmnopabcde
433lmnopabcdefghijklmno
Jack Palevichb6154502009-08-04 14:56:09 -0700434result: 0
435""","""""")
436
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700437 def testDefines(self):
438 self.compileCheck(["-R", "data/defines.c"], """Executing compiled code:
439result: 3
440""","""""")
441
Jack Palevich0a01a5d2009-08-19 10:53:43 -0700442 def testFuncArgs(self):
443 self.compileCheck(["-R", "data/funcargs.c"], """Executing compiled code:
444result: 4
445""","""""")
446
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700447def main():
448 parseArgv()
Jack Palevich609c9942009-06-25 11:49:43 -0700449 if not outputCanRun():
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700450 print "Can't run output of acc compiler."
Jack Palevich609c9942009-06-25 11:49:43 -0700451 unittest.main()
452
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700453if __name__ == '__main__':
454 main()
455