Commit d973a8eb authored by Hiroshi Mimaki's avatar Hiroshi Mimaki

Add `-r` option for `mruby` and `mirb`.

parent fc247449
......@@ -17,3 +17,18 @@ assert('mirb -d option') do
o, _ = Open3.capture2('bin/mirb -d', :stdin_data => "p $DEBUG\n")
assert_true o.include?('=> true')
end
assert('mirb -r option') do
lib = Tempfile.new('lib.rb')
lib.write <<EOS
class Hoge
def hoge
:hoge
end
end
EOS
lib.flush
o, _ = Open3.capture2("bin/mirb -r #{lib.path}", :stdin_data => "Hoge.new.hoge\n")
assert_true o.include?('=> :hoge')
end
......@@ -53,6 +53,7 @@
#include <mruby/array.h>
#include <mruby/proc.h>
#include <mruby/compile.h>
#include <mruby/dump.h>
#include <mruby/string.h>
#include <mruby/variable.h>
......@@ -223,6 +224,8 @@ struct _args {
mrb_bool debug : 1;
int argc;
char** argv;
int libc;
char **libv;
};
static void
......@@ -230,7 +233,8 @@ usage(const char *name)
{
static const char *const usage_msg[] = {
"switches:",
"-d Set $DEBUG to true (same as `mruby -d`)"
"-d set $DEBUG to true (same as `mruby -d`)"
"-r library same as `mruby -r`",
"-v print version number, then run in verbose mode",
"--verbose run in verbose mode",
"--version print the version",
......@@ -244,9 +248,19 @@ usage(const char *name)
printf(" %s\n", *p++);
}
static char *
dup_arg_item(mrb_state *mrb, const char *item)
{
size_t buflen = strlen(item) + 1;
char *buf = mrb_malloc(mrb, buflen);
memcpy(buf, item, buflen);
return buf;
}
static int
parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
{
char **origargv = argv;
static const struct _args args_zero = { 0 };
*args = args_zero;
......@@ -260,6 +274,23 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
case 'd':
args->debug = TRUE;
break;
case 'r':
if (!item[0]) {
if (argc <= 1) {
printf("%s: No library specified for -r\n", *origargv);
return EXIT_FAILURE;
}
argc--; argv++;
item = argv[0];
}
if (args->libc == 0) {
args->libv = (char**)mrb_malloc(mrb, sizeof(char*));
}
else {
args->libv = (char**)mrb_realloc(mrb, args->libv, sizeof(char*) * (args->libc + 1));
}
args->libv[args->libc++] = dup_arg_item(mrb, item);
break;
case 'v':
if (!args->verbose) mrb_show_version(mrb);
args->verbose = TRUE;
......@@ -305,6 +336,12 @@ cleanup(mrb_state *mrb, struct _args *args)
if (args->rfp)
fclose(args->rfp);
mrb_free(mrb, args->argv);
if (args->libc) {
while (args->libc--) {
mrb_free(mrb, args->libv[args->libc]);
}
mrb_free(mrb, args->libv);
}
mrb_close(mrb);
}
......@@ -395,6 +432,7 @@ main(int argc, char **argv)
mrb_bool code_block_open = FALSE;
int ai;
unsigned int stack_keep = 0;
FILE *lfp;
/* new interpreter instance */
mrb = mrb_open();
......@@ -436,6 +474,19 @@ main(int argc, char **argv)
print_hint();
cxt = mrbc_context_new(mrb);
/* Load libraries */
for (i = 0; i < args.libc; i++) {
lfp = fopen(args.libv[i], "r");
if (lfp == NULL) {
printf("Cannot open library file. (%s)\n", args.libv[i]);
cleanup(mrb, &args);
return EXIT_FAILURE;
}
mrb_load_file_cxt(mrb, lfp, cxt);
fclose(lfp);
}
cxt->capture_errors = TRUE;
cxt->lineno = 1;
mrbc_filename(mrb, cxt, "(mirb)");
......
......@@ -65,3 +65,26 @@ assert('mruby -d option') do
o = `#{cmd('mruby')} -d -e #{shellquote('p $DEBUG')}`
assert_equal "true\n", o
end
assert('mruby -r option') do
lib = Tempfile.new('lib.rb')
lib.write <<EOS
class Hoge
def hoge
:hoge
end
end
EOS
lib.flush
script = Tempfile.new('test.rb')
script.write <<EOS
print Hoge.new.hoge
EOS
script.flush
assert_equal 'hoge', `#{cmd('mruby')} -r #{lib.path} #{script.path}`
assert_equal 0, $?.exitstatus
assert_equal 'hogeClass', `#{cmd('mruby')} -r #{lib.path} -r #{script.path} -e #{shellquote('print Hoge.class')}`
assert_equal 0, $?.exitstatus
end
......@@ -30,6 +30,8 @@ struct _args {
mrb_bool debug : 1;
int argc;
char** argv;
int libc;
char **libv;
};
static void
......@@ -39,8 +41,9 @@ usage(const char *name)
"switches:",
"-b load and execute RiteBinary (mrb) file",
"-c check syntax only",
"-d Set debugging flags (set $DEBUG to true)"
"-d set debugging flags (set $DEBUG to true)"
"-e 'command' one line of script",
"-r library load the library before executing your script",
"-v print version number, then run in verbose mode",
"--verbose run in verbose mode",
"--version print the version",
......@@ -54,6 +57,15 @@ usage(const char *name)
printf(" %s\n", *p++);
}
static char *
dup_arg_item(mrb_state *mrb, const char *item)
{
size_t buflen = strlen(item) + 1;
char *buf = mrb_malloc(mrb, buflen);
memcpy(buf, item, buflen);
return buf;
}
static int
parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
{
......@@ -92,13 +104,7 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
item = argv[0];
append_cmdline:
if (!args->cmdline) {
size_t buflen;
char *buf;
buflen = strlen(item) + 1;
buf = (char *)mrb_malloc(mrb, buflen);
memcpy(buf, item, buflen);
args->cmdline = buf;
args->cmdline = dup_arg_item(mrb, item);
}
else {
size_t cmdlinelen;
......@@ -117,6 +123,23 @@ append_cmdline:
return EXIT_SUCCESS;
}
break;
case 'r':
if (!item[0]) {
if (argc <= 1) {
printf("%s: No library specified for -r\n", *origargv);
return EXIT_FAILURE;
}
argc--; argv++;
item = argv[0];
}
if (args->libc == 0) {
args->libv = (char**)mrb_malloc(mrb, sizeof(char*));
}
else {
args->libv = (char**)mrb_realloc(mrb, args->libv, sizeof(char*) * (args->libc + 1));
}
args->libv[args->libc++] = dup_arg_item(mrb, item);
break;
case 'v':
if (!args->verbose) mrb_show_version(mrb);
args->verbose = TRUE;
......@@ -167,6 +190,12 @@ cleanup(mrb_state *mrb, struct _args *args)
if (!args->fname)
mrb_free(mrb, args->cmdline);
mrb_free(mrb, args->argv);
if (args->libc) {
while (args->libc--) {
mrb_free(mrb, args->libv[args->libc]);
}
mrb_free(mrb, args->libv);
}
mrb_close(mrb);
}
......@@ -181,6 +210,7 @@ main(int argc, char **argv)
mrbc_context *c;
mrb_value v;
mrb_sym zero_sym;
FILE *lfp;
if (mrb == NULL) {
fputs("Invalid mrb_state, exiting mruby\n", stderr);
......@@ -225,6 +255,23 @@ main(int argc, char **argv)
mrb_gv_set(mrb, zero_sym, mrb_str_new_lit(mrb, "-e"));
}
/* Load libraries */
for (i = 0; i < args.libc; i++) {
lfp = fopen(args.libv[i], args.mrbfile ? "rb" : "r");
if (lfp == NULL) {
printf("Cannot open library file. (%s)\n", args.libv[i]);
cleanup(mrb, &args);
return EXIT_FAILURE;
}
if (args.mrbfile) {
v = mrb_load_irep_file_cxt(mrb, lfp, c);
}
else {
v = mrb_load_file_cxt(mrb, lfp, c);
}
fclose(lfp);
}
/* Load program */
if (args.mrbfile) {
v = mrb_load_irep_file_cxt(mrb, args.rfp, c);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment