RPA Toolkit
work on the RJS code segments
[rpatk.git] / rjs / rjsexec.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <sys/types.h>
6 #include <fcntl.h>
7 #include <unistd.h>
8 #include <sys/mman.h>
9
10 #include "rstring.h"
11 #include "rmem.h"
12 #include "rjs.h"
13 #include "rparecord.h"
14
15
16 static int debuginfo = 0;
17 static int parseinfo = 0;
18 static int compileonly = 0;
19 static int debugcompileonly = 0;
20 static int statinfo = 0;
21
22
23 static rchar *errormsg[] = {
24         "OK",
25         "Undefined identifier",
26         "Syntax error",
27         "Not a function",
28         "Not a function call",
29         "Not a loop",
30         "Not a if statement",
31         "Unknown",
32         "Unknown",
33         "Unknown",
34         "Unknown",
35         "Unknown",
36         "Unknown",
37         "Unknown",
38         "Unknown",
39         "Unknown",
40         "Unknown",
41 };
42
43 void rjs_unmap_file(rstr_t *buf)
44 {
45         if (buf) {
46                 munmap(buf->str, buf->size);
47                 r_free(buf);
48         }
49 }
50
51
52 rstr_t *rjs_map_file(const char *filename)
53 {
54         struct stat st;
55         rstr_t *str;
56         char *buffer;
57
58
59         int fd = open(filename, O_RDONLY);
60         if (fd < 0) {
61                 return (void*)0;
62         }
63         if (fstat(fd, &st) < 0) {
64                 close(fd);
65                 return (void*)0;
66         }
67         buffer = (char*)mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
68         if (buffer == (void*)-1) {
69                 close(fd);
70                 return (void*)0;
71         }
72         str = (rstr_t *)r_malloc(sizeof(*str));
73         if (!str)
74                 goto error;
75         r_memset(str, 0, sizeof(*str));
76         str->str = buffer;
77         str->size = st.st_size;
78         close(fd);
79         return str;
80
81 error:
82         munmap(buffer, st.st_size);
83         close(fd);
84         return str;
85 }
86
87
88 int rjs_exec_script(rjs_engine_t *jse, rstr_t  *script)
89 {
90         if (!script)
91                 return -1;
92         if (parseinfo) {
93                 rjs_engine_dumpast(jse, script->str, script->size);
94         } else if (debugcompileonly) {
95                 int res = 0;
96                 jse->debugcompile = 1;
97                 res = rjs_engine_compile(jse, script->str, script->size);
98                 jse->debugcompile = 0;
99                 if (res < 0)
100                         return -1;
101         } else if (compileonly) {
102                 if (rjs_engine_compile(jse, script->str, script->size) < 0)
103                         return -1;
104         } else {
105                 if (rjs_engine_compile(jse, script->str, script->size) < 0)
106                         return -1;
107                 if (rjs_engine_run(jse) < 0)
108                         return -1;
109         }
110
111         return 0;
112 }
113
114
115 rlong jrs_offset2line(const rchar *script, rlong offset)
116 {
117         rlong line = 0;
118         const rchar *ptr;
119
120         for (line = 1, ptr = script + offset; ptr >= script; --ptr) {
121                 if (*ptr == '\n')
122                         line += 1;
123         }
124
125         return line;
126 }
127
128
129 void rjs_display_errors(rjs_engine_t *jse, rstr_t *script)
130 {
131         rlong line = 0;
132         rlong i;
133         rjs_coerror_t *err;
134
135         for (i = 0; i < r_array_length(jse->co->errors); i++) {
136                 err = (rjs_coerror_t *)r_array_slot(jse->co->errors, i);
137                 line = jrs_offset2line(script->str, (rlong)(err->script - script->str));
138                 fprintf(stdout, "Line: %ld (%ld, %ld), Error Code: %ld, ", (rlong)line, (rlong)(err->script - script->str), (rlong)err->scriptsize, err->code);
139                 fprintf(stdout, "%s: ", errormsg[err->code]);
140                 fwrite(err->script, sizeof(rchar), err->scriptsize, stdout);
141                 fprintf(stdout, "\n");
142         }
143 }
144
145
146 int main(int argc, char *argv[])
147 {
148         rint i;
149         rstr_t *script = NULL, *unmapscript = NULL;
150         rstr_t line;
151         rjs_engine_t *jse;
152
153         jse = rjs_engine_create();
154         for (i = 1; i < argc; i++) {
155                 if (r_strcmp(argv[i], "-L") == 0) {
156
157                 } else if (r_strcmp(argv[i], "-d") == 0) {
158                         debuginfo = 1;
159                         jse->debugexec = 1;
160                 } else if (r_strcmp(argv[i], "-p") == 0) {
161                         parseinfo = 1;
162                 } else if (r_strcmp(argv[i], "-C") == 0) {
163                         debugcompileonly = 1;
164                 } else if (r_strcmp(argv[i], "-c") == 0) {
165                         compileonly = 1;
166                 } else if (r_strcmp(argv[i], "-t") == 0) {
167                         statinfo = 1;
168                 }
169         }
170
171         for (i = 1; i < argc; i++) {
172                 if (r_strcmp(argv[i], "-e") == 0) {
173                         if (++i < argc) {
174                                 line.str = argv[i];
175                                 line.size = r_strlen(argv[i]);
176                                 script = &line;
177                         }
178                         if (rjs_exec_script(jse, script) < 0)
179                                 goto end;
180                 }
181         }
182
183         for (i = 1; i < argc; i++) {
184                 if (r_strcmp(argv[i], "-f") == 0) {
185                         if (++i < argc) {
186                                 script = rjs_map_file(argv[i]);
187                                 if (script) {
188                                         unmapscript = script;
189                                 }
190                         }
191                         if (rjs_exec_script(jse, script) < 0)
192                                 goto end;
193                 }
194         }
195
196 end:
197         if (jse->co && r_array_length(jse->co->errors))
198                 rjs_display_errors(jse, script);
199         rjs_engine_destroy(jse);
200         if (unmapscript)
201                 rjs_unmap_file(unmapscript);
202         if (statinfo)
203                 fprintf(stdout, "\nRJS Version: %s, memory: %ld Bytes (leaked %ld Bytes)\n", rjs_version(), (rlong)r_debug_get_maxmem(), (rlong)r_debug_get_allocmem());
204         return 0;
205 }