summaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c116
1 files changed, 67 insertions, 49 deletions
diff --git a/hash.c b/hash.c
index 9141406410..34e7213856 100644
--- a/hash.c
+++ b/hash.c
@@ -6,12 +6,13 @@
$Date$
created at: Mon Nov 22 18:51:18 JST 1993
- Copyright (C) 1993-1998 Yukihiro Matsumoto
+ Copyright (C) 1993-1999 Yukihiro Matsumoto
************************************************/
#include "ruby.h"
#include "st.h"
+#include "util.h"
#include "rubysig.h"
#include <sys/types.h>
@@ -21,6 +22,10 @@
char *strchr _((char*,char));
#endif
+#ifdef USE_CWGUSI
+char* strdup(const char*);
+#endif
+
#define HASH_FREEZE FL_USER1
#define HASH_DELETED FL_USER2
@@ -30,7 +35,7 @@ rb_hash_modify(hash)
{
if (FL_TEST(hash, HASH_FREEZE))
rb_raise(rb_eTypeError, "can't modify frozen hash");
- if (rb_safe_level() >= 4 && !FL_TEST(hash, FL_TAINT))
+ if (!FL_TEST(hash, FL_TAINT) && rb_safe_level() >= 4)
rb_raise(rb_eSecurityError, "Insecure: can't modify hash");
}
@@ -127,7 +132,7 @@ rb_hash_foreach_iter(key, value, arg)
st_table *tbl = RHASH(arg->hash)->tbl;
struct st_table_entry **bins = tbl->bins;
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) 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");
@@ -187,7 +192,7 @@ rb_hash_s_new(argc, argv, klass)
VALUE *argv;
VALUE klass;
{
- VALUE sz, ifnone;
+ VALUE ifnone;
int size;
NEWOBJ(hash, struct RHash);
@@ -197,15 +202,11 @@ rb_hash_s_new(argc, argv, klass)
hash->ifnone = Qnil;
hash->tbl = 0; /* avoid GC crashing */
- rb_scan_args(argc, argv, "02", &ifnone, &sz);
- if (NIL_P(sz)) {
- size = 0;
- }
- else size = NUM2INT(sz);
+ rb_scan_args(argc, argv, "01", &ifnone);
hash->ifnone = ifnone;
- hash->tbl = st_init_table_with_size(&objhash, size);
- rb_obj_call_init((VALUE)hash);
+ hash->tbl = st_init_table(&objhash);
+ rb_obj_call_init((VALUE)hash, argc, argv);
return (VALUE)hash;
}
@@ -241,18 +242,16 @@ rb_hash_s_create(argc, argv, klass)
int i;
if (argc == 1 && TYPE(argv[0]) == T_HASH) {
- if (klass == CLASS_OF(argv[0])) return argv[0];
- else {
- NEWOBJ(hash, struct RHash);
- OBJSETUP(hash, klass, T_HASH);
+ NEWOBJ(hash, struct RHash);
+ OBJSETUP(hash, klass, T_HASH);
- hash->iter_lev = 0;
- hash->ifnone = Qnil;
- hash->tbl = 0; /* avoid GC crashing */
- hash->tbl = (st_table*)st_copy(RHASH(argv[0])->tbl);
- rb_obj_call_init((VALUE)hash);
- return (VALUE)hash;
- }
+ hash->iter_lev = 0;
+ hash->ifnone = Qnil;
+ hash->tbl = 0; /* avoid GC crashing */
+ hash->tbl = (st_table*)st_copy(RHASH(argv[0])->tbl);
+ rb_obj_call_init((VALUE)hash, argc, argv);
+
+ return (VALUE)hash;
}
if (argc % 2 != 0) {
@@ -263,7 +262,7 @@ rb_hash_s_create(argc, argv, klass)
for (i=0; i<argc; i+=2) {
st_insert(RHASH(hash)->tbl, argv[i], argv[i+1]);
}
- rb_obj_call_init(hash);
+ rb_obj_call_init(hash, argc, argv);
return hash;
}
@@ -428,7 +427,7 @@ shift_i(key, value, var)
VALUE key, value;
struct shift_var *var;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
if (var->stop) return ST_STOP;
var->stop = 1;
var->key = key;
@@ -454,8 +453,8 @@ static int
delete_if_i(key, value)
VALUE key, value;
{
- if (key == Qnil) return ST_CONTINUE;
- if (rb_yield(rb_assoc_new(key, value)))
+ if (value == Qnil) return ST_CONTINUE;
+ if (RTEST(rb_yield(rb_assoc_new(key, value))))
return ST_DELETE;
return ST_CONTINUE;
}
@@ -500,7 +499,7 @@ rb_hash_aset(hash, key, val)
st_insert(RHASH(hash)->tbl, key, val);
}
else {
- st_add_direct(RHASH(hash)->tbl, rb_str_dup_frozen(key), val);
+ st_add_direct(RHASH(hash)->tbl, rb_str_new4(key), val);
}
return val;
}
@@ -544,7 +543,7 @@ static int
each_value_i(key, value)
VALUE key, value;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
rb_yield(value);
return ST_CONTINUE;
}
@@ -561,7 +560,7 @@ static int
each_key_i(key, value)
VALUE key, value;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
rb_yield(key);
return ST_CONTINUE;
}
@@ -578,7 +577,7 @@ static int
each_pair_i(key, value)
VALUE key, value;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
rb_yield(rb_assoc_new(key, value));
return ST_CONTINUE;
}
@@ -595,7 +594,7 @@ static int
to_a_i(key, value, ary)
VALUE key, value, ary;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
rb_ary_push(ary, rb_assoc_new(key, value));
return ST_CONTINUE;
}
@@ -625,7 +624,7 @@ inspect_i(key, value, str)
{
VALUE str2;
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
if (RSTRING(str)->len > 1) {
rb_str_cat(str, ", ", 2);
}
@@ -687,7 +686,7 @@ static int
keys_i(key, value, ary)
VALUE key, value, ary;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
rb_ary_push(ary, key);
return ST_CONTINUE;
}
@@ -708,7 +707,7 @@ static int
values_i(key, value, ary)
VALUE key, value, ary;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
rb_ary_push(ary, value);
return ST_CONTINUE;
}
@@ -740,7 +739,7 @@ static int
rb_hash_search_value(key, value, data)
VALUE key, value, *data;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
if (rb_equal(value, data[1])) {
data[0] = Qtrue;
return ST_STOP;
@@ -773,7 +772,7 @@ equal_i(key, val1, data)
{
VALUE val2;
- if (key == Qnil) return ST_CONTINUE;
+ if (val1 == Qnil) return ST_CONTINUE;
if (!st_lookup(data->tbl, key, &val2)) {
data->result = Qfalse;
return ST_STOP;
@@ -807,7 +806,7 @@ rb_hash_invert_i(key, value, hash)
VALUE key, value;
VALUE hash;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
rb_hash_aset(hash, value, key);
return ST_CONTINUE;
}
@@ -827,7 +826,7 @@ rb_hash_update_i(key, value, hash)
VALUE key, value;
VALUE hash;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
rb_hash_aset(hash, key, value);
return ST_CONTINUE;
}
@@ -841,7 +840,6 @@ rb_hash_update(hash1, hash2)
return hash1;
}
-#ifndef __MACOS__ /* no environment variables on MacOS. */
static int path_tainted = -1;
#ifndef NT
@@ -849,6 +847,24 @@ extern char **environ;
#endif
static char **origenviron;
+void
+ruby_unsetenv(name)
+ char *name;
+{
+ int i, len;
+
+ len = strlen(name);
+ for(i=0; environ[i]; i++) {
+ if (strncmp(environ[i], name, len) == 0 && environ[i][len] == '=') {
+ break;
+ }
+ }
+ while (environ[i]) {
+ environ[i] = environ[i+1];
+ i++;
+ }
+}
+
static VALUE
env_delete(obj, name)
VALUE obj, name;
@@ -858,7 +874,9 @@ env_delete(obj, name)
rb_secure(4);
nam = STR2CSTR(name);
- if (strcmp(nam, "PATH") == 0) path_tainted = 0;
+ if (strcmp(nam, "PATH") == 0 && !OBJ_TAINTED(name)) {
+ path_tainted = 0;
+ }
len = strlen(nam);
for(i=0; environ[i]; i++) {
if (strncmp(environ[i], nam, len) == 0 && environ[i][len] == '=') {
@@ -894,7 +912,7 @@ rb_f_getenv(obj, name)
nam = str2cstr(name, &len);
if (strlen(nam) != len) {
- rb_raise(rb_eArgError, "Bad environment variable name");
+ rb_raise(rb_eArgError, "bad environment variable name");
}
env = getenv(nam);
if (env) {
@@ -988,8 +1006,8 @@ char *nam;
return i;
}
-static void
-my_setenv(name, value)
+void
+ruby_setenv(name, value)
char *name;
char *value;
{
@@ -1112,13 +1130,13 @@ rb_f_setenv(obj, nm, val)
}
name = str2cstr(nm, &nlen);
- value = STR2CSTR(val &vlen);
+ value = str2cstr(val, &vlen);
if (strlen(name) != nlen)
- rb_raise(rb_eArgError, "Bad environment name");
+ rb_raise(rb_eArgError, "bad environment variable name");
if (strlen(value) != vlen)
- rb_raise(rb_eArgError, "Bad environment value");
+ rb_raise(rb_eArgError, "bad environment variable value");
- my_setenv(name, value);
+ ruby_setenv(name, value);
if (strcmp(name, "PATH") == 0) {
if (OBJ_TAINTED(val)) {
/* already tainted, no check */
@@ -1363,8 +1381,6 @@ env_to_hash(obj)
return hash;
}
-#endif /* ifndef __MACOS__ no environment variables on MacOS. */
-
void
Init_Hash()
{
@@ -1414,6 +1430,7 @@ Init_Hash()
rb_define_method(rb_cHash,"shift", rb_hash_shift, 0);
rb_define_method(rb_cHash,"delete", rb_hash_delete, 1);
rb_define_method(rb_cHash,"delete_if", rb_hash_delete_if, 0);
+ rb_define_method(rb_cHash,"reject!", rb_hash_delete_if, 0);
rb_define_method(rb_cHash,"clear", rb_hash_clear, 0);
rb_define_method(rb_cHash,"invert", rb_hash_invert, 0);
rb_define_method(rb_cHash,"update", rb_hash_update, 1);
@@ -1438,6 +1455,7 @@ Init_Hash()
rb_define_singleton_method(envtbl,"each_value", env_each_value, 0);
rb_define_singleton_method(envtbl,"delete", env_delete_method, 1);
rb_define_singleton_method(envtbl,"delete_if", env_delete_if, 0);
+ rb_define_singleton_method(envtbl,"reject!", env_delete_if, 0);
rb_define_singleton_method(envtbl,"to_s", env_to_s, 0);
rb_define_singleton_method(envtbl,"rehash", env_none, 0);
rb_define_singleton_method(envtbl,"to_a", env_to_a, 0);