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

ruby-changes:56417

From: Nobuyoshi <ko1@a...>
Date: Thu, 11 Jul 2019 20:14:59 +0900 (JST)
Subject: [ruby-changes:56417] Nobuyoshi Nakada: 3e7d002118 (master): Check exception flag as a bool [Bug #15987]

https://git.ruby-lang.org/ruby.git/commit/?id=3e7d002118

From 3e7d002118a92fad5934e11c75be6768a1476c1b Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Thu, 11 Jul 2019 19:20:53 +0900
Subject: Check exception flag as a bool [Bug #15987]


diff --git a/complex.c b/complex.c
index 848d3ac..42b32d4 100644
--- a/complex.c
+++ b/complex.c
@@ -477,13 +477,7 @@ nucomp_f_complex(int argc, VALUE *argv, VALUE klass) https://github.com/ruby/ruby/blob/trunk/complex.c#L477
         a2 = Qundef;
     }
     if (!NIL_P(opts)) {
-        static ID kwds[1];
-        VALUE exception;
-        if (!kwds[0]) {
-            kwds[0] = idException;
-        }
-        rb_get_kwargs(opts, kwds, 0, 1, &exception);
-        raise = (exception != Qfalse);
+        raise = rb_opts_exception_p(opts, raise);
     }
     return nucomp_convert(rb_cComplex, a1, a2, raise);
 }
diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
index da1b24a..430707a 100644
--- a/ext/bigdecimal/bigdecimal.c
+++ b/ext/bigdecimal/bigdecimal.c
@@ -2560,6 +2560,10 @@ BigDecimal_clone(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L2560
   return self;
 }
 
+#ifdef HAVE_RB_OPTS_EXCEPTION_P
+int rb_opts_exception_p(VALUE opts, int default_value);
+#define opts_exception_p(opts) rb_opts_exception_p((opts), 1)
+#else
 static int
 opts_exception_p(VALUE opts)
 {
@@ -2569,8 +2573,16 @@ opts_exception_p(VALUE opts) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L2573
         kwds[0] = rb_intern_const("exception");
     }
     rb_get_kwargs(opts, kwds, 0, 1, &exception);
+    switch (exception) {
+      case Qtrue: case Qfalse:
+        break;
+      default:
+        rb_raise(rb_eArgError, "true or false is expected as exception: %+"PRIsVALUE,
+                 flagname, obj);
+    }
     return exception != Qfalse;
 }
+#endif
 
 static Real *
 BigDecimal_new(int argc, VALUE *argv)
diff --git a/ext/bigdecimal/extconf.rb b/ext/bigdecimal/extconf.rb
index a6a3630..7a7af10 100644
--- a/ext/bigdecimal/extconf.rb
+++ b/ext/bigdecimal/extconf.rb
@@ -27,6 +27,7 @@ have_func("rb_rational_num", "ruby.h") https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/extconf.rb#L27
 have_func("rb_rational_den", "ruby.h")
 have_func("rb_array_const_ptr", "ruby.h")
 have_func("rb_sym2str", "ruby.h")
+have_func("rb_opts_exception_p", "ruby.h")
 
 if File.file?(File.expand_path('../lib/bigdecimal.rb', __FILE__))
   bigdecimal_rb = "$(srcdir)/lib/bigdecimal.rb"
diff --git a/internal.h b/internal.h
index f2c9e9a..4f9c5b1 100644
--- a/internal.h
+++ b/internal.h
@@ -1891,6 +1891,7 @@ VALUE rb_immutable_obj_clone(int, VALUE *, VALUE); https://github.com/ruby/ruby/blob/trunk/internal.h#L1891
 VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
 VALUE rb_convert_type_with_id(VALUE,int,const char*,ID);
 VALUE rb_check_convert_type_with_id(VALUE,int,const char*,ID);
