mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
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]
This commit is contained in:
@@ -41,7 +41,7 @@ MRB_API struct RRange* mrb_range_ptr(mrb_state *mrb, mrb_value v);
|
||||
*/
|
||||
MRB_API mrb_value mrb_range_new(mrb_state *mrb, mrb_value start, mrb_value end, mrb_bool exclude);
|
||||
|
||||
MRB_API mrb_bool mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len);
|
||||
MRB_API int mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc);
|
||||
mrb_value mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int));
|
||||
|
||||
MRB_END_DECL
|
||||
|
||||
@@ -22,7 +22,7 @@ mrb_f_caller(mrb_state *mrb, mrb_value self)
|
||||
case 1:
|
||||
if (mrb_type(v) == MRB_TT_RANGE) {
|
||||
mrb_int beg, len;
|
||||
if (mrb_range_beg_len(mrb, v, &beg, &len, bt_len)) {
|
||||
if (mrb_range_beg_len(mrb, v, &beg, &len, bt_len, TRUE) == 1) {
|
||||
lev = beg;
|
||||
n = len;
|
||||
}
|
||||
|
||||
@@ -56,8 +56,14 @@ mrb_str_byteslice(mrb_state *mrb, mrb_value str)
|
||||
mrb_int beg;
|
||||
|
||||
len = RSTRING_LEN(str);
|
||||
if (mrb_range_beg_len(mrb, a1, &beg, &len, len)) {
|
||||
switch (mrb_range_beg_len(mrb, a1, &beg, &len, len, TRUE)) {
|
||||
case 0: /* not range */
|
||||
break;
|
||||
case 1: /* range */
|
||||
return mrb_str_substr(mrb, str, beg, len);
|
||||
case 2: /* out of range */
|
||||
mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", a1);
|
||||
break;
|
||||
}
|
||||
return mrb_nil_value();
|
||||
}
|
||||
|
||||
+9
-12
@@ -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,20 +808,17 @@ 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);
|
||||
}
|
||||
break;
|
||||
/* a[n] = v */
|
||||
case MRB_TT_FIXNUM:
|
||||
mrb_ary_set(mrb, self, mrb_fixnum(v1), v2);
|
||||
break;
|
||||
default:
|
||||
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;
|
||||
case 1: /* range */
|
||||
mrb_ary_splice(mrb, self, i, len, v2);
|
||||
break;
|
||||
case 2: /* out of range */
|
||||
mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", v1);
|
||||
break;
|
||||
}
|
||||
return v2;
|
||||
}
|
||||
|
||||
+7
-13
@@ -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));
|
||||
|
||||
+15
-12
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user