2 * Regular Pattern Analyzer (RPA)
3 * Copyright (c) 2009-2010 Martin Stoilov
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.
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.
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/>.
18 * Martin Stoilov <martin@rpasearch.com>
24 #include "rlib/rmem.h"
26 #include "rjs/rjsfile.h"
27 #include "rpa/rparecord.h"
30 static int debuginfo = 0;
31 static int parseinfo = 0;
32 static int compileonly = 0;
33 static int debugcompileonly = 0;
34 static int statinfo = 0;
37 static char *errormsg[] = {
39 "Undefined identifier",
42 "Not a function call",
58 static void rjs_exec_ltrim(rvmcpu_t *cpu, rvm_asmins_t *ins)
60 const char *ptr, *list;
62 rvmreg_t *r = NULL, *l = NULL;
63 rstring_t *src, *dest;
65 if (RJS_SWI_PARAMS(cpu) == 0)
66 RJS_SWI_ABORT(rjs_engine_get(cpu), NULL);
67 r = (rvmreg_t *) RJS_SWI_PARAM(cpu, 1);
68 if (RJS_SWI_PARAMS(cpu) > 1) {
69 l = (rvmreg_t *) RJS_SWI_PARAM(cpu, 2);
70 if (rvm_reg_gettype(l) != RVM_DTYPE_STRING)
71 RJS_SWI_ABORT(rjs_engine_get(cpu), NULL);
73 if (rvm_reg_gettype(r) != RVM_DTYPE_STRING)
74 RJS_SWI_ABORT(rjs_engine_get(cpu), NULL);
76 list = ((rstring_t *)RVM_REG_GETP(l))->s.str;
79 src = (rstring_t *)RVM_REG_GETP(r);
83 if (!r_strchr(list, *ptr))
88 dest = r_string_create_strsize(ptr, size);
89 r_gc_add(cpu->gc, (robject_t*)dest);
90 rvm_reg_setstring(RVM_CPUREG_PTR(cpu, R0), dest);
94 static void rjs_exec_rtrim(rvmcpu_t *cpu, rvm_asmins_t *ins)
96 const char *ptr, *list;
98 rvmreg_t *r = NULL, *l = NULL;
99 rstring_t *src, *dest;
101 if (RJS_SWI_PARAMS(cpu) == 0)
102 RJS_SWI_ABORT(rjs_engine_get(cpu), NULL);
103 r = (rvmreg_t *) RJS_SWI_PARAM(cpu, 1);
104 if (RJS_SWI_PARAMS(cpu) > 1) {
105 l = (rvmreg_t *) RJS_SWI_PARAM(cpu, 2);
106 if (rvm_reg_gettype(l) != RVM_DTYPE_STRING)
107 RJS_SWI_ABORT(rjs_engine_get(cpu), NULL);
109 if (rvm_reg_gettype(r) != RVM_DTYPE_STRING)
110 RJS_SWI_ABORT(rjs_engine_get(cpu), NULL);
112 list = ((rstring_t *)RVM_REG_GETP(l))->s.str;
115 src = (rstring_t *)RVM_REG_GETP(r);
117 ptr = src->s.str + size - 1;
119 if (!r_strchr(list, *ptr))
124 dest = r_string_create_strsize(src->s.str, size);
125 r_gc_add(cpu->gc, (robject_t*)dest);
126 rvm_reg_setstring(RVM_CPUREG_PTR(cpu, R0), dest);
130 static void rjs_exec_trim(rvmcpu_t *cpu, rvm_asmins_t *ins)
132 const char *start, *ptr, *list;
134 rvmreg_t *r = NULL, *l = NULL;
135 rstring_t *src, *dest;
137 if (RJS_SWI_PARAMS(cpu) == 0)
138 RJS_SWI_ABORT(rjs_engine_get(cpu), NULL);
140 r = (rvmreg_t *) RJS_SWI_PARAM(cpu, 1);
141 if (RJS_SWI_PARAMS(cpu) > 1) {
142 l = (rvmreg_t *) RJS_SWI_PARAM(cpu, 2);
143 if (rvm_reg_gettype(l) != RVM_DTYPE_STRING)
144 RJS_SWI_ABORT(rjs_engine_get(cpu), NULL);
146 if (rvm_reg_gettype(r) != RVM_DTYPE_STRING)
147 RJS_SWI_ABORT(rjs_engine_get(cpu), NULL);
149 list = ((rstring_t *)RVM_REG_GETP(l))->s.str;
152 src = (rstring_t *)RVM_REG_GETP(r);
156 if (!r_strchr(list, *ptr))
162 ptr = start + size - 1;
164 if (!r_strchr(list, *ptr))
169 dest = r_string_create_strsize(start, size);
170 r_gc_add(cpu->gc, (robject_t*)dest);
171 rvm_reg_setstring(RVM_CPUREG_PTR(cpu, R0), dest);
175 static rvm_switable_t swistring[] = {
176 {"ltrim", rjs_exec_ltrim},
177 {"rtrim", rjs_exec_rtrim},
178 {"trim", rjs_exec_trim},
183 int rjs_exec_script(rjs_engine_t *jse, rstr_t *script)
188 rjs_engine_dumpast(jse, script->str, script->size);
189 } else if (debugcompileonly) {
191 jse->debugcompile = 1;
192 res = rjs_engine_compile(jse, script->str, script->size);
193 jse->debugcompile = 0;
196 } else if (compileonly) {
197 if (rjs_engine_compile(jse, script->str, script->size) < 0)
200 if (rjs_engine_compile(jse, script->str, script->size) < 0)
202 if (rjs_engine_run(jse) < 0)
210 long jrs_offset2line(const char *script, long offset)
215 for (line = 1, ptr = script + offset; ptr >= script; --ptr) {
224 void rjs_display_errors(rjs_engine_t *jse, rstr_t *script)
229 for (i = 0; i < r_array_length(jse->errors); i++) {
230 err = (rjs_error_t *)r_array_slot(jse->errors, i);
231 fprintf(stdout, "Line: %ld (%ld, %ld), Error Code: %ld, ", (long)err->line, err->offset, err->lineoffset, err->error);
232 fprintf(stdout, "%s: ", errormsg[err->error]);
234 fwrite(script->str + err->offset, sizeof(char), err->size, stdout);
236 fwrite(script->str + err->lineoffset, sizeof(char), err->offset - err->lineoffset, stdout);
238 fprintf(stdout, "\n");
243 int usage(int argc, char *argv[])
245 fprintf(stderr, "RJS with RPA Engine: %s \n", rpa_dbex_version());
246 fprintf(stderr, "Copyright (C) 2010 Martin Stoilov\n\n");
248 fprintf(stderr, "\t-e <script_expression> Run the script supplied on the command line.\n");
249 fprintf(stderr, "\t-f <script_file> Run the script file.\n");
250 fprintf(stderr, "\t-p Display rules parsing records.\n");
251 fprintf(stderr, "\t-d Execute in debug mode.\n");
252 fprintf(stderr, "\t-c Compile the script, without running it.\n");
253 fprintf(stderr, "\t-C Compile the script, showing the compile info, without running it.\n");
254 fprintf(stderr, "\t-h, --help Display this help.\n");
259 int main(int argc, char *argv[])
262 rstr_t *script = NULL, *unmapscript = NULL;
266 for (i = 1; i < argc; i++) {
267 if (r_strcmp(argv[i], "--help") == 0 || r_strcmp(argv[i], "-help") == 0 || r_strcmp(argv[i], "/?") == 0 || r_strcmp(argv[i], "-h") == 0) {
273 jse = rjs_engine_create();
276 if (rjs_engine_addswitable(jse, "string", swistring) < 0) {
279 for (i = 1; i < argc; i++) {
280 if (r_strcmp(argv[i], "-L") == 0) {
282 } else if (r_strcmp(argv[i], "-d") == 0) {
285 } else if (r_strcmp(argv[i], "-p") == 0) {
287 } else if (r_strcmp(argv[i], "-C") == 0) {
288 debugcompileonly = 1;
289 } else if (r_strcmp(argv[i], "-c") == 0) {
291 } else if (r_strcmp(argv[i], "-t") == 0) {
296 for (i = 1; i < argc; i++) {
297 if (r_strcmp(argv[i], "-e") == 0) {
300 line.size = r_strlen(argv[i]);
303 if (rjs_exec_script(jse, script) < 0)
308 for (i = 1; i < argc; i++) {
309 if (r_strcmp(argv[i], "-f") == 0) {
311 script = rjs_file_map(argv[i]);
312 r_printf("%s\n", script->str);
314 unmapscript = script;
317 if (rjs_exec_script(jse, script) < 0)
323 if (jse && r_array_length(jse->errors))
324 rjs_display_errors(jse, script);
325 rjs_engine_destroy(jse);
327 rjs_file_unmap(unmapscript);
329 fprintf(stdout, "\nRJS Version: %s, memory: %ld Bytes (leaked %ld Bytes)\n", rjs_version(), (long)r_debug_get_maxmem(), (long)r_debug_get_allocmem());