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

ruby-changes:50572

From: nobu <ko1@a...>
Date: Sat, 10 Mar 2018 20:26:59 +0900 (JST)
Subject: [ruby-changes:50572] nobu:r62716 (trunk): signal.c: refine error messages

nobu	2018-03-10 20:26:54 +0900 (Sat, 10 Mar 2018)

  New Revision: 62716

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62716

  Log:
    signal.c: refine error messages

  Modified files:
    trunk/signal.c
    trunk/test/ruby/test_signal.rb
Index: test/ruby/test_signal.rb
===================================================================
--- test/ruby/test_signal.rb	(revision 62715)
+++ test/ruby/test_signal.rb	(revision 62716)
@@ -87,6 +87,8 @@ class TestSignal < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_signal.rb#L87
       assert_equal(signo, SignalException.new(signm.to_sym).signo, signm)
       assert_equal(signo, SignalException.new(signo).signo, signo)
     end
+    e = assert_raise(ArgumentError) {SignalException.new("-SIGEXIT")}
+    assert_not_match(/SIG-SIG/, e.message)
   end
 
   def test_interrupt
Index: signal.c
===================================================================
--- signal.c	(revision 62715)
+++ signal.c	(revision 62716)
@@ -206,16 +206,75 @@ static const struct signals { https://github.com/ruby/ruby/blob/trunk/signal.c#L206
 };
 
 static const char signame_prefix[3] = "SIG";
+static const int signame_prefix_len = (int)sizeof(signame_prefix);
 
 static int
-signm2signo(const char *nm)
+signm2signo(VALUE *sig_ptr, int negative, int exit, int *prefix_ptr)
 {
     const struct signals *sigs;
+    VALUE vsig = *sig_ptr;
+    const char *nm;
+    long len;
+    int prefix = 0;
+
+    if (RB_SYMBOL_P(vsig)) {
+	*sig_ptr = vsig = rb_sym2str(vsig);
+    }
+    else if (!RB_TYPE_P(vsig, T_STRING)) {
+	VALUE str = rb_check_string_type(vsig);
+	if (NIL_P(str)) {
+	    rb_raise(rb_eArgError, "bad signal type %s",
+		     rb_obj_classname(vsig));
+	}
+	*sig_ptr = vsig = str;
+    }
 
-    for (sigs = siglist; sigs->signm; sigs++)
-	if (strcmp(sigs->signm, nm) == 0)
-	    return sigs->signo;
-    return 0;
+    rb_must_asciicompat(vsig);
+    RSTRING_GETMEM(vsig, nm, len);
+    if (memchr(nm, '\0', len)) {
+	rb_raise(rb_eArgError, "signal name with null byte");
+    }
+
+    if (len > 0 && nm[0] == '-') {
+	if (!negative)
+	    rb_raise(rb_eArgError, "negative signal name: % "PRIsVALUE, vsig);
+	prefix = 1;
+    }
+    else {
+	negative = 0;
+    }
+    if (len >= prefix + signame_prefix_len) {
+	if (memcmp(nm + prefix, signame_prefix, sizeof(signame_prefix)) == 0)
+	    prefix += signame_prefix_len;
+    }
+    if (len <= (long)prefix) {
+      unsupported:
+	if (prefix == signame_prefix_len) {
+	    prefix = 0;
+	}
+	else if (prefix > signame_prefix_len) {
+	    prefix -= signame_prefix_len;
+	    len -= prefix;
+	    vsig = rb_str_subseq(vsig, prefix, len);
+	    prefix = 0;
+	}
+	else {
+	    len -= prefix;
+	    vsig = rb_str_subseq(vsig, prefix, len);
+	    prefix = signame_prefix_len;
+	}
+	rb_raise(rb_eArgError, "unsupported signal `%.*s%"PRIsVALUE"'",
+		 prefix, signame_prefix, vsig);
+    }
+
+    if (prefix_ptr) *prefix_ptr = prefix;
+    for (sigs = siglist + !exit; sigs->signm; sigs++) {
+	if (memcmp(sigs->signm, nm + prefix, len - prefix) == 0 &&
+	    sigs->signm[len - prefix] == '\0') {
+	    return negative ? -sigs->signo : sigs->signo;
+	}
+    }
+    goto unsupported;
 }
 
 static const char*
