summaryrefslogtreecommitdiffstats
path: root/libacc/tests/main.cpp
blob: e65103e837d63964c5d9f50daa83c577f0558155 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
 * 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);
}

int main(int argc, char** argv) {
    const char* inFile = NULL;
    bool printListing;
    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;
            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];
    size_t bytesRead = fread(text, 1, fileSize, in);
    if (bytesRead != fileSize) {
        fprintf(stderr, "Could not read all of file %s\n", inFile);
    }

    ACCscript* script = accCreateScript();

    const ACCchar* scriptSource[] = {text};
    accScriptSource(script, 1, scriptSource, NULL);
    delete[] text;

    accCompileScript(script);
    int result = accGetError(script);
    MainPtr mainPointer = 0;
    if (result != 0) {
        char buf[1024];
        accGetScriptInfoLog(script, sizeof(buf), NULL, buf);
        fprintf(stderr, "%ss", buf);
        goto exit;
    }

    accGetScriptLabel(script, "main", (ACCvoid**) & mainPointer);

    result = accGetError(script);
    if (result == ACC_NO_ERROR) {
        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;
}