Add `-r` option for `mruby` and `mirb`.
MODIFY
mrbgems/mruby-bin-mirb/bintest/mirb.rb
mrbgems/mruby-bin-mirb/bintest/mirb.rb
@@ -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

MODIFY
mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
#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)");

MODIFY
mrbgems/mruby-bin-mruby/bintest/mruby.rb
mrbgems/mruby-bin-mruby/bintest/mruby.rb
@@ -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

MODIFY
mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
@@ -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);

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