[前][次][番号順一覧][スレッド一覧]

ruby-changes:8519

From: nobu <ko1@a...>
Date: Thu, 30 Oct 2008 10:34:35 +0900 (JST)
Subject: [ruby-changes:8519] Ruby:r20053 (trunk): * ruby.c (moreswitches): splits option string and passes arguments.

nobu	2008-10-30 10:34:23 +0900 (Thu, 30 Oct 2008)

  New Revision: 20053

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=20053

  Log:
    * ruby.c (moreswitches): splits option string and passes arguments.
    * ruby.c (proc_options): checks if allowed in RUBYOPT.
    
    * ruby.c (process_options): allows long style options in RUBYOPT.
    
    * ruby.c (load_file_internal): ditto in shebang.  [ruby-dev:36979]

  Modified files:
    trunk/ChangeLog
    trunk/ruby.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 20052)
+++ ChangeLog	(revision 20053)
@@ -1,3 +1,13 @@
+Thu Oct 30 10:34:20 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* ruby.c (moreswitches): splits option string and passes arguments.
+
+	* ruby.c (proc_options): checks if allowed in RUBYOPT.
+
+	* ruby.c (process_options): allows long style options in RUBYOPT.
+
+	* ruby.c (load_file_internal): ditto in shebang.  [ruby-dev:36979]
+
 Thu Oct 30 09:31:45 2008  Nobuyoshi Nakada  <nobu@r...>
 
 	* encoding.c (rb_locale_encoding): makes an alias for locale.
Index: ruby.c
===================================================================
--- ruby.c	(revision 20052)
+++ ruby.c	(revision 20053)
@@ -514,27 +514,53 @@
 
 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;
+    int argc, i;
+    char **argv, *p;
+    const char *ap = 0;
+    VALUE argstr, argary;
 
-    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;
+    while (ISSPACE(*s)) s++;
+    if (!*s) return;
+    argstr = rb_str_tmp_new(strlen(s) + 2);
+    argary = rb_str_tmp_new(0);
+
+    p = RSTRING_PTR(argstr);
+    *p++ = ' ';
+    strcpy(p, s);
+    ap = 0;
+    rb_str_cat(argary, (char *)&ap, sizeof(ap));
+    while (*p) {
+	ap = p;
+	rb_str_cat(argary, (char *)&ap, sizeof(ap));
+	while (*p && !ISSPACE(*p)) ++p;
+	if (!*p) break;
+	*p++ = '\0';
+	while (ISSPACE(*p)) ++p; 
+    }
+    argc = RSTRING_LEN(argary) / sizeof(ap);
+    ap = 0;
+    rb_str_cat(argary, (char *)&ap, sizeof(ap));
+    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;
+	}
+    }
+
+    /* get rid of GC */
+    rb_str_resize(argary, 0);
+    rb_str_resize(argstr, 0);
 }
 
 #define NAME_MATCH_P(name, str, len) \
@@ -619,7 +645,7 @@
 }
 
 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;
     const char *s;
