blob: 1b444c7fb0b4e352b5fb3924ed55c570a2219c37 [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
Jack Paleviche0f9d912009-11-12 15:21:42 +080013gCompileOTCCANSI = True
Jack Palevich0b2de0d2009-08-18 16:04:03 -070014
15
16def parseArgv():
17 global gUseArm
Jack Palevichd3abe3c2009-08-19 11:12:56 -070018 global gUseX86
Jack Palevich0b2de0d2009-08-18 16:04:03 -070019 global gRunOTCCOutput
20 for arg in sys.argv[1:]:
21 if arg == "--noarm":
Jack Palevichd3abe3c2009-08-19 11:12:56 -070022 print "--noarm: not testing ARM"
Jack Palevich0b2de0d2009-08-18 16:04:03 -070023 gUseArm = False
Jack Palevichd3abe3c2009-08-19 11:12:56 -070024 elif arg == "--nox86":
25 print "--nox86: not testing x86"
26 gUseX86 = False
Jack Palevich0b2de0d2009-08-18 16:04:03 -070027 elif arg == "--norunotcc":
28 print "--norunotcc detected, not running OTCC output"
29 gRunOTCCOutput = False
30 else:
31 print "Unknown parameter: ", arg
32 raise "Unknown parameter"
33 sys.argv = sys.argv[0:1]
Jack Palevich609c9942009-06-25 11:49:43 -070034
35def compile(args):
36 proc = subprocess.Popen(["acc"] + args, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
37 result = proc.communicate()
38 return result
39
40def runCmd(args):
41 proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
42 result = proc.communicate()
43 return result[0].strip()
44
Jack Palevich0f400c52009-08-25 11:57:13 -070045def uname():
46 return runCmd(["uname"])
47
48def unameM():
49 return runCmd(["uname", "-m"])
50
Jack Palevich609c9942009-06-25 11:49:43 -070051def which(item):
52 return runCmd(["which", item])
53
54def fileType(item):
55 return runCmd(["file", item])
56
57def outputCanRun():
58 ft = fileType(which("acc"))
59 return ft.find("ELF 32-bit LSB executable, Intel 80386") >= 0
60
Jack Palevich0f400c52009-08-25 11:57:13 -070061def checkEnvironment():
62 global gRunOTCCOutput
Jack Paleviche0f9d912009-11-12 15:21:42 +080063 global gCompileOTCCANSI
64 osName = uname()
65 gRunOTCCOutput = osName == "Linux" and unameM() != "x86_64" and outputCanRun()
66 # OSX doesn't have stdin/stdout/stderr accessible through dll load symbols, so
67 # we can't compile the ANSI version of the OTCC compiler on OS X.
68 gCompileOTCCANSI = osName == "Linux"
Jack Palevich0f400c52009-08-25 11:57:13 -070069
Jack Palevich609c9942009-06-25 11:49:43 -070070def adb(args):
71 return runCmd(["adb"] + args)
72
Jack Palevich609c9942009-06-25 11:49:43 -070073def setupArm():
Jack Palevich59178c02009-07-13 14:15:18 -070074 global gArmInitialized
Jack Palevich609c9942009-06-25 11:49:43 -070075 if gArmInitialized:
76 return
77 print "Setting up arm"
78 adb(["remount"])
79 adb(["shell", "rm", "/system/bin/acc"])
80 adb(["shell", "mkdir", "/system/bin/accdata"])
81 adb(["shell", "mkdir", "/system/bin/accdata/data"])
82 # Clear out old data TODO: handle recursion
83 adb(["shell", "rm", "/system/bin/accdata/data/*"])
84 # Copy over data
85 for root, dirs, files in os.walk("data"):
86 for d in dirs:
87 adb(["shell", "mkdir", os.path.join(root, d)])
88 for f in files:
89 adb(["push", os.path.join(root, f), os.path.join("/system/bin/accdata", root, f)])
90 # Copy over compiler
91 adb(["sync"])
Jack Palevich59178c02009-07-13 14:15:18 -070092 gArmInitialized = True
Jack Palevich609c9942009-06-25 11:49:43 -070093
94def compileArm(args):
95 setupArm()
96 proc = subprocess.Popen(["adb", "shell", "/system/bin/acc"] + args, stdout=subprocess.PIPE)
97 result = proc.communicate()
98 return result[0].replace("\r","")
99
100def compare(a, b):
101 if a != b:
Jack Palevich40600de2009-07-01 15:32:35 -0700102 firstDiff = firstDifference(a, b)
Jack Palevichbab80642009-07-09 13:54:54 -0700103 print "Strings differ at character %d. Common: %s. Difference '%s' != '%s'" % (
104 firstDiff, a[0:firstDiff], safeAccess(a, firstDiff), safeAccess(b, firstDiff))
Jack Palevich40600de2009-07-01 15:32:35 -0700105
106def safeAccess(s, i):
107 if 0 <= i < len(s):
108 return s[i]
109 else:
110 return '?'
Jack Palevich609c9942009-06-25 11:49:43 -0700111
112def firstDifference(a, b):
113 commonLen = min(len(a), len(b))
114 for i in xrange(0, commonLen):
115 if a[i] != b[i]:
116 return i
117 return commonLen
118
Jack Palevich45431bc2009-07-13 15:57:26 -0700119# a1 and a2 are the expected stdout and stderr.
120# b1 and b2 are the actual stdout and stderr.
121# Compare the two, sets. Allow any individual line
122# to appear in either stdout or stderr. This is because
123# the way we obtain output on the ARM combines both
124# streams into one sequence.
125
126def compareOuput(a1,a2,b1,b2):
Jack Palevich59178c02009-07-13 14:15:18 -0700127 while True:
128 totalLen = len(a1) + len(a2) + len(b1) + len(b2)
129 a1, b1 = matchCommon(a1, b1)
130 a1, b2 = matchCommon(a1, b2)
131 a2, b1 = matchCommon(a2, b1)
132 a2, b2 = matchCommon(a2, b2)
133 newTotalLen = len(a1) + len(a2) + len(b1) + len(b2)
134 if newTotalLen == 0:
135 return True
136 if newTotalLen == totalLen:
137 print "Failed at %d %d %d %d" % (len(a1), len(a2), len(b1), len(b2))
138 print "a1", a1
139 print "a2", a2
140 print "b1", b1
141 print "b2", b2
142 return False
143
144def matchCommon(a, b):
Jack Palevich45431bc2009-07-13 15:57:26 -0700145 """Remove common items from the beginning of a and b,
146 return just the tails that are different."""
Jack Palevich59178c02009-07-13 14:15:18 -0700147 while len(a) > 0 and len(b) > 0 and a[0] == b[0]:
148 a = a[1:]
149 b = b[1:]
150 return a, b
151
152def rewritePaths(args):
153 return [rewritePath(x) for x in args]
154
155def rewritePath(p):
Jack Palevich45431bc2009-07-13 15:57:26 -0700156 """Take a path that's correct on the x86 and convert to a path
157 that's correct on ARM."""
Jack Palevich59178c02009-07-13 14:15:18 -0700158 if p.startswith("data/"):
159 p = "/system/bin/accdata/" + p
160 return p
161
Jack Palevich609c9942009-06-25 11:49:43 -0700162class TestACC(unittest.TestCase):
Jack Palevich609c9942009-06-25 11:49:43 -0700163
Jack Palevich59178c02009-07-13 14:15:18 -0700164 def checkResult(self, out, err, stdErrResult, stdOutResult=""):
165 a1 = out.splitlines()
166 a2 = err.splitlines()
167 b2 = stdErrResult.splitlines()
168 b1 = stdOutResult.splitlines()
Jack Palevich45431bc2009-07-13 15:57:26 -0700169 self.assertEqual(True, compareOuput(a1,a2,b1,b2))
Jack Palevich89baa202009-07-23 11:45:15 -0700170
Jack Palevich59178c02009-07-13 14:15:18 -0700171 def compileCheck(self, args, stdErrResult, stdOutResult="",
172 targets=['arm', 'x86']):
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700173 global gUseArm
174 global gUseX86
175 targetSet = frozenset(targets)
176 if gUseX86 and 'x86' in targetSet:
Jack Palevich59178c02009-07-13 14:15:18 -0700177 out, err = compile(args)
178 self.checkResult(out, err, stdErrResult, stdOutResult)
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700179 if gUseArm and 'arm' in targetSet:
Jack Palevich59178c02009-07-13 14:15:18 -0700180 out = compileArm(rewritePaths(args))
181 self.checkResult(out, "", stdErrResult, stdOutResult)
182
Jack Palevich609c9942009-06-25 11:49:43 -0700183 def compileCheckArm(self, args, result):
184 self.assertEqual(compileArm(args), result)
185
186 def testCompileReturnVal(self):
Jack Palevich89baa202009-07-23 11:45:15 -0700187 self.compileCheck(["data/returnval-ansi.c"], "")
Jack Palevich609c9942009-06-25 11:49:43 -0700188
Jack Paleviche0f9d912009-11-12 15:21:42 +0800189 def testCompileOTCCANSI(self):
190 global gCompileOTCCANSI
191 if gCompileOTCCANSI:
192 self.compileCheck(["data/otcc-ansi.c"], "", "", ['x86'])
Jack Palevich609c9942009-06-25 11:49:43 -0700193
194 def testRunReturnVal(self):
195 self.compileCheck(["-R", "data/returnval-ansi.c"],
Jack Palevich89baa202009-07-23 11:45:15 -0700196 "Executing compiled code:\nresult: 42\n")
Jack Palevich40600de2009-07-01 15:32:35 -0700197
Jack Palevichc951c592009-10-29 15:04:27 -0700198 def testContinue(self):
199 self.compileCheck(["-R", "data/continue.c"],
200 "Executing compiled code:\nresult: 400\n")
201
Jack Palevichbab80642009-07-09 13:54:54 -0700202 def testStringLiteralConcatenation(self):
Jack Palevich40600de2009-07-01 15:32:35 -0700203 self.compileCheck(["-R", "data/testStringConcat.c"],
Jack Palevich89baa202009-07-23 11:45:15 -0700204 "Executing compiled code:\nresult: 13\n", "Hello, world\n")
Jack Palevich40600de2009-07-01 15:32:35 -0700205
Jack Palevich609c9942009-06-25 11:49:43 -0700206 def testRunOTCCANSI(self):
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700207 global gRunOTCCOutput
208 if gRunOTCCOutput:
209 self.compileCheck(["-R", "data/otcc-ansi.c", "data/returnval.c"],
210 "Executing compiled code:\notcc-ansi.c: About to execute compiled code:\natcc-ansi.c: result: 42\nresult: 42\n", "",
211 ['x86'])
Jack Palevich609c9942009-06-25 11:49:43 -0700212
213 def testRunOTCCANSI2(self):
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700214 global gRunOTCCOutput
215 if gRunOTCCOutput:
216 self.compileCheck(["-R", "data/otcc-ansi.c", "data/otcc.c", "data/returnval.c"],
217 "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 -0700218
219 def testRunConstants(self):
220 self.compileCheck(["-R", "data/constants.c"],
221 "Executing compiled code:\nresult: 12\n",
222 "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" +
223 "'\\\"' = 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")
224
Jack Palevichbab80642009-07-09 13:54:54 -0700225 def testRunFloat(self):
226 self.compileCheck(["-R", "data/float.c"],
227 "Executing compiled code:\nresult: 0\n",
Jack Palevich2aaf21f2009-07-15 16:16:37 -0700228 """Constants: 0 0 0 0.01 0.01 0.1 10 10 0.1
229int: 1 float: 2.2 double: 3.3
230 ftoi(1.4f)=1
231 dtoi(2.4)=2
232 itof(3)=3
233 itod(4)=4
234globals: 1 2 3 4
235args: 1 2 3 4
236locals: 1 2 3 4
237cast rval: 2 4
238cast lval: 1.1 2 3.3 4
239""")
Jack Palevich89baa202009-07-23 11:45:15 -0700240
Jack Palevichbab80642009-07-09 13:54:54 -0700241 def testRunFlops(self):
242 self.compileCheck(["-R", "data/flops.c"],
Jack Palevich45431bc2009-07-13 15:57:26 -0700243 """Executing compiled code:
244result: 0""",
245"""-1.1 = -1.1
246!1.2 = 0
247!0 = 1
248double op double:
2491 + 2 = 3
2501 - 2 = -1
2511 * 2 = 2
2521 / 2 = 0.5
253float op float:
2541 + 2 = 3
2551 - 2 = -1
2561 * 2 = 2
2571 / 2 = 0.5
258double op float:
2591 + 2 = 3
2601 - 2 = -1
2611 * 2 = 2
2621 / 2 = 0.5
263double op int:
2641 + 2 = 3
2651 - 2 = -1
2661 * 2 = 2
2671 / 2 = 0.5
268int op double:
2691 + 2 = 3
2701 - 2 = -1
2711 * 2 = 2
2721 / 2 = 0.5
273double op double:
2741 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
2751 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2762 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
277double op float:
2781 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
2791 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2802 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
281float op float:
2821 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
2831 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2842 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
285int op double:
2861 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
2871 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2882 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
289double op int:
2901 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
2911 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2922 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
293branching: 1 0 1
Jack Palevichfd3db482009-07-14 19:39:36 -0700294testpassi: 1 2 3 4 5 6 7 8 9 10 11 12
295testpassf: 1 2 3 4 5 6 7 8 9 10 11 12
296testpassd: 1 2 3 4 5 6 7 8 9 10 11 12
297testpassi: 1 2 3 4 5 6 7 8 9 10 11 12
298testpassf: 1 2 3 4 5 6 7 8 9 10 11 12
299testpassd: 1 2 3 4 5 6 7 8 9 10 11 12
300testpassi: 1 2 3 4 5 6 7 8 9 10 11 12
301testpassf: 1 2 3 4 5 6 7 8 9 10 11 12
302testpassd: 1 2 3 4 5 6 7 8 9 10 11 12
Jack Palevich45431bc2009-07-13 15:57:26 -0700303testpassidf: 1 2 3
304""")
305 def testCasts(self):
306 self.compileCheck(["-R", "data/casts.c"],
307 """Executing compiled code:
308result: 0""", """Reading from a pointer: 3 3
309Writing to a pointer: 4
310Testing casts: 3 3 4.5 4
311Testing reading (int*): 4
312Testing writing (int*): 8 9
313Testing reading (char*): 0x78 0x56 0x34 0x12
314Testing writing (char*): 0x87654321
315f(10)
316Function pointer result: 70
317Testing read/write (float*): 8.8 9.9
318Testing read/write (double*): 8.8 9.9
319""")
Jack Palevich609c9942009-06-25 11:49:43 -0700320
Jack Palevich25c0cca2009-07-13 16:56:28 -0700321 def testChar(self):
322 self.compileCheck(["-R", "data/char.c"], """Executing compiled code:
323result: 0""", """a = 99, b = 41
324ga = 100, gb = 44""")
325
Jack Palevichee1f8292009-10-28 16:10:17 -0700326 def testTypedef(self):
327 self.compileCheck(["-R", "data/typedef.c"], """Executing compiled code:
328result: 0""", """x = 3
329(4, 6) = (1, 2) + (3, 4)
330""")
331
Jack Palevicha8f427f2009-07-13 18:40:08 -0700332 def testPointerArithmetic(self):
333 self.compileCheck(["-R", "data/pointers.c"], """Executing compiled code:
334result: 0""", """Pointer difference: 1 4
335Pointer addition: 2
336Pointer comparison to zero: 0 0 1
337Pointer comparison: 1 0 0 0 1
338""")
Jack Palevich37c54bd2009-07-14 18:35:36 -0700339 def testRollo3(self):
340 self.compileCheck(["-R", "data/rollo3.c"], """Executing compiled code:
341result: 10""", """""")
342
Jack Palevich8148c5b2009-07-16 18:24:47 -0700343 def testFloatDouble(self):
344 self.compileCheck(["-R", "data/floatdouble.c"], """Executing compiled code:
345result: 0""", """0.002 0.1 10""")
Jack Palevicha8f427f2009-07-13 18:40:08 -0700346
Jack Palevichddf7c9c2009-07-29 10:28:18 -0700347 def testIncDec(self):
348 self.compileCheck(["-R", "data/inc.c"], """Executing compiled code:
3490
3501
3512
3521
Jack Palevichaaac9282009-07-31 14:34:34 -07003531
3542
3551
3560
Jack Palevichddf7c9c2009-07-29 10:28:18 -0700357result: 0
358""","""""")
359
Jack Palevich89baa202009-07-23 11:45:15 -0700360 def testIops(self):
361 self.compileCheck(["-R", "data/iops.c"], """Executing compiled code:
362result: 0""", """Literals: 1 -1
363++
3640
3651
3662
3673
3684
3695
3706
3717
3728
3739
374--
37510
3769
3778
3787
3796
3805
3814
3823
3832
3841
3850
386""")
Jack Palevich25c0cca2009-07-13 16:56:28 -0700387
Jack Palevichbeb4fe92009-07-31 11:27:29 -0700388 def testFilm(self):
Jack Palevich8f361fa2009-07-30 16:19:43 -0700389 self.compileCheck(["-R", "data/film.c"], """Executing compiled code:
390result: 0""", """testing...
391Total bad: 0
392""")
Jack Palevichbeb4fe92009-07-31 11:27:29 -0700393
Jack Palevich188a5a72009-10-27 17:23:20 -0700394 def testMacros(self):
395 self.compileCheck(["-R", "data/macros.c"], """Executing compiled code:
396result: 0""", """A = 6
397A = 10
398""")
399
Jack Palevichbeb4fe92009-07-31 11:27:29 -0700400 def testpointers2(self):
401 self.compileCheck(["-R", "data/pointers2.c"], """Executing compiled code:
402result: 0""", """a = 0, *pa = 0
403a = 2, *pa = 2
404a = 0, *pa = 0 **ppa = 0
405a = 2, *pa = 2 **ppa = 2
406a = 0, *pa = 0 **ppa = 0
407a = 2, *pa = 2 **ppa = 2
408""")
409
Jack Palevich0c017742009-07-31 12:00:39 -0700410 def testassignmentop(self):
411 self.compileCheck(["-R", "data/assignmentop.c"], """Executing compiled code:
412result: 0""", """2 *= 5 10
41320 /= 5 4
41417 %= 5 2
41517 += 5 22
41617 -= 5 12
41717<<= 1 34
41817>>= 1 8
41917&= 1 1
42017^= 1 16
42116|= 1 17
Jack Palevich96138992009-07-31 15:58:19 -0700422*f() = *f() + 10;
423f()
424f()
425a = 10
426*f() += 10;
427f()
428a = 10
Jack Palevich0c017742009-07-31 12:00:39 -0700429""")
430
Jack Palevich43aaee32009-07-31 14:01:37 -0700431 def testcomma(self):
432 self.compileCheck(["-R", "data/comma.c"], """Executing compiled code:
433result: 0""", """statement: 10
434if: a = 0
435while: b = 11
436for: b = 22
437return: 30
438arg: 12
439""")
440
Jack Palevich47cbea92009-07-31 15:25:53 -0700441 def testBrackets(self):
442 self.compileCheck(["-R", "data/brackets.c"], """Executing compiled code:
443Errors: 0
4442D Errors: 0
445result: 0
446""","""""")
447
Jack Palevichc9b8ffc2009-08-03 14:42:57 -0700448 def testShort(self):
449 self.compileCheck(["-R", "data/short.c"], """Executing compiled code:
450result: -2
451""","""""")
452
Jack Palevich02effee2009-11-09 12:52:45 +0800453 def testAssignment(self):
454 self.compileCheck(["-R", "data/assignment.c"], """Executing compiled code:
455result: 7
456""","""""")
457
Jack Palevichb6154502009-08-04 14:56:09 -0700458 def testArray(self):
459 self.compileCheck(["-R", "data/array.c"], """Executing compiled code:
460localInt: 3
461localDouble: 3 3
462globalChar: 3
463globalDouble: 3
464testArgs: 0 2 4
Jack Palevich80e49722009-08-04 15:39:49 -0700465testDecay: Hi!
466test2D:
467abcdefghijdefghijklm
468defghijklmghijklmnop
469ghijklmnopjklmnopabc
470jklmnopabcmnopabcdef
471mnopabcdefpabcdefghi
472pabcdefghicdefghijkl
473cdefghijklfghijklmno
474fghijklmnoijklmnopab
475ijklmnopablmnopabcde
476lmnopabcdefghijklmno
Jack Palevichb6154502009-08-04 14:56:09 -0700477result: 0
478""","""""")
479
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700480 def testDefines(self):
481 self.compileCheck(["-R", "data/defines.c"], """Executing compiled code:
482result: 3
483""","""""")
484
Jack Palevich0a01a5d2009-08-19 10:53:43 -0700485 def testFuncArgs(self):
486 self.compileCheck(["-R", "data/funcargs.c"], """Executing compiled code:
487result: 4
488""","""""")
489
Jack Palevichc0f25332009-08-25 12:23:43 -0700490 def testB2071670(self):
491 self.compileCheck(["-R", "data/b2071670.c"], """Executing compiled code:
492result: 1092616192
493""","""""")
494
Jack Palevich9221bcc2009-08-26 16:15:07 -0700495 def testStructs(self):
496 self.compileCheck(["-R", "data/structs.c"], """Executing compiled code:
497testCopying: 37 == 37
498testUnion: 1 == 0x3f800000
499testArgs: (6, 8, 10, 12)
500result: 6
501""","""""")
Jack Palevichc0f25332009-08-25 12:23:43 -0700502
Jack Palevich5fd66ae2009-09-04 15:24:23 -0700503 def testAddressOf(self):
504 self.compileCheck(["-R", "data/addressOf.c"], """Executing compiled code:
505testStruct: 10 10 10
506testArray: 1 1 1
507result: 0
508""","""""")
509
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700510def main():
Jack Palevich0f400c52009-08-25 11:57:13 -0700511 checkEnvironment()
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700512 parseArgv()
Jack Palevich609c9942009-06-25 11:49:43 -0700513 unittest.main()
514
Jack Palevich0b2de0d2009-08-18 16:04:03 -0700515if __name__ == '__main__':
516 main()
517