blob: e65103e837d63964c5d9f50daa83c577f0558155 [file] [log] [blame]
Jack Palevich1cdef202009-05-22 12:06:27 -07001/*
2 * Android "Almost" C Compiler.
3 * This is a compiler for a small subset of the C language, intended for use
4 * in scripting environments where speed and memory footprint are important.
5 *
6 * This code is based upon the "unobfuscated" version of the
7 * Obfuscated Tiny C compiler, see the file LICENSE for details.
8 *
9 */
10
11#include <ctype.h>
12#include <dlfcn.h>
13#include <stdarg.h>
14#include <stdint.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18
19#if defined(__arm__)
20#include <unistd.h>
21#endif
22
23#include <acc/acc.h>
24
25
26typedef int (*MainPtr)(int, char**);
27// This is a separate function so it can easily be set by breakpoint in gdb.
28int run(MainPtr mainFunc, int argc, char** argv) {
29 return mainFunc(argc, argv);
30}
31
32int main(int argc, char** argv) {
33 const char* inFile = NULL;
34 bool printListing;
35 FILE* in = stdin;
36 int i;
37 for (i = 1; i < argc; i++) {
38 char* arg = argv[i];
39 if (arg[0] == '-') {
40 switch (arg[1]) {
41 case 'S':
42 printListing = true;
43 break;
44 default:
45 fprintf(stderr, "Unrecognized flag %s\n", arg);
46 return 3;
47 }
48 } else if (inFile == NULL) {
49 inFile = arg;
50 } else {
51 break;
52 }
53 }
54
55 if (! inFile) {
56 fprintf(stderr, "input file required\n");
57 return 2;
58 }
59
60 if (inFile) {
61 in = fopen(inFile, "r");
62 if (!in) {
63 fprintf(stderr, "Could not open input file %s\n", inFile);
64 return 1;
65 }
66 }
67
68 fseek(in, 0, SEEK_END);
69 size_t fileSize = (size_t) ftell(in);
70 rewind(in);
71 ACCchar* text = new ACCchar[fileSize];
72 size_t bytesRead = fread(text, 1, fileSize, in);
73 if (bytesRead != fileSize) {
74 fprintf(stderr, "Could not read all of file %s\n", inFile);
75 }
76
77 ACCscript* script = accCreateScript();
78
79 const ACCchar* scriptSource[] = {text};
80 accScriptSource(script, 1, scriptSource, NULL);
81 delete[] text;
82
83 accCompileScript(script);
Jack Palevichac0e95e2009-05-29 13:53:44 -070084 int result = accGetError(script);
Jack Palevich1cdef202009-05-22 12:06:27 -070085 MainPtr mainPointer = 0;
Jack Palevichac0e95e2009-05-29 13:53:44 -070086 if (result != 0) {
87 char buf[1024];
88 accGetScriptInfoLog(script, sizeof(buf), NULL, buf);
89 fprintf(stderr, "%ss", buf);
90 goto exit;
91 }
Jack Palevich1cdef202009-05-22 12:06:27 -070092
93 accGetScriptLabel(script, "main", (ACCvoid**) & mainPointer);
94
Jack Palevichac0e95e2009-05-29 13:53:44 -070095 result = accGetError(script);
Jack Palevich1cdef202009-05-22 12:06:27 -070096 if (result == ACC_NO_ERROR) {
97 fprintf(stderr, "Executing compiled code:\n");
98 int codeArgc = argc - i + 1;
99 char** codeArgv = argv + i - 1;
100 codeArgv[0] = (char*) (inFile ? inFile : "stdin");
101 result = run(mainPointer, codeArgc, codeArgv);
102 fprintf(stderr, "result: %d\n", result);
103 }
104
Jack Palevichac0e95e2009-05-29 13:53:44 -0700105exit:
106
Jack Palevich1cdef202009-05-22 12:06:27 -0700107 accDeleteScript(script);
108
109 return result;
110}