@@ -635,14 +661,17 @@
       reswitch:
 	switch (*s) {
 	  case 'a':
+	    if (envopt) goto noenvopt;
 	    opt->do_split = Qtrue;
 	    s++;
 	    goto reswitch;
 
 	  case 'p':
+	    if (envopt) goto noenvopt;
 	    opt->do_print = Qtrue;
 	    /* through */
 	  case 'n':
+	    if (envopt) goto noenvopt;
 	    opt->do_loop = Qtrue;
 	    s++;
 	    goto reswitch;
@@ -654,6 +683,7 @@
 	    goto reswitch;
 
 	  case 'y':
+	    if (envopt) goto noenvopt;
 	    opt->yydebug = 1;
 	    s++;
 	    goto reswitch;
@@ -696,34 +726,40 @@
 	    goto reswitch;
 
 	  case 'c':
+	    if (envopt) goto noenvopt;
 	    opt->do_check = Qtrue;
 	    s++;
 	    goto reswitch;
 
 	  case 's':
+	    if (envopt) goto noenvopt;
 	    forbid_setid("-s");
 	    opt->sflag = 1;
 	    s++;
 	    goto reswitch;
 
 	  case 'h':
+	    if (envopt) goto noenvopt;
 	    usage(origarg.argv[0]);
 	    rb_exit(EXIT_SUCCESS);
 	    break;
 
 	  case 'l':
+	    if (envopt) goto noenvopt;
 	    opt->do_line = Qtrue;
 	    rb_output_rs = rb_rs;
 	    s++;
 	    goto reswitch;
 
 	  case 'S':
+	    if (envopt) goto noenvopt;
 	    forbid_setid("-S");
 	    opt->do_search = Qtrue;
 	    s++;
 	    goto reswitch;
 
 	  case 'e':
+	    if (envopt) goto noenvopt;
 	    forbid_setid("-e");
 	    if (!*++s) {
 		s = argv[1];
@@ -753,11 +789,13 @@
 	    break;
 
 	  case 'i':
+	    if (envopt) goto noenvopt;
 	    forbid_setid("-i");
 	    ruby_set_inplace_mode(s + 1);
 	    break;
 
 	  case 'x':
+	    if (envopt) goto noenvopt;
 	    opt->xflag = Qtrue;
 	    s++;
 	    if (*s && chdir(s) < 0) {
@@ -767,6 +805,7 @@
 
 	  case 'C':
 	  case 'X':
+	    if (envopt) goto noenvopt;
 	    s++;
 	    if (!*s) {
 		s = argv[1];
@@ -781,13 +820,16 @@
 	    break;
 
 	  case 'F':
+	    if (envopt) goto noenvopt;
 	    if (*++s) {
 		rb_fs = rb_reg_new(s, strlen(s), 0);
 	    }
 	    break;
 
 	  case 'E':
-	    if (!*++s) goto next_encoding;
+	    if (!*++s && (!--argc || !(s = *++argv))) {
+		rb_raise(rb_eRuntimeError, "missing argument for -E");
+	    }
 	    goto encoding;
 
 	  case 'U':
@@ -847,6 +889,7 @@
 	    break;
 
 	  case '0':
+	    if (envopt) goto noenvopt;
 	    {
 		int numlen;
 		int v;
@@ -872,35 +915,36 @@
 		goto switch_end;
 	    }
 	    s++;
-	    if (strcmp("copyright", s) == 0)
+
+#	define is_option_end(c, allow_hyphen) \
+	    (!(c) || (allow_hyphen && (c) == '-') || (c) == '=')
+#	define check_envopt(name, allow_envopt) \
+	    ((allow_envopt || !envopt) ? (void)0 : \
+	     rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: --" name))
+#	define need_argument(name, s) \
+	    ((*s++ ? !*s : (!--argc || !(s = *++argv))) ?		\
+	     rb_raise(rb_eRuntimeError, "missing argument for --" name) \
+	     : (void)0)
+#	define is_option_with_arg(name, allow_hyphen, allow_envopt) \
+	    (strncmp(name, s, n = sizeof(name) - 1) == 0 && is_option_end(s[n], allow_hyphen) ? \
+	     (check_envopt(name, allow_envopt), s += n, need_argument(name, s), 1) : 0)
+
+	    if (strcmp("copyright", s) == 0) {
+		if (envopt) goto noenvopt_long;
 		opt->copyright = 1;
+	    }
 	    else if (strcmp("debug", s) == 0) {
 		ruby_debug = Qtrue;
                 ruby_verbose = Qtrue;
             }
-	    else if (strncmp("enable", s, n = 6) == 0 &&
-		     (!s[n] || s[n] == '-' || s[n] == '=')) {
-		if ((s += n + 1)[-1] ? !*s : (!--argc || !(s = *++argv))) {
-		    rb_raise(rb_eRuntimeError, "missing argument for --enable");
-		}
+	    else if (is_option_with_arg("enable", Qtrue, Qtrue)) {
 		ruby_each_words(s, enable_option, &opt->disable);
 	    }
-	    else if (strncmp("disable", s, n = 7) == 0 &&
-		     (!s[n] || s[n] == '-' || s[n] == '=')) {
-		if ((s += n + 1)[-1] ? !*s : (!--argc || !(s = *++argv))) {
-		    rb_raise(rb_eRuntimeError, "missing argument for --disable");
-		}
+	    else if (is_option_with_arg("disable", Qtrue, Qtrue)) {
 		ruby_each_words(s, disable_option, &opt->disable);
 	    }
-	    else if (strncmp("encoding", s, n = 8) == 0 && (!s[n] || s[n] == '=')) {
+	    else if (is_option_with_arg("encoding", Qfalse, Qtrue)) {
 		char *p;
-		s += n;
-		if (!*s++) {
-		  next_encoding:
-		    if (!--argc || !(s = *++argv)) {
-			rb_raise(rb_eRuntimeError, "missing argument for --encoding");
-		    }
-		}
 	      encoding:
 		p = strchr(s, ':');
 		if (p) {
@@ -912,19 +956,23 @@
 		else    
 		    set_external_encoding_once(opt, s, 0);
 	    }
-	    else if (strcmp("version", s) == 0)
+	    else if (strcmp("version", s) == 0) {
+		if (envopt) goto noenvopt_long;
 		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_long;
 		opt->yydebug = 1;
-	    else if (strncmp("dump", s, n = 4) == 0 && (!s[n] || s[n] == '=')) {
-		if (!(s += n + 1)[-1] && (!--argc || !(s = *++argv)) && *s != '-') break;
+	    }
+	    else if (is_option_with_arg("dump", Qfalse, Qfalse)) {
 		ruby_each_words(s, dump_option, &opt->dump);
 	    }
 	    else if (strcmp("help", s) == 0) {
+		if (envopt) goto noenvopt_long;
 		usage(origarg.argv[0]);
 		rb_exit(EXIT_SUCCESS);
 	    }
@@ -953,8 +1001,21 @@
 	    }
 	    goto switch_end;
 
+	  noenvopt:
+	    /* "EIdvwWrKU" only */
+	    rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: -%c", *s);
+	    break;
+
+	  noenvopt_long:
+	    rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: --%s", s);
+	    break;
+
 	  case 0:
 	    break;
+#	undef is_option_end
+#	undef check_envopt
+#	undef need_argument
+#	undef is_option_with_arg
 	}
     }
 
@@ -1002,7 +1063,7 @@
     rb_encoding *enc, *lenc;
     const char *s;
     char fbuf[MAXPATHLEN];
-    int i = proc_options(argc, argv, opt);
+    int i = proc_options(argc, argv, opt, 0);
     int safe;
 
     argc -= i;
@@ -1015,40 +1076,7 @@
 	VALUE int_enc_name = opt->intern.enc.name;
 
 	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;
 	if (ext_enc_name)
@@ -1320,10 +1348,7 @@
 		if (RSTRING_PTR(line)[RSTRING_LEN(line) - 2] == '\r')
 		    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);
 		}
 
 		/* push back shebang for pragma may exist in next line */

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]