RPA Toolkit
work on rjs build for windows. not ready yet.
[rpatk.git] / rjs / windows / rjsexec.c
1 /*
2  *  Regular Pattern Analyzer (RPA)
3  *  Copyright (c) 2009-2010 Martin Stoilov
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  *  Martin Stoilov <martin@rpasearch.com>
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <windows.h>
24
25 #include "rlib/rstring.h"
26 #include "rlib/rmem.h"
27 #include "rjs/rjs.h"
28 #include "rpa/rparecord.h"
29
30
31 static int debuginfo = 0;
32 static int parseinfo = 0;
33 static int compileonly = 0;
34 static int debugcompileonly = 0;
35 static int statinfo = 0;
36
37
38 static char *errormsg[] = {
39         "OK",
40         "Undefined identifier",
41         "Syntax error",
42         "Not a function",
43         "Not a function call",
44         "Not a loop",
45         "Not a if statement",
46         "Unknown",
47         "Unknown",
48         "Unknown",
49         "Unknown",
50         "Unknown",
51         "Unknown",
52         "Unknown",
53         "Unknown",
54         "Unknown",
55         "Unknown",
56 };
57
58
59 static void rjs_exec_ltrim(rvmcpu_t *cpu, rvm_asmins_t *ins)
60 {
61         const char *ptr, *list;
62         rsize_t size;
63         rvmreg_t *r = NULL, *l = NULL;
64         rstring_t *src, *dest;
65
66         if (RJS_SWI_PARAMS(cpu) == 0)
67                 RJS_SWI_ABORT(rjs_engine_get(cpu), NULL);
68         r = (rvmreg_t *) RJS_SWI_PARAM(cpu, 1);
69         if (RJS_SWI_PARAMS(cpu) > 1) {
70                 l = (rvmreg_t *) RJS_SWI_PARAM(cpu, 2);
71                 if (rvm_reg_gettype(l) != RVM_DTYPE_STRING)
72                         RJS_SWI_ABORT(rjs_engine_get(cpu), NULL);
73         }
74         if (rvm_reg_gettype(r) != RVM_DTYPE_STRING)
75                 RJS_SWI_ABORT(rjs_engine_get(cpu), NULL);
76         if (l)
77                 list = ((rstring_t *)RVM_REG_GETP(l))->s.str;
78         else
79                 list = " \t\n\r\0";
80         src = (rstring_t *)RVM_REG_GETP(r);
81         ptr = src->s.str;
82         size = src->s.size;
83         while (size > 0) {
84                 if (!r_strchr(list, *ptr))
85                         break;
86                 size--;
87                 ptr++;
88         }
89         dest = r_string_create_strsize(ptr, size);
90         r_gc_add(cpu->gc, (robject_t*)dest);
91         rvm_reg_setstring(RVM_CPUREG_PTR(cpu, R0), dest);
92 }
93
94
95 static void rjs_exec_rtrim(rvmcpu_t *cpu, rvm_asmins_t *ins)
96 {
97         const char *ptr, *list;
98         rsize_t size;
99         rvmreg_t *r = NULL, *l = NULL;
100         rstring_t *src, *dest;
101
102         if (RJS_SWI_PARAMS(cpu) == 0)
103                 RJS_SWI_ABORT(rjs_engine_get(cpu), NULL);
104         r = (rvmreg_t *) RJS_SWI_PARAM(cpu, 1);
105         if (RJS_SWI_PARAMS(cpu) > 1) {
106                 l = (rvmreg_t *) RJS_SWI_PARAM(cpu, 2);
107                 if (rvm_reg_gettype(l) != RVM_DTYPE_STRING)
108                         RJS_SWI_ABORT(rjs_engine_get(cpu), NULL);
109         }
110         if (rvm_reg_gettype(r) != RVM_DTYPE_STRING)
111                 RJS_SWI_ABORT(rjs_engine_get(cpu), NULL);
112         if (l)
113                 list = ((rstring_t *)RVM_REG_GETP(l))->s.str;
114         else
115                 list = " \t\n\r\0";
116         src = (rstring_t *)RVM_REG_GETP(r);
117         size = src->s.size;
118         ptr = src->s.str + size - 1;
119         while (size > 0) {
120                 if (!r_strchr(list, *ptr))
121                         break;
122                 size--;
123                 ptr--;
124         }
125         dest = r_string_create_strsize(src->s.str, size);
126         r_gc_add(cpu->gc, (robject_t*)dest);
127         rvm_reg_setstring(RVM_CPUREG_PTR(cpu, R0), dest);
128 }
129
130
131 static void rjs_exec_trim(rvmcpu_t *cpu, rvm_asmins_t *ins)
132 {
133         const char *start, *ptr, *list;
134         rsize_t size;
135         rvmreg_t *r = NULL, *l = NULL;
136         rstring_t *src, *dest;
137
138         if (RJS_SWI_PARAMS(cpu) == 0)
139                 RJS_SWI_ABORT(rjs_engine_get(cpu), NULL);
140
141         r = (rvmreg_t *) RJS_SWI_PARAM(cpu, 1);
142         if (RJS_SWI_PARAMS(cpu) > 1) {
143                 l = (rvmreg_t *) RJS_SWI_PARAM(cpu, 2);
144                 if (rvm_reg_gettype(l) != RVM_DTYPE_STRING)
145                         RJS_SWI_ABORT(rjs_engine_get(cpu), NULL);
146         }
147         if (rvm_reg_gettype(r) != RVM_DTYPE_STRING)
148                 RJS_SWI_ABORT(rjs_engine_get(cpu), NULL);
149         if (l)
150                 list = ((rstring_t *)RVM_REG_GETP(l))->s.str;
151         else
152                 list = " \t\n\r\0";
153         src = (rstring_t *)RVM_REG_GETP(r);
154         ptr = src->s.str;
155         size = src->s.size;
156         while (size > 0) {
157                 if (!r_strchr(list, *ptr))
158                         break;
159                 size--;
160                 ptr++;
161         }
162         start = ptr;
163         ptr = start + size - 1;
164         while (size > 0) {
165                 if (!r_strchr(list, *ptr))
166                         break;
167                 size--;
168                 ptr--;
169         }
170         dest = r_string_create_strsize(start, size);
171         r_gc_add(cpu->gc, (robject_t*)dest);
172         rvm_reg_setstring(RVM_CPUREG_PTR(cpu, R0), dest);
173 }
174
175
176 static rvm_switable_t swistring[] = {
177                 {"ltrim", rjs_exec_ltrim},
178                 {"rtrim", rjs_exec_rtrim},
179                 {"trim", rjs_exec_trim},
180                 {NULL, NULL},
181 };
182
183
184
185 void rjs_unmap_file(rstr_t *buf)
186 {
187         if (buf) {
188                 r_free(buf);
189         }
190 }
191
192
193 rstr_t *rjs_map_file(const char *filename)
194 {
195         rstr_t *str;
196
197         return NULL;
198 }
199
200
201 int rjs_exec_script(rjs_engine_t *jse, rstr_t  *script)
202 {
203         if (!script)
204                 return -1;
205         if (parseinfo) {
206                 rjs_engine_dumpast(jse, script->str, script->size);
207         } else if (debugcompileonly) {
208                 int res = 0;
209                 jse->debugcompile = 1;
210                 res = rjs_engine_compile(jse, script->str, script->size);
211                 jse->debugcompile = 0;
212                 if (res < 0)
213                         return -1;
214         } else if (compileonly) {
215                 if (rjs_engine_compile(jse, script->str, script->size) < 0)
216                         return -1;
217         } else {
218                 if (rjs_engine_compile(jse, script->str, script->size) < 0)
219                         return -1;
220                 if (rjs_engine_run(jse) < 0)
221                         return -1;
222         }
223
224         return 0;
225 }
226
227
228 long jrs_offset2line(const char *script, long offset)
229 {
230         long line = 0;
231         const char *ptr;
232
233         for (line = 1, ptr = script + offset; ptr >= script; --ptr) {
234                 if (*ptr == '\n')
235                         line += 1;
236         }
237
238         return line;
239 }
240
241
242 void rjs_display_errors(rjs_engine_t *jse, rstr_t *script)
243 {
244         long i;
245         rjs_error_t *err;
246
247         for (i = 0; i < r_array_length(jse->errors); i++) {
248                 err = (rjs_error_t *)r_array_slot(jse->errors, i);
249                 fprintf(stdout, "Line: %ld (%ld, %ld), Error Code: %ld, ", (long)err->line, err->offset, err->lineoffset, err->error);
250                 fprintf(stdout, "%s: ", errormsg[err->error]);
251                 if (err->size) {
252                         fwrite(script->str + err->offset, sizeof(char), err->size, stdout);
253                 } else {
254                         fwrite(script->str + err->lineoffset, sizeof(char), err->offset - err->lineoffset, stdout);
255                 }
256                 fprintf(stdout, "\n");
257         }
258 }
259
260
261 int main(int argc, char *argv[])
262 {
263         int i;
264         rstr_t *script = NULL, *unmapscript = NULL;
265         rstr_t line;
266         rjs_engine_t *jse;
267
268         jse = rjs_engine_create();
269         if (!jse)
270                 return 1;
271         if (rjs_engine_addswitable(jse, "string", swistring) < 0) {
272                 return 2;
273         }
274         for (i = 1; i < argc; i++) {
275                 if (r_strcmp(argv[i], "-L") == 0) {
276
277                 } else if (r_strcmp(argv[i], "-d") == 0) {
278                         debuginfo = 1;
279                         jse->debugexec = 1;
280                 } else if (r_strcmp(argv[i], "-p") == 0) {
281                         parseinfo = 1;
282                 } else if (r_strcmp(argv[i], "-C") == 0) {
283                         debugcompileonly = 1;
284                 } else if (r_strcmp(argv[i], "-c") == 0) {
285                         compileonly = 1;
286                 } else if (r_strcmp(argv[i], "-t") == 0) {
287                         statinfo = 1;
288                 }
289         }
290
291         for (i = 1; i < argc; i++) {
292                 if (r_strcmp(argv[i], "-e") == 0) {
293                         if (++i < argc) {
294                                 line.str = argv[i];
295                                 line.size = r_strlen(argv[i]);
296                                 script = &line;
297                         }
298                         if (rjs_exec_script(jse, script) < 0)
299                                 goto end;
300                 }
301         }
302
303         for (i = 1; i < argc; i++) {
304                 if (r_strcmp(argv[i], "-f") == 0) {
305                         if (++i < argc) {
306                                 script = rjs_map_file(argv[i]);
307                                 if (script) {
308                                         unmapscript = script;
309                                 }
310                         }
311                         if (rjs_exec_script(jse, script) < 0)
312                                 goto end;
313                 }
314         }
315
316 end:
317         if (jse && r_array_length(jse->errors))
318                 rjs_display_errors(jse, script);
319         rjs_engine_destroy(jse);
320         if (unmapscript)
321                 rjs_unmap_file(unmapscript);
322         if (statinfo)
323                 fprintf(stdout, "\nRJS Version: %s, memory: %ld Bytes (leaked %ld Bytes)\n", rjs_version(), (long)r_debug_get_maxmem(), (long)r_debug_get_allocmem());
324         return 0;
325 }