summaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2004-09-29 05:15:33 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2004-09-29 05:15:33 +0000
commit30116ff8c286c91090722f4d6aada2cc47fcae7e (patch)
tree020bde425e972437d6945522f1d628236286e106 /hash.c
parentc0e71a8a97b907ab934d02d3cc4d9e55538a2e5f (diff)
* array.c (rb_ary_delete): comparison may change the capacity.
[ruby-dev:24348] * array.c (rb_ary_fill): fill should honor length argument. [ruby-dev:24346] * array.c (rb_ary_replace): should not use ptr from shared array. [ruby-dev:24345] * ext/socket/socket.c (s_accept): don't retry for EWOULDBLOCK. [ruby-talk:113807] * array.c (flatten): element size might change during comparison. [ruby-dev:24343] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6972 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c136
1 files changed, 87 insertions, 49 deletions
diff --git a/hash.c b/hash.c
index 3bde16eecf..13a6e26c6a 100644
--- a/hash.c
+++ b/hash.c
@@ -104,9 +104,47 @@ static struct st_hash_type objhash = {
rb_any_hash,
};
+struct foreach_safe_arg {
+ st_table *tbl;
+ int (*func)();
+ st_data_t arg;
+};
+
+static int
+foreach_safe_i(key, value, arg, err)
+ st_data_t key, value;
+ struct foreach_safe_arg *arg;
+{
+ int status;
+
+ if (err) {
+ rb_raise(rb_eRuntimeError, "hash modified during iteration");
+ }
+ if (key == Qundef) return ST_CONTINUE;
+ status = (*arg->func)(key, value, arg->arg, err);
+ if (status == ST_CONTINUE) {
+ return ST_CHECK;
+ }
+ return status;
+}
+
+void
+st_foreach_safe(table, func, a)
+ st_table *table;
+ int (*func)();
+ st_data_t a;
+{
+ struct foreach_safe_arg arg;
+
+ arg.tbl = table;
+ arg.func = func;
+ arg.arg = a;
+ st_foreach(table, foreach_safe_i, (st_data_t)&arg);
+}
+
struct hash_foreach_arg {
VALUE hash;
- enum st_retval (*func)();
+ int (*func)();
VALUE arg;
};
@@ -163,10 +201,10 @@ hash_foreach_call(arg)
return Qnil;
}
-static int
-hash_foreach(hash, func, farg)
+void
+rb_hash_foreach(hash, func, farg)
VALUE hash;
- enum st_retval (*func)();
+ int (*func)();
VALUE farg;
{
struct hash_foreach_arg arg;
@@ -175,7 +213,7 @@ hash_foreach(hash, func, farg)
arg.hash = hash;
arg.func = func;
arg.arg = farg;
- return rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash);
+ rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash);
}
static VALUE hash_alloc _((VALUE));
@@ -318,7 +356,7 @@ to_hash(hash)
return rb_convert_type(hash, T_HASH, "Hash", "to_hash");
}
-static enum st_retval
+static int
rb_hash_rehash_i(key, value, tbl)
VALUE key, value;
st_table *tbl;
@@ -358,7 +396,7 @@ rb_hash_rehash(hash)
}
rb_hash_modify(hash);
tbl = st_init_table_with_size(&objhash, RHASH(hash)->tbl->num_entries);
- hash_foreach(hash, rb_hash_rehash_i, (st_data_t)tbl);
+ rb_hash_foreach(hash, rb_hash_rehash_i, (st_data_t)tbl);
st_free_table(RHASH(hash)->tbl);
RHASH(hash)->tbl = tbl;
@@ -537,7 +575,7 @@ rb_hash_default_proc(hash)
return Qnil;
}
-static enum st_retval
+static int
key_i(key, value, args)
VALUE key, value;
VALUE *args;
@@ -570,7 +608,7 @@ rb_hash_key(hash, value)
args[0] = value;
args[1] = Qnil;
- hash_foreach(hash, key_i, (st_data_t)args);
+ rb_hash_foreach(hash, key_i, (st_data_t)args);
return args[1];
}
@@ -628,7 +666,7 @@ struct shift_var {
VALUE val;
};
-static enum st_retval
+static int
shift_i(key, value, var)
VALUE key, value;
struct shift_var *var;
@@ -662,7 +700,7 @@ rb_hash_shift(hash)
rb_hash_modify(hash);
var.stop = 0;
- hash_foreach(hash, shift_i, (st_data_t)&var);
+ rb_hash_foreach(hash, shift_i, (st_data_t)&var);
if (var.stop) {
return rb_assoc_new(var.key, var.val);
@@ -675,7 +713,7 @@ rb_hash_shift(hash)
}
}
-static enum st_retval
+static int
delete_if_i(key, value, hash)
VALUE key, value, hash;
{
@@ -703,7 +741,7 @@ rb_hash_delete_if(hash)
VALUE hash;
{
rb_hash_modify(hash);
- hash_foreach(hash, delete_if_i, hash);
+ rb_hash_foreach(hash, delete_if_i, hash);
return hash;
}
@@ -742,7 +780,7 @@ rb_hash_reject(hash)
return rb_hash_delete_if(rb_obj_dup(hash));
}
-static enum st_retval
+static int
select_i(key, value, result)
VALUE key, value, result;
{
@@ -798,11 +836,11 @@ rb_hash_select(hash)
VALUE result;
result = rb_ary_new();
- hash_foreach(hash, select_i, result);
+ rb_hash_foreach(hash, select_i, result);
return result;
}
-static enum st_retval
+static int
clear_i(key, value, dummy)
VALUE key, value, dummy;
{
@@ -828,7 +866,7 @@ rb_hash_clear(hash)
rb_hash_modify(hash);
if (RHASH(hash)->tbl->num_entries > 0) {
- hash_foreach(hash, clear_i, 0);
+ rb_hash_foreach(hash, clear_i, 0);
}
return hash;
@@ -866,7 +904,7 @@ rb_hash_aset(hash, key, val)
return val;
}
-static enum st_retval
+static int
replace_i(key, val, hash)
VALUE key, val, hash;
{
@@ -896,7 +934,7 @@ rb_hash_replace(hash, hash2)
hash2 = to_hash(hash2);
if (hash == hash2) return hash;
rb_hash_clear(hash);
- hash_foreach(hash2, replace_i, hash);
+ rb_hash_foreach(hash2, replace_i, hash);
RHASH(hash)->ifnone = RHASH(hash2)->ifnone;
if (FL_TEST(hash2, HASH_PROC_DEFAULT)) {
FL_SET(hash, HASH_PROC_DEFAULT);
@@ -948,7 +986,7 @@ rb_hash_empty_p(hash)
return Qfalse;
}
-static enum st_retval
+static int
each_value_i(key, value)
VALUE key, value;
{
@@ -977,11 +1015,11 @@ static VALUE
rb_hash_each_value(hash)
VALUE hash;
{
- hash_foreach(hash, each_value_i, 0);
+ rb_hash_foreach(hash, each_value_i, 0);
return hash;
}
-static enum st_retval
+static int
each_key_i(key, value)
VALUE key, value;
{
@@ -1009,11 +1047,11 @@ static VALUE
rb_hash_each_key(hash)
VALUE hash;
{
- hash_foreach(hash, each_key_i, 0);
+ rb_hash_foreach(hash, each_key_i, 0);
return hash;
}
-static enum st_retval
+static int
each_pair_i(key, value)
VALUE key, value;
{
@@ -1043,11 +1081,11 @@ static VALUE
rb_hash_each_pair(hash)
VALUE hash;
{
- hash_foreach(hash, each_pair_i, 0);
+ rb_hash_foreach(hash, each_pair_i, 0);
return hash;
}
-static enum st_retval
+static int
each_i(key, value)
VALUE key, value;
{
@@ -1080,11 +1118,11 @@ static VALUE
rb_hash_each(hash)
VALUE hash;
{
- hash_foreach(hash, each_i, 0);
+ rb_hash_foreach(hash, each_i, 0);
return hash;
}
-static enum st_retval
+static int
to_a_i(key, value, ary)
VALUE key, value, ary;
{
@@ -1111,7 +1149,7 @@ rb_hash_to_a(hash)
VALUE ary;
ary = rb_ary_new();
- hash_foreach(hash, to_a_i, ary);
+ rb_hash_foreach(hash, to_a_i, ary);
if (OBJ_TAINTED(hash)) OBJ_TAINT(ary);
return ary;
@@ -1141,7 +1179,7 @@ rb_hash_sort(hash)
return entries;
}
-static enum st_retval
+static int
inspect_i(key, value, str)
VALUE key, value, str;
{
@@ -1169,7 +1207,7 @@ inspect_hash(hash)
VALUE str;
str = rb_str_buf_new2("{");
- hash_foreach(hash, inspect_i, str);
+ rb_hash_foreach(hash, inspect_i, str);
rb_str_buf_cat2(str, "}");
OBJ_INFECT(str, hash);
@@ -1235,7 +1273,7 @@ rb_hash_to_hash(hash)
return hash;
}
-static enum st_retval
+static int
keys_i(key, value, ary)
VALUE key, value, ary;
{
@@ -1263,12 +1301,12 @@ rb_hash_keys(hash)
VALUE ary;
ary = rb_ary_new();
- hash_foreach(hash, keys_i, ary);
+ rb_hash_foreach(hash, keys_i, ary);
return ary;
}
-static enum st_retval
+static int
values_i(key, value, ary)
VALUE key, value, ary;
{
@@ -1296,7 +1334,7 @@ rb_hash_values(hash)
VALUE ary;
ary = rb_ary_new();
- hash_foreach(hash, values_i, ary);
+ rb_hash_foreach(hash, values_i, ary);
return ary;
}
@@ -1327,7 +1365,7 @@ rb_hash_has_key(hash, key)
return Qfalse;
}
-static enum st_retval
+static int
rb_hash_search_value(key, value, data)
VALUE key, value, *data;
{
@@ -1361,7 +1399,7 @@ rb_hash_has_value(hash, val)
data[0] = Qfalse;
data[1] = val;
- hash_foreach(hash, rb_hash_search_value, (st_data_t)data);
+ rb_hash_foreach(hash, rb_hash_search_value, (st_data_t)data);
return data[0];
}
@@ -1370,7 +1408,7 @@ struct equal_data {
st_table *tbl;
};
-static enum st_retval
+static int
equal_i(key, val1, data)
VALUE key, val1;
struct equal_data *data;
@@ -1413,7 +1451,7 @@ hash_equal(hash1, hash2, eql)
data.tbl = RHASH(hash2)->tbl;
data.result = Qtrue;
- hash_foreach(hash1, equal_i, (st_data_t)&data);
+ rb_hash_foreach(hash1, equal_i, (st_data_t)&data);
return data.result;
}
@@ -1460,7 +1498,7 @@ rb_hash_eql(hash1, hash2)
return hash_equal(hash1, hash2, Qtrue);
}
-static enum st_retval
+static int
rb_hash_invert_i(key, value, hash)
VALUE key, value;
VALUE hash;
@@ -1488,11 +1526,11 @@ rb_hash_invert(hash)
{
VALUE h = rb_hash_new();
- hash_foreach(hash, rb_hash_invert_i, h);
+ rb_hash_foreach(hash, rb_hash_invert_i, h);
return h;
}
-static enum st_retval
+static int
rb_hash_update_i(key, value, hash)
VALUE key, value;
VALUE hash;
@@ -1502,7 +1540,7 @@ rb_hash_update_i(key, value, hash)
return ST_CONTINUE;
}
-static enum st_retval
+static int
rb_hash_update_block_i(key, value, hash)
VALUE key, value;
VALUE hash;
@@ -1534,10 +1572,10 @@ rb_hash_update(hash1, hash2)
{
hash2 = to_hash(hash2);
if (rb_block_given_p()) {
- hash_foreach(hash2, rb_hash_update_block_i, hash1);
+ rb_hash_foreach(hash2, rb_hash_update_block_i, hash1);
}
else {
- hash_foreach(hash2, rb_hash_update_i, hash1);
+ rb_hash_foreach(hash2, rb_hash_update_i, hash1);
}
return hash1;
}
@@ -2273,7 +2311,7 @@ env_invert()
return rb_hash_invert(env_to_hash());
}
-static enum st_retval
+static int
env_replace_i(key, val, keys)
VALUE key, val, keys;
{
@@ -2295,7 +2333,7 @@ env_replace(env, hash)
if (env == hash) return env;
hash = to_hash(hash);
- hash_foreach(hash, env_replace_i, keys);
+ rb_hash_foreach(hash, env_replace_i, keys);
for (i=0; i<RARRAY(keys)->len; i++) {
env_delete(env, RARRAY(keys)->ptr[i]);
@@ -2303,7 +2341,7 @@ env_replace(env, hash)
return env;
}
-static enum st_retval
+static int
env_update_i(key, val)
VALUE key, val;
{
@@ -2322,7 +2360,7 @@ env_update(env, hash)
{
if (env == hash) return env;
hash = to_hash(hash);
- hash_foreach(hash, env_update_i, 0);
+ rb_hash_foreach(hash, env_update_i, 0);
return env;
}