mruby mbed

Dependencies:   EthernetInterface SDFileSystem mbed-rtos mbed-src mruby-mbed

Committer:
mzta
Date:
Wed Mar 25 18:25:34 2015 +0000
Revision:
0:4bb480aaa402
mruby_mbed_web initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mzta 0:4bb480aaa402 1 #include "mbed.h"
mzta 0:4bb480aaa402 2 #include "SDFileSystem.h"
mzta 0:4bb480aaa402 3
mzta 0:4bb480aaa402 4 extern SDFileSystem sd;
mzta 0:4bb480aaa402 5 extern Serial pc;
mzta 0:4bb480aaa402 6
mzta 0:4bb480aaa402 7 #include <stdio.h>
mzta 0:4bb480aaa402 8 #include <stdlib.h>
mzta 0:4bb480aaa402 9 #include <string.h>
mzta 0:4bb480aaa402 10 #include "mruby.h"
mzta 0:4bb480aaa402 11 #include "mruby/array.h"
mzta 0:4bb480aaa402 12 #include "mruby/compile.h"
mzta 0:4bb480aaa402 13 #include "mruby/dump.h"
mzta 0:4bb480aaa402 14 #include "mruby/variable.h"
mzta 0:4bb480aaa402 15 #include "cmd.h"
mzta 0:4bb480aaa402 16
mzta 0:4bb480aaa402 17 #ifndef ENABLE_STDIO
mzta 0:4bb480aaa402 18 static void
mzta 0:4bb480aaa402 19 p(mrb_state *mrb, mrb_value obj)
mzta 0:4bb480aaa402 20 {
mzta 0:4bb480aaa402 21 obj = mrb_funcall(mrb, obj, "inspect", 0);
mzta 0:4bb480aaa402 22 fwrite(RSTRING_PTR(obj), RSTRING_LEN(obj), 1, stdout);
mzta 0:4bb480aaa402 23 putc('\n', stdout);
mzta 0:4bb480aaa402 24 }
mzta 0:4bb480aaa402 25 #else
mzta 0:4bb480aaa402 26 #define p(mrb,obj) mrb_p(mrb,obj)
mzta 0:4bb480aaa402 27 #endif
mzta 0:4bb480aaa402 28
mzta 0:4bb480aaa402 29 void mrb_show_version(mrb_state *);
mzta 0:4bb480aaa402 30 void mrb_show_copyright(mrb_state *);
mzta 0:4bb480aaa402 31
mzta 0:4bb480aaa402 32 struct _args {
mzta 0:4bb480aaa402 33 FILE *rfp;
mzta 0:4bb480aaa402 34 char* cmdline;
mzta 0:4bb480aaa402 35 mrb_bool fname : 1;
mzta 0:4bb480aaa402 36 mrb_bool mrbfile : 1;
mzta 0:4bb480aaa402 37 mrb_bool check_syntax : 1;
mzta 0:4bb480aaa402 38 mrb_bool verbose : 1;
mzta 0:4bb480aaa402 39 int argc;
mzta 0:4bb480aaa402 40 char** argv;
mzta 0:4bb480aaa402 41 };
mzta 0:4bb480aaa402 42
mzta 0:4bb480aaa402 43 static void
mzta 0:4bb480aaa402 44 usage(const char *name)
mzta 0:4bb480aaa402 45 {
mzta 0:4bb480aaa402 46 static const char *const usage_msg[] = {
mzta 0:4bb480aaa402 47 "switches:",
mzta 0:4bb480aaa402 48 "-b load and execute RiteBinary (mrb) file",
mzta 0:4bb480aaa402 49 "-c check syntax only",
mzta 0:4bb480aaa402 50 "-e 'command' one line of script",
mzta 0:4bb480aaa402 51 "-v print version number, then run in verbose mode",
mzta 0:4bb480aaa402 52 "--verbose run in verbose mode",
mzta 0:4bb480aaa402 53 "--version print the version",
mzta 0:4bb480aaa402 54 "--copyright print the copyright",
mzta 0:4bb480aaa402 55 NULL
mzta 0:4bb480aaa402 56 };
mzta 0:4bb480aaa402 57 const char *const *p = usage_msg;
mzta 0:4bb480aaa402 58
mzta 0:4bb480aaa402 59 printf("Usage: %s [switches] programfile\n", name);
mzta 0:4bb480aaa402 60 while (*p)
mzta 0:4bb480aaa402 61 printf(" %s\n", *p++);
mzta 0:4bb480aaa402 62 }
mzta 0:4bb480aaa402 63
mzta 0:4bb480aaa402 64 static int
mzta 0:4bb480aaa402 65 parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
mzta 0:4bb480aaa402 66 {
mzta 0:4bb480aaa402 67 char **origargv = argv;
mzta 0:4bb480aaa402 68 static const struct _args args_zero = { 0 };
mzta 0:4bb480aaa402 69
mzta 0:4bb480aaa402 70 *args = args_zero;
mzta 0:4bb480aaa402 71
mzta 0:4bb480aaa402 72 for (argc--,argv++; argc > 0; argc--,argv++) {
mzta 0:4bb480aaa402 73 char *item;
mzta 0:4bb480aaa402 74 if (argv[0][0] != '-') break;
mzta 0:4bb480aaa402 75
mzta 0:4bb480aaa402 76 if (strlen(*argv) <= 1) {
mzta 0:4bb480aaa402 77 argc--; argv++;
mzta 0:4bb480aaa402 78 args->rfp = stdin;
mzta 0:4bb480aaa402 79 break;
mzta 0:4bb480aaa402 80 }
mzta 0:4bb480aaa402 81
mzta 0:4bb480aaa402 82 item = argv[0] + 1;
mzta 0:4bb480aaa402 83 switch (*item++) {
mzta 0:4bb480aaa402 84 case 'b':
mzta 0:4bb480aaa402 85 args->mrbfile = TRUE;
mzta 0:4bb480aaa402 86 break;
mzta 0:4bb480aaa402 87 case 'c':
mzta 0:4bb480aaa402 88 args->check_syntax = TRUE;
mzta 0:4bb480aaa402 89 break;
mzta 0:4bb480aaa402 90 case 'e':
mzta 0:4bb480aaa402 91 if (item[0]) {
mzta 0:4bb480aaa402 92 goto append_cmdline;
mzta 0:4bb480aaa402 93 }
mzta 0:4bb480aaa402 94 else if (argc > 1) {
mzta 0:4bb480aaa402 95 argc--; argv++;
mzta 0:4bb480aaa402 96 item = argv[0];
mzta 0:4bb480aaa402 97 append_cmdline:
mzta 0:4bb480aaa402 98 if (!args->cmdline) {
mzta 0:4bb480aaa402 99 size_t buflen;
mzta 0:4bb480aaa402 100 char *buf;
mzta 0:4bb480aaa402 101
mzta 0:4bb480aaa402 102 buflen = strlen(item) + 1;
mzta 0:4bb480aaa402 103 buf = (char *)mrb_malloc(mrb, buflen);
mzta 0:4bb480aaa402 104 memcpy(buf, item, buflen);
mzta 0:4bb480aaa402 105 args->cmdline = buf;
mzta 0:4bb480aaa402 106 }
mzta 0:4bb480aaa402 107 else {
mzta 0:4bb480aaa402 108 size_t cmdlinelen;
mzta 0:4bb480aaa402 109 size_t itemlen;
mzta 0:4bb480aaa402 110
mzta 0:4bb480aaa402 111 cmdlinelen = strlen(args->cmdline);
mzta 0:4bb480aaa402 112 itemlen = strlen(item);
mzta 0:4bb480aaa402 113 args->cmdline =
mzta 0:4bb480aaa402 114 (char *)mrb_realloc(mrb, args->cmdline, cmdlinelen + itemlen + 2);
mzta 0:4bb480aaa402 115 args->cmdline[cmdlinelen] = '\n';
mzta 0:4bb480aaa402 116 memcpy(args->cmdline + cmdlinelen + 1, item, itemlen + 1);
mzta 0:4bb480aaa402 117 }
mzta 0:4bb480aaa402 118 }
mzta 0:4bb480aaa402 119 else {
mzta 0:4bb480aaa402 120 printf("%s: No code specified for -e\n", *origargv);
mzta 0:4bb480aaa402 121 return EXIT_SUCCESS;
mzta 0:4bb480aaa402 122 }
mzta 0:4bb480aaa402 123 break;
mzta 0:4bb480aaa402 124 case 'v':
mzta 0:4bb480aaa402 125 // if (!args->verbose) mrb_show_version(mrb);
mzta 0:4bb480aaa402 126 args->verbose = TRUE;
mzta 0:4bb480aaa402 127 break;
mzta 0:4bb480aaa402 128 case '-':
mzta 0:4bb480aaa402 129 if (strcmp((*argv) + 2, "version") == 0) {
mzta 0:4bb480aaa402 130 // mrb_show_version(mrb);
mzta 0:4bb480aaa402 131 exit(EXIT_SUCCESS);
mzta 0:4bb480aaa402 132 }
mzta 0:4bb480aaa402 133 else if (strcmp((*argv) + 2, "verbose") == 0) {
mzta 0:4bb480aaa402 134 args->verbose = TRUE;
mzta 0:4bb480aaa402 135 break;
mzta 0:4bb480aaa402 136 }
mzta 0:4bb480aaa402 137 else if (strcmp((*argv) + 2, "copyright") == 0) {
mzta 0:4bb480aaa402 138 // mrb_show_copyright(mrb);
mzta 0:4bb480aaa402 139 exit(EXIT_SUCCESS);
mzta 0:4bb480aaa402 140 }
mzta 0:4bb480aaa402 141 default:
mzta 0:4bb480aaa402 142 return EXIT_FAILURE;
mzta 0:4bb480aaa402 143 }
mzta 0:4bb480aaa402 144 }
mzta 0:4bb480aaa402 145
mzta 0:4bb480aaa402 146 if (args->rfp == NULL && args->cmdline == NULL) {
mzta 0:4bb480aaa402 147 if (*argv == NULL) args->rfp = stdin;
mzta 0:4bb480aaa402 148 else {
mzta 0:4bb480aaa402 149 args->rfp = fopen(argv[0], args->mrbfile ? "rb" : "r");
mzta 0:4bb480aaa402 150 if (args->rfp == NULL) {
mzta 0:4bb480aaa402 151 printf("%s: Cannot open program file. (%s)\n", *origargv, *argv);
mzta 0:4bb480aaa402 152 return EXIT_FAILURE;
mzta 0:4bb480aaa402 153 }
mzta 0:4bb480aaa402 154 args->fname = TRUE;
mzta 0:4bb480aaa402 155 args->cmdline = argv[0];
mzta 0:4bb480aaa402 156 argc--; argv++;
mzta 0:4bb480aaa402 157 }
mzta 0:4bb480aaa402 158 }
mzta 0:4bb480aaa402 159 args->argv = (char **)mrb_realloc(mrb, args->argv, sizeof(char*) * (argc + 1));
mzta 0:4bb480aaa402 160 memcpy(args->argv, argv, (argc+1) * sizeof(char*));
mzta 0:4bb480aaa402 161 args->argc = argc;
mzta 0:4bb480aaa402 162
mzta 0:4bb480aaa402 163 return EXIT_SUCCESS;
mzta 0:4bb480aaa402 164 }
mzta 0:4bb480aaa402 165
mzta 0:4bb480aaa402 166 static void
mzta 0:4bb480aaa402 167 cleanup(mrb_state *mrb, struct _args *args)
mzta 0:4bb480aaa402 168 {
mzta 0:4bb480aaa402 169 if (args->rfp && args->rfp != stdin)
mzta 0:4bb480aaa402 170 fclose(args->rfp);
mzta 0:4bb480aaa402 171 if (args->cmdline && !args->fname)
mzta 0:4bb480aaa402 172 mrb_free(mrb, args->cmdline);
mzta 0:4bb480aaa402 173 if (args->argv)
mzta 0:4bb480aaa402 174 mrb_free(mrb, args->argv);
mzta 0:4bb480aaa402 175 mrb_close(mrb);
mzta 0:4bb480aaa402 176 }
mzta 0:4bb480aaa402 177
mzta 0:4bb480aaa402 178 int
mzta 0:4bb480aaa402 179 cmd_mruby(int argc, char **argv)
mzta 0:4bb480aaa402 180 {
mzta 0:4bb480aaa402 181 mrb_state *mrb = mrb_open();
mzta 0:4bb480aaa402 182 int n = -1;
mzta 0:4bb480aaa402 183 int i;
mzta 0:4bb480aaa402 184 struct _args args;
mzta 0:4bb480aaa402 185 mrb_value ARGV;
mzta 0:4bb480aaa402 186 mrbc_context *c;
mzta 0:4bb480aaa402 187 mrb_value v;
mzta 0:4bb480aaa402 188 mrb_sym zero_sym;
mzta 0:4bb480aaa402 189
mzta 0:4bb480aaa402 190 if (mrb == NULL) {
mzta 0:4bb480aaa402 191 fputs("Invalid mrb_state, exiting mruby\n", stderr);
mzta 0:4bb480aaa402 192 return EXIT_FAILURE;
mzta 0:4bb480aaa402 193 }
mzta 0:4bb480aaa402 194
mzta 0:4bb480aaa402 195 n = parse_args(mrb, argc, argv, &args);
mzta 0:4bb480aaa402 196 if (n == EXIT_FAILURE || (args.cmdline == NULL && args.rfp == NULL)) {
mzta 0:4bb480aaa402 197 cleanup(mrb, &args);
mzta 0:4bb480aaa402 198 usage(argv[0]);
mzta 0:4bb480aaa402 199 return n;
mzta 0:4bb480aaa402 200 }
mzta 0:4bb480aaa402 201
mzta 0:4bb480aaa402 202 ARGV = mrb_ary_new_capa(mrb, args.argc);
mzta 0:4bb480aaa402 203 for (i = 0; i < args.argc; i++) {
mzta 0:4bb480aaa402 204 mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, args.argv[i]));
mzta 0:4bb480aaa402 205 }
mzta 0:4bb480aaa402 206 mrb_define_global_const(mrb, "ARGV", ARGV);
mzta 0:4bb480aaa402 207
mzta 0:4bb480aaa402 208 c = mrbc_context_new(mrb);
mzta 0:4bb480aaa402 209 if (args.verbose)
mzta 0:4bb480aaa402 210 c->dump_result = TRUE;
mzta 0:4bb480aaa402 211 if (args.check_syntax)
mzta 0:4bb480aaa402 212 c->no_exec = TRUE;
mzta 0:4bb480aaa402 213
mzta 0:4bb480aaa402 214 /* Set $0 */
mzta 0:4bb480aaa402 215 zero_sym = mrb_intern_lit(mrb, "$0");
mzta 0:4bb480aaa402 216 if (args.rfp) {
mzta 0:4bb480aaa402 217 const char *cmdline;
mzta 0:4bb480aaa402 218 cmdline = args.cmdline ? args.cmdline : "-";
mzta 0:4bb480aaa402 219 mrbc_filename(mrb, c, cmdline);
mzta 0:4bb480aaa402 220 mrb_gv_set(mrb, zero_sym, mrb_str_new_cstr(mrb, cmdline));
mzta 0:4bb480aaa402 221 }
mzta 0:4bb480aaa402 222 else {
mzta 0:4bb480aaa402 223 mrbc_filename(mrb, c, "-e");
mzta 0:4bb480aaa402 224 mrb_gv_set(mrb, zero_sym, mrb_str_new_lit(mrb, "-e"));
mzta 0:4bb480aaa402 225 }
mzta 0:4bb480aaa402 226
mzta 0:4bb480aaa402 227 /* Load program */
mzta 0:4bb480aaa402 228 if (args.mrbfile) {
mzta 0:4bb480aaa402 229 v = mrb_load_irep_file_cxt(mrb, args.rfp, c);
mzta 0:4bb480aaa402 230 }
mzta 0:4bb480aaa402 231 else if (args.rfp) {
mzta 0:4bb480aaa402 232 v = mrb_load_file_cxt(mrb, args.rfp, c);
mzta 0:4bb480aaa402 233 }
mzta 0:4bb480aaa402 234 else {
mzta 0:4bb480aaa402 235 v = mrb_load_string_cxt(mrb, args.cmdline, c);
mzta 0:4bb480aaa402 236 }
mzta 0:4bb480aaa402 237
mzta 0:4bb480aaa402 238 mrbc_context_free(mrb, c);
mzta 0:4bb480aaa402 239 if (mrb->exc) {
mzta 0:4bb480aaa402 240 if (!mrb_undef_p(v)) {
mzta 0:4bb480aaa402 241 mrb_print_error(mrb);
mzta 0:4bb480aaa402 242 }
mzta 0:4bb480aaa402 243 n = -1;
mzta 0:4bb480aaa402 244 }
mzta 0:4bb480aaa402 245 else if (args.check_syntax) {
mzta 0:4bb480aaa402 246 printf("Syntax OK\n");
mzta 0:4bb480aaa402 247 }
mzta 0:4bb480aaa402 248 cleanup(mrb, &args);
mzta 0:4bb480aaa402 249
mzta 0:4bb480aaa402 250 return n == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
mzta 0:4bb480aaa402 251 }
mzta 0:4bb480aaa402 252