From 698a24674eb0707fdc8d934084932e845db955cd Mon Sep 17 00:00:00 2001 From: nobu Date: Thu, 8 May 2003 03:56:12 +0000 Subject: * compar.c (rb_cmperr): raise comparison failure. * intern.h: prototype; rb_cmperr * numeric.c (flo_gt, flo_ge, flo_lt, flo_le, fix_gt, fix_ge, fix_lt, fix_le): should fail unless the argument is comparable. (ruby-bugs-ja:PR#456) git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3768 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 12 ++++++++++-- compar.c | 20 ++++++++++++++++---- intern.h | 1 + numeric.c | 62 ++++++++++++++++++++++++++++---------------------------------- 4 files changed, 55 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index 42eab2cf84..55045bfb16 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,12 @@ -Thu May 8 08:56:04 2003 Nobuyoshi Nakada +Thu May 8 12:56:04 2003 Nobuyoshi Nakada + + * compar.c (rb_cmperr): raise comparison failure. + + * intern.h: prototype; rb_cmperr + + * numeric.c (flo_gt, flo_ge, flo_lt, flo_le, fix_gt, fix_ge, + fix_lt, fix_le): should fail unless the argument is comparable. + (ruby-bugs-ja:PR#456) * numeric.c (int_upto, int_downto): should fail unless the argument is comparable. (ruby-bugs-ja:PR#454) @@ -43,7 +51,7 @@ Mon May 5 21:19:25 2003 Koji Arai * ext/dbm/testdbm.rb: ditto. * ext/dbm/testdbm.rb (setup): DBM.open(path, 0400) cause EACCESS - on Berkeley DB[234]. + on Berkeley DB[234]. Mon May 5 22:57:07 2003 Tadayoshi Funaba diff --git a/compar.c b/compar.c index 0a5a10ee23..bb90125bff 100644 --- a/compar.c +++ b/compar.c @@ -30,13 +30,25 @@ rb_cmpint(val) return 0; } -static VALUE -cmperr() +void +rb_cmperr(x, y) + VALUE x, y; { - rb_raise(rb_eArgError, "comparison failed"); - return Qnil; /* not reached */ + const char *classname; + + if (SPECIAL_CONST_P(y)) { + y = rb_inspect(y); + classname = StringValuePtr(y); + } + else { + classname = rb_obj_classname(y); + } + rb_raise(rb_eArgError, "comparison of %s to %s failed", + rb_obj_classname(x), classname); } +#define cmperr() (rb_cmperr(x, y), Qnil) + static VALUE cmp_equal(x, y) VALUE x, y; diff --git a/intern.h b/intern.h index 5a299f3003..9b4c86ce9a 100644 --- a/intern.h +++ b/intern.h @@ -122,6 +122,7 @@ void rb_define_singleton_method _((VALUE, const char*, VALUE(*)(ANYARGS), int)); VALUE rb_singleton_class _((VALUE)); /* compar.c */ int rb_cmpint _((VALUE)); +NORETURN(void rb_cmperr _((VALUE, VALUE))); /* enum.c */ /* error.c */ RUBY_EXTERN int ruby_nerrs; diff --git a/numeric.c b/numeric.c index edc42ef6bd..186a2db901 100644 --- a/numeric.c +++ b/numeric.c @@ -143,6 +143,20 @@ rb_num_coerce_cmp(x, y) return Qnil; } +static VALUE +num_coerce_relop(x, y) + VALUE x, y; +{ + VALUE c, x0 = x, y0 = y; + + if (!do_coerce(&x, &y, Qfalse) || + NIL_P(c = rb_funcall(x, rb_frame_last_func(), 1, y))) { + rb_cmperr(x0, y0); + return Qnil; /* not reached */ + } + return c; +} + static VALUE num_copy_object(x, y) VALUE x, y; @@ -604,7 +618,7 @@ flo_gt(x, y) break; default: - return rb_num_coerce_cmp(x, y); + return num_coerce_relop(x, y); } if (isnan(a) || isnan(b)) return Qfalse; return (a > b)?Qtrue:Qfalse; @@ -631,7 +645,7 @@ flo_ge(x, y) break; default: - return rb_num_coerce_cmp(x, y); + return num_coerce_relop(x, y); } if (isnan(a) || isnan(b)) return Qfalse; return (a >= b)?Qtrue:Qfalse; @@ -658,7 +672,7 @@ flo_lt(x, y) break; default: - return rb_num_coerce_cmp(x, y); + return num_coerce_relop(x, y); } if (isnan(a) || isnan(b)) return Qfalse; return (a < b)?Qtrue:Qfalse; @@ -685,7 +699,7 @@ flo_le(x, y) break; default: - return rb_num_coerce_cmp(x, y); + return num_coerce_relop(x, y); } if (isnan(a) || isnan(b)) return Qfalse; return (a <= b)?Qtrue:Qfalse; @@ -1439,7 +1453,7 @@ fix_gt(x, y) return Qfalse; } else { - return rb_num_coerce_cmp(x, y); + return num_coerce_relop(x, y); } } @@ -1454,7 +1468,7 @@ fix_ge(x, y) return Qfalse; } else { - return rb_num_coerce_cmp(x, y); + return num_coerce_relop(x, y); } } @@ -1469,7 +1483,7 @@ fix_lt(x, y) return Qfalse; } else { - return rb_num_coerce_cmp(x, y); + return num_coerce_relop(x, y); } } @@ -1484,7 +1498,7 @@ fix_le(x, y) return Qfalse; } else { - return rb_num_coerce_cmp(x, y); + return num_coerce_relop(x, y); } } @@ -1653,28 +1667,6 @@ fix_size(fix) return INT2FIX(sizeof(long)); } -static VALUE -int_compare(i, to, id) - VALUE i, to; - ID id; -{ - VALUE cmp = rb_funcall(i, id, 1, to); - if (NIL_P(cmp)) { - char *toclass; - - if (SPECIAL_CONST_P(to)) { - to = rb_inspect(to); - toclass = StringValuePtr(to); - } - else { - toclass = rb_obj_classname(to); - } - rb_raise(rb_eArgError, "cannot compare %s with %s", - rb_obj_classname(i), toclass); - } - return cmp; -} - static VALUE int_upto(from, to) VALUE from, to; @@ -1688,12 +1680,13 @@ int_upto(from, to) } } else { - VALUE i = from; + VALUE i = from, c; - while (!int_compare(i, to, '>')) { + while (!(c = rb_funcall(i, '>', 1, to))) { rb_yield(i); i = rb_funcall(i, '+', 1, INT2FIX(1)); } + if (NIL_P(c)) rb_cmperr(i, to); } return from; } @@ -1711,12 +1704,13 @@ int_downto(from, to) } } else { - VALUE i = from; + VALUE i = from, c; - while (!int_compare(i, to, '<')) { + while (!(c = rb_funcall(i, '<', 1, to))) { rb_yield(i); i = rb_funcall(i, '-', 1, INT2FIX(1)); } + if (NIL_P(c)) rb_cmperr(i, to); } return from; } -- cgit v1.2.3