@@ -284,7 +343,6 @@ esignal_init(int argc, VALUE *argv, VALU https://github.com/ruby/ruby/blob/trunk/signal.c#L343
     int argnum = 1;
     VALUE sig = Qnil;
     int signo;
-    const char *signm;
 
     if (argc > 0) {
 	sig = rb_check_to_integer(argv[0], "to_int");
@@ -305,19 +363,11 @@ esignal_init(int argc, VALUE *argv, VALU https://github.com/ruby/ruby/blob/trunk/signal.c#L363
 	}
     }
     else {
-	int len = sizeof(signame_prefix);
-	if (SYMBOL_P(sig)) sig = rb_sym2str(sig); else StringValue(sig);
-	signm = RSTRING_PTR(sig);
-	if (strncmp(signm, signame_prefix, len) == 0) {
-	    signm += len;
-	    len = 0;
+	int prefix;
+	signo = signm2signo(&sig, FALSE, FALSE, &prefix);
+	if (prefix != signame_prefix_len) {
+	    sig = rb_str_append(rb_str_new_cstr("SIG"), sig);
 	}
-	signo = signm2signo(signm);
-	if (!signo) {
-	    rb_raise(rb_eArgError, "unsupported name `%.*s%"PRIsVALUE"'",
-		     len, signame_prefix, sig);
-	}
-	sig = rb_sprintf("SIG%s", signm);
     }
     rb_call_super(1, &sig);
     rb_ivar_set(self, id_signo, INT2NUM(signo));
@@ -402,51 +452,18 @@ rb_f_kill(int argc, const VALUE *argv) https://github.com/ruby/ruby/blob/trunk/signal.c#L452
 #ifndef HAVE_KILLPG
 #define killpg(pg, sig) kill(-(pg), (sig))
 #endif
-    int negative = 0;
     int sig;
     int i;
     VALUE str;
-    const char *s;
 
     rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);
 
-    switch (TYPE(argv[0])) {
-      case T_FIXNUM:
+    if (FIXNUM_P(argv[0])) {
 	sig = FIX2INT(argv[0]);
-	break;
-
-      case T_SYMBOL:
-	str = rb_sym2str(argv[0]);
-	goto str_signal;
-
-      case T_STRING:
+    }
+    else {
 	str = argv[0];
-      str_signal:
-	s = RSTRING_PTR(str);
-	if (s[0] == '-') {
-	    negative++;
-	    s++;
-	}
-	if (strncmp(signame_prefix, s, sizeof(signame_prefix)) == 0)
-	    s += 3;
-	if ((sig = signm2signo(s)) == 0) {
-	    long ofs = s - RSTRING_PTR(str);
-	    if (ofs) str = rb_str_subseq(str, ofs, RSTRING_LEN(str)-ofs);
-	    rb_raise(rb_eArgError, "unsupported name `SIG%"PRIsVALUE"'", str);
-	}
-
-	if (negative)
-	    sig = -sig;
-	break;
-
-      default:
-	str = rb_check_string_type(argv[0]);
-	if (!NIL_P(str)) {
-	    goto str_signal;
-	}
-	rb_raise(rb_eArgError, "bad signal type %s",
-		 rb_obj_classname(argv[0]));
-	break;
+	sig = signm2signo(&str, TRUE, FALSE, NULL);
     }
 
     if (argc <= 1) return INT2FIX(0);
@@ -1204,7 +1221,6 @@ static int https://github.com/ruby/ruby/blob/trunk/signal.c#L1221
 trap_signm(VALUE vsig)
 {
     int sig = -1;
-    const char *s;
 
     if (FIXNUM_P(vsig)) {
 	sig = FIX2INT(vsig);
@@ -1213,18 +1229,7 @@ trap_signm(VALUE vsig) https://github.com/ruby/ruby/blob/trunk/signal.c#L1229
 	}
     }
     else {
-	if (RB_SYMBOL_P(vsig)) {
-	    vsig = rb_sym2str(vsig);
-	}
-	s = StringValueCStr(vsig);
-	if (strncmp(signame_prefix, s, sizeof(signame_prefix)) == 0)
-	    s += 3;
-	sig = signm2signo(s);
-	if (sig == 0 && strcmp(s, "EXIT") != 0) {
-	    long ofs = s - RSTRING_PTR(vsig);
-	    if (ofs) vsig = rb_str_subseq(vsig, ofs, RSTRING_LEN(vsig)-ofs);
-	    rb_raise(rb_eArgError, "unsupported signal SIG%"PRIsVALUE"", vsig);
-	}
+	sig = signm2signo(&vsig, FALSE, TRUE, NULL);
     }
     return sig;
 }

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

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