diff options
| author | Yukihiro Matsumoto <[email protected]> | 2012-07-08 00:20:56 +0900 |
|---|---|---|
| committer | Yukihiro Matsumoto <[email protected]> | 2012-07-08 00:20:56 +0900 |
| commit | 0d99856b57f172948c4e579c8f96cc19aa3d8568 (patch) | |
| tree | a8f0b7c55a3ee86b317dbc7eecea69d7d0fa63cd | |
| parent | becb7e98779914cdb1e5703ffe01ce408910523f (diff) | |
| download | mruby-0d99856b57f172948c4e579c8f96cc19aa3d8568.tar.gz mruby-0d99856b57f172948c4e579c8f96cc19aa3d8568.zip | |
proper type check when creating a range; #345
| -rw-r--r-- | src/range.c | 58 | ||||
| -rw-r--r-- | test/t/bs_block.rb | 2 |
2 files changed, 27 insertions, 33 deletions
diff --git a/src/range.c b/src/range.c index 34ca79a0d..a26d38e22 100644 --- a/src/range.c +++ b/src/range.c @@ -21,6 +21,30 @@ #define RANGE_CLASS (mrb_class_obj_get(mrb, "Range")) +static void +range_check(mrb_state *mrb, mrb_value a, mrb_value b) +{ + mrb_value ans; + + switch (mrb_type(a)) { + case MRB_TT_FIXNUM: + case MRB_TT_FLOAT: + switch (mrb_type(b)) { + case MRB_TT_FIXNUM: + case MRB_TT_FLOAT: + return; + } + } + + mrb_p(mrb, a); + mrb_p(mrb, b); + ans = mrb_funcall(mrb, a, "<=>", 1, b); + if (mrb_nil_p(ans)) { + /* can not be compared */ + mrb_raise(mrb, E_ARGUMENT_ERROR, "bad value for range"); + } +} + mrb_value mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, int excl) { @@ -28,6 +52,7 @@ mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, int excl) r = (struct RRange*)mrb_obj_alloc(mrb, MRB_TT_RANGE, RANGE_CLASS); r->edges = mrb_malloc(mrb, sizeof(struct mrb_range_edges)); + range_check(mrb, beg, end); r->edges->beg = beg; r->edges->end = end; r->excl = excl; @@ -82,39 +107,12 @@ mrb_range_excl(mrb_state *mrb, mrb_value range) return r->excl ? mrb_true_value() : mrb_false_value(); } -/* - * call-seq: - * beg end - * args[0] <= args[1] => true - * args[0] > args[1] => false - */ -static int -range_check(mrb_state *mrb, mrb_value *args) -{ - mrb_value ans = mrb_funcall(mrb, args[0], "<=>", 1, args[1]); - /* beg end - ans :args[0] < args[1] => -1 - args[0] = args[1] => 0 - args[0] > args[1] => +1 */ - if (mrb_nil_p(ans)) return FALSE; - //if (mrb_obj_equal(mrb, ans, mrb_fixnum_value(1))) return FALSE; - if (mrb_fixnum(ans) == 1) return FALSE; - return TRUE; -} - static void range_init(mrb_state *mrb, mrb_value range, mrb_value beg, mrb_value end, mrb_int exclude_end) { - mrb_value args[2]; struct RRange *r = mrb_range_ptr(range); - if ((mrb_type(beg) != MRB_TT_FIXNUM) || (mrb_type(end) != MRB_TT_FIXNUM)) { - args[0] = beg; - args[1] = end; - if (!range_check(mrb, args)) { - printf("range_failed()\n"); - } - } + range_check(mrb, beg, end); r->excl = exclude_end; r->edges->beg = beg; r->edges->end = end; @@ -166,7 +164,6 @@ mrb_range_eq(mrb_state *mrb, mrb_value range) if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value(); /* same class? */ - // if (!rb_obj_is_instance_of(obj, rb_obj_class(range))) if (!mrb_obj_is_instance_of(mrb, obj, mrb_obj_class(mrb, range))) return mrb_false_value(); @@ -199,12 +196,10 @@ r_le(mrb_state *mrb, mrb_value a, mrb_value b) static int r_gt(mrb_state *mrb, mrb_value a, mrb_value b) { - //int c; mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* output :a < b => -1, a = b => 0, a > b => +1 */ if (mrb_nil_p(r)) return FALSE; - if (mrb_obj_equal(mrb, r, mrb_fixnum_value(1))) return TRUE; return FALSE; } @@ -212,7 +207,6 @@ r_gt(mrb_state *mrb, mrb_value a, mrb_value b) static int r_ge(mrb_state *mrb, mrb_value a, mrb_value b) { - //int c; mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */ /* output :a < b => -1, a = b => 0, a > b => +1 */ diff --git a/test/t/bs_block.rb b/test/t/bs_block.rb index 654a9ba5c..bef9a8564 100644 --- a/test/t/bs_block.rb +++ b/test/t/bs_block.rb @@ -62,7 +62,7 @@ end assert('BS Block 7') do ans = [] for m in 1..3 - for n in 1..3 + for n in 2..4 a = [m, n] ans << a end |
