зеркало из https://github.com/github/ruby.git
* numeric.c (num_step): better iteration condition for float
values; suggested by Masahiro TANAKA <masa@ir.isas.ac.jp>. * range.c (range_step): step (for Range#step method) <= 0 makes no sence, thus ArgError will be raised. * range.c (range_each): Range#each method is special case for Range#step(1) * file.c (rb_find_file): load must be done from an abolute path if $SAFE >= 4. * enum.c (enum_partition): new method. [new] * re.c (rb_reg_s_quote): quote whitespaces for /x cases. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2420 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
ca55fe4f0d
Коммит
4fa0cdea78
26
ChangeLog
26
ChangeLog
|
@ -1,7 +1,33 @@
|
||||||
|
Tue Apr 30 09:23:05 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* numeric.c (num_step): better iteration condition for float
|
||||||
|
values; suggested by Masahiro TANAKA <masa@ir.isas.ac.jp>.
|
||||||
|
|
||||||
|
Tue Apr 30 05:59:42 2002 Michal Rokos <m.rokos@sh.cvut.cz>
|
||||||
|
|
||||||
|
* range.c (range_step): step (for Range#step method) <= 0 makes no
|
||||||
|
sence, thus ArgError will be raised.
|
||||||
|
|
||||||
|
* range.c (range_each): Range#each method is special case for
|
||||||
|
Range#step(1)
|
||||||
|
|
||||||
|
Mon Apr 29 18:46:42 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* file.c (rb_find_file): load must be done from an abolute path if
|
||||||
|
$SAFE >= 4.
|
||||||
|
|
||||||
Sun Apr 28 17:01:56 2002 WATANABE Hirofumi <eban@ruby-lang.org>
|
Sun Apr 28 17:01:56 2002 WATANABE Hirofumi <eban@ruby-lang.org>
|
||||||
|
|
||||||
* win32/win32.c (insert): fix prototype for ANSI C.
|
* win32/win32.c (insert): fix prototype for ANSI C.
|
||||||
|
|
||||||
|
Fri Apr 26 13:47:15 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* enum.c (enum_partition): new method. [new]
|
||||||
|
|
||||||
|
Fri Apr 26 13:41:00 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* re.c (rb_reg_s_quote): quote whitespaces for /x cases.
|
||||||
|
|
||||||
Fri Apr 26 06:48:23 2002 Takaaki Tateishi <ttate@kt.jaist.ac.jp>
|
Fri Apr 26 06:48:23 2002 Takaaki Tateishi <ttate@kt.jaist.ac.jp>
|
||||||
|
|
||||||
* ext/dl/ptr.c (cary2ary): missing break in switch statements.
|
* ext/dl/ptr.c (cary2ary): missing break in switch statements.
|
||||||
|
|
27
enum.c
27
enum.c
|
@ -216,6 +216,32 @@ enum_inject(argc, argv, obj)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
partition_i(i, ary)
|
||||||
|
VALUE i, *ary;
|
||||||
|
{
|
||||||
|
if (RTEST(rb_yield(i))) {
|
||||||
|
rb_ary_push(ary[0], i);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rb_ary_push(ary[1], i);
|
||||||
|
}
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
enum_partition(obj)
|
||||||
|
VALUE obj;
|
||||||
|
{
|
||||||
|
VALUE ary[2];
|
||||||
|
|
||||||
|
ary[0] = rb_ary_new();
|
||||||
|
ary[1] = rb_ary_new();
|
||||||
|
rb_iterate(rb_each, obj, partition_i, (VALUE)ary);
|
||||||
|
|
||||||
|
return rb_assoc_new(ary[0], ary[1]);
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
enum_sort(obj)
|
enum_sort(obj)
|
||||||
VALUE obj;
|
VALUE obj;
|
||||||
|
@ -475,6 +501,7 @@ Init_Enumerable()
|
||||||
rb_define_method(rb_mEnumerable,"collect", enum_collect, 0);
|
rb_define_method(rb_mEnumerable,"collect", enum_collect, 0);
|
||||||
rb_define_method(rb_mEnumerable,"map", enum_collect, 0);
|
rb_define_method(rb_mEnumerable,"map", enum_collect, 0);
|
||||||
rb_define_method(rb_mEnumerable,"inject", enum_inject, -1);
|
rb_define_method(rb_mEnumerable,"inject", enum_inject, -1);
|
||||||
|
rb_define_method(rb_mEnumerable,"partition", enum_partition, 0);
|
||||||
rb_define_method(rb_mEnumerable,"all?", enum_all, 0);
|
rb_define_method(rb_mEnumerable,"all?", enum_all, 0);
|
||||||
rb_define_method(rb_mEnumerable,"any?", enum_any, 0);
|
rb_define_method(rb_mEnumerable,"any?", enum_any, 0);
|
||||||
rb_define_method(rb_mEnumerable,"min", enum_min, 0);
|
rb_define_method(rb_mEnumerable,"min", enum_min, 0);
|
||||||
|
|
32
eval.c
32
eval.c
|
@ -227,7 +227,7 @@ rb_add_method(klass, mid, node, noex)
|
||||||
NODE *body;
|
NODE *body;
|
||||||
|
|
||||||
if (NIL_P(klass)) klass = rb_cObject;
|
if (NIL_P(klass)) klass = rb_cObject;
|
||||||
if (rb_safe_level() >= 4 && (klass == rb_cObject || !OBJ_TAINTED(klass))) {
|
if (ruby_safe_level >= 4 && (klass == rb_cObject || !OBJ_TAINTED(klass))) {
|
||||||
rb_raise(rb_eSecurityError, "Insecure: can't define method");
|
rb_raise(rb_eSecurityError, "Insecure: can't define method");
|
||||||
}
|
}
|
||||||
if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
|
if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
|
||||||
|
@ -310,7 +310,7 @@ remove_method(klass, mid)
|
||||||
if (klass == rb_cObject) {
|
if (klass == rb_cObject) {
|
||||||
rb_secure(4);
|
rb_secure(4);
|
||||||
}
|
}
|
||||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
|
if (ruby_safe_level >= 4 && !OBJ_TAINTED(klass)) {
|
||||||
rb_raise(rb_eSecurityError, "Insecure: can't remove method");
|
rb_raise(rb_eSecurityError, "Insecure: can't remove method");
|
||||||
}
|
}
|
||||||
if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
|
if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
|
||||||
|
@ -1588,7 +1588,7 @@ rb_undef(klass, id)
|
||||||
if (ruby_class == rb_cObject) {
|
if (ruby_class == rb_cObject) {
|
||||||
rb_secure(4);
|
rb_secure(4);
|
||||||
}
|
}
|
||||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
|
if (ruby_safe_level >= 4 && !OBJ_TAINTED(klass)) {
|
||||||
rb_raise(rb_eSecurityError, "Insecure: can't undef");
|
rb_raise(rb_eSecurityError, "Insecure: can't undef");
|
||||||
if (id == __id__ || id == __send__ || id == init) {
|
if (id == __id__ || id == __send__ || id == init) {
|
||||||
rb_name_error(id, "undefining `%s' prohibited", rb_id2name(id));
|
rb_name_error(id, "undefining `%s' prohibited", rb_id2name(id));
|
||||||
|
@ -3166,7 +3166,7 @@ rb_eval(self, n)
|
||||||
VALUE klass;
|
VALUE klass;
|
||||||
NODE *body = 0, *defn;
|
NODE *body = 0, *defn;
|
||||||
|
|
||||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(recv)) {
|
if (ruby_safe_level >= 4 && !OBJ_TAINTED(recv)) {
|
||||||
rb_raise(rb_eSecurityError, "Insecure: can't define singleton method");
|
rb_raise(rb_eSecurityError, "Insecure: can't define singleton method");
|
||||||
}
|
}
|
||||||
if (FIXNUM_P(recv) || SYMBOL_P(recv)) {
|
if (FIXNUM_P(recv) || SYMBOL_P(recv)) {
|
||||||
|
@ -3179,7 +3179,7 @@ rb_eval(self, n)
|
||||||
if (OBJ_FROZEN(recv)) rb_error_frozen("object");
|
if (OBJ_FROZEN(recv)) rb_error_frozen("object");
|
||||||
klass = rb_singleton_class(recv);
|
klass = rb_singleton_class(recv);
|
||||||
if (st_lookup(RCLASS(klass)->m_tbl, node->nd_mid, &body)) {
|
if (st_lookup(RCLASS(klass)->m_tbl, node->nd_mid, &body)) {
|
||||||
if (rb_safe_level() >= 4) {
|
if (ruby_safe_level >= 4) {
|
||||||
rb_raise(rb_eSecurityError, "redefining method prohibited");
|
rb_raise(rb_eSecurityError, "redefining method prohibited");
|
||||||
}
|
}
|
||||||
if (RTEST(ruby_verbose)) {
|
if (RTEST(ruby_verbose)) {
|
||||||
|
@ -3248,7 +3248,7 @@ rb_eval(self, n)
|
||||||
goto override_class;
|
goto override_class;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rb_safe_level() >= 4) {
|
if (ruby_safe_level >= 4) {
|
||||||
rb_raise(rb_eSecurityError, "extending class prohibited");
|
rb_raise(rb_eSecurityError, "extending class prohibited");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3288,7 +3288,7 @@ rb_eval(self, n)
|
||||||
rb_raise(rb_eTypeError, "%s is not a module",
|
rb_raise(rb_eTypeError, "%s is not a module",
|
||||||
rb_id2name(node->nd_cname));
|
rb_id2name(node->nd_cname));
|
||||||
}
|
}
|
||||||
if (rb_safe_level() >= 4) {
|
if (ruby_safe_level >= 4) {
|
||||||
rb_raise(rb_eSecurityError, "extending module prohibited");
|
rb_raise(rb_eSecurityError, "extending module prohibited");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3315,7 +3315,7 @@ rb_eval(self, n)
|
||||||
rb_raise(rb_eTypeError, "no virtual class for %s",
|
rb_raise(rb_eTypeError, "no virtual class for %s",
|
||||||
rb_class2name(CLASS_OF(result)));
|
rb_class2name(CLASS_OF(result)));
|
||||||
}
|
}
|
||||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(result))
|
if (ruby_safe_level >= 4 && !OBJ_TAINTED(result))
|
||||||
rb_raise(rb_eSecurityError, "Insecure: can't extend object");
|
rb_raise(rb_eSecurityError, "Insecure: can't extend object");
|
||||||
klass = rb_singleton_class(result);
|
klass = rb_singleton_class(result);
|
||||||
|
|
||||||
|
@ -5603,7 +5603,7 @@ static void
|
||||||
secure_visibility(self)
|
secure_visibility(self)
|
||||||
VALUE self;
|
VALUE self;
|
||||||
{
|
{
|
||||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(self)) {
|
if (ruby_safe_level >= 4 && !OBJ_TAINTED(self)) {
|
||||||
rb_raise(rb_eSecurityError, "Insecure: can't change method visibility");
|
rb_raise(rb_eSecurityError, "Insecure: can't change method visibility");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6315,7 +6315,7 @@ proc_save_safe_level(data)
|
||||||
VALUE data;
|
VALUE data;
|
||||||
{
|
{
|
||||||
if (OBJ_TAINTED(data)) {
|
if (OBJ_TAINTED(data)) {
|
||||||
switch (rb_safe_level()) {
|
switch (ruby_safe_level) {
|
||||||
case 3:
|
case 3:
|
||||||
FL_SET(data, PROC_T3);
|
FL_SET(data, PROC_T3);
|
||||||
break;
|
break;
|
||||||
|
@ -6323,7 +6323,7 @@ proc_save_safe_level(data)
|
||||||
FL_SET(data, PROC_T4);
|
FL_SET(data, PROC_T4);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (rb_safe_level() > 4) {
|
if (ruby_safe_level > 4) {
|
||||||
FL_SET(data, PROC_TMAX);
|
FL_SET(data, PROC_TMAX);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -6621,8 +6621,8 @@ block_pass(self, node)
|
||||||
block = b;
|
block = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rb_safe_level() >= 1 && OBJ_TAINTED(block)) {
|
if (ruby_safe_level >= 1 && OBJ_TAINTED(block)) {
|
||||||
if (rb_safe_level() > proc_get_safe_level(block)) {
|
if (ruby_safe_level > proc_get_safe_level(block)) {
|
||||||
rb_raise(rb_eSecurityError, "Insecure: tainted block value");
|
rb_raise(rb_eSecurityError, "Insecure: tainted block value");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8316,7 +8316,7 @@ rb_thread_safe_level(thread)
|
||||||
|
|
||||||
th = rb_thread_check(thread);
|
th = rb_thread_check(thread);
|
||||||
if (th == curr_thread) {
|
if (th == curr_thread) {
|
||||||
return INT2NUM(rb_safe_level());
|
return INT2NUM(ruby_safe_level);
|
||||||
}
|
}
|
||||||
return INT2NUM(th->safe);
|
return INT2NUM(th->safe);
|
||||||
}
|
}
|
||||||
|
@ -8859,7 +8859,7 @@ rb_thread_local_aref(thread, id)
|
||||||
VALUE val;
|
VALUE val;
|
||||||
|
|
||||||
th = rb_thread_check(thread);
|
th = rb_thread_check(thread);
|
||||||
if (rb_safe_level() >= 4 && th != curr_thread) {
|
if (ruby_safe_level >= 4 && th != curr_thread) {
|
||||||
rb_raise(rb_eSecurityError, "Insecure: thread locals");
|
rb_raise(rb_eSecurityError, "Insecure: thread locals");
|
||||||
}
|
}
|
||||||
if (!th->locals) return Qnil;
|
if (!th->locals) return Qnil;
|
||||||
|
@ -8884,7 +8884,7 @@ rb_thread_local_aset(thread, id, val)
|
||||||
{
|
{
|
||||||
rb_thread_t th = rb_thread_check(thread);
|
rb_thread_t th = rb_thread_check(thread);
|
||||||
|
|
||||||
if (rb_safe_level() >= 4 && th != curr_thread) {
|
if (ruby_safe_level >= 4 && th != curr_thread) {
|
||||||
rb_raise(rb_eSecurityError, "Insecure: can't modify thread locals");
|
rb_raise(rb_eSecurityError, "Insecure: can't modify thread locals");
|
||||||
}
|
}
|
||||||
if (OBJ_FROZEN(thread)) rb_error_frozen("thread locals");
|
if (OBJ_FROZEN(thread)) rb_error_frozen("thread locals");
|
||||||
|
|
4
file.c
4
file.c
|
@ -2482,6 +2482,10 @@ rb_find_file(path)
|
||||||
if (file_load_ok(f)) return path;
|
if (file_load_ok(f)) return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rb_safe_level() >= 4) {
|
||||||
|
rb_raise(rb_eSecurityError, "loading from non-absolute path %s", f);
|
||||||
|
}
|
||||||
|
|
||||||
if (rb_load_path) {
|
if (rb_load_path) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
18
numeric.c
18
numeric.c
|
@ -788,6 +788,7 @@ num_step(argc, argv, from)
|
||||||
while (i <= end) {
|
while (i <= end) {
|
||||||
rb_yield(INT2FIX(i));
|
rb_yield(INT2FIX(i));
|
||||||
i += diff;
|
i += diff;
|
||||||
|
printf("<<%g>>\n", i - end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -798,21 +799,16 @@ num_step(argc, argv, from)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (TYPE(from) == T_FLOAT || TYPE(to) == T_FLOAT || TYPE(step) == T_FLOAT) {
|
else if (TYPE(from) == T_FLOAT || TYPE(to) == T_FLOAT || TYPE(step) == T_FLOAT) {
|
||||||
|
const double epsilon = 2.2204460492503131E-16;
|
||||||
double beg = NUM2DBL(from);
|
double beg = NUM2DBL(from);
|
||||||
double end = NUM2DBL(to);
|
double end = NUM2DBL(to);
|
||||||
double unit = NUM2DBL(step);
|
double unit = NUM2DBL(step);
|
||||||
double n = beg;
|
double n = (end - beg)/unit;
|
||||||
long i = 0;
|
long i;
|
||||||
|
|
||||||
if (unit > 0) {
|
n = floor(n + n*epsilon) + 1;
|
||||||
for (i=0; n<=end; i++, n=beg+unit*i) {
|
for (i=0; i<n; i++) {
|
||||||
rb_yield(rb_float_new(n));
|
rb_yield(rb_float_new(i*unit+beg));
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (i=0; n>=end; i++, n=beg+unit*i) {
|
|
||||||
rb_yield(rb_float_new(n));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
111
range.c
111
range.c
|
@ -75,7 +75,7 @@ range_initialize(argc, argv, obj)
|
||||||
rb_scan_args(argc, argv, "21", &beg, &end, &flags);
|
rb_scan_args(argc, argv, "21", &beg, &end, &flags);
|
||||||
/* Ranges are immutable, so that they should be initialized only once. */
|
/* Ranges are immutable, so that they should be initialized only once. */
|
||||||
if (rb_ivar_defined(obj, id_beg)) {
|
if (rb_ivar_defined(obj, id_beg)) {
|
||||||
rb_name_error(rb_intern("initialized"), "`initialize' called twice");
|
rb_name_error(rb_intern("initialize"), "`initialize' called twice");
|
||||||
}
|
}
|
||||||
range_init(obj, beg, end, RTEST(flags));
|
range_init(obj, beg, end, RTEST(flags));
|
||||||
return Qnil;
|
return Qnil;
|
||||||
|
@ -230,59 +230,6 @@ range_hash(range, obj)
|
||||||
return INT2FIX(hash);
|
return INT2FIX(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
|
||||||
range_each(range)
|
|
||||||
VALUE range;
|
|
||||||
{
|
|
||||||
VALUE b, e;
|
|
||||||
|
|
||||||
b = rb_ivar_get(range, id_beg);
|
|
||||||
e = rb_ivar_get(range, id_end);
|
|
||||||
|
|
||||||
if (FIXNUM_P(b) && FIXNUM_P(e)) { /* fixnums are special */
|
|
||||||
long end = FIX2LONG(e);
|
|
||||||
long i;
|
|
||||||
|
|
||||||
if (!EXCL(range)) end += 1;
|
|
||||||
for (i=FIX2LONG(b); i<end; i++) {
|
|
||||||
rb_yield(INT2NUM(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (TYPE(b) == T_STRING) {
|
|
||||||
rb_str_upto(b, e, EXCL(range));
|
|
||||||
}
|
|
||||||
else if (rb_obj_is_kind_of(b, rb_cNumeric)) {
|
|
||||||
b = rb_Integer(b);
|
|
||||||
e = rb_Integer(e);
|
|
||||||
|
|
||||||
if (!EXCL(range)) e = rb_funcall(e, '+', 1, INT2FIX(1));
|
|
||||||
while (RTEST(rb_funcall(b, '<', 1, e))) {
|
|
||||||
rb_yield(b);
|
|
||||||
b = rb_funcall(b, '+', 1, INT2FIX(1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { /* generic each */
|
|
||||||
VALUE v = b;
|
|
||||||
|
|
||||||
if (EXCL(range)) {
|
|
||||||
while (r_lt(v, e)) {
|
|
||||||
if (r_eq(v, e)) break;
|
|
||||||
rb_yield(v);
|
|
||||||
v = rb_funcall(v, id_succ, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
while (r_le(v, e)) {
|
|
||||||
rb_yield(v);
|
|
||||||
if (r_eq(v, e)) break;
|
|
||||||
v = rb_funcall(v, id_succ, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return range;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
r_step_str(args)
|
r_step_str(args)
|
||||||
VALUE *args;
|
VALUE *args;
|
||||||
|
@ -313,26 +260,52 @@ range_step(argc, argv, range)
|
||||||
|
|
||||||
b = rb_ivar_get(range, id_beg);
|
b = rb_ivar_get(range, id_beg);
|
||||||
e = rb_ivar_get(range, id_end);
|
e = rb_ivar_get(range, id_end);
|
||||||
rb_scan_args(argc, argv, "01", &step);
|
if (rb_scan_args(argc, argv, "01", &step) == 0) {
|
||||||
|
step = INT2FIX(1);
|
||||||
|
}
|
||||||
|
|
||||||
if (FIXNUM_P(b) && FIXNUM_P(e)) { /* fixnums are special */
|
if (FIXNUM_P(b) && FIXNUM_P(e)) { /* fixnums are special */
|
||||||
long end = FIX2LONG(e);
|
long beg = FIX2LONG(b), end = FIX2LONG(e), s = NUM2LONG(step);
|
||||||
long i, s = (argc == 0) ? 1 : NUM2LONG(step);
|
long i;
|
||||||
|
if (s <= 0) {
|
||||||
if (!EXCL(range)) end += 1;
|
rb_raise(rb_eArgError, "step can't be <= 0");
|
||||||
for (i=FIX2LONG(b); i<end; i+=s) {
|
}
|
||||||
rb_yield(INT2NUM(i));
|
if ((end - beg) < 0) {
|
||||||
|
if (!EXCL(range)) end -= 1;
|
||||||
|
for (i=beg; i>end; i-=s) {
|
||||||
|
rb_yield(LONG2NUM(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!EXCL(range)) end += 1;
|
||||||
|
for (i=beg; i<end; i+=s) {
|
||||||
|
rb_yield(INT2NUM(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (rb_obj_is_kind_of(b, rb_cNumeric)) {
|
else if (rb_obj_is_kind_of(b, rb_cNumeric)) {
|
||||||
|
VALUE diff;
|
||||||
b = rb_Integer(b);
|
b = rb_Integer(b);
|
||||||
e = rb_Integer(e);
|
e = rb_Integer(e);
|
||||||
step = rb_Integer(step);
|
step = rb_Integer(step);
|
||||||
|
|
||||||
if (!EXCL(range)) e = rb_funcall(e, '+', 1, INT2FIX(1));
|
if (RTEST(rb_funcall(step, rb_intern("<="), 1, INT2FIX(0)))) {
|
||||||
while (RTEST(rb_funcall(b, '<', 1, e))) {
|
rb_raise(rb_eArgError, "step can't be <= 0");
|
||||||
rb_yield(b);
|
}
|
||||||
b = rb_funcall(b, '+', 1, step);
|
diff = rb_funcall(e, '-', 1, b);
|
||||||
|
if (RTEST(rb_funcall(diff, '<', 1, INT2FIX(0)))) {
|
||||||
|
if (!EXCL(range)) e = rb_funcall(e, '-', 1, INT2FIX(1));
|
||||||
|
while (RTEST(rb_funcall(b, '>', 1, e))) {
|
||||||
|
rb_yield(b);
|
||||||
|
b = rb_funcall(b, '-', 1, step);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!EXCL(range)) e = rb_funcall(e, '+', 1, INT2FIX(1));
|
||||||
|
while (RTEST(rb_funcall(b, '<', 1, e))) {
|
||||||
|
rb_yield(b);
|
||||||
|
b = rb_funcall(b, '+', 1, step);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (TYPE(b) == T_STRING) {
|
else if (TYPE(b) == T_STRING) {
|
||||||
|
@ -366,10 +339,16 @@ range_step(argc, argv, range)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
range_each(range)
|
||||||
|
VALUE range;
|
||||||
|
{
|
||||||
|
return range_step(0, NULL, range);
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
range_first(obj)
|
range_first(obj)
|
||||||
VALUE obj;
|
VALUE obj;
|
||||||
|
|
41
re.c
41
re.c
|
@ -861,7 +861,8 @@ match_to_a(match)
|
||||||
for (i=0; i<regs->num_regs; i++) {
|
for (i=0; i<regs->num_regs; i++) {
|
||||||
if (regs->beg[i] == -1) {
|
if (regs->beg[i] == -1) {
|
||||||
rb_ary_push(ary, Qnil);
|
rb_ary_push(ary, Qnil);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
VALUE str = rb_str_new(ptr+regs->beg[i], regs->end[i]-regs->beg[i]);
|
VALUE str = rb_str_new(ptr+regs->beg[i], regs->end[i]-regs->beg[i]);
|
||||||
if (taint) OBJ_TAINT(str);
|
if (taint) OBJ_TAINT(str);
|
||||||
rb_ary_push(ary, str);
|
rb_ary_push(ary, str);
|
||||||
|
@ -1170,6 +1171,7 @@ rb_reg_s_quote(argc, argv)
|
||||||
int kcode_saved = reg_kcode;
|
int kcode_saved = reg_kcode;
|
||||||
char *s, *send, *t;
|
char *s, *send, *t;
|
||||||
VALUE tmp;
|
VALUE tmp;
|
||||||
|
int c;
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "11", &str, &kcode);
|
rb_scan_args(argc, argv, "11", &str, &kcode);
|
||||||
if (!NIL_P(kcode)) {
|
if (!NIL_P(kcode)) {
|
||||||
|
@ -1184,24 +1186,41 @@ rb_reg_s_quote(argc, argv)
|
||||||
t = RSTRING(tmp)->ptr;
|
t = RSTRING(tmp)->ptr;
|
||||||
|
|
||||||
for (; s < send; s++) {
|
for (; s < send; s++) {
|
||||||
if (ismbchar(*s)) {
|
c = *s;
|
||||||
int n = mbclen(*s);
|
if (ismbchar(c)) {
|
||||||
|
int n = mbclen(c);
|
||||||
|
|
||||||
while (n-- && s < send)
|
while (n-- && s < send)
|
||||||
*t++ = *s++;
|
*t++ = *s++;
|
||||||
s--;
|
s--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (*s == '[' || *s == ']'
|
switch (c) {
|
||||||
|| *s == '{' || *s == '}'
|
case '\t':
|
||||||
|| *s == '(' || *s == ')'
|
c = 't';
|
||||||
|| *s == '|' || *s == '-'
|
|
||||||
|| *s == '*' || *s == '.' || *s == '\\'
|
|
||||||
|| *s == '?' || *s == '+'
|
|
||||||
|| *s == '^' || *s == '$') {
|
|
||||||
*t++ = '\\';
|
*t++ = '\\';
|
||||||
|
break;
|
||||||
|
case '\f':
|
||||||
|
c = 'f';
|
||||||
|
*t++ = '\\';
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
c = 'r';
|
||||||
|
*t++ = '\\';
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
c = 'n';
|
||||||
|
*t++ = '\\';
|
||||||
|
break;
|
||||||
|
case '[': case ']': case '{': case '}':
|
||||||
|
case '(': case ')': case '|': case '-':
|
||||||
|
case '*': case '.': case '\\':
|
||||||
|
case '?': case '+': case '^': case '$':
|
||||||
|
case ' ':
|
||||||
|
*t++ = '\\';
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
*t++ = *s;
|
*t++ = c;
|
||||||
}
|
}
|
||||||
kcode_reset_option();
|
kcode_reset_option();
|
||||||
rb_str_resize(tmp, t - RSTRING(tmp)->ptr);
|
rb_str_resize(tmp, t - RSTRING(tmp)->ptr);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче