forked from cesanta/v7
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.c
132 lines (116 loc) · 3.12 KB
/
main.c
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* Copyright (c) 2014 Cesanta Software Limited
* All rights reserved
*/
#include "internal.h"
#if defined(_MSC_VER) && _MSC_VER >= 1800
#define fileno _fileno
#endif
#ifdef V7_EXE
#define V7_MAIN
#endif
#ifdef V7_MAIN
#include <sys/stat.h>
static void show_usage(char *argv[]) {
fprintf(stderr, "V7 version %s (c) Cesanta Software, built on %s\n",
V7_VERSION, __DATE__);
fprintf(stderr, "Usage: %s [OPTIONS] js_file ...\n", argv[0]);
fprintf(stderr, "%s\n", "OPTIONS:");
fprintf(stderr, "%s\n", " -e <expr> execute expression");
fprintf(stderr, "%s\n", " -t dump generated text AST");
fprintf(stderr, "%s\n", " -b dump generated binary AST");
exit(EXIT_FAILURE);
}
static char *read_file(const char *path, size_t *size) {
FILE *fp;
struct stat st;
char *data = NULL;
if ((fp = fopen(path, "rb")) != NULL && !fstat(fileno(fp), &st)) {
*size = st.st_size;
data = (char *) malloc(*size + 1);
if (data != NULL) {
if (fread(data, 1, *size, fp) != *size) {
free(data);
return NULL;
}
data[*size] = '\0';
}
fclose(fp);
}
return data;
}
static void print_error(struct v7 *v7, const char *f, val_t e) {
char buf[512];
char *s = v7_to_json(v7, e, buf, sizeof(buf));
fprintf(stderr, "Exec error [%s]: %s\n", f, s);
if (s != buf) {
free(s);
}
}
/*
* V7 executable main function.
* `init_func()` is an optional intialization function, aimed to export any
* extra functionality into vanilla v7 engine.
*/
int v7_main(int argc, char *argv[], void (*init_func)(struct v7 *)) {
struct v7 *v7 = v7_create();
int i, show_ast = 0, binary_ast = 0;
val_t res = v7_create_undefined();
if (init_func != NULL) {
init_func(v7);
}
/* Execute inline code */
for (i = 1; i < argc && argv[i][0] == '-'; i++) {
if (strcmp(argv[i], "-e") == 0 && i + 1 < argc) {
if (show_ast) {
v7_compile(argv[i + 1], binary_ast, stdout);
} else if (v7_exec(v7, &res, argv[i + 1]) != V7_OK) {
print_error(v7, argv[i + 1], res);
res = v7_create_undefined();
}
i++;
} else if (strcmp(argv[i], "-t") == 0) {
show_ast = 1;
} else if (strcmp(argv[i], "-b") == 0) {
show_ast = 1;
binary_ast = 1;
} else if (strcmp(argv[i], "-h") == 0) {
show_usage(argv);
}
}
if (argc == 1) {
show_usage(argv);
}
/* Execute files */
for (; i < argc; i++) {
if (show_ast) {
size_t size;
char *source_code;
if ((source_code = read_file(argv[i], &size)) == NULL) {
fprintf(stderr, "Cannot read [%s]\n", argv[i]);
} else {
v7_compile(source_code, binary_ast, stdout);
free(source_code);
}
} else if (v7_exec_file(v7, &res, argv[i]) != V7_OK) {
print_error(v7, argv[i], res);
res = v7_create_undefined();
}
}
if (!show_ast) {
char buf[2000];
char *s = v7_to_json(v7, res, buf, sizeof(buf));
printf("%s\n", s);
if (s != buf) {
free(s);
}
}
v7_destroy(v7);
return EXIT_SUCCESS;
}
#endif
#ifdef V7_EXE
int main(int argc, char *argv[]) {
return v7_main(argc, argv, NULL);
}
#endif