VALUE range_spec_rb_range_values(VALUE self, VALUE range) { VALUE beg; VALUE end; int excl; VALUE ary = rb_ary_new(); rb_range_values(range, &beg, &end, &excl); rb_ary_store(ary, 0, beg); rb_ary_store(ary, 1, end); rb_ary_store(ary, 2, excl ? Qtrue : Qfalse); return ary; }
VALUE rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err) { long beg, end, origbeg, origend; VALUE b, e; int excl; if (!rb_range_values(range, &b, &e, &excl)) { return Qfalse; } beg = NUM2LONG(b); end = NUM2LONG(e); origbeg = beg; origend = end; if (beg < 0) { beg += len; if (beg < 0) goto out_of_range; } if (err == 0 || err == 2) { if (beg > len) goto out_of_range; if (end > len) end = len; } if (end < 0) end += len; if (!excl) end++; /* include end point */ len = end - beg; if (len < 0) len = 0; *begp = beg; *lenp = len; return Qtrue; out_of_range: if (err) { rb_raise(rb_eRangeError, "%ld..%s%ld out of range", origbeg, excl ? "." : "", origend); } return Qnil; }