+int rb_bool_expected(VALUE, const char *);
 
 struct RBasicRaw {
     VALUE flags;
@@ -2349,6 +2350,9 @@ void rb_write_error_str(VALUE mesg); https://github.com/ruby/ruby/blob/trunk/internal.h#L2350
 /* numeric.c (export) */
 VALUE rb_int_positive_pow(long x, unsigned long y);
 
+/* object.c (export) */
+int rb_opts_exception_p(VALUE opts, int default_value);
+
 /* process.c (export) */
 int rb_exec_async_signal_safe(const struct rb_execarg *e, char *errmsg, size_t errmsg_buflen);
 rb_pid_t rb_fork_async_signal_safe(int *status, int (*chfunc)(void*, char *, size_t), void *charg, VALUE fds, char *errmsg, size_t errmsg_buflen);
diff --git a/io.c b/io.c
index 5e04da8..65da68e 100644
--- a/io.c
+++ b/io.c
@@ -171,7 +171,6 @@ VALUE rb_default_rs; https://github.com/ruby/ruby/blob/trunk/io.c#L171
 
 static VALUE argf;
 
-#define id_exception idException
 static ID id_write, id_read, id_getc, id_flush, id_readpartial, id_set_encoding;
 static VALUE sym_mode, sym_perm, sym_flags, sym_extenc, sym_intenc, sym_encoding, sym_open_args;
 static VALUE sym_textmode, sym_binmode, sym_autoclose;
@@ -2793,18 +2792,10 @@ read_internal_locktmp(VALUE str, struct io_internal_read_struct *iis) https://github.com/ruby/ruby/blob/trunk/io.c#L2792
     return (long)rb_str_locktmp_ensure(str, read_internal_call, (VALUE)iis);
 }
 
-static int
-no_exception_p(VALUE opts)
-{
-    VALUE except;
-    ID id = id_exception;
-
-    rb_get_kwargs(opts, &id, 0, 1, &except);
-    return except == Qfalse;
-}
+#define no_exception_p(opts) !rb_opts_exception_p((opts), TRUE)
 
 static VALUE
