diff options
| author | KOBAYASHI Shuji <[email protected]> | 2019-11-17 16:38:50 +0900 |
|---|---|---|
| committer | KOBAYASHI Shuji <[email protected]> | 2019-11-17 16:38:50 +0900 |
| commit | 9de7130a9a77482b27a101211ff0f4a63d57a613 (patch) | |
| tree | da4007a02288aead291372e128ddf4a9275c9bef /mrbgems/mruby-bin-mruby | |
| parent | 74310f41d74ad1d6622d59278da20627f069f074 (diff) | |
| download | mruby-9de7130a9a77482b27a101211ff0f4a63d57a613.tar.gz mruby-9de7130a9a77482b27a101211ff0f4a63d57a613.zip | |
Support short options concatenation to `mruby` command
#### Before this patch:
```
$ bin/mruby -ce 1
bin/mruby: Cannot open program file: 1
```
#### After this patch:
```
$ bin/mruby -ce 1
Syntax OK
```
Diffstat (limited to 'mrbgems/mruby-bin-mruby')
| -rw-r--r-- | mrbgems/mruby-bin-mruby/bintest/mruby.rb | 6 | ||||
| -rw-r--r-- | mrbgems/mruby-bin-mruby/tools/mruby/mruby.c | 170 |
2 files changed, 106 insertions, 70 deletions
diff --git a/mrbgems/mruby-bin-mruby/bintest/mruby.rb b/mrbgems/mruby-bin-mruby/bintest/mruby.rb index e032ff79a..8da51bac9 100644 --- a/mrbgems/mruby-bin-mruby/bintest/mruby.rb +++ b/mrbgems/mruby-bin-mruby/bintest/mruby.rb @@ -80,10 +80,8 @@ assert('mruby -c option') do end assert('mruby -d option') do - o = `#{cmd('mruby')} -e #{shellquote('p $DEBUG')}` - assert_equal "false\n", o - o = `#{cmd('mruby')} -d -e #{shellquote('p $DEBUG')}` - assert_equal "true\n", o + assert_mruby("false\n", "", true, ["-e", "p $DEBUG"]) + assert_mruby("true\n", "", true, ["-dep $DEBUG"]) end assert('mruby -e option (no code specified)') do diff --git a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c index 461e91918..41354d3f2 100644 --- a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +++ b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c @@ -9,18 +9,26 @@ struct _args { FILE *rfp; - char* cmdline; + char *cmdline; mrb_bool fname : 1; mrb_bool mrbfile : 1; mrb_bool check_syntax : 1; mrb_bool verbose : 1; mrb_bool debug : 1; int argc; - char** argv; + char **argv; int libc; char **libv; }; +struct options { + int argc; + char **argv; + char *program; + char *opt; + char short_opt[2]; +}; + static void usage(const char *name) { @@ -44,6 +52,51 @@ usage(const char *name) printf(" %s\n", *p++); } +static void +options_init(struct options *opts, int argc, char **argv) +{ + opts->argc = argc; + opts->argv = argv; + opts->program = *argv; + *opts->short_opt = 0; +} + +static const char * +options_opt(struct options *opts) +{ + if (*opts->short_opt && *++opts->opt) { + short_opt: + opts->short_opt[0] = *opts->opt; + opts->short_opt[1] = 0; + return opts->short_opt; + } + while (++opts->argv, --opts->argc) { + opts->opt = *opts->argv; + if (!opts->opt[0] || opts->opt[0] != '-' || !opts->opt[1]) return NULL; + if (opts->opt[1] == '-') { + opts->opt += 2; + *opts->short_opt = 0; + return opts->opt; + } + else { + ++opts->opt; + goto short_opt; + } + } + return NULL; +} + +static const char * +options_arg(struct options *opts) +{ + if (*opts->short_opt && opts->opt[1]) { + *opts->short_opt = 0; + return opts->opt + 1; + } + --opts->argc, ++opts->argv; + return opts->argc ? *opts->argv : NULL; +} + static char * dup_arg_item(mrb_state *mrb, const char *item) { @@ -56,40 +109,24 @@ dup_arg_item(mrb_state *mrb, const char *item) static int parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args) { - char **origargv = argv; static const struct _args args_zero = { 0 }; + struct options opts[1]; + const char *opt, *item; *args = args_zero; - - for (argc--,argv++; argc > 0; argc--,argv++) { - char *item; - if (argv[0][0] != '-') break; - - if (strlen(*argv) <= 1) { - argc--; argv++; - args->rfp = stdin; - break; - } - - item = argv[0] + 1; - switch (*item++) { - case 'b': + options_init(opts, argc, argv); + while ((opt = options_opt(opts))) { + if (strcmp(opt, "b") == 0) { args->mrbfile = TRUE; - break; - case 'c': + } + else if (strcmp(opt, "c") == 0) { args->check_syntax = TRUE; - break; - case 'd': + } + else if (strcmp(opt, "d") == 0) { args->debug = TRUE; - break; - case 'e': - if (item[0]) { - goto append_cmdline; - } - else if (argc > 1) { - argc--; argv++; - item = argv[0]; -append_cmdline: + } + else if (strcmp(opt, "e") == 0) { + if ((item = options_arg(opts))) { if (!args->cmdline) { args->cmdline = dup_arg_item(mrb, item); } @@ -106,59 +143,60 @@ append_cmdline: } } else { - fprintf(stderr, "%s: No code specified for -e\n", *origargv); + fprintf(stderr, "%s: No code specified for -e\n", opts->program); return EXIT_FAILURE; } - break; - case 'h': - usage(*origargv); + } + else if (strcmp(opt, "h") == 0) { + usage(opts->program); exit(EXIT_SUCCESS); - case 'r': - if (!item[0]) { - if (argc <= 1) { - fprintf(stderr, "%s: No library specified for -r\n", *origargv); - return EXIT_FAILURE; + } + else if (strcmp(opt, "r") == 0) { + if ((item = options_arg(opts))) { + if (args->libc == 0) { + args->libv = (char**)mrb_malloc(mrb, sizeof(char*)); } - 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); } else { - args->libv = (char**)mrb_realloc(mrb, args->libv, sizeof(char*) * (args->libc + 1)); + fprintf(stderr, "%s: No library specified for -r\n", opts->program); + return EXIT_FAILURE; } - args->libv[args->libc++] = dup_arg_item(mrb, item); - break; - case 'v': + } + else if (strcmp(opt, "v") == 0) { if (!args->verbose) mrb_show_version(mrb); args->verbose = TRUE; + } + else if (strcmp(opt, "version") == 0) { + mrb_show_version(mrb); + exit(EXIT_SUCCESS); + } + else if (strcmp(opt, "verbose") == 0) { + args->verbose = TRUE; break; - case '-': - if (strcmp((*argv) + 2, "version") == 0) { - mrb_show_version(mrb); - exit(EXIT_SUCCESS); - } - else if (strcmp((*argv) + 2, "verbose") == 0) { - args->verbose = TRUE; - break; - } - else if (strcmp((*argv) + 2, "copyright") == 0) { - mrb_show_copyright(mrb); - exit(EXIT_SUCCESS); - } - default: - fprintf(stderr, "%s: invalid option %s (-h will show valid options)\n", *origargv, *argv); + } + else if (strcmp(opt, "copyright") == 0) { + mrb_show_copyright(mrb); + exit(EXIT_SUCCESS); + } + else { + fprintf(stderr, "%s: invalid option %s%s (-h will show valid options)\n", + opts->program, opt[1] ? "--" : "-", opt); return EXIT_FAILURE; } } - if (args->rfp == NULL && args->cmdline == NULL) { + if (args->cmdline == NULL) { + argc = opts->argc; argv = opts->argv; if (*argv == NULL) args->rfp = stdin; else { - args->rfp = fopen(argv[0], args->mrbfile ? "rb" : "r"); + args->rfp = strcmp(argv[0], "-") == 0 ? + stdin : fopen(argv[0], args->mrbfile ? "rb" : "r"); if (args->rfp == NULL) { - fprintf(stderr, "%s: Cannot open program file: %s\n", *origargv, *argv); + fprintf(stderr, "%s: Cannot open program file: %s\n", opts->program, argv[0]); return EXIT_FAILURE; } args->fname = TRUE; |
