summaryrefslogtreecommitdiffstats
path: root/libacc/tests
diff options
context:
space:
mode:
Diffstat (limited to 'libacc/tests')
-rw-r--r--libacc/tests/.gitignore2
-rw-r--r--libacc/tests/Android.mk65
-rw-r--r--libacc/tests/data/bellard.otccex.c126
-rw-r--r--libacc/tests/data/casts.c85
-rw-r--r--libacc/tests/data/char.c13
-rw-r--r--libacc/tests/data/constants.c30
-rw-r--r--libacc/tests/data/double.c7
-rw-r--r--libacc/tests/data/error.c2
-rw-r--r--libacc/tests/data/expr-ansi.c60
-rw-r--r--libacc/tests/data/expr.c60
-rw-r--r--libacc/tests/data/expr2.c6
-rw-r--r--libacc/tests/data/float.c57
-rw-r--r--libacc/tests/data/floatdouble.c9
-rw-r--r--libacc/tests/data/flops.c158
-rw-r--r--libacc/tests/data/hello.c3
-rw-r--r--libacc/tests/data/locals.c71
-rw-r--r--libacc/tests/data/missing-main.c4
-rw-r--r--libacc/tests/data/otcc-ansi.c466
-rw-r--r--libacc/tests/data/otcc-noinclude.c446
-rw-r--r--libacc/tests/data/otcc.c448
-rw-r--r--libacc/tests/data/pointers.c15
-rw-r--r--libacc/tests/data/returnval-ansi.c8
-rw-r--r--libacc/tests/data/returnval.c4
-rw-r--r--libacc/tests/data/rollo3.c9
-rw-r--r--libacc/tests/data/simplest.c1
-rw-r--r--libacc/tests/data/testStringConcat.c4
-rw-r--r--libacc/tests/main.cpp148
-rw-r--r--libacc/tests/runtimeTest.cpp110
-rwxr-xr-xlibacc/tests/test6
-rw-r--r--libacc/tests/test.py295
30 files changed, 2718 insertions, 0 deletions
diff --git a/libacc/tests/.gitignore b/libacc/tests/.gitignore
new file mode 100644
index 0000000..a26b298
--- /dev/null
+++ b/libacc/tests/.gitignore
@@ -0,0 +1,2 @@
+test-acc
+*.out
diff --git a/libacc/tests/Android.mk b/libacc/tests/Android.mk
new file mode 100644
index 0000000..77e48be
--- /dev/null
+++ b/libacc/tests/Android.mk
@@ -0,0 +1,65 @@
+LOCAL_PATH:= $(call my-dir)
+
+# Executable for host
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE:= acc
+
+LOCAL_SRC_FILES:= \
+ main.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libacc
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_HOST_EXECUTABLE)
+
+# Executable for target
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE:= acc
+
+LOCAL_SRC_FILES:= \
+ main.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libacc
+
+LOCAL_CFLAGS := -O0 -g
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
+
+# Runtime tests for host
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE:= accRuntimeTest
+
+LOCAL_SRC_FILES:= \
+ runtimeTest.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libacc
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_HOST_EXECUTABLE)
+
+# Runtime tests for target
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE:= accRuntimeTest
+
+LOCAL_SRC_FILES:= \
+ runtimeTest.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libacc
+
+LOCAL_CFLAGS := -O0 -g
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/libacc/tests/data/bellard.otccex.c b/libacc/tests/data/bellard.otccex.c
new file mode 100644
index 0000000..e8f0989
--- /dev/null
+++ b/libacc/tests/data/bellard.otccex.c
@@ -0,0 +1,126 @@
+/* #!/usr/local/bin/otcc */
+/*
+ * Sample OTCC C example. You can uncomment the first line and install
+ * otcc in /usr/local/bin to make otcc scripts !
+ */
+
+/* Any preprocessor directive except #define are ignored. We put this
+ include so that a standard C compiler can compile this code too. */
+#include <stdio.h>
+
+/* defines are handled, but macro arguments cannot be given. No
+ recursive defines are tolerated */
+#define DEFAULT_BASE 10
+
+/*
+ * Only old style K&R prototypes are parsed. Only int arguments are
+ * allowed (implicit types).
+ *
+ * By benchmarking the execution time of this function (for example
+ * for fib(35)), you'll notice that OTCC is quite fast because it
+ * generates native i386 machine code.
+ */
+fib(n)
+{
+ if (n <= 2)
+ return 1;
+ else
+ return fib(n-1) + fib(n-2);
+}
+
+/* Identifiers are parsed the same way as C: begins with letter or
+ '_', and then letters, '_' or digits */
+fact(n)
+{
+ /* local variables can be declared. Only 'int' type is supported */
+ int i, r;
+ r = 1;
+ /* 'while' and 'for' loops are supported */
+ for(i=2;i<=n;i++)
+ r = r * i;
+ return r;
+}
+
+/* Well, we could use printf, but it would be too easy */
+print_num(n, b)
+{
+ int tab, p, c;
+ /* Numbers can be entered in decimal, hexadecimal ('0x' prefix) and
+ octal ('0' prefix) */
+ /* more complex programs use malloc */
+ tab = malloc(0x100);
+ p = tab;
+ while (1) {
+ c = n % b;
+ /* Character constants can be used */
+ if (c >= 10)
+ c = c + 'a' - 10;
+ else
+ c = c + '0';
+ *(char *)p = c;
+ p++;
+ n = n / b;
+ /* 'break' is supported */
+ if (n == 0)
+ break;
+ }
+ while (p != tab) {
+ p--;
+ printf("%c", *(char *)p);
+ }
+ free(tab);
+}
+
+/* 'main' takes standard 'argc' and 'argv' parameters */
+main(argc, argv)
+{
+ /* no local name space is supported, but local variables ARE
+ supported. As long as you do not use a globally defined
+ variable name as local variable (which is a bad habbit), you
+ won't have any problem */
+ int s, n, f, base;
+
+ /* && and || operator have the same semantics as C (left to right
+ evaluation and early exit) */
+ if (argc != 2 && argc != 3) {
+ /* '*' operator is supported with explicit casting to 'int *',
+ 'char *' or 'int (*)()' (function pointer). Of course, 'int'
+ are supposed to be used as pointers too. */
+ s = *(int *)argv;
+ help(s);
+ return 1;
+ }
+ /* Any libc function can be used because OTCC uses dynamic linking */
+ n = atoi(*(int *)(argv + 4));
+ base = DEFAULT_BASE;
+ if (argc >= 3) {
+ base = atoi(*(int *)(argv + 8));
+ if (base < 2 || base > 36) {
+ /* external variables can be used too (here: 'stderr') */
+ fprintf(stderr, "Invalid base\n");
+ return 1;
+ }
+ }
+ printf("fib(%d) = ", n);
+ print_num(fib(n), base);
+ printf("\n");
+
+ printf("fact(%d) = ", n);
+ if (n > 12) {
+ printf("Overflow");
+ } else {
+ /* why not using a function pointer ? */
+ f = &fact;
+ print_num((*(int (*)())f)(n), base);
+ }
+ printf("\n");
+ return 0;
+}
+
+/* functions can be used before being defined */
+help(name)
+{
+ printf("usage: %s n [base]\n", name);
+ printf("Compute fib(n) and fact(n) and output the result in base 'base'\n");
+}
+
diff --git a/libacc/tests/data/casts.c b/libacc/tests/data/casts.c
new file mode 100644
index 0000000..d3a49b4
--- /dev/null
+++ b/libacc/tests/data/casts.c
@@ -0,0 +1,85 @@
+void test1() {
+ int a = 3;
+ int* pb = &a;
+ int c = *pb;
+ printf("Reading from a pointer: %d %d\n", a, c);
+ *pb = 4;
+ printf("Writing to a pointer: %d\n", a);
+ printf("Testing casts: %d %g %g %d\n", 3, (float) 3, 4.5, (int) 4.5);
+}
+
+void test2() {
+ int x = 4;
+ int px = &x;
+ // int z = * px; // An error, expected a pointer type
+ int y = * (int*) px;
+ printf("Testing reading (int*): %d\n", y);
+}
+
+void test3() {
+ int px = (int) malloc(120);
+ * (int*) px = 8;
+ * (int*) (px + 4) = 9;
+ printf("Testing writing (int*): %d %d\n", * (int*) px, * (int*) (px + 4));
+ free((void*) px);
+}
+
+void test4() {
+ int x = 0x12345678;
+ int px = &x;
+ int a = * (char*) px;
+ int b = * (char*) (px + 1);
+ int c = * (char*) (px + 2);
+ int d = * (char*) (px + 3);
+ printf("Testing reading (char*): 0x%02x 0x%02x 0x%02x 0x%02x\n", a, b, c, d);
+}
+
+void test5() {
+ int x = 0xFFFFFFFF;
+ int px = &x;
+ * (char*) px = 0x21;
+ * (char*) (px + 1) = 0x43;
+ * (char*) (px + 2) = 0x65;
+ * (char*) (px + 3) = 0x87;
+ printf("Testing writing (char*): 0x%08x\n", x);
+}
+
+int f(int b) {
+ printf("f(%d)\n", b);
+ return 7 * b;
+}
+
+void test6() {
+ int fp = &f;
+ int x = (*(int(*)()) fp)(10);
+ printf("Function pointer result: %d\n", x);
+}
+
+void test7() {
+ int px = (int) malloc(120);
+ * (float*) px = 8.8f;
+ * (float*) (px + 4) = 9.9f;
+ printf("Testing read/write (float*): %g %g\n", * (float*) px, * (float*) (px + 4));
+ free((void*) px);
+}
+
+void test8() {
+ int px = (int) malloc(120);
+ * (double*) px = 8.8;
+ * (double*) (px + 8) = 9.9;
+ printf("Testing read/write (double*): %g %g\n", * (double*) px, * (double*) (px + 8));
+ free((void*) px);
+}
+
+
+int main() {
+ test1();
+ test2();
+ test3();
+ test4();
+ test5();
+ test6();
+ test7();
+ test8();
+ return 0;
+}
diff --git a/libacc/tests/data/char.c b/libacc/tests/data/char.c
new file mode 100644
index 0000000..8c63ba2
--- /dev/null
+++ b/libacc/tests/data/char.c
@@ -0,0 +1,13 @@
+char ga;
+char gb;
+
+int main() {
+ char a = 'c';
+ char b = a * 3;
+ printf("a = %d, b = %d\n", a, b);
+ ga = 'd';
+ gb = ga * 3;
+ printf("ga = %d, gb = %d\n", ga, gb);
+ return 0;
+}
+
diff --git a/libacc/tests/data/constants.c b/libacc/tests/data/constants.c
new file mode 100644
index 0000000..230109a
--- /dev/null
+++ b/libacc/tests/data/constants.c
@@ -0,0 +1,30 @@
+#define FOO 0x10
+
+int main() {
+ printf("0 = %d\n", 0);
+ printf("010 = %d\n", 010);
+ printf("0x10 = %d\n", FOO);
+ printf("'\\a' = %d\n", '\a');
+ printf("'\\b' = %d\n", '\b');
+ printf("'\\f' = %d\n", '\f');
+ printf("'\\n' = %d\n", '\n');
+ printf("'\\r' = %d\n", '\r');
+ printf("'\\t' = %d\n", '\t');
+ printf("'\\v' = %d\n", '\v');
+ // Undefined
+ // printf("'\\z' = %d\n", '\z');
+ printf("'\\\\' = %d\n", '\\');
+ printf("'\\'' = %d\n", '\'');
+ printf("'\\\"' = %d\n", '\"');
+ printf("'\\?' = %d\n", '\?');
+ printf("'\\0' = %d\n", '\0');
+ printf("'\\1' = %d\n", '\1');
+ printf("'\\12' = %d\n", '\12');
+ printf("'\\123' = %d\n", '\123');
+ printf("'\\x0' = %d\n", '\x0');
+ printf("'\\x1' = %d\n", '\x1');
+ printf("'\\x12' = %d\n", '\x12');
+ printf("'\\x123' = %d\n", '\x123');
+ printf("'\\x1f' = %d\n", '\x1f');
+ printf("'\\x1F' = %d\n", '\x1F');
+}
diff --git a/libacc/tests/data/double.c b/libacc/tests/data/double.c
new file mode 100644
index 0000000..5bc20a3
--- /dev/null
+++ b/libacc/tests/data/double.c
@@ -0,0 +1,7 @@
+double atof(char *nptr);
+
+int main() {
+ printf("Value = %g\n", atof("10.42"));
+ return 0;
+}
+
diff --git a/libacc/tests/data/error.c b/libacc/tests/data/error.c
new file mode 100644
index 0000000..2e08dcc
--- /dev/null
+++ b/libacc/tests/data/error.c
@@ -0,0 +1,2 @@
+void foo;
+
diff --git a/libacc/tests/data/expr-ansi.c b/libacc/tests/data/expr-ansi.c
new file mode 100644
index 0000000..d463659
--- /dev/null
+++ b/libacc/tests/data/expr-ansi.c
@@ -0,0 +1,60 @@
+/* Test operators */
+
+void testInc() { int a, b; a = 3; b = a++; printf("3++ = %d %d\n", b, a); }
+void testDec() { int a, b; a = 3; b = a--; printf("3-- = %d %d\n", b, a); }
+void testTimes(){ printf("%d * %d = %d\n", 10, 4, 10 * 4); }
+void testDiv(){ printf("%d / %d = %d\n", 11, 4, 11 / 4); }
+void testMod(){ printf("%d %% %d = %d\n", 11, 4, 11 % 4); }
+void testPlus(){ printf("%d + %d = %d\n", 10, 4, 10 + 4); }
+void testMinus(){ printf("%d - %d = %d\n", 10, 4, 10 - 4); }
+void testShiftLeft(){ printf("%d << %d = %d\n", 10, 4, 10 << 4); }
+void testShiftRight(){ printf("%d >> %d = %d\n", 100, 4, 100 >> 4); }
+void testLess(){ printf("%d < %d = %d\n", 10, 4, 10 < 4); }
+void testLesEqual(){ printf("%d <= %d = %d\n", 10, 4, 10 <= 4); }
+void testGreater(){ printf("%d > %d = %d\n", 10, 4, 10 > 4); }
+void testGreaterEqual(){ printf("%d >= %d = %d\n", 10, 4, 10 >= 4); }
+void testEqualTo(){ printf("%d == %d = %d\n", 10, 4, 10 == 4); }
+void testNotEqualTo(){ printf("%d != %d = %d\n", 10, 4, 10 != 4); }
+void testBitAnd(){ printf("%d & %d = %d\n", 10, 7, 10 & 7); }
+void testBitXor(){ printf("%d ^ %d = %d\n", 10, 7, 10 ^ 7); }
+void testBitOr(){ printf("%d | %d = %d\n", 10, 4, 10 | 4); }
+void testAssignment(){ int a, b; a = 3; b = a; printf("b == %d\n", b); }
+void testLogicalAnd(){ printf("%d && %d = %d\n", 10, 4, 10 && 4); }
+void testLogicalOr(){ printf("%d || %d = %d\n", 10, 4, 10 || 4); }
+void testAddressOf(){ int a; printf("&a is %d\n", &a); }
+void testPointerIndirection(){ int a, b; a = &b; b = 17; printf("*%d = %d =?= %d\n", a, * (int*) a, b); }
+void testNegation(){ printf("-%d = %d\n", 10, -10); }
+void testUnaryPlus(){ printf("+%d = %d\n", 10, +10); }
+void testUnaryNot(){ printf("!%d = %d\n", 10, !10); }
+void testBitNot(){ printf("~%d = %d\n", 10, ~10); }
+
+int main(int a, char** b) {
+ testInc();
+ testDec();
+ testTimes();
+ testDiv();
+ testMod();
+ testPlus();
+ testMinus();
+ testShiftLeft();
+ testShiftRight();
+ testLess();
+ testLesEqual();
+ testGreater();
+ testGreaterEqual();
+ testEqualTo();
+ testNotEqualTo();
+ testBitAnd();
+ testBinXor();
+ testBitOr();
+ testAssignment();
+ testLogicalAnd();
+ testLogicalOr();
+ testAddressOf();
+ testPointerIndirection();
+ testNegation();
+ testUnaryPlus();
+ testUnaryNot();
+ testBitNot();
+ return 0;
+}
diff --git a/libacc/tests/data/expr.c b/libacc/tests/data/expr.c
new file mode 100644
index 0000000..4f2d2e7
--- /dev/null
+++ b/libacc/tests/data/expr.c
@@ -0,0 +1,60 @@
+/* Test operators */
+
+testInc() { int a, b; a = 3; b = a++; printf("3++ = %d %d\n", b, a); }
+testDec() { int a, b; a = 3; b = a--; printf("3-- = %d %d\n", b, a); }
+testTimes(){ printf("%d * %d = %d\n", 10, 4, 10 * 4); }
+testDiv(){ printf("%d / %d = %d\n", 11, 4, 11 / 4); }
+testMod(){ printf("%d %% %d = %d\n", 11, 4, 11 % 4); }
+testPlus(){ printf("%d + %d = %d\n", 10, 4, 10 + 4); }
+testMinus(){ printf("%d - %d = %d\n", 10, 4, 10 - 4); }
+testShiftLeft(){ printf("%d << %d = %d\n", 10, 4, 10 << 4); }
+testShiftRight(){ printf("%d >> %d = %d\n", 100, 4, 100 >> 4); }
+testLess(){ printf("%d < %d = %d\n", 10, 4, 10 < 4); }
+testLesEqual(){ printf("%d <= %d = %d\n", 10, 4, 10 <= 4); }
+testGreater(){ printf("%d > %d = %d\n", 10, 4, 10 > 4); }
+testGreaterEqual(){ printf("%d >= %d = %d\n", 10, 4, 10 >= 4); }
+testEqualTo(){ printf("%d == %d = %d\n", 10, 4, 10 == 4); }
+testNotEqualTo(){ printf("%d != %d = %d\n", 10, 4, 10 != 4); }
+testBitAnd(){ printf("%d & %d = %d\n", 10, 7, 10 & 7); }
+testBitXor(){ printf("%d ^ %d = %d\n", 10, 7, 10 ^ 7); }
+testBitOr(){ printf("%d | %d = %d\n", 10, 4, 10 | 4); }
+testAssignment(){ int a, b; a = 3; b = a; printf("b == %d\n", b); }
+testLogicalAnd(){ printf("%d && %d = %d\n", 10, 4, 10 && 4); }
+testLogicalOr(){ printf("%d || %d = %d\n", 10, 4, 10 || 4); }
+testAddressOf(){ int a; printf("&a is %d\n", &a); }
+testPointerIndirection(){ int a, b; a = &b; b = 17; printf("*%d = %d =?= %d\n", a, * (int*) a, b); }
+testNegation(){ printf("-%d = %d\n", 10, -10); }
+testUnaryPlus(){ printf("+%d = %d\n", 10, +10); }
+testUnaryNot(){ printf("!%d = %d\n", 10, !10); }
+testBitNot(){ printf("~%d = %d\n", 10, ~10); }
+
+main(a,b) {
+ testInc();
+ testDec();
+ testTimes();
+ testDiv();
+ testMod();
+ testPlus();
+ testMinus();
+ testShiftLeft();
+ testShiftRight();
+ testLess();
+ testLesEqual();
+ testGreater();
+ testGreaterEqual();
+ testEqualTo();
+ testNotEqualTo();
+ testBitAnd();
+ testBinXor();
+ testBitOr();
+ testAssignment();
+ testLogicalAnd();
+ testLogicalOr();
+ testAddressOf();
+ testPointerIndirection();
+ testNegation();
+ testUnaryPlus();
+ testUnaryNot();
+ testBitNot();
+ return 0;
+} \ No newline at end of file
diff --git a/libacc/tests/data/expr2.c b/libacc/tests/data/expr2.c
new file mode 100644
index 0000000..04b6a38
--- /dev/null
+++ b/libacc/tests/data/expr2.c
@@ -0,0 +1,6 @@
+/* Test operators */
+
+main() {
+ int a;
+ a = a++;
+}
diff --git a/libacc/tests/data/float.c b/libacc/tests/data/float.c
new file mode 100644
index 0000000..f48b3d1
--- /dev/null
+++ b/libacc/tests/data/float.c
@@ -0,0 +1,57 @@
+int ftoi(float f) {
+ return f;
+}
+
+int dtoi(double d) {
+ return d;
+}
+
+float itof(int i) {
+ return i;
+}
+
+double itod(int i) {
+ return i;
+}
+
+float f0, f1;
+double d0, d1;
+
+void testParseConsts() {
+ printf("Constants: %g %g %g %g %g %g %g %g %g\n", 0e1, 0E1, 0.f, .01f,
+ .01e0f, 1.0e-1, 1.0e1, 1.0e+1,
+ .1f);
+}
+void testVars(float arg0, float arg1, double arg2, double arg3) {
+ float local0, local1;
+ double local2, local3;
+ f0 = arg0;
+ f1 = arg1;
+ d0 = arg2;
+ d1 = arg3;
+ local0 = arg0;
+ local1 = arg1;
+ local2 = arg2;
+ local3 = arg3;
+ printf("globals: %g %g %g %g\n", f0, f1, d0, d1);
+ printf("args: %g %g %g %g\n", arg0, arg1, arg2, arg3);
+ printf("locals: %g %g %g %g\n", local0, local1, local2, local3);
+
+
+ printf("cast rval: %g %g\n", * (float*) & f1, * (double*) & d1);
+
+ * (float*) & f0 = 1.1f;
+ * (double*) & d0 = 3.3;
+ printf("cast lval: %g %g %g %g\n", f0, f1, d0, d1);
+}
+
+int main() {
+ testParseConsts();
+ printf("int: %d float: %g double: %g\n", 1, 2.2f, 3.3);
+ printf(" ftoi(1.4f)=%d\n", ftoi(1.4f));
+ printf(" dtoi(2.4)=%d\n", dtoi(2.4));
+ printf(" itof(3)=%g\n", itof(3));
+ printf(" itod(4)=%g\n", itod(4));
+ testVars(1.0f, 2.0f, 3.0, 4.0);
+ return 0;
+}
diff --git a/libacc/tests/data/floatdouble.c b/libacc/tests/data/floatdouble.c
new file mode 100644
index 0000000..264c641
--- /dev/null
+++ b/libacc/tests/data/floatdouble.c
@@ -0,0 +1,9 @@
+int main()
+{
+ // Test coercing values when storing.
+ float a = 0.002;
+ double b = 0.1f;
+ int c = 10.002;
+ printf("%g %g %d\n", a, b, c);
+ return 0;
+}
diff --git a/libacc/tests/data/flops.c b/libacc/tests/data/flops.c
new file mode 100644
index 0000000..40b1b28
--- /dev/null
+++ b/libacc/tests/data/flops.c
@@ -0,0 +1,158 @@
+// Test floating point operations.
+
+void unaryOps() {
+ // Unary ops
+ printf("-%g = %g\n", 1.1, -1.1);
+ printf("!%g = %d\n", 1.2, !1.2);
+ printf("!%g = %d\n", 0.0, !0.0);
+}
+
+void binaryOps() {
+ printf("double op double:\n");
+ printf("%g + %g = %g\n", 1.0, 2.0, 1.0 + 2.0);
+ printf("%g - %g = %g\n", 1.0, 2.0, 1.0 - 2.0);
+ printf("%g * %g = %g\n", 1.0, 2.0, 1.0 * 2.0);
+ printf("%g / %g = %g\n", 1.0, 2.0, 1.0 / 2.0);
+
+ printf("float op float:\n");
+ printf("%g + %g = %g\n", 1.0f, 2.0f, 1.0f + 2.0f);
+ printf("%g - %g = %g\n", 1.0f, 2.0f, 1.0f - 2.0f);
+ printf("%g * %g = %g\n", 1.0f, 2.0f, 1.0f * 2.0f);
+ printf("%g / %g = %g\n", 1.0f, 2.0f, 1.0f / 2.0f);
+
+ printf("double op float:\n");
+ printf("%g + %g = %g\n", 1.0, 2.0f, 1.0 + 2.0f);
+ printf("%g - %g = %g\n", 1.0, 2.0f, 1.0 - 2.0f);
+ printf("%g * %g = %g\n", 1.0, 2.0f, 1.0 * 2.0f);
+ printf("%g / %g = %g\n", 1.0, 2.0f, 1.0 / 2.0f);
+
+ printf("double op int:\n");
+ printf("%g + %d = %g\n", 1.0, 2, 1.0 + 2);
+ printf("%g - %d = %g\n", 1.0, 2, 1.0 - 2);
+ printf("%g * %d = %g\n", 1.0, 2, 1.0 * 2);
+ printf("%g / %d = %g\n", 1.0, 2, 1.0 / 2);
+
+ printf("int op double:\n");
+ printf("%d + %g = %g\n", 1, 2.0, 1 + 2.0);
+ printf("%d - %g = %g\n", 1, 2.0, 1 - 2.0);
+ printf("%d * %g = %g\n", 1, 2.0, 1 * 2.0);
+ printf("%d / %g = %g\n", 1, 2.0, 1 / 2.0);
+}
+
+void comparisonTestdd(double a, double b) {
+ printf("%g op %g: < %d <= %d == %d >= %d > %d != %d\n",
+ a, b, a < b, a <= b, a == b, a >= b, a > b, a != b);
+}
+
+void comparisonOpsdd() {
+ printf("double op double:\n");
+ comparisonTestdd(1.0, 2.0);
+ comparisonTestdd(1.0, 1.0);
+ comparisonTestdd(2.0, 1.0);
+}
+
+
+void comparisonTestdf(double a, float b) {
+ printf("%g op %g: < %d <= %d == %d >= %d > %d != %d\n",
+ a, b, a < b, a <= b, a == b, a >= b, a > b, a != b);
+}
+
+void comparisonOpsdf() {
+ printf("double op float:\n");
+ comparisonTestdf(1.0, 2.0f);
+ comparisonTestdf(1.0, 1.0f);
+ comparisonTestdf(2.0, 1.0f);
+}
+
+void comparisonTestff(float a, float b) {
+ printf("%g op %g: < %d <= %d == %d >= %d > %d != %d\n",
+ a, b, a < b, a <= b, a == b, a >= b, a > b, a != b);
+}
+
+void comparisonOpsff() {
+ printf("float op float:\n");
+ comparisonTestff(1.0f, 2.0f);
+ comparisonTestff(1.0f, 1.0f);
+ comparisonTestff(2.0f, 1.0f);
+}
+
+void comparisonTestid(int a, double b) {
+ printf("%d op %g: < %d <= %d == %d >= %d > %d != %d\n",
+ a, b, a < b, a <= b, a == b, a >= b, a > b, a != b);
+}
+
+void comparisonOpsid() {
+ printf("int op double:\n");
+ comparisonTestid(1, 2.0);
+ comparisonTestid(1, 1.0);
+ comparisonTestid(2, 1.0);
+}
+void comparisonTestdi(double a, int b) {
+ printf("%g op %d: < %d <= %d == %d >= %d > %d != %d\n",
+ a, b, a < b, a <= b, a == b, a >= b, a > b, a != b);
+}
+
+void comparisonOpsdi() {
+ printf("double op int:\n");
+ comparisonTestdi(1.0f, 2);
+ comparisonTestdi(1.0f, 1);
+ comparisonTestdi(2.0f, 1);
+}
+
+void comparisonOps() {
+ comparisonOpsdd();
+ comparisonOpsdf();
+ comparisonOpsff();
+ comparisonOpsid();
+ comparisonOpsdi();
+}
+
+int branch(double d) {
+ if (d) {
+ return 1;
+ }
+ return 0;
+}
+
+void testBranching() {
+ printf("branching: %d %d %d\n", branch(-1.0), branch(0.0), branch(1.0));
+}
+
+void testpassi(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l) {
+ printf("testpassi: %d %d %d %d %d %d %d %d %d %d %d %d\n", a, b, c, d, e, f, g, h, i, j, k, l);
+}
+
+void testpassf(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j, float k, float l) {
+ printf("testpassf: %g %g %g %g %g %g %g %g %g %g %g %g\n", a, b, c, d, e, f, g, h, i, j, k, l);
+}
+
+void testpassd(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j, double k, double l) {
+ printf("testpassd: %g %g %g %g %g %g %g %g %g %g %g %g\n", a, b, c, d, e, f, g, h, i, j, k, l);
+}
+
+void testpassidf(int i, double d, float f) {
+ printf("testpassidf: %d %g %g\n", i, d, f);
+}
+
+void testParameterPassing() {
+ float x;
+ testpassi(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
+ testpassf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
+ testpassd(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
+ testpassi(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f);
+ testpassf(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f);
+ testpassd(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f);
+ testpassi(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0);
+ testpassf(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0);
+ testpassd(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0);
+ testpassidf(1, 2.0, 3.0f);
+}
+
+int main() {
+ unaryOps();
+ binaryOps();
+ comparisonOps();
+ testBranching();
+ testParameterPassing();
+ return 0;
+}
diff --git a/libacc/tests/data/hello.c b/libacc/tests/data/hello.c
new file mode 100644
index 0000000..585ce6c
--- /dev/null
+++ b/libacc/tests/data/hello.c
@@ -0,0 +1,3 @@
+main(a,b) {
+ printf("Hello, world\n");
+}
diff --git a/libacc/tests/data/locals.c b/libacc/tests/data/locals.c
new file mode 100644
index 0000000..f1ef363
--- /dev/null
+++ b/libacc/tests/data/locals.c
@@ -0,0 +1,71 @@
+int a;
+
+int f() {
+ int a;
+ // Undefined variable b
+ // printf("f 0: a = %d b = %d\n", a, b);
+ printf("f 0: a = %d\n", a);
+ a = 2;
+ printf("f 1: a = %d\n", a);
+}
+
+int g(int a) {
+ printf("g 0: a = %d\n", a);
+ a = 3;
+ printf("g 1: a = %d\n", a);
+}
+
+int h(int a) {
+ // int a; // gcc 4.3 says error: 'a' redeclared as different kind of symbol
+
+ printf("h 0: a = %d\n", a);
+ a = 4;
+ printf("h 1: a = %d\n", a);
+}
+
+// Already defined global
+// int h() {}
+int globCheck() {
+ fprintf(stdout, "globCheck()\n");
+}
+
+int fwdCheck() {
+ b();
+ // Undefined forward reference
+ // c();
+}
+
+int b() {
+ printf("b()\n");
+}
+
+int nested() {
+ int a;
+ printf("nested 0: a = %d\n", a);
+ a = 50;
+ printf("nested 1: a = %d\n", a);
+ {
+ int a;
+ printf("nested 2: a = %d\n", a);
+ a = 51;
+ printf("nested 3: a = %d\n", a);
+ }
+ printf("nested 4: a = %d\n", a);
+}
+
+int main() {
+ globCheck();
+ fwdCheck();
+ printf("main 0: a = %d\n", a);
+ a = 5;
+ printf("main 1: a = %d\n", a);
+ f();
+ printf("main 2: a = %d\n", a);
+ g(77);
+ printf("main 3: a = %d\n", a);
+ h(30);
+ printf("main 4: a = %d\n", a);
+ nested();
+ printf("main 5: a = %d\n", a);
+ return 0;
+}
diff --git a/libacc/tests/data/missing-main.c b/libacc/tests/data/missing-main.c
new file mode 100644
index 0000000..e73eec4
--- /dev/null
+++ b/libacc/tests/data/missing-main.c
@@ -0,0 +1,4 @@
+/* No main. */
+
+a() {
+} \ No newline at end of file
diff --git a/libacc/tests/data/otcc-ansi.c b/libacc/tests/data/otcc-ansi.c
new file mode 100644
index 0000000..72580e9
--- /dev/null
+++ b/libacc/tests/data/otcc-ansi.c
@@ -0,0 +1,466 @@
+// #include <stdio.h>
+int d, z, C, h, P, K, ac, q, G, v, Q, R, D, L, W, M;
+
+void E(int e) {
+ *(char*) D++ = e;
+}
+
+void o() {
+ if (L) {
+ h = *(char*) L++;
+ if (h == 2) {
+ L = 0;
+ h = W;
+ }
+ } else
+ h = fgetc(Q);
+}
+
+int X() {
+ return isalnum(h) | h == 95;
+}
+
+void Y() {
+ if (h == 92) {
+ o();
+ if (h == 110)
+ h = 10;
+ }
+}
+
+void ad() {
+ int e, j, m;
+ while (isspace(h) | h == 35) {
+ if (h == 35) {
+ o();
+ ad();
+ if (d == 536) {
+ ad();
+ E(32);
+ *(int*) d = 1;
+ *(int*) (d + 4) = D;
+ }
+ while (h != 10) {
+ E(h);
+ o();
+ }
+ E(h);
+ E(2);
+ }
+ o();
+ }
+ C = 0;
+ d = h;
+ if (X()) {
+ E(32);
+ M = D;
+ while (X()) {
+ E(h);
+ o();
+ }
+ if (isdigit(d)) {
+ z = strtol(M, 0, 0);
+ d = 2;
+ } else {
+ *(char*) D = 32;
+ d = strstr(R, M - 1) - R;
+ *(char*) D = 0;
+ d = d * 8 + 256;
+ if (d > 536) {
+ d = P + d;
+ if (*(int*) d == 1) {
+ L = *(int*) (d + 4);
+ W = h;
+ o();
+ ad();
+ }
+ }
+ }
+ } else {
+ o();
+ if (d == 39) {
+ d = 2;
+ Y();
+ z = h;
+ o();
+ o();
+ } else if (d == 47 & h == 42) {
+ o();
+ while (h) {
+ while (h != 42)
+ o();
+ o();
+ if (h == 47)
+ h = 0;
+ }
+ o();
+ ad();
+ } else {
+ e
+ = "++#m--%am*@R<^1c/@%[_[H3c%@%[_[H3c+@.B#d-@%:_^BKd<<Z/03e>>`/03e<=0f>=/f<@.f>@1f==&g!='g&&k||#l&@.BCh^@.BSi|@.B+j~@/%Yd!@&d*@b";
+ while (j = *(char*) e++) {
+ m = *(char*) e++;
+ z = 0;
+ while ((C = *(char*) e++ - 98) < 0)
+ z = z * 64 + C + 64;
+ if (j == d & (m == h | m == 64)) {
+ if (m == h) {
+ o();
+ d = 1;
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+
+void ae(int g) {
+ while( g&&g!=-1) {
+ *(char*) q++=g;
+ g=g>>8;
+ }
+}
+
+void A(int e) {
+ int g;
+ while( e) {
+ g=*(int*) e;
+ *(int*) e=q-e-4;
+ e=g;
+ }
+}
+
+int s(int g, int e) {
+ ae(g);
+ *(int*) q = e;
+ e = q;
+ q = q + 4;
+ return e;
+}
+
+void H(int e) {
+ s(184,e);
+}
+
+int B(int e) {
+ return s(233,e);
+}
+
+int S(int j, int e) {
+ ae(1032325);
+ return s(132 + j, e);
+}
+
+void Z(int e) {
+ ae( 49465);
+ H(0);
+ ae( 15);
+ ae( e+144);
+ ae( 192);
+}
+
+void N(int j, int e) {
+ ae(j + 131);
+ s((e > -512 && e < 512) << 7 | 5, e);
+}
+
+void T (int j) {
+ int g,e,m,aa;
+ g=1;
+ if( d == 34) {
+ H(v);
+ while( h!=34) {
+ Y ();
+ *(char*) v++=h;
+ o ();
+ }
+ *(char*) v=0;
+ v=v +4&-4;
+ o ();
+ ad();
+ }
+ else {
+ aa=C;
+ m= z;
+ e=d;
+ ad();
+ if( e == 2) {
+ H(m);
+ }
+ else if( aa == 2) {
+ T(0);
+ s(185,0);
+ if( e == 33)Z(m);
+ else ae( m);
+ }
+ else if( e == 40) {
+ w ();
+ ad();
+ }
+ else if( e == 42) {
+ ad();
+ e=d;
+ ad();
+ ad();
+ if( d == 42) {
+ ad();
+ ad();
+ ad();
+ ad();
+ e=0;
+ }
+ ad();
+ T(0);
+ if( d == 61) {
+ ad();
+ ae( 80);
+ w ();
+ ae( 89);
+ ae( 392+(e == 256));
+ }
+ else if( e) {
+ if( e == 256)ae( 139);
+ else ae( 48655);
+ q++;
+ }
+ }
+ else if( e == 38) {
+ N(10,*(int*) d);
+ ad();
+ }
+ else {
+ g=*(int*) e;
+ if(!g)g=dlsym(0,M);
+ if( d == 61&j) {
+ ad();
+ w ();
+ N(6,g);
+ }
+ else if( d!= 40) {
+ N(8,g);
+ if( C == 11) {
+ N(0,g);
+ ae( z);
+ ad();
+ }
+ }
+ }
+ }
+ if( d == 40) {
+ if( g == 1)ae( 80);
+ m= s(60545,0);
+ ad();
+ j=0;
+ while( d!= 41) {
+ w ();
+ s(2393225,j);
+ if( d == 44)ad();
+ j=j +4;
+ }
+ *(int*) m= j;
+ ad();
+ if(!g) {
+ e=e +4;
+ *(int*) e=s(232,*(int*) e);
+ }
+ else if( g == 1) {
+ s(2397439,j);
+ j=j +4;
+ }
+ else {
+ s(232,g-q-5);
+ }
+ if( j)s(50305,j);
+ }
+}
+
+void O (int j) {
+ int e,g,m;
+ if( j--== 1)T(1);
+ else {
+ O (j);
+ m= 0;
+ while( j == C) {
+ g=d;
+ e=z;
+ ad();
+ if( j>8) {
+ m= S(e,m);
+ O (j);
+ }
+ else {
+ ae( 80);
+ O (j);
+ ae( 89);
+ if( j == 4|j == 5) {
+ Z(e);
+ }
+ else {
+ ae( e);
+ if( g == 37)ae( 146);
+ }
+ }
+ }
+ if( m&&j>8) {
+ m= S(e,m);
+ H(e^1);
+ B(5);
+ A(m);
+ H(e);
+ }
+ }
+}
+
+void w() {
+ O(11);
+}
+
+int U() {
+ w();
+ return S(0, 0);
+}
+
+void I (int j) {
+ int m,g,e;
+ if( d == 288) {
+ ad();
+ ad();
+ m= U ();
+ ad();
+ I (j);
+ if( d == 312) {
+ ad();
+ g=B(0);
+ A(m);
+ I (j);
+ A(g);
+ }
+ else {
+ A(m);
+ }
+ }
+ else if( d == 352|d == 504) {
+ e=d;
+ ad();
+ ad();
+ if( e == 352) {
+ g=q;
+ m= U ();
+ }
+ else {
+ if( d!= 59)w ();
+ ad();
+ g=q;
+ m= 0;
+ if( d!= 59)m= U ();
+ ad();
+ if( d!= 41) {
+ e=B(0);
+ w ();
+ B(g-q-5);
+ A(e);
+ g=e +4;
+ }
+ }
+ ad();
+ I(&m);
+ B(g-q-5);
+ A(m);
+ }
+ else if( d == 123) {
+ ad();
+ ab(1);
+ while( d!= 125)I (j);
+ ad();
+ }
+ else {
+ if( d == 448) {
+ ad();
+ if( d!= 59)w ();
+ K=B(K);
+ }
+ else if( d == 400) {
+ ad();
+ *(int*) j=B(*(int*) j);
+ }
+ else if( d!= 59)w ();
+ ad();
+ }
+}
+
+void ab (int j) {
+ int m;
+ while( d == 256|d!=-1&!j) {
+ if( d == 256) {
+ ad();
+ while( d!= 59) {
+ if( j) {
+ G=G +4;
+ *(int*) d=-G;
+ }
+ else {
+ *(int*) d=v;
+ v=v +4;
+ }
+ ad();
+ if( d == 44)ad() ;
+ }
+ ad();
+ }
+ else {
+ A(*(int*)(d +4));
+ *(int*) d=q;
+ ad();
+ ad();
+ m= 8;
+ while( d!= 41) {
+ *(int*) d=m;
+ m= m +4;
+ ad();
+ if( d == 44)ad();
+ }
+ ad();
+ K=G=0;
+ ae( 15042901);
+ m= s(60545,0);
+ I(0);
+ A(K);
+ ae( 50121);
+ *(int*) m= G;
+ }
+ }
+}
+
+int run(int g, int e) {
+ return (*(int(*)()) *(int*) (P + 592))(g, e);
+}
+
+int main(int g, int e) {
+ int result;
+ Q = stdin;
+ if (g-- > 1) {
+ e = e + 4;
+ Q = fopen(*(int*) e, "r");
+ if (!Q) {
+ fprintf(stderr, "otcc-ansi.c: could not open file %s\n", *(int*) e);
+ return -2;
+ }
+ }
+ D = strcpy(R = calloc(1, 99999), " int if else while break return for define main ") + 48;
+ v = calloc(1, 99999);
+ q = ac = calloc(1, 99999);
+ P = calloc(1, 99999);
+ o();
+ ad();
+ ab(0);
+ if (mprotect(ac & (~ 4095), (99999 + 4095) & (~ 4095), 7)) {
+ printf("Mprotect failed. %d\n", errno);
+ return -1;
+ }
+ fprintf(stderr, "otcc-ansi.c: About to execute compiled code:\n");
+ result = run(g, e);
+ fprintf(stderr, "atcc-ansi.c: result: %d\n", result);
+ return result;
+}
+
diff --git a/libacc/tests/data/otcc-noinclude.c b/libacc/tests/data/otcc-noinclude.c
new file mode 100644
index 0000000..530f9e2
--- /dev/null
+++ b/libacc/tests/data/otcc-noinclude.c
@@ -0,0 +1,446 @@
+// #include <stdio.h>
+#define k *(int*)
+#define a if(
+#define c ad()
+#define i else
+#define p while(
+#define x *(char*)
+#define b ==
+#define V =calloc(1,99999)
+#define f ()
+#define J return
+#define l ae(
+#define n e)
+#define u d!=
+#define F int
+#define y (j)
+#define r m=
+#define t +4
+F d,z,C,h,P,K,ac,q,G,v,Q,R,D,L,W,M;
+E(n{
+x D++=e;
+}
+o f{
+a L){
+h=x L++;
+a h b 2){
+L=0;
+h=W;
+}
+}
+i h=fgetc(Q);
+}
+X f{
+J isalnum(h)|h b 95;
+}
+Y f{
+a h b 92){
+o f;
+a h b 110)h=10;
+}
+}
+c{
+F e,j,m;
+p isspace(h)|h b 35){
+a h b 35){
+o f;
+c;
+a d b 536){
+c;
+E(32);
+k d=1;
+k(d t)=D;
+}
+p h!=10){
+E(h);
+o f;
+}
+E(h);
+E(2);
+}
+o f;
+}
+C=0;
+d=h;
+a X f){
+E(32);
+M=D;
+p X f){
+E(h);
+o f;
+}
+a isdigit(d)){
+z=strtol(M,0,0);
+d=2;
+}
+i{
+x D=32;
+d=strstr(R,M-1)-R;
+x D=0;
+d=d*8+256;
+a d>536){
+d=P+d;
+a k d b 1){
+L=k(d t);
+W=h;
+o f;
+c;
+}
+}
+}
+}
+i{
+o f;
+a d b 39){
+d=2;
+Y f;
+z=h;
+o f;
+o f;
+}
+i a d b 47&h b 42){
+o f;
+p h){
+p h!=42)o f;
+o f;
+a h b 47)h=0;
+}
+o f;
+c;
+}
+i{
+e="++#m--%am*@R<^1c/@%[_[H3c%@%[_[H3c+@.B#d-@%:_^BKd<<Z/03e>>`/03e<=0f>=/f<@.f>@1f==&g!='g&&k||#l&@.BCh^@.BSi|@.B+j~@/%Yd!@&d*@b";
+p j=x e++){
+r x e++;
+z=0;
+p(C=x e++-98)<0)z=z*64+C+64;
+a j b d&(m b h|m b 64)){
+a m b h){
+o f;
+d=1;
+}
+break;
+}
+}
+}
+}
+}
+l g){
+p g&&g!=-1){
+x q++=g;
+g=g>>8;
+}
+}
+A(n{
+F g;
+p n{
+g=k e;
+k e=q-e-4;
+e=g;
+}
+}
+s(g,n{
+l g);
+k q=e;
+e=q;
+q=q t;
+J e;
+}
+H(n{
+s(184,n;
+}
+B(n{
+J s(233,n;
+}
+S(j,n{
+l 1032325);
+J s(132+j,n;
+}
+Z(n{
+l 49465);
+H(0);
+l 15);
+l e+144);
+l 192);
+}
+N(j,n{
+l j+131);
+s((e<512)<<7|5,n;
+}
+T y{
+F g,e,m,aa;
+g=1;
+a d b 34){
+H(v);
+p h!=34){
+Y f;
+x v++=h;
+o f;
+}
+x v=0;
+v=v t&-4;
+o f;
+c;
+}
+i{
+aa=C;
+r z;
+e=d;
+c;
+a e b 2){
+H(m);
+}
+i a aa b 2){
+T(0);
+s(185,0);
+a e b 33)Z(m);
+i l m);
+}
+i a e b 40){
+w f;
+c;
+}
+i a e b 42){
+c;
+e=d;
+c;
+c;
+a d b 42){
+c;
+c;
+c;
+c;
+e=0;
+}
+c;
+T(0);
+a d b 61){
+c;
+l 80);
+w f;
+l 89);
+l 392+(e b 256));
+}
+i a n{
+a e b 256)l 139);
+i l 48655);
+q++;
+}
+}
+i a e b 38){
+N(10,k d);
+c;
+}
+i{
+g=k e;
+a!g)g=dlsym(0,M);
+a d b 61&j){
+c;
+w f;
+N(6,g);
+}
+i a u 40){
+N(8,g);
+a C b 11){
+N(0,g);
+l z);
+c;
+}
+}
+}
+}
+a d b 40){
+a g b 1)l 80);
+r s(60545,0);
+c;
+j=0;
+p u 41){
+w f;
+s(2393225,j);
+a d b 44)c;
+j=j t;
+}
+k r j;
+c;
+a!g){
+e=e t;
+k e=s(232,k n;
+}
+i a g b 1){
+s(2397439,j);
+j=j t;
+}
+i{
+s(232,g-q-5);
+}
+a j)s(50305,j);
+}
+}
+O y{
+F e,g,m;
+a j--b 1)T(1);
+i{
+O y;
+r 0;
+p j b C){
+g=d;
+e=z;
+c;
+a j>8){
+r S(e,m);
+O y;
+}
+i{
+l 80);
+O y;
+l 89);
+a j b 4|j b 5){
+Z(n;
+}
+i{
+l n;
+a g b 37)l 146);
+}
+}
+}
+a m&&j>8){
+r S(e,m);
+H(e^1);
+B(5);
+A(m);
+H(n;
+}
+}
+}
+w f{
+O(11);
+}
+U f{
+w f;
+J S(0,0);
+}
+I y{
+F m,g,e;
+a d b 288){
+c;
+c;
+r U f;
+c;
+I y;
+a d b 312){
+c;
+g=B(0);
+A(m);
+I y;
+A(g);
+}
+i{
+A(m);
+}
+}
+i a d b 352|d b 504){
+e=d;
+c;
+c;
+a e b 352){
+g=q;
+r U f;
+}
+i{
+a u 59)w f;
+c;
+g=q;
+r 0;
+a u 59)r U f;
+c;
+a u 41){
+e=B(0);
+w f;
+B(g-q-5);
+A(n;
+g=e t;
+}
+}
+c;
+I(&m);
+B(g-q-5);
+A(m);
+}
+i a d b 123){
+c;
+ab(1);
+p u 125)I y;
+c;
+}
+i{
+a d b 448){
+c;
+a u 59)w f;
+K=B(K);
+}
+i a d b 400){
+c;
+k j=B(k j);
+}
+i a u 59)w f;
+c;
+}
+}
+ab y{
+F m;
+p d b 256|u-1&!j){
+a d b 256){
+c;
+p u 59){
+a j){
+G=G t;
+k d=-G;
+}
+i{
+k d=v;
+v=v t;
+}
+c;
+a d b 44)c;
+}
+c;
+}
+i{
+A(k(d t));
+k d=q;
+c;
+c;
+r 8;
+p u 41){
+k d=m;
+r m t;
+c;
+a d b 44)c;
+}
+c;
+K=G=0;
+l 15042901);
+r s(60545,0);
+I(0);
+A(K);
+l 50121);
+k r G;
+}
+}
+}
+main(g,n{
+Q=stdin;
+a g-->1){
+e=e t;
+Q=fopen(k e,"r");
+}
+D=strcpy(R V," int if else while break return for define main ")+48;
+v V;
+q=ac V;
+P V;
+o f;
+c;
+ab(0);
+J(*(int(*)f)k(P+592))(g,n;
+}
+
diff --git a/libacc/tests/data/otcc.c b/libacc/tests/data/otcc.c
new file mode 100644
index 0000000..433ae2e
--- /dev/null
+++ b/libacc/tests/data/otcc.c
@@ -0,0 +1,448 @@
+#include <stdio.h>
+#define k *(int*)
+#define a if(
+#define c ad()
+#define i else
+#define p while(
+#define x *(char*)
+#define b ==
+#define V =calloc(1,99999)
+#define f ()
+#define J return
+#define l ae(
+#define n e)
+#define u d!=
+#define F int
+#define y (j)
+#define r m=
+#define t +4
+F d,z,C,h,P,K,ac,q,G,v,Q,R,D,L,W,M;
+E(n{
+x D++=e;
+}
+o f{
+a L){
+h=x L++;
+a h b 2){
+L=0;
+h=W;
+}
+}
+i h=fgetc(Q);
+}
+X f{
+J isalnum(h)|h b 95;
+}
+Y f{
+a h b 92){
+o f;
+a h b 110)h=10;
+}
+}
+c{
+F e,j,m;
+p isspace(h)|h b 35){
+a h b 35){
+o f;
+c;
+a d b 536){
+c;
+E(32);
+k d=1;
+k(d t)=D;
+}
+p h!=10){
+E(h);
+o f;
+}
+E(h);
+E(2);
+}
+o f;
+}
+C=0;
+d=h;
+a X f){
+E(32);
+M=D;
+p X f){
+E(h);
+o f;
+}
+a isdigit(d)){
+z=strtol(M,0,0);
+d=2;
+}
+i{
+x D=32;
+d=strstr(R,M-1)-R;
+x D=0;
+d=d*8+256;
+a d>536){
+d=P+d;
+a k d b 1){
+L=k(d t);
+W=h;
+o f;
+c;
+}
+}
+}
+}
+i{
+o f;
+a d b 39){
+d=2;
+Y f;
+z=h;
+o f;
+o f;
+}
+i a d b 47&h b 42){
+o f;
+p h){
+p h!=42)o f;
+o f;
+a h b 47)h=0;
+}
+o f;
+c;
+}
+i{
+e="++#m--%am*@R<^1c/@%[_[H3c%@%[_[H3c+@.B#d-@%:_^BKd<<Z/03e>>`/03e<=0f>=/f<@.f>@1f==&g!='g&&k||#l&@.BCh^@.BSi|@.B+j~@/%Yd!@&d*@b";
+p j=x e++){
+r x e++;
+z=0;
+p(C=x e++-98)<0)z=z*64+C+64;
+a j b d&(m b h|m b 64)){
+a m b h){
+o f;
+d=1;
+}
+break;
+}
+}
+}
+}
+}
+l g){
+p g&&g!=-1){
+x q++=g;
+g=g>>8;
+}
+}
+A(n{
+F g;
+p n{
+g=k e;
+k e=q-e-4;
+e=g;
+}
+}
+s(g,n{
+l g);
+k q=e;
+e=q;
+q=q t;
+J e;
+}
+H(n{
+s(184,n;
+}
+B(n{
+J s(233,n;
+}
+S(j,n{
+l 1032325);
+J s(132+j,n;
+}
+Z(n{
+l 49465);
+H(0);
+l 15);
+l e+144);
+l 192);
+}
+N(j,n{
+l j+131);
+s((e<512)<<7|5,n;
+}
+T y{
+F g,e,m,aa;
+g=1;
+a d b 34){
+H(v);
+p h!=34){
+Y f;
+x v++=h;
+o f;
+}
+x v=0;
+v=v t&-4;
+o f;
+c;
+}
+i{
+aa=C;
+r z;
+e=d;
+c;
+a e b 2){
+H(m);
+}
+i a aa b 2){
+T(0);
+s(185,0);
+a e b 33)Z(m);
+i l m);
+}
+i a e b 40){
+w f;
+c;
+}
+i a e b 42){
+c;
+e=d;
+c;
+c;
+a d b 42){
+c;
+c;
+c;
+c;
+e=0;
+}
+c;
+T(0);
+a d b 61){
+c;
+l 80);
+w f;
+l 89);
+l 392+(e b 256));
+}
+i a n{
+a e b 256)l 139);
+i l 48655);
+q++;
+}
+}
+i a e b 38){
+N(10,k d);
+c;
+}
+i{
+g=k e;
+a!g)g=dlsym(0,M);
+a d b 61&j){
+c;
+w f;
+N(6,g);
+}
+i a u 40){
+N(8,g);
+a C b 11){
+N(0,g);
+l z);
+c;
+}
+}
+}
+}
+a d b 40){
+a g b 1)l 80);
+r s(60545,0);
+c;
+j=0;
+p u 41){
+w f;
+s(2393225,j);
+a d b 44)c;
+j=j t;
+}
+k r j;
+c;
+a!g){
+e=e t;
+k e=s(232,k n;
+}
+i a g b 1){
+s(2397439,j);
+j=j t;
+}
+i{
+s(232,g-q-5);
+}
+a j)s(50305,j);
+}
+}
+O y{
+F e,g,m;
+a j--b 1)T(1);
+i{
+O y;
+r 0;
+p j b C){
+g=d;
+e=z;
+c;
+a j>8){
+r S(e,m);
+O y;
+}
+i{
+l 80);
+O y;
+l 89);
+a j b 4|j b 5){
+Z(n;
+}
+i{
+l n;
+a g b 37)l 146);
+}
+}
+}
+a m&&j>8){
+r S(e,m);
+H(e^1);
+B(5);
+A(m);
+H(n;
+}
+}
+}
+w f{
+O(11);
+}
+U f{
+w f;
+J S(0,0);
+}
+I y{
+F m,g,e;
+a d b 288){
+c;
+c;
+r U f;
+c;
+I y;
+a d b 312){
+c;
+g=B(0);
+A(m);
+I y;
+A(g);
+}
+i{
+A(m);
+}
+}
+i a d b 352|d b 504){
+e=d;
+c;
+c;
+a e b 352){
+g=q;
+r U f;
+}
+i{
+a u 59)w f;
+c;
+g=q;
+r 0;
+a u 59)r U f;
+c;
+a u 41){
+e=B(0);
+w f;
+B(g-q-5);
+A(n;
+g=e t;
+}
+}
+c;
+I(&m);
+B(g-q-5);
+A(m);
+}
+i a d b 123){
+c;
+ab(1);
+p u 125)I y;
+c;
+}
+i{
+a d b 448){
+c;
+a u 59)w f;
+K=B(K);
+}
+i a d b 400){
+c;
+k j=B(k j);
+}
+i a u 59)w f;
+c;
+}
+}
+ab y{
+F m;
+p d b 256|u-1&!j){
+a d b 256){
+c;
+p u 59){
+a j){
+G=G t;
+k d=-G;
+}
+i{
+k d=v;
+v=v t;
+}
+c;
+a d b 44)c;
+}
+c;
+}
+i{
+A(k(d t));
+k d=q;
+c;
+c;
+r 8;
+p u 41){
+k d=m;
+r m t;
+c;
+a d b 44)c;
+}
+c;
+K=G=0;
+l 15042901);
+r s(60545,0);
+I(0);
+A(K);
+l 50121);
+k r G;
+}
+}
+}
+main(g,n{
+Q=stdin;
+a g-->1){
+e=e t;
+Q=fopen(k e,"r");
+}
+D=strcpy(R V," int if else while break return for define main ")+48;
+v V;
+q=ac V;
+P V;
+o f;
+c;
+ab(0);
+mprotect(ac & (~ 4095), (99999 + 4095) & (~ 4095), 7);
+fprintf(stderr, "otcc.c: about to execute compiled code.\n");
+J(*(int(*)f)k(P+592))(g,n;
+}
+
diff --git a/libacc/tests/data/pointers.c b/libacc/tests/data/pointers.c
new file mode 100644
index 0000000..461ebeb
--- /dev/null
+++ b/libacc/tests/data/pointers.c
@@ -0,0 +1,15 @@
+int main() {
+ int* pa = (int*) malloc(100);
+ int* pb = pa + 1;
+ int* pc = (int*) 0;
+ *pa = 1;
+ *pb = 2;
+ printf("Pointer difference: %d %d\n", pb - pa, ((int) pb) - ((int) pa));
+ int c = * (pa + 1);
+ printf("Pointer addition: %d\n", c);
+ printf("Pointer comparison to zero: %d %d %d\n", pa == 0, pb == 0, pc == 0);
+ printf("Pointer comparison: %d %d %d %d %d\n", pa < pb, pa == pb, pa > pb, ! pb, ! pc);
+ free(pa);
+ return 0;
+}
+
diff --git a/libacc/tests/data/returnval-ansi.c b/libacc/tests/data/returnval-ansi.c
new file mode 100644
index 0000000..6b53fd5
--- /dev/null
+++ b/libacc/tests/data/returnval-ansi.c
@@ -0,0 +1,8 @@
+
+int main(int argc, char** argv) {
+ return f();
+}
+
+int f() {
+ return 42;
+}
diff --git a/libacc/tests/data/returnval.c b/libacc/tests/data/returnval.c
new file mode 100644
index 0000000..1cf5bae
--- /dev/null
+++ b/libacc/tests/data/returnval.c
@@ -0,0 +1,4 @@
+main() {
+ return 42;
+}
+
diff --git a/libacc/tests/data/rollo3.c b/libacc/tests/data/rollo3.c
new file mode 100644
index 0000000..b21c12f
--- /dev/null
+++ b/libacc/tests/data/rollo3.c
@@ -0,0 +1,9 @@
+
+float fabsf(float);
+
+int main(void* con, int ft, int launchID)
+{
+ float f = fabsf(-10.0f);
+ return f;
+}
+
diff --git a/libacc/tests/data/simplest.c b/libacc/tests/data/simplest.c
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/libacc/tests/data/simplest.c
@@ -0,0 +1 @@
+main() {}
diff --git a/libacc/tests/data/testStringConcat.c b/libacc/tests/data/testStringConcat.c
new file mode 100644
index 0000000..bf06ae1
--- /dev/null
+++ b/libacc/tests/data/testStringConcat.c
@@ -0,0 +1,4 @@
+int main() {
+ return printf("Hello" "," " world\n");
+}
+
diff --git a/libacc/tests/main.cpp b/libacc/tests/main.cpp
new file mode 100644
index 0000000..5e9e816
--- /dev/null
+++ b/libacc/tests/main.cpp
@@ -0,0 +1,148 @@
+/*
+ * Android "Almost" C Compiler.
+ * This is a compiler for a small subset of the C language, intended for use
+ * in scripting environments where speed and memory footprint are important.
+ *
+ * This code is based upon the "unobfuscated" version of the
+ * Obfuscated Tiny C compiler, see the file LICENSE for details.
+ *
+ */
+
+#include <ctype.h>
+#include <dlfcn.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(__arm__)
+#include <unistd.h>
+#endif
+
+#include <acc/acc.h>
+
+
+typedef int (*MainPtr)(int, char**);
+// This is a separate function so it can easily be set by breakpoint in gdb.
+int run(MainPtr mainFunc, int argc, char** argv) {
+ return mainFunc(argc, argv);
+}
+
+// Private API for development:
+
+extern "C"
+void accDisassemble(ACCscript* script);
+
+ACCvoid* symbolLookup(ACCvoid* pContext, const ACCchar* name) {
+ return (ACCvoid*) dlsym(RTLD_DEFAULT, name);
+}
+
+int main(int argc, char** argv) {
+ const char* inFile = NULL;
+ bool printListing;
+ bool runResults = false;
+ FILE* in = stdin;
+ int i;
+ for (i = 1; i < argc; i++) {
+ char* arg = argv[i];
+ if (arg[0] == '-') {
+ switch (arg[1]) {
+ case 'S':
+ printListing = true;
+ break;
+ case 'R':
+ runResults = true;
+ break;
+ default:
+ fprintf(stderr, "Unrecognized flag %s\n", arg);
+ return 3;
+ }
+ } else if (inFile == NULL) {
+ inFile = arg;
+ } else {
+ break;
+ }
+ }
+
+ if (! inFile) {
+ fprintf(stderr, "input file required\n");
+ return 2;
+ }
+
+ if (inFile) {
+ in = fopen(inFile, "r");
+ if (!in) {
+ fprintf(stderr, "Could not open input file %s\n", inFile);
+ return 1;
+ }
+ }
+
+ fseek(in, 0, SEEK_END);
+ size_t fileSize = (size_t) ftell(in);
+ rewind(in);
+ ACCchar* text = new ACCchar[fileSize + 1];
+ size_t bytesRead = fread(text, 1, fileSize, in);
+ if (bytesRead != fileSize) {
+ fprintf(stderr, "Could not read all of file %s\n", inFile);
+ }
+
+ text[fileSize] = '\0';
+
+ ACCscript* script = accCreateScript();
+
+ const ACCchar* scriptSource[] = {text};
+ accScriptSource(script, 1, scriptSource, NULL);
+ delete[] text;
+
+ accRegisterSymbolCallback(script, symbolLookup, NULL);
+
+ accCompileScript(script);
+ int result = accGetError(script);
+ MainPtr mainPointer = 0;
+ if (result != 0) {
+ char buf[1024];
+ accGetScriptInfoLog(script, sizeof(buf), NULL, buf);
+ fprintf(stderr, "%s", buf);
+ goto exit;
+ }
+
+ {
+ ACCsizei numPragmaStrings;
+ accGetPragmas(script, &numPragmaStrings, 0, NULL);
+ if (numPragmaStrings) {
+ char** strings = new char*[numPragmaStrings];
+ accGetPragmas(script, NULL, numPragmaStrings, strings);
+ for(ACCsizei i = 0; i < numPragmaStrings; i += 2) {
+ fprintf(stderr, "#pragma %s(%s)\n", strings[i], strings[i+1]);
+ }
+ delete[] strings;
+ }
+ }
+
+ if (printListing) {
+ accDisassemble(script);
+ }
+
+ if (runResults) {
+ accGetScriptLabel(script, "main", (ACCvoid**) & mainPointer);
+
+ result = accGetError(script);
+ if (result != ACC_NO_ERROR) {
+ fprintf(stderr, "Could not find main: %d\n", result);
+ } else {
+ fprintf(stderr, "Executing compiled code:\n");
+ int codeArgc = argc - i + 1;
+ char** codeArgv = argv + i - 1;
+ codeArgv[0] = (char*) (inFile ? inFile : "stdin");
+ result = run(mainPointer, codeArgc, codeArgv);
+ fprintf(stderr, "result: %d\n", result);
+ }
+ }
+
+exit:
+
+ accDeleteScript(script);
+
+ return result;
+}
diff --git a/libacc/tests/runtimeTest.cpp b/libacc/tests/runtimeTest.cpp
new file mode 100644
index 0000000..d59e1d1
--- /dev/null
+++ b/libacc/tests/runtimeTest.cpp
@@ -0,0 +1,110 @@
+/*
+ * RuntimeTest for ACC compiler.
+ *
+ */
+
+#include <ctype.h>
+#include <dlfcn.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(__arm__)
+#include <unistd.h>
+#endif
+
+#include <acc/acc.h>
+
+
+typedef void (*ScriptPtr)();
+
+// This is a separate function so it can easily be set by breakpoint in gdb.
+void run(ScriptPtr scriptFn) {
+ scriptFn();
+}
+
+// Private API for development:
+
+extern "C"
+void accDisassemble(ACCscript* script);
+
+void op_int(int a) {
+ printf("op_int(%d)\n", a);
+}
+
+void op_float12(float a, float b, float c, float d,
+ float e, float f, float g, float h,
+ float i, float j, float k, float l) {
+ printf("op_float12(%g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g)\n",
+ a, b, c, d, e, f, g, h, i, j, k, l);
+}
+
+const char* text = "void op_int(int a);\n"
+ "void op_float12(float a, float b, float c, float d,\n"
+ " float e, float f, float g, float h,\n"
+ " float i, float j, float k, float l);\n"
+ "void script() {\n"
+ " op_int(123);\n"
+ " op_float12(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0);\n"
+ "}\n";
+
+ACCvoid* symbolLookup(ACCvoid* pContext, const ACCchar* name) {
+ if (strcmp("op_int", name) == 0) {
+ return (ACCvoid*) op_int;
+ }
+ if (strcmp("op_float12", name) == 0) {
+ return (ACCvoid*) op_float12;
+ }
+ return (ACCvoid*) dlsym(RTLD_DEFAULT, name);
+}
+
+int main(int argc, char** argv) {
+ ACCscript* script = accCreateScript();
+
+ accRegisterSymbolCallback(script, symbolLookup, NULL);
+
+ const ACCchar* scriptSource[] = {text};
+ accScriptSource(script, 1, scriptSource, NULL);
+
+ accCompileScript(script);
+ int result = accGetError(script);
+ ScriptPtr scriptPointer = 0;
+ if (result != 0) {
+ char buf[1024];
+ accGetScriptInfoLog(script, sizeof(buf), NULL, buf);
+ fprintf(stderr, "%s", buf);
+ goto exit;
+ }
+
+ {
+ ACCsizei numPragmaStrings;
+ accGetPragmas(script, &numPragmaStrings, 0, NULL);
+ if (numPragmaStrings) {
+ char** strings = new char*[numPragmaStrings];
+ accGetPragmas(script, NULL, numPragmaStrings, strings);
+ for(ACCsizei i = 0; i < numPragmaStrings; i += 2) {
+ fprintf(stderr, "#pragma %s(%s)\n", strings[i], strings[i+1]);
+ }
+ delete[] strings;
+ }
+ }
+
+ accGetScriptLabel(script, "script", (ACCvoid**) & scriptPointer);
+
+ result = accGetError(script);
+ if (result != ACC_NO_ERROR) {
+ fprintf(stderr, "Could not find script: %d\n", result);
+ } else {
+ fprintf(stderr, "Executing script:\n");
+ run(scriptPointer);
+ }
+
+
+exit:
+
+ accDeleteScript(script);
+
+ return result;
+}
diff --git a/libacc/tests/test b/libacc/tests/test
new file mode 100755
index 0000000..ef10500
--- /dev/null
+++ b/libacc/tests/test
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+SCRIPT_DIR=`dirname $BASH_SOURCE`
+cd $SCRIPT_DIR
+python test.py
+
diff --git a/libacc/tests/test.py b/libacc/tests/test.py
new file mode 100644
index 0000000..909886d
--- /dev/null
+++ b/libacc/tests/test.py
@@ -0,0 +1,295 @@
+#
+# Test the acc compiler
+
+import unittest
+import subprocess
+import os
+import sets
+
+gArmInitialized = False
+
+def compile(args):
+ proc = subprocess.Popen(["acc"] + args, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
+ result = proc.communicate()
+ return result
+
+def runCmd(args):
+ proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ result = proc.communicate()
+ return result[0].strip()
+
+def which(item):
+ return runCmd(["which", item])
+
+def fileType(item):
+ return runCmd(["file", item])
+
+def outputCanRun():
+ ft = fileType(which("acc"))
+ return ft.find("ELF 32-bit LSB executable, Intel 80386") >= 0
+
+def adb(args):
+ return runCmd(["adb"] + args)
+
+def setupArm():
+ global gArmInitialized
+ if gArmInitialized:
+ return
+ print "Setting up arm"
+ adb(["remount"])
+ adb(["shell", "rm", "/system/bin/acc"])
+ adb(["shell", "mkdir", "/system/bin/accdata"])
+ adb(["shell", "mkdir", "/system/bin/accdata/data"])
+ # Clear out old data TODO: handle recursion
+ adb(["shell", "rm", "/system/bin/accdata/data/*"])
+ # Copy over data
+ for root, dirs, files in os.walk("data"):
+ for d in dirs:
+ adb(["shell", "mkdir", os.path.join(root, d)])
+ for f in files:
+ adb(["push", os.path.join(root, f), os.path.join("/system/bin/accdata", root, f)])
+ # Copy over compiler
+ adb(["sync"])
+ gArmInitialized = True
+
+def compileArm(args):
+ setupArm()
+ proc = subprocess.Popen(["adb", "shell", "/system/bin/acc"] + args, stdout=subprocess.PIPE)
+ result = proc.communicate()
+ return result[0].replace("\r","")
+
+def compare(a, b):
+ if a != b:
+ firstDiff = firstDifference(a, b)
+ print "Strings differ at character %d. Common: %s. Difference '%s' != '%s'" % (
+ firstDiff, a[0:firstDiff], safeAccess(a, firstDiff), safeAccess(b, firstDiff))
+
+def safeAccess(s, i):
+ if 0 <= i < len(s):
+ return s[i]
+ else:
+ return '?'
+
+def firstDifference(a, b):
+ commonLen = min(len(a), len(b))
+ for i in xrange(0, commonLen):
+ if a[i] != b[i]:
+ return i
+ return commonLen
+
+# a1 and a2 are the expected stdout and stderr.
+# b1 and b2 are the actual stdout and stderr.
+# Compare the two, sets. Allow any individual line
+# to appear in either stdout or stderr. This is because
+# the way we obtain output on the ARM combines both
+# streams into one sequence.
+
+def compareOuput(a1,a2,b1,b2):
+ while True:
+ totalLen = len(a1) + len(a2) + len(b1) + len(b2)
+ a1, b1 = matchCommon(a1, b1)
+ a1, b2 = matchCommon(a1, b2)
+ a2, b1 = matchCommon(a2, b1)
+ a2, b2 = matchCommon(a2, b2)
+ newTotalLen = len(a1) + len(a2) + len(b1) + len(b2)
+ if newTotalLen == 0:
+ return True
+ if newTotalLen == totalLen:
+ print "Failed at %d %d %d %d" % (len(a1), len(a2), len(b1), len(b2))
+ print "a1", a1
+ print "a2", a2
+ print "b1", b1
+ print "b2", b2
+ return False
+
+def matchCommon(a, b):
+ """Remove common items from the beginning of a and b,
+ return just the tails that are different."""
+ while len(a) > 0 and len(b) > 0 and a[0] == b[0]:
+ a = a[1:]
+ b = b[1:]
+ return a, b
+
+def rewritePaths(args):
+ return [rewritePath(x) for x in args]
+
+def rewritePath(p):
+ """Take a path that's correct on the x86 and convert to a path
+ that's correct on ARM."""
+ if p.startswith("data/"):
+ p = "/system/bin/accdata/" + p
+ return p
+
+class TestACC(unittest.TestCase):
+
+ def checkResult(self, out, err, stdErrResult, stdOutResult=""):
+ a1 = out.splitlines()
+ a2 = err.splitlines()
+ b2 = stdErrResult.splitlines()
+ b1 = stdOutResult.splitlines()
+ self.assertEqual(True, compareOuput(a1,a2,b1,b2))
+
+ def compileCheck(self, args, stdErrResult, stdOutResult="",
+ targets=['arm', 'x86']):
+ targetSet = sets.ImmutableSet(targets)
+ if 'x86' in targetSet:
+ out, err = compile(args)
+ self.checkResult(out, err, stdErrResult, stdOutResult)
+ if 'arm' in targetSet:
+ out = compileArm(rewritePaths(args))
+ self.checkResult(out, "", stdErrResult, stdOutResult)
+
+ def compileCheckArm(self, args, result):
+ self.assertEqual(compileArm(args), result)
+
+ def testCompileReturnVal(self):
+ self.compileCheck(["data/returnval-ansi.c"], "")
+
+ def testCompileOTCCANSII(self):
+ self.compileCheck(["data/otcc-ansi.c"], "", "", ['x86'])
+
+ def testRunReturnVal(self):
+ self.compileCheck(["-R", "data/returnval-ansi.c"],
+ "Executing compiled code:\nresult: 42\n")
+
+ def testStringLiteralConcatenation(self):
+ self.compileCheck(["-R", "data/testStringConcat.c"],
+ "Executing compiled code:\nresult: 13\n", "Hello, world\n")
+
+ def testRunOTCCANSI(self):
+ self.compileCheck(["-R", "data/otcc-ansi.c", "data/returnval.c"],
+ "Executing compiled code:\notcc-ansi.c: About to execute compiled code:\natcc-ansi.c: result: 42\nresult: 42\n", "",
+ ['x86'])
+
+ def testRunOTCCANSI2(self):
+ self.compileCheck(["-R", "data/otcc-ansi.c", "data/otcc.c", "data/returnval.c"],
+ "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'])
+
+ def testRunConstants(self):
+ self.compileCheck(["-R", "data/constants.c"],
+ "Executing compiled code:\nresult: 12\n",
+ "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" +
+ "'\\\"' = 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")
+
+ def testRunFloat(self):
+ self.compileCheck(["-R", "data/float.c"],
+ "Executing compiled code:\nresult: 0\n",
+ """Constants: 0 0 0 0.01 0.01 0.1 10 10 0.1
+int: 1 float: 2.2 double: 3.3
+ ftoi(1.4f)=1
+ dtoi(2.4)=2
+ itof(3)=3
+ itod(4)=4
+globals: 1 2 3 4
+args: 1 2 3 4
+locals: 1 2 3 4
+cast rval: 2 4
+cast lval: 1.1 2 3.3 4
+""")
+
+ def testRunFlops(self):
+ self.compileCheck(["-R", "data/flops.c"],
+ """Executing compiled code:
+result: 0""",
+"""-1.1 = -1.1
+!1.2 = 0
+!0 = 1
+double op double:
+1 + 2 = 3
+1 - 2 = -1
+1 * 2 = 2
+1 / 2 = 0.5
+float op float:
+1 + 2 = 3
+1 - 2 = -1
+1 * 2 = 2
+1 / 2 = 0.5
+double op float:
+1 + 2 = 3
+1 - 2 = -1
+1 * 2 = 2
+1 / 2 = 0.5
+double op int:
+1 + 2 = 3
+1 - 2 = -1
+1 * 2 = 2
+1 / 2 = 0.5
+int op double:
+1 + 2 = 3
+1 - 2 = -1
+1 * 2 = 2
+1 / 2 = 0.5
+double op double:
+1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
+1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
+2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
+double op float:
+1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
+1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
+2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
+float op float:
+1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
+1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
+2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
+int op double:
+1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
+1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
+2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
+double op int:
+1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
+1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
+2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
+branching: 1 0 1
+testpassi: 1 2 3 4 5 6 7 8 9 10 11 12
+testpassf: 1 2 3 4 5 6 7 8 9 10 11 12
+testpassd: 1 2 3 4 5 6 7 8 9 10 11 12
+testpassi: 1 2 3 4 5 6 7 8 9 10 11 12
+testpassf: 1 2 3 4 5 6 7 8 9 10 11 12
+testpassd: 1 2 3 4 5 6 7 8 9 10 11 12
+testpassi: 1 2 3 4 5 6 7 8 9 10 11 12
+testpassf: 1 2 3 4 5 6 7 8 9 10 11 12
+testpassd: 1 2 3 4 5 6 7 8 9 10 11 12
+testpassidf: 1 2 3
+""")
+ def testCasts(self):
+ self.compileCheck(["-R", "data/casts.c"],
+ """Executing compiled code:
+result: 0""", """Reading from a pointer: 3 3
+Writing to a pointer: 4
+Testing casts: 3 3 4.5 4
+Testing reading (int*): 4
+Testing writing (int*): 8 9
+Testing reading (char*): 0x78 0x56 0x34 0x12
+Testing writing (char*): 0x87654321
+f(10)
+Function pointer result: 70
+Testing read/write (float*): 8.8 9.9
+Testing read/write (double*): 8.8 9.9
+""")
+
+ def testChar(self):
+ self.compileCheck(["-R", "data/char.c"], """Executing compiled code:
+result: 0""", """a = 99, b = 41
+ga = 100, gb = 44""")
+
+ def testPointerArithmetic(self):
+ self.compileCheck(["-R", "data/pointers.c"], """Executing compiled code:
+result: 0""", """Pointer difference: 1 4
+Pointer addition: 2
+Pointer comparison to zero: 0 0 1
+Pointer comparison: 1 0 0 0 1
+""")
+ def testRollo3(self):
+ self.compileCheck(["-R", "data/rollo3.c"], """Executing compiled code:
+result: 10""", """""")
+
+ def testFloatDouble(self):
+ self.compileCheck(["-R", "data/floatdouble.c"], """Executing compiled code:
+result: 0""", """0.002 0.1 10""")
+
+
+if __name__ == '__main__':
+ if not outputCanRun():
+ print "Many tests are expected to fail, because acc is not a 32-bit x86 Linux executable."
+ unittest.main()
+