summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2017-01-23 14:35:26 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2017-01-23 14:35:26 +0900
commit5e1d923381072ebcbe002d70bc198a6e95c31f50 (patch)
treea34b1dd90e3931d91d4cc11666187907f10de877 /src
parent708088c5fafd469d04a1b428fc49b8b7c27607d2 (diff)
downloadmruby-5e1d923381072ebcbe002d70bc198a6e95c31f50.tar.gz
mruby-5e1d923381072ebcbe002d70bc198a6e95c31f50.zip
Changed the behavior of mrb_range_beg_len(); close #3411
The new API is: int mrb_range_beg_len(mrb, range, &beg, &len, len, trunc) The new argument `trunc` is a boolean value that specifies whether the function truncates the range. The new return value is an integer instead of a boolean, that is: 0: not a range 1: range with proper edges 2: out of range To get the old behavior, you have to rewrite: mrb_range_beg_len(mrb, range, &beg, &len, len) to: mrn_range_beg_len(mrb, range, &beg, &len, len, TRUE) == 1 [Breaking Change]
Diffstat (limited to 'src')
-rw-r--r--src/array.c19
-rw-r--r--src/range.c20
-rw-r--r--src/string.c27
3 files changed, 30 insertions, 36 deletions
diff --git a/src/array.c b/src/array.c
index f9155d173..e41183d68 100644
--- a/src/array.c
+++ b/src/array.c
@@ -742,7 +742,7 @@ mrb_ary_aget(mrb_state *mrb, mrb_value self)
switch (mrb_type(index)) {
/* a[n..m] */
case MRB_TT_RANGE:
- if (mrb_range_beg_len(mrb, index, &i, &len, a->len)) {
+ if (mrb_range_beg_len(mrb, index, &i, &len, a->len, TRUE) == 1) {
return ary_subseq(mrb, a, i, len);
}
else {
@@ -808,19 +808,16 @@ mrb_ary_aset(mrb_state *mrb, mrb_value self)
mrb_ary_modify(mrb, mrb_ary_ptr(self));
if (mrb_get_args(mrb, "oo|o", &v1, &v2, &v3) == 2) {
- switch (mrb_type(v1)) {
/* a[n..m] = v */
- case MRB_TT_RANGE:
- if (mrb_range_beg_len(mrb, v1, &i, &len, RARRAY_LEN(self))) {
- mrb_ary_splice(mrb, self, i, len, v2);
- }
+ switch (mrb_range_beg_len(mrb, v1, &i, &len, RARRAY_LEN(self), FALSE)) {
+ case 0: /* not range */
+ mrb_ary_set(mrb, self, aget_index(mrb, v1), v2);
break;
- /* a[n] = v */
- case MRB_TT_FIXNUM:
- mrb_ary_set(mrb, self, mrb_fixnum(v1), v2);
+ case 1: /* range */
+ mrb_ary_splice(mrb, self, i, len, v2);
break;
- default:
- mrb_ary_set(mrb, self, aget_index(mrb, v1), v2);
+ case 2: /* out of range */
+ mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", v1);
break;
}
return v2;
diff --git a/src/range.c b/src/range.c
index 73fe7589b..800e64611 100644
--- a/src/range.c
+++ b/src/range.c
@@ -248,13 +248,13 @@ mrb_range_include(mrb_state *mrb, mrb_value range)
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)
+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;
- 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);
@@ -262,11 +262,11 @@ range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb
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;
}
@@ -278,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) */
@@ -405,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));
diff --git a/src/string.c b/src/string.c
index 02c7ce426..7a75bb63e 100644
--- a/src/string.c
+++ b/src/string.c
@@ -1091,22 +1091,25 @@ num_index:
return mrb_nil_value();
case MRB_TT_RANGE:
- /* check if indx is Range */
- {
- mrb_int beg, len;
+ goto range_arg;
- len = RSTRING_CHAR_LEN(str);
- if (mrb_range_beg_len(mrb, indx, &beg, &len, len)) {
- return str_subseq(mrb, str, beg, len);
- }
- else {
- return mrb_nil_value();
- }
- }
- case MRB_TT_FLOAT:
default:
indx = mrb_Integer(mrb, indx);
if (mrb_nil_p(indx)) {
+ range_arg:
+ {
+ mrb_int beg, len;
+
+ len = RSTRING_CHAR_LEN(str);
+ switch (mrb_range_beg_len(mrb, indx, &beg, &len, len, TRUE)) {
+ case 1:
+ return str_subseq(mrb, str, beg, len);
+ case 2:
+ return mrb_nil_value();
+ default:
+ break;
+ }
+ }
mrb_raise(mrb, E_TYPE_ERROR, "can't convert to Fixnum");
}
idx = mrb_fixnum(indx);