diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-05-01 09:41:50 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-05-01 09:41:50 +0000 |
commit | 4fa0cdea7838a12afac492ee58af7f30660c6a8f (patch) | |
tree | 30895168554835060498505a41c9f5e72c4cddea | |
parent | ca55fe4f0d1477f9b2b14793468c370ebbb96ea7 (diff) | |
download | ruby-4fa0cdea7838a12afac492ee58af7f30660c6a8f.tar.gz |
* 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
-rw-r--r-- | ChangeLog | 26 | ||||
-rw-r--r-- | enum.c | 27 | ||||
-rw-r--r-- | eval.c | 32 | ||||
-rw-r--r-- | file.c | 4 | ||||
-rw-r--r-- | numeric.c | 18 | ||||
-rw-r--r-- | range.c | 111 | ||||
-rw-r--r-- | re.c | 41 |
7 files changed, 155 insertions, 104 deletions
@@ -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> * 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> * ext/dl/ptr.c (cary2ary): missing break in switch statements. @@ -217,6 +217,32 @@ enum_inject(argc, argv, obj) } 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 enum_sort(obj) VALUE obj; { @@ -475,6 +501,7 @@ Init_Enumerable() rb_define_method(rb_mEnumerable,"collect", 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,"partition", enum_partition, 0); rb_define_method(rb_mEnumerable,"all?", enum_all, 0); rb_define_method(rb_mEnumerable,"any?", enum_any, 0); rb_define_method(rb_mEnumerable,"min", enum_min, 0); @@ -227,7 +227,7 @@ rb_add_method(klass, mid, node, noex) NODE *body; 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"); } if (OBJ_FROZEN(klass)) rb_error_frozen("class/module"); @@ -310,7 +310,7 @@ remove_method(klass, mid) if (klass == rb_cObject) { 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"); } if (OBJ_FROZEN(klass)) rb_error_frozen("class/module"); @@ -1588,7 +1588,7 @@ rb_undef(klass, id) if (ruby_class == rb_cObject) { 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"); if (id == __id__ || id == __send__ || id == init) { rb_name_error(id, "undefining `%s' prohibited", rb_id2name(id)); @@ -3166,7 +3166,7 @@ rb_eval(self, n) VALUE klass; 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"); } if (FIXNUM_P(recv) || SYMBOL_P(recv)) { @@ -3179,7 +3179,7 @@ rb_eval(self, n) if (OBJ_FROZEN(recv)) rb_error_frozen("object"); klass = rb_singleton_class(recv); 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"); } if (RTEST(ruby_verbose)) { @@ -3248,7 +3248,7 @@ rb_eval(self, n) goto override_class; } } - if (rb_safe_level() >= 4) { + if (ruby_safe_level >= 4) { 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_id2name(node->nd_cname)); } - if (rb_safe_level() >= 4) { + if (ruby_safe_level >= 4) { 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_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"); klass = rb_singleton_class(result); @@ -5603,7 +5603,7 @@ static void secure_visibility(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"); } } @@ -6315,7 +6315,7 @@ proc_save_safe_level(data) VALUE data; { if (OBJ_TAINTED(data)) { - switch (rb_safe_level()) { + switch (ruby_safe_level) { case 3: FL_SET(data, PROC_T3); break; @@ -6323,7 +6323,7 @@ proc_save_safe_level(data) FL_SET(data, PROC_T4); break; default: - if (rb_safe_level() > 4) { + if (ruby_safe_level > 4) { FL_SET(data, PROC_TMAX); } break; @@ -6621,8 +6621,8 @@ block_pass(self, node) block = b; } - if (rb_safe_level() >= 1 && OBJ_TAINTED(block)) { - if (rb_safe_level() > proc_get_safe_level(block)) { + if (ruby_safe_level >= 1 && OBJ_TAINTED(block)) { + if (ruby_safe_level > proc_get_safe_level(block)) { rb_raise(rb_eSecurityError, "Insecure: tainted block value"); } } @@ -8316,7 +8316,7 @@ rb_thread_safe_level(thread) th = rb_thread_check(thread); if (th == curr_thread) { - return INT2NUM(rb_safe_level()); + return INT2NUM(ruby_safe_level); } return INT2NUM(th->safe); } @@ -8859,7 +8859,7 @@ rb_thread_local_aref(thread, id) VALUE val; 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"); } if (!th->locals) return Qnil; @@ -8884,7 +8884,7 @@ rb_thread_local_aset(thread, id, val) { 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"); } if (OBJ_FROZEN(thread)) rb_error_frozen("thread locals"); @@ -2482,6 +2482,10 @@ rb_find_file(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) { int i; @@ -788,6 +788,7 @@ num_step(argc, argv, from) while (i <= end) { rb_yield(INT2FIX(i)); i += diff; + printf("<<%g>>\n", i - end); } } else { @@ -798,21 +799,16 @@ num_step(argc, argv, from) } } 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 end = NUM2DBL(to); double unit = NUM2DBL(step); - double n = beg; - long i = 0; + double n = (end - beg)/unit; + long i; - if (unit > 0) { - for (i=0; n<=end; i++, n=beg+unit*i) { - rb_yield(rb_float_new(n)); - } - } - else { - for (i=0; n>=end; i++, n=beg+unit*i) { - rb_yield(rb_float_new(n)); - } + n = floor(n + n*epsilon) + 1; + for (i=0; i<n; i++) { + rb_yield(rb_float_new(i*unit+beg)); } } else { @@ -75,7 +75,7 @@ range_initialize(argc, argv, obj) rb_scan_args(argc, argv, "21", &beg, &end, &flags); /* Ranges are immutable, so that they should be initialized only once. */ 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)); return Qnil; @@ -231,59 +231,6 @@ range_hash(range, obj) } 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 r_step_str(args) VALUE *args; { @@ -313,26 +260,52 @@ range_step(argc, argv, range) b = rb_ivar_get(range, id_beg); 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 */ - long end = FIX2LONG(e); - long i, s = (argc == 0) ? 1 : NUM2LONG(step); - - if (!EXCL(range)) end += 1; - for (i=FIX2LONG(b); i<end; i+=s) { - rb_yield(INT2NUM(i)); + long beg = FIX2LONG(b), end = FIX2LONG(e), s = NUM2LONG(step); + long i; + if (s <= 0) { + rb_raise(rb_eArgError, "step can't be <= 0"); + } + 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)) { + VALUE diff; b = rb_Integer(b); e = rb_Integer(e); step = rb_Integer(step); - 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); + if (RTEST(rb_funcall(step, rb_intern("<="), 1, INT2FIX(0)))) { + rb_raise(rb_eArgError, "step can't be <= 0"); + } + 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) { @@ -366,11 +339,17 @@ range_step(argc, argv, range) } } } - return range; } static VALUE +range_each(range) + VALUE range; +{ + return range_step(0, NULL, range); +} + +static VALUE range_first(obj) VALUE obj; { @@ -861,7 +861,8 @@ match_to_a(match) for (i=0; i<regs->num_regs; i++) { if (regs->beg[i] == -1) { rb_ary_push(ary, Qnil); - } else { + } + else { VALUE str = rb_str_new(ptr+regs->beg[i], regs->end[i]-regs->beg[i]); if (taint) OBJ_TAINT(str); rb_ary_push(ary, str); @@ -1170,6 +1171,7 @@ rb_reg_s_quote(argc, argv) int kcode_saved = reg_kcode; char *s, *send, *t; VALUE tmp; + int c; rb_scan_args(argc, argv, "11", &str, &kcode); if (!NIL_P(kcode)) { @@ -1184,24 +1186,41 @@ rb_reg_s_quote(argc, argv) t = RSTRING(tmp)->ptr; for (; s < send; s++) { - if (ismbchar(*s)) { - int n = mbclen(*s); + c = *s; + if (ismbchar(c)) { + int n = mbclen(c); while (n-- && s < send) *t++ = *s++; s--; continue; } - if (*s == '[' || *s == ']' - || *s == '{' || *s == '}' - || *s == '(' || *s == ')' - || *s == '|' || *s == '-' - || *s == '*' || *s == '.' || *s == '\\' - || *s == '?' || *s == '+' - || *s == '^' || *s == '$') { + switch (c) { + case '\t': + c = '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(); rb_str_resize(tmp, t - RSTRING(tmp)->ptr); |