summaryrefslogtreecommitdiffhomepage
path: root/src/range.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/range.c')
-rw-r--r--src/range.c67
1 files changed, 38 insertions, 29 deletions
diff --git a/src/range.c b/src/range.c
index 079a1035e..2cb6f2361 100644
--- a/src/range.c
+++ b/src/range.c
@@ -12,6 +12,17 @@
#define RANGE_CLASS (mrb_class_get(mrb, "Range"))
+MRB_API struct RRange*
+mrb_range_ptr(mrb_state *mrb, mrb_value v)
+{
+ struct RRange *r = (struct RRange*)mrb_ptr(v);
+
+ if (r->edges == NULL) {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized range");
+ }
+ return r;
+}
+
static void
range_check(mrb_state *mrb, mrb_value a, mrb_value b)
{
@@ -57,7 +68,7 @@ mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, mrb_bool excl)
mrb_value
mrb_range_beg(mrb_state *mrb, mrb_value range)
{
- struct RRange *r = mrb_range_ptr(range);
+ struct RRange *r = mrb_range_ptr(mrb, range);
return r->edges->beg;
}
@@ -76,7 +87,7 @@ mrb_range_beg(mrb_state *mrb, mrb_value range)
mrb_value
mrb_range_end(mrb_state *mrb, mrb_value range)
{
- struct RRange *r = mrb_range_ptr(range);
+ struct RRange *r = mrb_range_ptr(mrb, range);
return r->edges->end;
}
@@ -90,7 +101,7 @@ mrb_range_end(mrb_state *mrb, mrb_value range)
mrb_value
mrb_range_excl(mrb_state *mrb, mrb_value range)
{
- struct RRange *r = mrb_range_ptr(range);
+ struct RRange *r = mrb_range_ptr(mrb, range);
return mrb_bool_value(r->excl);
}
@@ -98,7 +109,7 @@ mrb_range_excl(mrb_state *mrb, mrb_value range)
static void
range_init(mrb_state *mrb, mrb_value range, mrb_value beg, mrb_value end, mrb_bool exclude_end)
{
- struct RRange *r = mrb_range_ptr(range);
+ struct RRange *r = mrb_range_raw_ptr(range);
range_check(mrb, beg, end);
r->excl = exclude_end;
@@ -129,6 +140,9 @@ mrb_range_initialize(mrb_state *mrb, mrb_value range)
exclusive = FALSE;
}
/* Ranges are immutable, so that they should be initialized only once. */
+ if (mrb_range_raw_ptr(range)->edges) {
+ mrb_name_error(mrb, mrb_intern_lit(mrb, "initialize"), "`initialize' called twice");
+ }
range_init(mrb, range, beg, end, exclusive);
return range;
}
@@ -161,8 +175,8 @@ mrb_range_eq(mrb_state *mrb, mrb_value range)
return mrb_false_value();
}
- rr = mrb_range_ptr(range);
- ro = mrb_range_ptr(obj);
+ rr = mrb_range_ptr(mrb, range);
+ ro = mrb_range_ptr(mrb, obj);
v1 = mrb_funcall(mrb, rr->edges->beg, "==", 1, ro->edges->beg);
v2 = mrb_funcall(mrb, rr->edges->end, "==", 1, ro->edges->end);
if (!mrb_bool(v1) || !mrb_bool(v2) || rr->excl != ro->excl) {
@@ -219,7 +233,7 @@ mrb_value
mrb_range_include(mrb_state *mrb, mrb_value range)
{
mrb_value val;
- struct RRange *r = mrb_range_ptr(range);
+ struct RRange *r = mrb_range_ptr(mrb, range);
mrb_value beg, end;
mrb_bool include_p;
@@ -227,31 +241,32 @@ mrb_range_include(mrb_state *mrb, mrb_value range)
beg = r->edges->beg;
end = r->edges->end;
- include_p = r_le(mrb, beg, val) && /* beg <= val */
- ((r->excl && r_gt(mrb, end, val)) || /* end > val */
- (r_ge(mrb, end, val))); /* end >= val */
+ include_p = r_le(mrb, beg, val) && /* beg <= val */
+ (r->excl ? r_gt(mrb, end, val) /* end > val */
+ : r_ge(mrb, end, val)); /* end >= val */
return mrb_bool_value(include_p);
}
-static mrb_bool
-range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc)
+MRB_API mrb_int
+mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc)
{
mrb_int beg, end;
- struct RRange *r = mrb_range_ptr(range);
+ struct RRange *r;
- if (mrb_type(range) != MRB_TT_RANGE) return FALSE;
+ if (mrb_type(range) != MRB_TT_RANGE) return 0;
+ r = mrb_range_ptr(mrb, range);
beg = mrb_int(mrb, r->edges->beg);
end = mrb_int(mrb, r->edges->end);
if (beg < 0) {
beg += len;
- if (beg < 0) return FALSE;
+ if (beg < 0) return 2;
}
if (trunc) {
- if (beg > len) return FALSE;
+ if (beg > len) return 2;
if (end > len) end = len;
}
@@ -263,13 +278,7 @@ range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb
*begp = beg;
*lenp = len;
- return TRUE;
-}
-
-MRB_API mrb_bool
-mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len)
-{
- return range_beg_len(mrb, range, begp, lenp, len, TRUE);
+ return 1;
}
/* 15.2.14.4.12(x) */
@@ -284,7 +293,7 @@ static mrb_value
range_to_s(mrb_state *mrb, mrb_value range)
{
mrb_value str, str2;
- struct RRange *r = mrb_range_ptr(range);
+ struct RRange *r = mrb_range_ptr(mrb, range);
str = mrb_obj_as_string(mrb, r->edges->beg);
str2 = mrb_obj_as_string(mrb, r->edges->end);
@@ -309,7 +318,7 @@ static mrb_value
range_inspect(mrb_state *mrb, mrb_value range)
{
mrb_value str, str2;
- struct RRange *r = mrb_range_ptr(range);
+ struct RRange *r = mrb_range_ptr(mrb, range);
str = mrb_inspect(mrb, r->edges->beg);
str2 = mrb_inspect(mrb, r->edges->end);
@@ -349,8 +358,8 @@ range_eql(mrb_state *mrb, mrb_value range)
}
if (mrb_type(obj) != MRB_TT_RANGE) return mrb_false_value();
- r = mrb_range_ptr(range);
- o = mrb_range_ptr(obj);
+ r = mrb_range_ptr(mrb, range);
+ o = mrb_range_ptr(mrb, obj);
if (!mrb_eql(mrb, r->edges->beg, o->edges->beg) ||
!mrb_eql(mrb, r->edges->end, o->edges->end) ||
(r->excl != o->excl)) {
@@ -373,7 +382,7 @@ range_initialize_copy(mrb_state *mrb, mrb_value copy)
mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class");
}
- r = mrb_range_ptr(src);
+ r = mrb_range_ptr(mrb, src);
range_init(mrb, copy, r->edges->beg, r->edges->end, r->excl);
return copy;
@@ -390,7 +399,7 @@ mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, con
if (mrb_fixnum_p(argv[i])) {
mrb_ary_push(mrb, result, func(mrb, obj, mrb_fixnum(argv[i])));
}
- else if (range_beg_len(mrb, argv[i], &beg, &len, olen, FALSE)) {
+ else if (mrb_range_beg_len(mrb, argv[i], &beg, &len, olen, FALSE) == 1) {
mrb_int const end = olen < beg + len ? olen : beg + len;
for (j = beg; j < end; ++j) {
mrb_ary_push(mrb, result, func(mrb, obj, j));