-io_getpartial(int argc, VALUE *argv, VALUE io, VALUE opts, int nonblock)
+io_getpartial(int argc, VALUE *argv, VALUE io, int no_exception, int nonblock)
 {
     rb_io_t *fptr;
     VALUE length, str;
@@ -2846,7 +2837,7 @@ io_getpartial(int argc, VALUE *argv, VALUE io, VALUE opts, int nonblock) https://github.com/ruby/ruby/blob/trunk/io.c#L2837
             if (!nonblock && fptr_wait_readable(fptr))
                 goto again;
 	    if (nonblock && (e == EWOULDBLOCK || e == EAGAIN)) {
-                if (no_exception_p(opts))
+                if (no_exception)
                     return sym_wait_readable;
                 else
 		    rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE,
@@ -2940,9 +2931,9 @@ io_readpartial(int argc, VALUE *argv, VALUE io) https://github.com/ruby/ruby/blob/trunk/io.c#L2931
 }
 
 static VALUE
-io_nonblock_eof(VALUE opts)
+io_nonblock_eof(int no_exception)
 {
-    if (!no_exception_p(opts)) {
+    if (!no_exception) {
         rb_eof_error();
     }
     return Qnil;
@@ -2963,6 +2954,8 @@ io_read_nonblock(VALUE io, VALUE length, VALUE str, VALUE ex) https://github.com/ruby/ruby/blob/trunk/io.c#L2954
 
     shrinkable = io_setstrbuf(&str, len);
     OBJ_TAINT(str);
+    rb_bool_expected(ex, "exception");
+
     GetOpenFile(io, fptr);
     rb_io_check_byte_readable(fptr);
 
@@ -2981,7 +2974,7 @@ io_read_nonblock(VALUE io, VALUE length, VALUE str, VALUE ex) https://github.com/ruby/ruby/blob/trunk/io.c#L2974
         if (n < 0) {
 	    int e = errno;
 	    if ((e == EWOULDBLOCK || e == EAGAIN)) {
-                if (ex == Qfalse) return sym_wait_readable;
+                if (!ex) return sym_wait_readable;
 		rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE,
 					 e, "read would block");
             }
@@ -2991,7 +2984,7 @@ io_read_nonblock(VALUE io, VALUE length, VALUE str, VALUE ex) https://github.com/ruby/ruby/blob/trunk/io.c#L2984
     io_set_read_length(str, n, shrinkable);
 
     if (n == 0) {
-	if (ex == Qfalse) return Qnil;
+	if (!ex) return Qnil;
 	rb_eof_error();
     }
 
@@ -3007,6 +3000,7 @@ io_write_nonblock(VALUE io, VALUE str, VALUE ex) https://github.com/ruby/ruby/blob/trunk/io.c#L3000
 
     if (!RB_TYPE_P(str, T_STRING))
 	str = rb_obj_as_string(str);
+    rb_bool_expected(ex, "exception");
 
     io = GetWriteIO(io);
     GetOpenFile(io, fptr);
@@ -3022,7 +3016,7 @@ io_write_nonblock(VALUE io, VALUE str, VALUE ex) https://github.com/ruby/ruby/blob/trunk/io.c#L3016
     if (n < 0) {
 	int e = errno;
 	if (e == EWOULDBLOCK || e == EAGAIN) {
-	    if (ex == Qfalse) {
+	    if (!ex) {
 		return sym_wait_writable;
 	    }
 	    else {
@@ -12193,12 +12187,14 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/io.c#L12187
 argf_getpartial(int argc, VALUE *argv, VALUE argf, VALUE opts, int nonblock)
 {
     VALUE tmp, str, length;
+    int no_exception;
 
     rb_scan_args(argc, argv, "11", &length, &str);
     if (!NIL_P(str)) {
         StringValue(str);
         argv[1] = str;
     }
+    no_exception = no_exception_p(opts);
 
     if (!next_argv()) {
 	if (!NIL_P(str)) {
@@ -12215,16 +12211,16 @@ argf_getpartial(int argc, VALUE *argv, VALUE argf, VALUE opts, int nonblock) https://github.com/ruby/ruby/blob/trunk/io.c#L12211
 			 RUBY_METHOD_FUNC(0), Qnil, rb_eEOFError, (VALUE)0);
     }
     else {
-        tmp = io_getpartial(argc, argv, ARGF.current_file, opts, nonblock);
+        tmp = io_getpartial(argc, argv, ARGF.current_file, no_exception, nonblock);
     }
     if (NIL_P(tmp)) {
         if (ARGF.next_p == -1) {
-	    return io_nonblock_eof(opts);
+	    return io_nonblock_eof(no_exception);
         }
         argf_close(argf);
         ARGF.next_p = 1;
         if (RARRAY_LEN(ARGF.argv) == 0) {
-	    return io_nonblock_eof(opts);
+	    return io_nonblock_eof(no_exception);
 	}
         if (NIL_P(str))
             str = rb_str_new(NULL, 0);
diff --git a/object.c b/object.c
index 3fc1ed9..6b7a8f2 100644
--- a/object.c
+++ b/object.c
@@ -3330,18 +3330,31 @@ rb_Integer(VALUE val) https://github.com/ruby/ruby/blob/trunk/object.c#L3330
     return rb_convert_to_integer(val, 0, TRUE);
 }
 
-static int
-opts_exception_p(VALUE opts)
+int
+rb_bool_expected(VALUE obj, const char *flagname)
 {
-    static ID kwds[1];
-    VALUE exception;
-    if (!kwds[0]) {
-        kwds[0] = idException;
+    switch (obj) {
+      case Qtrue: case Qfalse:
+        break;
+      default:
+        rb_raise(rb_eArgError, "true or false is expected as %s: %+"PRIsVALUE,
+                 flagname, obj);
     }
-    rb_get_kwargs(opts, kwds, 0, 1, &exception);
-    return exception != Qfalse;
+    return obj != Qfalse;
+}
+
+int
+rb_opts_exception_p(VALUE opts, int default_value)
+{
+    static ID kwds[1] = {idException};
+    VALUE exception;
+    if (rb_get_kwargs(opts, kwds, 0, 1, &exception))
+        return rb_bool_expected(exception, "exception");
+    return default_value;
 }
 
+#define opts_exception_p(opts) rb_opts_exception_p((opts), TRUE)
+
 /*
  *  call-seq:
  *     Integer(arg, base=0, exception: true)    -> integer or nil
diff --git a/rational.c b/rational.c
index 207c4c4..e137ac2 100644
--- a/rational.c
+++ b/rational.c
@@ -574,13 +574,7 @@ nurat_f_rational(int argc, VALUE *argv, VALUE klass) https://github.com/ruby/ruby/blob/trunk/rational.c#L574
         a2 = Qundef;
     }
     if (!NIL_P(opts)) {
-        static ID kwds[1];
-        VALUE exception;
-        if (!kwds[0]) {
-            kwds[0] = idException;
-        }
-        rb_get_kwargs(opts, kwds, 0, 1, &exception);
-        raise = (exception != Qfalse);
+       (... truncated)

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

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