From: Nobuyoshi Nakada Date: 2008-10-29T00:36:39+09:00 Subject: [ruby-dev:36979] RUBYOPT enhancement なかだです。 RUBYOPT環境変数で長い形式のオプションも指定できるように拡張して みました。 また、EIdvwWrKU以外のオプションはRUBYOPTには使えないはずですが、 使用可能なオプションを先につけると他のオプションも有効になってし まいます。 Index: ruby.c =================================================================== --- ruby.c (revision 19983) +++ ruby.c (working copy) @@ -515,25 +515,52 @@ process_sflag(struct cmdline_options *op NODE *rb_parser_append_print(VALUE, NODE *); NODE *rb_parser_while_loop(VALUE, NODE *, int, int); -static int proc_options(int argc, char **argv, struct cmdline_options *opt); +static int proc_options(int argc, char **argv, struct cmdline_options *opt, int envopt); -static char * -moreswitches(const char *s, struct cmdline_options *opt) +static void +moreswitches(const char *s, struct cmdline_options *opt, int envopt) { - int argc; - char *argv[3]; - const char *p = s; - - argc = 2; - argv[0] = argv[2] = 0; - while (*s && !ISSPACE(*s)) - s++; - argv[1] = ALLOCA_N(char, s - p + 2); - argv[1][0] = '-'; - strncpy(argv[1] + 1, p, s - p); - argv[1][s - p + 1] = '\0'; - proc_options(argc, argv, opt); - while (*s && ISSPACE(*s)) - s++; - return (char *)s; + int argc, i; + char **argv, *p; + const char *argstr = 0; + VALUE envs, argary; + + while (ISSPACE(*s)) s++; + if (!*s) return; + envs = rb_str_tmp_new(strlen(s) + 2); + argary = rb_str_tmp_new(0); + + p = RSTRING_PTR(envs); + if (*s != '-') { + p[0] = '-'; + strcpy(p+1, s); + } + else { + strcpy(p, s); + } + + argstr = 0; + rb_str_cat(argary, (char *)&argstr, sizeof(argstr)); + while (*p) { + argstr = p; + rb_str_cat(argary, (char *)&argstr, sizeof(argstr)); + while (*p && !ISSPACE(*p)) ++p; + if (!*p) break; + *p++ = '\0'; + while (ISSPACE(*p)) ++p; + } + argc = RSTRING_LEN(argary) / sizeof(argstr); + argstr = 0; + rb_str_cat(argary, (char *)&argstr, sizeof(argstr)); + argv = (char **)RSTRING_PTR(argary); + while ((i = proc_options(argc, argv, opt, envopt)) > 1 && (argc -= i) > 0) { + argv += i; + if (**argv != '-') { + *--*argv = '-'; + } + if ((*argv)[1]) { + ++argc; + --argv; + } + } } @@ -620,5 +647,5 @@ set_external_encoding_once(struct cmdlin static int -proc_options(int argc, char **argv, struct cmdline_options *opt) +proc_options(int argc, char **argv, struct cmdline_options *opt, int envopt) { int n, argc0 = argc; @@ -636,4 +663,5 @@ proc_options(int argc, char **argv, stru switch (*s) { case 'a': + if (envopt) goto noenvopt; opt->do_split = Qtrue; s++; @@ -641,7 +669,9 @@ proc_options(int argc, char **argv, stru case 'p': + if (envopt) goto noenvopt; opt->do_print = Qtrue; /* through */ case 'n': + if (envopt) goto noenvopt; opt->do_loop = Qtrue; s++; @@ -655,4 +685,5 @@ proc_options(int argc, char **argv, stru case 'y': + if (envopt) goto noenvopt; opt->yydebug = 1; s++; @@ -697,4 +728,5 @@ proc_options(int argc, char **argv, stru case 'c': + if (envopt) goto noenvopt; opt->do_check = Qtrue; s++; @@ -702,4 +734,5 @@ proc_options(int argc, char **argv, stru case 's': + if (envopt) goto noenvopt; forbid_setid("-s"); opt->sflag = 1; @@ -708,4 +741,5 @@ proc_options(int argc, char **argv, stru case 'h': + if (envopt) goto noenvopt; usage(origarg.argv[0]); rb_exit(EXIT_SUCCESS); @@ -713,4 +747,5 @@ proc_options(int argc, char **argv, stru case 'l': + if (envopt) goto noenvopt; opt->do_line = Qtrue; rb_output_rs = rb_rs; @@ -719,4 +754,5 @@ proc_options(int argc, char **argv, stru case 'S': + if (envopt) goto noenvopt; forbid_setid("-S"); opt->do_search = Qtrue; @@ -725,4 +761,5 @@ proc_options(int argc, char **argv, stru case 'e': + if (envopt) goto noenvopt; forbid_setid("-e"); if (!*++s) { @@ -754,4 +791,5 @@ proc_options(int argc, char **argv, stru case 'i': + if (envopt) goto noenvopt; forbid_setid("-i"); ruby_set_inplace_mode(s + 1); @@ -759,4 +797,5 @@ proc_options(int argc, char **argv, stru case 'x': + if (envopt) goto noenvopt; opt->xflag = Qtrue; s++; @@ -768,4 +807,5 @@ proc_options(int argc, char **argv, stru case 'C': case 'X': + if (envopt) goto noenvopt; s++; if (!*s) { @@ -782,4 +822,5 @@ proc_options(int argc, char **argv, stru case 'F': + if (envopt) goto noenvopt; if (*++s) { rb_fs = rb_reg_new(s, strlen(s), 0); @@ -848,4 +889,5 @@ proc_options(int argc, char **argv, stru case '0': + if (envopt) goto noenvopt; { int numlen; @@ -869,10 +911,13 @@ proc_options(int argc, char **argv, stru case '-': if (!s[1] || (s[1] == '\r' && !s[2])) { + if (envopt) goto noenvopt; argc--, argv++; goto switch_end; } s++; - if (strcmp("copyright", s) == 0) + if (strcmp("copyright", s) == 0) { + if (envopt) goto noenvopt; opt->copyright = 1; + } else if (strcmp("debug", s) == 0) { ruby_debug = Qtrue; @@ -913,17 +958,23 @@ proc_options(int argc, char **argv, stru set_external_encoding_once(opt, s, 0); } - else if (strcmp("version", s) == 0) + else if (strcmp("version", s) == 0) { + if (envopt) goto noenvopt; opt->version = 1; + } else if (strcmp("verbose", s) == 0) { opt->verbose = 1; ruby_verbose = Qtrue; } - else if (strcmp("yydebug", s) == 0) + else if (strcmp("yydebug", s) == 0) { + if (envopt) goto noenvopt; opt->yydebug = 1; + } else if (strncmp("dump", s, n = 4) == 0 && (!s[n] || s[n] == '=')) { + if (envopt) goto noenvopt; if (!(s += n + 1)[-1] && (!--argc || !(s = *++argv)) && *s != '-') break; ruby_each_words(s, dump_option, &opt->dump); } else if (strcmp("help", s) == 0) { + if (envopt) goto noenvopt; usage(origarg.argv[0]); rb_exit(EXIT_SUCCESS); @@ -954,4 +1005,8 @@ proc_options(int argc, char **argv, stru goto switch_end; + noenvopt: + /* "EIdvwWrKU" only */ + rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: -%c", *s); + case 0: break; @@ -1003,5 +1058,5 @@ process_options(VALUE arg) const char *s; char fbuf[MAXPATHLEN]; - int i = proc_options(argc, argv, opt); + int i = proc_options(argc, argv, opt, 0); int safe; @@ -1016,38 +1071,5 @@ process_options(VALUE arg) opt->src.enc.name = opt->ext.enc.name = opt->intern.enc.name = 0; - while (ISSPACE(*s)) - s++; - if (*s == 'T' || (*s == '-' && *(s + 1) == 'T')) { - int numlen; - int v = 1; - - if (*s != 'T') - ++s; - if (*++s) { - v = scan_oct(s, 2, &numlen); - if (numlen == 0) - v = 1; - } - rb_set_safe_level(v); - } - else { - while (s && *s) { - if (*s == '-') { - s++; - if (ISSPACE(*s)) { - do { - s++; - } while (ISSPACE(*s)); - continue; - } - } - if (!*s) - break; - if (!strchr("EIdvwWrKU", *s)) - rb_raise(rb_eRuntimeError, - "invalid switch in RUBYOPT: -%c", *s); - s = moreswitches(s, opt); - } - } + moreswitches(s, opt, 1); if (src_enc_name) opt->src.enc.name = src_enc_name; @@ -1319,8 +1341,5 @@ load_file_internal(VALUE arg) RSTRING_PTR(line)[RSTRING_LEN(line) - 2] = '\0'; if ((p = strstr(p, " -")) != 0) { - p++; /* skip space before `-' */ - while (*p == '-') { - p = moreswitches(p + 1, opt); - } + moreswitches(p + 1, opt, 0); } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