diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-09-21 09:35:29 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-09-21 09:35:29 +0000 |
commit | ba19ba779cc232474d75eb190e7420bf667832dc (patch) | |
tree | ac9f317f71df73b44ce9a4b0b485f6df646d44bc /array.c | |
parent | de5a85496ac4ae7bd24b5fc7acb8001a5e4d8b7d (diff) |
* array.c (rb_ary_uniq_bang): element size might change during
comparison. [ruby-dev:24298]
* enum.c (enum_sort_by): do not use qsort directly. use
rb_ary_sort_bang() instead. [ruby-dev:24291]
* enum.c (enum_sort_by): pedantic type check added.
[ruby-dev:24291]
* hash.c (rb_hash_foreach_iter): check iter_lev after each
iteration. [ruby-dev:24289]
* array.c (rb_ary_and): element size might change during
comparison. [ruby-dev:24290]
* array.c (rb_ary_or): ditto. [ruby-dev:24292]
* array.c (rb_ary_equal): wrong fix. [ruby-dev:24286]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@6940 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'array.c')
-rw-r--r-- | array.c | 94 |
1 files changed, 63 insertions, 31 deletions
@@ -561,23 +561,30 @@ rb_ary_unshift_m(argc, argv, ary) return ary; } -VALUE -rb_ary_entry(ary, offset) +/* faster version - use this if you don't need to treat negative offset */ +static inline VALUE +rb_ary_elt(ary, offset) VALUE ary; long offset; { if (RARRAY(ary)->len == 0) return Qnil; - - if (offset < 0) { - offset += RARRAY(ary)->len; - } if (offset < 0 || RARRAY(ary)->len <= offset) { return Qnil; } - return RARRAY(ary)->ptr[offset]; } +VALUE +rb_ary_entry(ary, offset) + VALUE ary; + long offset; +{ + if (offset < 0) { + offset += RARRAY(ary)->len; + } + return rb_ary_elt(ary, offset); +} + static VALUE rb_ary_subseq(ary, beg, len) VALUE ary; @@ -857,6 +864,10 @@ rb_ary_index(ary, val) * array.rindex(obj) -> int or nil * * Returns the index of the last object in <i>array</i> + if (i > RARRAY(ary)->len) { + i = RARRAY(ary)->len; + continue; + } * <code>==</code> to <i>obj</i>. Returns <code>nil</code> if * no match is found. * @@ -1533,17 +1544,36 @@ rb_ary_reverse_m(ary) return rb_ary_reverse(rb_ary_dup(ary)); } +struct ary_sort_data { + VALUE ary; + VALUE *ptr; + long len; +}; + +static void +ary_sort_check(data) + struct ary_sort_data *data; +{ + if (RARRAY(data->ary)->ptr != data->ptr || RARRAY(data->ary)->len != data->len) { + rb_raise(rb_eArgError, "array modified during sort"); + } +} + static int -sort_1(a, b) +sort_1(a, b, data) VALUE *a, *b; + struct ary_sort_data *data; { VALUE retval = rb_yield_values(2, *a, *b); + + ary_sort_check(data); return rb_cmpint(retval, *a, *b); } static int -sort_2(ap, bp) +sort_2(ap, bp, data) VALUE *ap, *bp; + struct ary_sort_data *data; { VALUE retval; long a = (long)*ap, b = (long)*bp; @@ -1558,6 +1588,7 @@ sort_2(ap, bp) } retval = rb_funcall(a, id_cmp, 1, b); + ary_sort_check(data); return rb_cmpint(retval, a, b); } @@ -1565,8 +1596,12 @@ static VALUE sort_internal(ary) VALUE ary; { + struct ary_sort_data data; + + data.ary = ary; + data.ptr = RARRAY(ary)->ptr; data.len = RARRAY(ary)->len; qsort(RARRAY(ary)->ptr, RARRAY(ary)->len, sizeof(VALUE), - rb_block_given_p()?sort_1:sort_2); + rb_block_given_p()?sort_1:sort_2, &data); return ary; } @@ -1775,7 +1810,7 @@ rb_ary_select(argc, argv, ary) result = rb_ary_new2(RARRAY(ary)->len); for (i = 0; i < RARRAY(ary)->len; i++) { if (RTEST(rb_yield(RARRAY(ary)->ptr[i]))) { - rb_ary_push(result, rb_ary_entry(ary, i)); + rb_ary_push(result, rb_ary_elt(ary, i)); } } return result; @@ -2038,9 +2073,9 @@ rb_ary_zip(argc, argv, ary) for (i=0; i<RARRAY(ary)->len; i++) { VALUE tmp = rb_ary_new2(argc+1); - rb_ary_push(tmp, rb_ary_entry(ary, i)); + rb_ary_push(tmp, rb_ary_elt(ary, i)); for (j=0; j<argc; j++) { - rb_ary_push(tmp, rb_ary_entry(argv[j], i)); + rb_ary_push(tmp, rb_ary_elt(argv[j], i)); } rb_yield(tmp); } @@ -2051,9 +2086,9 @@ rb_ary_zip(argc, argv, ary) for (i=0; i<len; i++) { VALUE tmp = rb_ary_new2(argc+1); - rb_ary_push(tmp, rb_ary_entry(ary, i)); + rb_ary_push(tmp, rb_ary_elt(ary, i)); for (j=0; j<argc; j++) { - rb_ary_push(tmp, rb_ary_entry(argv[j], i)); + rb_ary_push(tmp, rb_ary_elt(argv[j], i)); } rb_ary_push(result, tmp); } @@ -2081,7 +2116,7 @@ rb_ary_transpose(ary) alen = RARRAY(ary)->len; if (alen == 0) return rb_ary_dup(ary); for (i=0; i<alen; i++) { - tmp = to_ary(rb_ary_entry(ary, i)); + tmp = to_ary(rb_ary_elt(ary, i)); if (elen < 0) { /* first element */ elen = RARRAY(tmp)->len; result = rb_ary_new2(elen); @@ -2094,7 +2129,7 @@ rb_ary_transpose(ary) RARRAY(tmp)->len, elen); } for (j=0; j<elen; j++) { - rb_ary_store(rb_ary_entry(result, j), i, rb_ary_entry(tmp, j)); + rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j)); } } return result; @@ -2441,7 +2476,7 @@ rb_ary_equal(ary1, ary2) } for (i=0; i<RARRAY(ary1)->len; i++) { if (RARRAY(ary1)->len != RARRAY(ary2)->len) return Qfalse; - if (!rb_equal(RARRAY(ary1)->ptr[i], RARRAY(ary2)->ptr[i])) + if (!rb_equal(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i))) return Qfalse; } return Qtrue; @@ -2640,7 +2675,7 @@ rb_ary_and(ary1, ary2) for (i=0; i<RARRAY(ary1)->len; i++) { VALUE v = RARRAY(ary1)->ptr[i]; if (st_delete(RHASH(hash)->tbl, (st_data_t*)&v, 0)) { - rb_ary_push(ary3, RARRAY(ary1)->ptr[i]); + rb_ary_push(ary3, rb_ary_elt(ary1, i)); } } @@ -2671,15 +2706,15 @@ rb_ary_or(ary1, ary2) hash = ary_make_hash(ary1, ary2); for (i=0; i<RARRAY(ary1)->len; i++) { - v = RARRAY(ary1)->ptr[i]; + v = rb_ary_elt(ary1, i); if (st_delete(RHASH(hash)->tbl, (st_data_t*)&v, 0)) { - rb_ary_push(ary3, RARRAY(ary1)->ptr[i]); + rb_ary_push(ary3, v); } } for (i=0; i<RARRAY(ary2)->len; i++) { - v = RARRAY(ary2)->ptr[i]; + v = rb_ary_elt(ary2, i); if (st_delete(RHASH(hash)->tbl, (st_data_t*)&v, 0)) { - rb_ary_push(ary3, RARRAY(ary2)->ptr[i]); + rb_ary_push(ary3, v); } } return ary3; @@ -2704,7 +2739,7 @@ rb_ary_uniq_bang(ary) VALUE ary; { VALUE hash; - VALUE *p, *q, *end; + long i, j; rb_ary_modify(ary); @@ -2713,16 +2748,13 @@ rb_ary_uniq_bang(ary) if (RARRAY(ary)->len == RHASH(hash)->tbl->num_entries) { return Qnil; } - p = q = RARRAY(ary)->ptr; - end = p + RARRAY(ary)->len; - while (p < end) { - VALUE v = *p; + for (i=j=0; i<RARRAY(ary)->len; i++) { + VALUE v = rb_ary_elt(ary, i); if (st_delete(RHASH(hash)->tbl, (st_data_t*)&v, 0)) { - *q++ = *p; + rb_ary_store(ary, j++, v); } - p++; } - RARRAY(ary)->len = (q - RARRAY(ary)->ptr); + RARRAY(ary)->len = j; return ary; } |