summaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2004-09-22 04:47:37 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2004-09-22 04:47:37 +0000
commit9dcc08646f0a26b61ae162daffeb0ce5fbc60f0e (patch)
treebf615848ad985f59c4154afcc05d8765506ddb51 /hash.c
parent94fe90346327efaea9c7dff75ea9ff0ed5a6ed04 (diff)
* 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
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/hash.c b/hash.c
index 89666ca831..4485305024 100644
--- a/hash.c
+++ b/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;
}