mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* hash.c (rb_hash_rehash): add iteration check. [ruby-dev:24301]
* st.c (st_foreach): add deep check. * array.c (rb_ary_collect_bang): element size might change during comparison. [ruby-dev:24300] * array.c (rb_ary_reject_bang): ditto. [ruby-dev:24300] * array.c (rb_ary_eql): ditto. [ruby-dev:24300] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@6949 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
94fe903463
commit
9dcc08646f
5 changed files with 61 additions and 17 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,9 @@
|
|||
Wed Sep 22 13:38:12 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* hash.c (rb_hash_rehash): add iteration check. [ruby-dev:24301]
|
||||
|
||||
* st.c (st_foreach): add deep check.
|
||||
|
||||
Wed Sep 22 13:06:14 2004 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||
|
||||
* win32/win32.c (rb_w32_call_handler): workaround for Ctrl-C.
|
||||
|
@ -7,6 +13,15 @@ Wed Sep 22 00:11:12 2004 Dave Thomas <dave@pragprog.com>
|
|||
|
||||
* process.c: Add documentation for fork()
|
||||
|
||||
Wed Sep 22 09:04:41 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* array.c (rb_ary_collect_bang): element size might change during
|
||||
comparison. [ruby-dev:24300]
|
||||
|
||||
* array.c (rb_ary_reject_bang): ditto. [ruby-dev:24300]
|
||||
|
||||
* array.c (rb_ary_eql): ditto. [ruby-dev:24300]
|
||||
|
||||
Tue Sep 21 18:29:49 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* array.c (rb_ary_equal): merge miss.
|
||||
|
|
12
array.c
12
array.c
|
@ -1717,7 +1717,7 @@ rb_ary_collect_bang(ary)
|
|||
|
||||
rb_ary_modify(ary);
|
||||
for (i = 0; i < RARRAY(ary)->len; i++) {
|
||||
RARRAY(ary)->ptr[i] = rb_yield(RARRAY(ary)->ptr[i]);
|
||||
rb_ary_store(ary, i, rb_yield(RARRAY(ary)->ptr[i]));
|
||||
}
|
||||
return ary;
|
||||
}
|
||||
|
@ -1983,14 +1983,16 @@ rb_ary_reject_bang(ary)
|
|||
|
||||
rb_ary_modify(ary);
|
||||
for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) {
|
||||
if (RTEST(rb_yield(RARRAY(ary)->ptr[i1]))) continue;
|
||||
VALUE v = RARRAY(ary)->ptr[i1];
|
||||
if (RTEST(rb_yield(v))) continue;
|
||||
if (i1 != i2) {
|
||||
RARRAY(ary)->ptr[i2] = RARRAY(ary)->ptr[i1];
|
||||
rb_ary_store(ary, i2, v);
|
||||
}
|
||||
i2++;
|
||||
}
|
||||
if (RARRAY(ary)->len == i2) return Qnil;
|
||||
RARRAY(ary)->len = i2;
|
||||
if (i2 < RARRAY(ary)->len)
|
||||
RARRAY(ary)->len = i2;
|
||||
|
||||
return ary;
|
||||
}
|
||||
|
@ -2497,7 +2499,7 @@ rb_ary_eql(ary1, ary2)
|
|||
if (TYPE(ary2) != T_ARRAY) return Qfalse;
|
||||
if (RARRAY(ary1)->len != RARRAY(ary2)->len) return Qfalse;
|
||||
for (i=0; i<RARRAY(ary1)->len; i++) {
|
||||
if (!rb_eql(RARRAY(ary1)->ptr[i], RARRAY(ary2)->ptr[i]))
|
||||
if (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
|
||||
return Qfalse;
|
||||
}
|
||||
return Qtrue;
|
||||
|
|
33
hash.c
33
hash.c
|
@ -121,24 +121,33 @@ struct rb_hash_foreach_arg {
|
|||
};
|
||||
|
||||
static int
|
||||
rb_hash_foreach_iter(key, value, arg)
|
||||
rb_hash_foreach_iter(key, value, arg, err)
|
||||
VALUE key, value;
|
||||
struct rb_hash_foreach_arg *arg;
|
||||
int err;
|
||||
{
|
||||
int status;
|
||||
st_table *tbl = RHASH(arg->hash)->tbl;
|
||||
struct st_table_entry **bins = tbl->bins;
|
||||
st_table *tbl;
|
||||
|
||||
if (err) {
|
||||
rb_raise(rb_eRuntimeError, "hash modified during iteration");
|
||||
}
|
||||
tbl = RHASH(arg->hash)->tbl;
|
||||
if (key == Qundef) return ST_CONTINUE;
|
||||
status = (*arg->func)(key, value, arg->arg);
|
||||
if (RHASH(arg->hash)->tbl != tbl ||
|
||||
RHASH(arg->hash)->tbl->bins != bins) {
|
||||
rb_raise(rb_eIndexError, "rehash occurred during iteration");
|
||||
if (RHASH(arg->hash)->tbl != tbl) {
|
||||
rb_raise(rb_eRuntimeError, "rehash occurred during iteration");
|
||||
}
|
||||
if (RHASH(arg->hash)->iter_lev == 0) {
|
||||
rb_raise(rb_eArgError, "block re-entered");
|
||||
switch (status) {
|
||||
case ST_DELETE:
|
||||
st_delete_safe(tbl, (st_data_t*)&key, 0, Qundef);
|
||||
FL_SET(arg->hash, HASH_DELETED);
|
||||
case ST_CONTINUE:
|
||||
break;
|
||||
case ST_STOP:
|
||||
return ST_STOP;
|
||||
}
|
||||
return status;
|
||||
return ST_CHECK;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -836,8 +845,12 @@ static VALUE
|
|||
rb_hash_clear(hash)
|
||||
VALUE hash;
|
||||
{
|
||||
void *tmp;
|
||||
|
||||
rb_hash_modify(hash);
|
||||
st_foreach(RHASH(hash)->tbl, clear_i, 0);
|
||||
if (RHASH(hash)->tbl->num_entries > 0) {
|
||||
st_foreach(RHASH(hash)->tbl, clear_i, 0);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
|
16
st.c
16
st.c
|
@ -3,6 +3,7 @@
|
|||
/* static char sccsid[] = "@(#) st.c 5.1 89/12/14 Crucible"; */
|
||||
|
||||
#include "config.h"
|
||||
#include "defines.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -492,8 +493,21 @@ st_foreach(table, func, arg)
|
|||
for(i = 0; i < table->num_bins; i++) {
|
||||
last = 0;
|
||||
for(ptr = table->bins[i]; ptr != 0;) {
|
||||
retval = (*func)(ptr->key, ptr->record, arg);
|
||||
retval = (*func)(ptr->key, ptr->record, arg, 0);
|
||||
switch (retval) {
|
||||
case ST_CHECK: /* check if hash is modified during iteration */
|
||||
tmp = 0;
|
||||
if (i < table->num_bins) {
|
||||
for (tmp = table->bins[i]; tmp; tmp=tmp->next) {
|
||||
if (tmp == ptr) break;
|
||||
}
|
||||
}
|
||||
if (!tmp) {
|
||||
/* call func with error notice */
|
||||
retval = (*func)(0, 0, arg, 1);
|
||||
return;
|
||||
}
|
||||
/* fall through */
|
||||
case ST_CONTINUE:
|
||||
last = ptr;
|
||||
ptr = ptr->next;
|
||||
|
|
2
st.h
2
st.h
|
@ -25,7 +25,7 @@ struct st_table {
|
|||
|
||||
#define st_is_member(table,key) st_lookup(table,key,(st_data_t *)0)
|
||||
|
||||
enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE};
|
||||
enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK};
|
||||
|
||||
st_table *st_init_table(struct st_hash_type *);
|
||||
st_table *st_init_table_with_size(struct st_hash_type *, int);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue