hash.c

Go to the documentation of this file.
00001 /**********************************************************************
00002 
00003   hash.c -
00004 
00005   $Author: nagachika $
00006   created at: Mon Nov 22 18:51:18 JST 1993
00007 
00008   Copyright (C) 1993-2007 Yukihiro Matsumoto
00009   Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
00010   Copyright (C) 2000  Information-technology Promotion Agency, Japan
00011 
00012 **********************************************************************/
00013 
00014 #include "ruby/ruby.h"
00015 #include "ruby/st.h"
00016 #include "ruby/util.h"
00017 #include "ruby/encoding.h"
00018 #include "internal.h"
00019 #include <errno.h>
00020 #include "probes.h"
00021 
00022 #ifdef __APPLE__
00023 # ifdef HAVE_CRT_EXTERNS_H
00024 #  include <crt_externs.h>
00025 # else
00026 #  include "missing/crt_externs.h"
00027 # endif
00028 #endif
00029 
00030 #define HAS_EXTRA_STATES(hash, klass) ( \
00031     ((klass = has_extra_methods(rb_obj_class(hash))) != 0) || \
00032     FL_TEST((hash), FL_EXIVAR|FL_TAINT|HASH_PROC_DEFAULT) || \
00033     !NIL_P(RHASH_IFNONE(hash)))
00034 #define HASH_REJECT_COPY_EXTRA_STATES 1
00035 
00036 static VALUE
00037 has_extra_methods(VALUE klass)
00038 {
00039     const VALUE base = rb_cHash;
00040     VALUE c = klass;
00041     while (c != base) {
00042         st_table *mtbl = RCLASS_M_TBL(c);
00043         if (mtbl && mtbl->num_entries) return klass;
00044         c = RCLASS_SUPER(c);
00045     }
00046     return 0;
00047 }
00048 
00049 static VALUE rb_hash_s_try_convert(VALUE, VALUE);
00050 
00051 /*
00052  * Hash WB strategy:
00053  *  1. Check mutate st_* functions
00054  *     * st_insert()
00055  *     * st_insert2()
00056  *     * st_update()
00057  *     * st_add_direct()
00058  *  2. Insert WBs
00059  */
00060 
00061 VALUE
00062 rb_hash_freeze(VALUE hash)
00063 {
00064     return rb_obj_freeze(hash);
00065 }
00066 
00067 VALUE rb_cHash;
00068 
00069 static VALUE envtbl;
00070 static ID id_hash, id_yield, id_default, id_flatten_bang;
00071 
00072 VALUE
00073 rb_hash_set_ifnone(VALUE hash, VALUE ifnone)
00074 {
00075     RB_OBJ_WRITE(hash, (&RHASH(hash)->ifnone), ifnone);
00076     return hash;
00077 }
00078 
00079 static int
00080 rb_any_cmp(VALUE a, VALUE b)
00081 {
00082     if (a == b) return 0;
00083     if (FIXNUM_P(a) && FIXNUM_P(b)) {
00084         return a != b;
00085     }
00086     if (RB_TYPE_P(a, T_STRING) && RBASIC(a)->klass == rb_cString &&
00087         RB_TYPE_P(b, T_STRING) && RBASIC(b)->klass == rb_cString) {
00088         return rb_str_hash_cmp(a, b);
00089     }
00090     if (a == Qundef || b == Qundef) return -1;
00091     if (SYMBOL_P(a) && SYMBOL_P(b)) {
00092         return a != b;
00093     }
00094 
00095     return !rb_eql(a, b);
00096 }
00097 
00098 static VALUE
00099 hash_recursive(VALUE obj, VALUE arg, int recurse)
00100 {
00101     if (recurse) return INT2FIX(0);
00102     return rb_funcallv(obj, id_hash, 0, 0);
00103 }
00104 
00105 VALUE
00106 rb_hash(VALUE obj)
00107 {
00108     VALUE hval = rb_exec_recursive_outer(hash_recursive, obj, 0);
00109 
00110     while (!FIXNUM_P(hval)) {
00111         if (RB_TYPE_P(hval, T_BIGNUM)) {
00112             int sign;
00113             unsigned long ul;
00114             sign = rb_integer_pack(hval, &ul, 1, sizeof(ul), 0,
00115                     INTEGER_PACK_NATIVE_BYTE_ORDER);
00116             ul &= (1UL << (sizeof(long)*CHAR_BIT-1)) - 1;
00117             if (sign < 0)
00118                 return LONG2FIX(-(long)ul);
00119             return LONG2FIX((long)ul);
00120         }
00121         hval = rb_to_int(hval);
00122     }
00123     return hval;
00124 }
00125 
00126 long rb_objid_hash(st_index_t index);
00127 
00128 static st_index_t
00129 rb_any_hash(VALUE a)
00130 {
00131     VALUE hval;
00132     st_index_t hnum;
00133 
00134     if (SPECIAL_CONST_P(a)) {
00135         if (a == Qundef) return 0;
00136         hnum = rb_objid_hash((st_index_t)a);
00137     }
00138     else if (BUILTIN_TYPE(a) == T_STRING) {
00139         hnum = rb_str_hash(a);
00140     }
00141     else {
00142         hval = rb_hash(a);
00143         hnum = FIX2LONG(hval);
00144     }
00145     hnum <<= 1;
00146     return (st_index_t)RSHIFT(hnum, 1);
00147 }
00148 
00149 long
00150 rb_objid_hash(st_index_t index)
00151 {
00152     st_index_t hnum = rb_hash_start(index);
00153     hnum = rb_hash_uint(hnum, (st_index_t)rb_any_hash);
00154     hnum = rb_hash_end(hnum);
00155     return hnum;
00156 }
00157 
00158 static const struct st_hash_type objhash = {
00159     rb_any_cmp,
00160     rb_any_hash,
00161 };
00162 
00163 extern const struct st_hash_type st_hashtype_num;
00164 #define identhash st_hashtype_num
00165 
00166 typedef int st_foreach_func(st_data_t, st_data_t, st_data_t);
00167 
00168 struct foreach_safe_arg {
00169     st_table *tbl;
00170     st_foreach_func *func;
00171     st_data_t arg;
00172 };
00173 
00174 static int
00175 foreach_safe_i(st_data_t key, st_data_t value, st_data_t args, int error)
00176 {
00177     int status;
00178     struct foreach_safe_arg *arg = (void *)args;
00179 
00180     if (error) return ST_STOP;
00181     status = (*arg->func)(key, value, arg->arg);
00182     if (status == ST_CONTINUE) {
00183         return ST_CHECK;
00184     }
00185     return status;
00186 }
00187 
00188 void
00189 st_foreach_safe(st_table *table, int (*func)(ANYARGS), st_data_t a)
00190 {
00191     struct foreach_safe_arg arg;
00192 
00193     arg.tbl = table;
00194     arg.func = (st_foreach_func *)func;
00195     arg.arg = a;
00196     if (st_foreach_check(table, foreach_safe_i, (st_data_t)&arg, 0)) {
00197         rb_raise(rb_eRuntimeError, "hash modified during iteration");
00198     }
00199 }
00200 
00201 typedef int rb_foreach_func(VALUE, VALUE, VALUE);
00202 
00203 struct hash_foreach_arg {
00204     VALUE hash;
00205     rb_foreach_func *func;
00206     VALUE arg;
00207 };
00208 
00209 static int
00210 hash_foreach_iter(st_data_t key, st_data_t value, st_data_t argp, int error)
00211 {
00212     struct hash_foreach_arg *arg = (struct hash_foreach_arg *)argp;
00213     int status;
00214     st_table *tbl;
00215 
00216     if (error) return ST_STOP;
00217     tbl = RHASH(arg->hash)->ntbl;
00218     status = (*arg->func)((VALUE)key, (VALUE)value, arg->arg);
00219     if (RHASH(arg->hash)->ntbl != tbl) {
00220         rb_raise(rb_eRuntimeError, "rehash occurred during iteration");
00221     }
00222     switch (status) {
00223       case ST_DELETE:
00224         FL_SET(arg->hash, HASH_DELETED);
00225         return ST_DELETE;
00226       case ST_CONTINUE:
00227         break;
00228       case ST_STOP:
00229         return ST_STOP;
00230     }
00231     return ST_CHECK;
00232 }
00233 
00234 static VALUE
00235 hash_foreach_ensure_rollback(VALUE hash)
00236 {
00237     RHASH_ITER_LEV(hash)++;
00238     return 0;
00239 }
00240 
00241 static VALUE
00242 hash_foreach_ensure(VALUE hash)
00243 {
00244     if (--RHASH_ITER_LEV(hash) == 0) {
00245         if (FL_TEST(hash, HASH_DELETED)) {
00246             st_cleanup_safe(RHASH(hash)->ntbl, (st_data_t)Qundef);
00247             FL_UNSET(hash, HASH_DELETED);
00248         }
00249     }
00250     return 0;
00251 }
00252 
00253 static VALUE
00254 hash_foreach_call(VALUE arg)
00255 {
00256     VALUE hash = ((struct hash_foreach_arg *)arg)->hash;
00257     if (st_foreach_check(RHASH(hash)->ntbl, hash_foreach_iter, (st_data_t)arg, (st_data_t)Qundef)) {
00258         rb_raise(rb_eRuntimeError, "hash modified during iteration");
00259     }
00260     return Qnil;
00261 }
00262 
00263 void
00264 rb_hash_foreach(VALUE hash, int (*func)(ANYARGS), VALUE farg)
00265 {
00266     struct hash_foreach_arg arg;
00267 
00268     if (!RHASH(hash)->ntbl)
00269         return;
00270     RHASH_ITER_LEV(hash)++;
00271     arg.hash = hash;
00272     arg.func = (rb_foreach_func *)func;
00273     arg.arg  = farg;
00274     rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash);
00275 }
00276 
00277 static VALUE
00278 hash_alloc(VALUE klass)
00279 {
00280     NEWOBJ_OF(hash, struct RHash, klass, T_HASH | (RGENGC_WB_PROTECTED_HASH ? FL_WB_PROTECTED : 0));
00281 
00282     RHASH_SET_IFNONE((VALUE)hash, Qnil);
00283 
00284     return (VALUE)hash;
00285 }
00286 
00287 static VALUE
00288 empty_hash_alloc(VALUE klass)
00289 {
00290     if (RUBY_DTRACE_HASH_CREATE_ENABLED()) {
00291         RUBY_DTRACE_HASH_CREATE(0, rb_sourcefile(), rb_sourceline());
00292     }
00293 
00294     return hash_alloc(klass);
00295 }
00296 
00297 VALUE
00298 rb_hash_new(void)
00299 {
00300     return hash_alloc(rb_cHash);
00301 }
00302 
00303 static VALUE
00304 rb_hash_dup_empty(VALUE hash)
00305 {
00306     NEWOBJ_OF(ret, struct RHash,
00307                 rb_obj_class(hash),
00308                 (RBASIC(hash)->flags)&(T_MASK|FL_EXIVAR|FL_TAINT));
00309     if (FL_TEST((hash), FL_EXIVAR))
00310         rb_copy_generic_ivar((VALUE)(ret),(VALUE)(hash));
00311 
00312     if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
00313         FL_SET(ret, HASH_PROC_DEFAULT);
00314     }
00315     RHASH_SET_IFNONE(ret, RHASH_IFNONE(hash));
00316     return (VALUE)ret;
00317 }
00318 
00319 VALUE
00320 rb_hash_dup(VALUE hash)
00321 {
00322     VALUE ret = rb_hash_dup_empty(hash);
00323     if (!RHASH_EMPTY_P(hash))
00324         RHASH(ret)->ntbl = st_copy(RHASH(hash)->ntbl);
00325     return ret;
00326 }
00327 
00328 static void
00329 rb_hash_modify_check(VALUE hash)
00330 {
00331     rb_check_frozen(hash);
00332 }
00333 
00334 static struct st_table *
00335 hash_tbl(VALUE hash)
00336 {
00337     if (!RHASH(hash)->ntbl) {
00338         RHASH(hash)->ntbl = st_init_table(&objhash);
00339     }
00340     return RHASH(hash)->ntbl;
00341 }
00342 
00343 struct st_table *
00344 rb_hash_tbl(VALUE hash)
00345 {
00346     OBJ_WB_UNPROTECT(hash);
00347     return hash_tbl(hash);
00348 }
00349 
00350 struct st_table *
00351 rb_hash_tbl_raw(VALUE hash)
00352 {
00353     return hash_tbl(hash);
00354 }
00355 
00356 static void
00357 rb_hash_modify(VALUE hash)
00358 {
00359     rb_hash_modify_check(hash);
00360     hash_tbl(hash);
00361 }
00362 
00363 NORETURN(static void no_new_key(void));
00364 static void
00365 no_new_key(void)
00366 {
00367     rb_raise(rb_eRuntimeError, "can't add a new key into hash during iteration");
00368 }
00369 
00370 struct update_callback_arg {
00371     VALUE hash;
00372     st_data_t arg;
00373 };
00374 
00375 #define NOINSERT_UPDATE_CALLBACK(func)                                       \
00376 static int                                                                   \
00377 func##_noinsert(st_data_t *key, st_data_t *val, st_data_t arg, int existing) \
00378 {                                                                            \
00379     if (!existing) no_new_key();                                             \
00380     return func(key, val, (struct update_arg *)arg, existing);               \
00381 }                                                                            \
00382                                                                              \
00383 static int                                                                   \
00384 func##_insert(st_data_t *key, st_data_t *val, st_data_t arg, int existing)   \
00385 {                                                                            \
00386     return func(key, val, (struct update_arg *)arg, existing);               \
00387 }
00388 
00389 struct update_arg {
00390     st_data_t arg;
00391     VALUE hash;
00392     VALUE new_key;
00393     VALUE old_key;
00394     VALUE new_value;
00395     VALUE old_value;
00396 };
00397 
00398 static int
00399 tbl_update(VALUE hash, VALUE key, int (*func)(st_data_t *key, st_data_t *val, st_data_t arg, int existing), st_data_t optional_arg)
00400 {
00401     struct update_arg arg;
00402     int result;
00403 
00404     arg.arg = optional_arg;
00405     arg.hash = hash;
00406     arg.new_key = 0;
00407     arg.old_key = Qundef;
00408     arg.new_value = 0;
00409     arg.old_value = Qundef;
00410 
00411     result = st_update(RHASH(hash)->ntbl, (st_data_t)key, func, (st_data_t)&arg);
00412 
00413     /* write barrier */
00414     if (arg.new_key)   RB_OBJ_WRITTEN(hash, arg.old_key, arg.new_key);
00415     if (arg.new_value) RB_OBJ_WRITTEN(hash, arg.old_value, arg.new_value);
00416 
00417     return result;
00418 }
00419 
00420 #define UPDATE_CALLBACK(iter_lev, func) ((iter_lev) > 0 ? func##_noinsert : func##_insert)
00421 
00422 #define RHASH_UPDATE_ITER(h, iter_lev, key, func, a) do {                        \
00423     tbl_update((h), (key), UPDATE_CALLBACK((iter_lev), func), (st_data_t)(a)); \
00424 } while (0)
00425 
00426 #define RHASH_UPDATE(hash, key, func, arg) \
00427     RHASH_UPDATE_ITER(hash, RHASH_ITER_LEV(hash), key, func, arg)
00428 
00429 static void
00430 default_proc_arity_check(VALUE proc)
00431 {
00432     int n = rb_proc_arity(proc);
00433 
00434     if (rb_proc_lambda_p(proc) && n != 2 && (n >= 0 || n < -3)) {
00435         if (n < 0) n = -n-1;
00436         rb_raise(rb_eTypeError, "default_proc takes two arguments (2 for %d)", n);
00437     }
00438 }
00439 
00440 /*
00441  *  call-seq:
00442  *     Hash.new                          -> new_hash
00443  *     Hash.new(obj)                     -> new_hash
00444  *     Hash.new {|hash, key| block }     -> new_hash
00445  *
00446  *  Returns a new, empty hash. If this hash is subsequently accessed by
00447  *  a key that doesn't correspond to a hash entry, the value returned
00448  *  depends on the style of <code>new</code> used to create the hash. In
00449  *  the first form, the access returns <code>nil</code>. If
00450  *  <i>obj</i> is specified, this single object will be used for
00451  *  all <em>default values</em>. If a block is specified, it will be
00452  *  called with the hash object and the key, and should return the
00453  *  default value. It is the block's responsibility to store the value
00454  *  in the hash if required.
00455  *
00456  *     h = Hash.new("Go Fish")
00457  *     h["a"] = 100
00458  *     h["b"] = 200
00459  *     h["a"]           #=> 100
00460  *     h["c"]           #=> "Go Fish"
00461  *     # The following alters the single default object
00462  *     h["c"].upcase!   #=> "GO FISH"
00463  *     h["d"]           #=> "GO FISH"
00464  *     h.keys           #=> ["a", "b"]
00465  *
00466  *     # While this creates a new default object each time
00467  *     h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }
00468  *     h["c"]           #=> "Go Fish: c"
00469  *     h["c"].upcase!   #=> "GO FISH: C"
00470  *     h["d"]           #=> "Go Fish: d"
00471  *     h.keys           #=> ["c", "d"]
00472  *
00473  */
00474 
00475 static VALUE
00476 rb_hash_initialize(int argc, VALUE *argv, VALUE hash)
00477 {
00478     VALUE ifnone;
00479 
00480     rb_hash_modify(hash);
00481     if (rb_block_given_p()) {
00482         rb_check_arity(argc, 0, 0);
00483         ifnone = rb_block_proc();
00484         default_proc_arity_check(ifnone);
00485         RHASH_SET_IFNONE(hash, ifnone);
00486         FL_SET(hash, HASH_PROC_DEFAULT);
00487     }
00488     else {
00489         rb_scan_args(argc, argv, "01", &ifnone);
00490         RHASH_SET_IFNONE(hash, ifnone);
00491     }
00492 
00493     return hash;
00494 }
00495 
00496 /*
00497  *  call-seq:
00498  *     Hash[ key, value, ... ]         -> new_hash
00499  *     Hash[ [ [key, value], ... ] ]   -> new_hash
00500  *     Hash[ object ]                  -> new_hash
00501  *
00502  *  Creates a new hash populated with the given objects.
00503  *
00504  *  Similar to the literal <code>{ _key_ => _value_, ... }</code>. In the first
00505  *  form, keys and values occur in pairs, so there must be an even number of
00506  *  arguments.
00507  *
00508  *  The second and third form take a single argument which is either an array
00509  *  of key-value pairs or an object convertible to a hash.
00510  *
00511  *     Hash["a", 100, "b", 200]             #=> {"a"=>100, "b"=>200}
00512  *     Hash[ [ ["a", 100], ["b", 200] ] ]   #=> {"a"=>100, "b"=>200}
00513  *     Hash["a" => 100, "b" => 200]         #=> {"a"=>100, "b"=>200}
00514  */
00515 
00516 static VALUE
00517 rb_hash_s_create(int argc, VALUE *argv, VALUE klass)
00518 {
00519     VALUE hash, tmp;
00520     int i;
00521 
00522     if (argc == 1) {
00523         tmp = rb_hash_s_try_convert(Qnil, argv[0]);
00524         if (!NIL_P(tmp)) {
00525             hash = hash_alloc(klass);
00526             if (RHASH(tmp)->ntbl) {
00527                 RHASH(hash)->ntbl = st_copy(RHASH(tmp)->ntbl);
00528             }
00529             return hash;
00530         }
00531 
00532         tmp = rb_check_array_type(argv[0]);
00533         if (!NIL_P(tmp)) {
00534             long i;
00535 
00536             hash = hash_alloc(klass);
00537             for (i = 0; i < RARRAY_LEN(tmp); ++i) {
00538                 VALUE e = RARRAY_AREF(tmp, i);
00539                 VALUE v = rb_check_array_type(e);
00540                 VALUE key, val = Qnil;
00541 
00542                 if (NIL_P(v)) {
00543 #if 0 /* refix in the next release */
00544                     rb_raise(rb_eArgError, "wrong element type %s at %ld (expected array)",
00545                              rb_builtin_class_name(e), i);
00546 
00547 #else
00548                     rb_warn("wrong element type %s at %ld (expected array)",
00549                             rb_builtin_class_name(e), i);
00550                     rb_warn("ignoring wrong elements is deprecated, remove them explicitly");
00551                     rb_warn("this causes ArgumentError in the next release");
00552                     continue;
00553 #endif
00554                 }
00555                 switch (RARRAY_LEN(v)) {
00556                   default:
00557                     rb_raise(rb_eArgError, "invalid number of elements (%ld for 1..2)",
00558                              RARRAY_LEN(v));
00559                   case 2:
00560                     val = RARRAY_AREF(v, 1);
00561                   case 1:
00562                     key = RARRAY_AREF(v, 0);
00563                     rb_hash_aset(hash, key, val);
00564                 }
00565             }
00566             return hash;
00567         }
00568     }
00569     if (argc % 2 != 0) {
00570         rb_raise(rb_eArgError, "odd number of arguments for Hash");
00571     }
00572 
00573     hash = hash_alloc(klass);
00574     for (i=0; i<argc; i+=2) {
00575         rb_hash_aset(hash, argv[i], argv[i + 1]);
00576     }
00577 
00578     return hash;
00579 }
00580 
00581 static VALUE
00582 to_hash(VALUE hash)
00583 {
00584     return rb_convert_type(hash, T_HASH, "Hash", "to_hash");
00585 }
00586 
00587 VALUE
00588 rb_check_hash_type(VALUE hash)
00589 {
00590     return rb_check_convert_type(hash, T_HASH, "Hash", "to_hash");
00591 }
00592 
00593 /*
00594  *  call-seq:
00595  *     Hash.try_convert(obj) -> hash or nil
00596  *
00597  *  Try to convert <i>obj</i> into a hash, using to_hash method.
00598  *  Returns converted hash or nil if <i>obj</i> cannot be converted
00599  *  for any reason.
00600  *
00601  *     Hash.try_convert({1=>2})   # => {1=>2}
00602  *     Hash.try_convert("1=>2")   # => nil
00603  */
00604 static VALUE
00605 rb_hash_s_try_convert(VALUE dummy, VALUE hash)
00606 {
00607     return rb_check_hash_type(hash);
00608 }
00609 
00610 struct rehash_arg {
00611     VALUE hash;
00612     st_table *tbl;
00613 };
00614 
00615 static int
00616 rb_hash_rehash_i(VALUE key, VALUE value, VALUE arg)
00617 {
00618     st_table *tbl = (st_table *)arg;
00619 
00620     st_insert(tbl, (st_data_t)key, (st_data_t)value);
00621     return ST_CONTINUE;
00622 }
00623 
00624 /*
00625  *  call-seq:
00626  *     hsh.rehash -> hsh
00627  *
00628  *  Rebuilds the hash based on the current hash values for each key. If
00629  *  values of key objects have changed since they were inserted, this
00630  *  method will reindex <i>hsh</i>. If <code>Hash#rehash</code> is
00631  *  called while an iterator is traversing the hash, an
00632  *  <code>RuntimeError</code> will be raised in the iterator.
00633  *
00634  *     a = [ "a", "b" ]
00635  *     c = [ "c", "d" ]
00636  *     h = { a => 100, c => 300 }
00637  *     h[a]       #=> 100
00638  *     a[0] = "z"
00639  *     h[a]       #=> nil
00640  *     h.rehash   #=> {["z", "b"]=>100, ["c", "d"]=>300}
00641  *     h[a]       #=> 100
00642  */
00643 
00644 static VALUE
00645 rb_hash_rehash(VALUE hash)
00646 {
00647     VALUE tmp;
00648     st_table *tbl;
00649 
00650     if (RHASH_ITER_LEV(hash) > 0) {
00651         rb_raise(rb_eRuntimeError, "rehash during iteration");
00652     }
00653     rb_hash_modify_check(hash);
00654     if (!RHASH(hash)->ntbl)
00655         return hash;
00656     tmp = hash_alloc(0);
00657     tbl = st_init_table_with_size(RHASH(hash)->ntbl->type, RHASH(hash)->ntbl->num_entries);
00658     RHASH(tmp)->ntbl = tbl;
00659 
00660     rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tbl);
00661     st_free_table(RHASH(hash)->ntbl);
00662     RHASH(hash)->ntbl = tbl;
00663     RHASH(tmp)->ntbl = 0;
00664 
00665     return hash;
00666 }
00667 
00668 static VALUE
00669 hash_default_value(VALUE hash, VALUE key)
00670 {
00671     if (rb_method_basic_definition_p(CLASS_OF(hash), id_default)) {
00672         VALUE ifnone = RHASH_IFNONE(hash);
00673         if (!FL_TEST(hash, HASH_PROC_DEFAULT)) return ifnone;
00674         if (key == Qundef) return Qnil;
00675         return rb_funcall(ifnone, id_yield, 2, hash, key);
00676     }
00677     else {
00678         return rb_funcall(hash, id_default, 1, key);
00679     }
00680 }
00681 
00682 /*
00683  *  call-seq:
00684  *     hsh[key]    ->  value
00685  *
00686  *  Element Reference---Retrieves the <i>value</i> object corresponding
00687  *  to the <i>key</i> object. If not found, returns the default value (see
00688  *  <code>Hash::new</code> for details).
00689  *
00690  *     h = { "a" => 100, "b" => 200 }
00691  *     h["a"]   #=> 100
00692  *     h["c"]   #=> nil
00693  *
00694  */
00695 
00696 VALUE
00697 rb_hash_aref(VALUE hash, VALUE key)
00698 {
00699     st_data_t val;
00700 
00701     if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
00702         return hash_default_value(hash, key);
00703     }
00704     return (VALUE)val;
00705 }
00706 
00707 VALUE
00708 rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
00709 {
00710     st_data_t val;
00711 
00712     if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
00713         return def; /* without Hash#default */
00714     }
00715     return (VALUE)val;
00716 }
00717 
00718 VALUE
00719 rb_hash_lookup(VALUE hash, VALUE key)
00720 {
00721     return rb_hash_lookup2(hash, key, Qnil);
00722 }
00723 
00724 /*
00725  *  call-seq:
00726  *     hsh.fetch(key [, default] )       -> obj
00727  *     hsh.fetch(key) {| key | block }   -> obj
00728  *
00729  *  Returns a value from the hash for the given key. If the key can't be
00730  *  found, there are several options: With no other arguments, it will
00731  *  raise an <code>KeyError</code> exception; if <i>default</i> is
00732  *  given, then that will be returned; if the optional code block is
00733  *  specified, then that will be run and its result returned.
00734  *
00735  *     h = { "a" => 100, "b" => 200 }
00736  *     h.fetch("a")                            #=> 100
00737  *     h.fetch("z", "go fish")                 #=> "go fish"
00738  *     h.fetch("z") { |el| "go fish, #{el}"}   #=> "go fish, z"
00739  *
00740  *  The following example shows that an exception is raised if the key
00741  *  is not found and a default value is not supplied.
00742  *
00743  *     h = { "a" => 100, "b" => 200 }
00744  *     h.fetch("z")
00745  *
00746  *  <em>produces:</em>
00747  *
00748  *     prog.rb:2:in `fetch': key not found (KeyError)
00749  *      from prog.rb:2
00750  *
00751  */
00752 
00753 static VALUE
00754 rb_hash_fetch_m(int argc, VALUE *argv, VALUE hash)
00755 {
00756     VALUE key, if_none;
00757     st_data_t val;
00758     long block_given;
00759 
00760     rb_scan_args(argc, argv, "11", &key, &if_none);
00761 
00762     block_given = rb_block_given_p();
00763     if (block_given && argc == 2) {
00764         rb_warn("block supersedes default value argument");
00765     }
00766     if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
00767         if (block_given) return rb_yield(key);
00768         if (argc == 1) {
00769             volatile VALUE desc = rb_protect(rb_inspect, key, 0);
00770             if (NIL_P(desc)) {
00771                 desc = rb_any_to_s(key);
00772             }
00773             desc = rb_str_ellipsize(desc, 65);
00774             rb_raise(rb_eKeyError, "key not found: %"PRIsVALUE, desc);
00775         }
00776         return if_none;
00777     }
00778     return (VALUE)val;
00779 }
00780 
00781 VALUE
00782 rb_hash_fetch(VALUE hash, VALUE key)
00783 {
00784     return rb_hash_fetch_m(1, &key, hash);
00785 }
00786 
00787 /*
00788  *  call-seq:
00789  *     hsh.default(key=nil)   -> obj
00790  *
00791  *  Returns the default value, the value that would be returned by
00792  *  <i>hsh</i>[<i>key</i>] if <i>key</i> did not exist in <i>hsh</i>.
00793  *  See also <code>Hash::new</code> and <code>Hash#default=</code>.
00794  *
00795  *     h = Hash.new                            #=> {}
00796  *     h.default                               #=> nil
00797  *     h.default(2)                            #=> nil
00798  *
00799  *     h = Hash.new("cat")                     #=> {}
00800  *     h.default                               #=> "cat"
00801  *     h.default(2)                            #=> "cat"
00802  *
00803  *     h = Hash.new {|h,k| h[k] = k.to_i*10}   #=> {}
00804  *     h.default                               #=> nil
00805  *     h.default(2)                            #=> 20
00806  */
00807 
00808 static VALUE
00809 rb_hash_default(int argc, VALUE *argv, VALUE hash)
00810 {
00811     VALUE key, ifnone;
00812 
00813     rb_scan_args(argc, argv, "01", &key);
00814     ifnone = RHASH_IFNONE(hash);
00815     if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
00816         if (argc == 0) return Qnil;
00817         return rb_funcall(ifnone, id_yield, 2, hash, key);
00818     }
00819     return ifnone;
00820 }
00821 
00822 /*
00823  *  call-seq:
00824  *     hsh.default = obj     -> obj
00825  *
00826  *  Sets the default value, the value returned for a key that does not
00827  *  exist in the hash. It is not possible to set the default to a
00828  *  <code>Proc</code> that will be executed on each key lookup.
00829  *
00830  *     h = { "a" => 100, "b" => 200 }
00831  *     h.default = "Go fish"
00832  *     h["a"]     #=> 100
00833  *     h["z"]     #=> "Go fish"
00834  *     # This doesn't do what you might hope...
00835  *     h.default = proc do |hash, key|
00836  *       hash[key] = key + key
00837  *     end
00838  *     h[2]       #=> #<Proc:0x401b3948@-:6>
00839  *     h["cat"]   #=> #<Proc:0x401b3948@-:6>
00840  */
00841 
00842 static VALUE
00843 rb_hash_set_default(VALUE hash, VALUE ifnone)
00844 {
00845     rb_hash_modify_check(hash);
00846     RHASH_SET_IFNONE(hash, ifnone);
00847     FL_UNSET(hash, HASH_PROC_DEFAULT);
00848     return ifnone;
00849 }
00850 
00851 /*
00852  *  call-seq:
00853  *     hsh.default_proc -> anObject
00854  *
00855  *  If <code>Hash::new</code> was invoked with a block, return that
00856  *  block, otherwise return <code>nil</code>.
00857  *
00858  *     h = Hash.new {|h,k| h[k] = k*k }   #=> {}
00859  *     p = h.default_proc                 #=> #<Proc:0x401b3d08@-:1>
00860  *     a = []                             #=> []
00861  *     p.call(a, 2)
00862  *     a                                  #=> [nil, nil, 4]
00863  */
00864 
00865 
00866 static VALUE
00867 rb_hash_default_proc(VALUE hash)
00868 {
00869     if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
00870         return RHASH_IFNONE(hash);
00871     }
00872     return Qnil;
00873 }
00874 
00875 /*
00876  *  call-seq:
00877  *     hsh.default_proc = proc_obj or nil
00878  *
00879  *  Sets the default proc to be executed on each failed key lookup.
00880  *
00881  *     h.default_proc = proc do |hash, key|
00882  *       hash[key] = key + key
00883  *     end
00884  *     h[2]       #=> 4
00885  *     h["cat"]   #=> "catcat"
00886  */
00887 
00888 static VALUE
00889 rb_hash_set_default_proc(VALUE hash, VALUE proc)
00890 {
00891     VALUE b;
00892 
00893     rb_hash_modify_check(hash);
00894     if (NIL_P(proc)) {
00895         FL_UNSET(hash, HASH_PROC_DEFAULT);
00896         RHASH_SET_IFNONE(hash, proc);
00897         return proc;
00898     }
00899     b = rb_check_convert_type(proc, T_DATA, "Proc", "to_proc");
00900     if (NIL_P(b) || !rb_obj_is_proc(b)) {
00901         rb_raise(rb_eTypeError,
00902                  "wrong default_proc type %s (expected Proc)",
00903                  rb_obj_classname(proc));
00904     }
00905     proc = b;
00906     default_proc_arity_check(proc);
00907     RHASH_SET_IFNONE(hash, proc);
00908     FL_SET(hash, HASH_PROC_DEFAULT);
00909     return proc;
00910 }
00911 
00912 static int
00913 key_i(VALUE key, VALUE value, VALUE arg)
00914 {
00915     VALUE *args = (VALUE *)arg;
00916 
00917     if (rb_equal(value, args[0])) {
00918         args[1] = key;
00919         return ST_STOP;
00920     }
00921     return ST_CONTINUE;
00922 }
00923 
00924 /*
00925  *  call-seq:
00926  *     hsh.key(value)    -> key
00927  *
00928  *  Returns the key of an occurrence of a given value. If the value is
00929  *  not found, returns <code>nil</code>.
00930  *
00931  *     h = { "a" => 100, "b" => 200, "c" => 300, "d" => 300 }
00932  *     h.key(200)   #=> "b"
00933  *     h.key(300)   #=> "c"
00934  *     h.key(999)   #=> nil
00935  *
00936  */
00937 
00938 static VALUE
00939 rb_hash_key(VALUE hash, VALUE value)
00940 {
00941     VALUE args[2];
00942 
00943     args[0] = value;
00944     args[1] = Qnil;
00945 
00946     rb_hash_foreach(hash, key_i, (VALUE)args);
00947 
00948     return args[1];
00949 }
00950 
00951 /* :nodoc: */
00952 static VALUE
00953 rb_hash_index(VALUE hash, VALUE value)
00954 {
00955     rb_warn("Hash#index is deprecated; use Hash#key");
00956     return rb_hash_key(hash, value);
00957 }
00958 
00959 static VALUE
00960 rb_hash_delete_key(VALUE hash, VALUE key)
00961 {
00962     st_data_t ktmp = (st_data_t)key, val;
00963 
00964     if (!RHASH(hash)->ntbl)
00965         return Qundef;
00966     if (RHASH_ITER_LEV(hash) > 0) {
00967         if (st_delete_safe(RHASH(hash)->ntbl, &ktmp, &val, (st_data_t)Qundef)) {
00968             FL_SET(hash, HASH_DELETED);
00969             return (VALUE)val;
00970         }
00971     }
00972     else if (st_delete(RHASH(hash)->ntbl, &ktmp, &val))
00973         return (VALUE)val;
00974     return Qundef;
00975 }
00976 
00977 /*
00978  *  call-seq:
00979  *     hsh.delete(key)                   -> value
00980  *     hsh.delete(key) {| key | block }  -> value
00981  *
00982  *  Deletes the key-value pair and returns the value from <i>hsh</i> whose
00983  *  key is equal to <i>key</i>. If the key is not found, returns the
00984  *  <em>default value</em>. If the optional code block is given and the
00985  *  key is not found, pass in the key and return the result of
00986  *  <i>block</i>.
00987  *
00988  *     h = { "a" => 100, "b" => 200 }
00989  *     h.delete("a")                              #=> 100
00990  *     h.delete("z")                              #=> nil
00991  *     h.delete("z") { |el| "#{el} not found" }   #=> "z not found"
00992  *
00993  */
00994 
00995 VALUE
00996 rb_hash_delete(VALUE hash, VALUE key)
00997 {
00998     VALUE val;
00999 
01000     rb_hash_modify_check(hash);
01001     val = rb_hash_delete_key(hash, key);
01002     if (val != Qundef) return val;
01003     if (rb_block_given_p()) {
01004         return rb_yield(key);
01005     }
01006     return Qnil;
01007 }
01008 
01009 struct shift_var {
01010     VALUE key;
01011     VALUE val;
01012 };
01013 
01014 static int
01015 shift_i_safe(VALUE key, VALUE value, VALUE arg)
01016 {
01017     struct shift_var *var = (struct shift_var *)arg;
01018 
01019     var->key = key;
01020     var->val = value;
01021     return ST_STOP;
01022 }
01023 
01024 /*
01025  *  call-seq:
01026  *     hsh.shift -> anArray or obj
01027  *
01028  *  Removes a key-value pair from <i>hsh</i> and returns it as the
01029  *  two-item array <code>[</code> <i>key, value</i> <code>]</code>, or
01030  *  the hash's default value if the hash is empty.
01031  *
01032  *     h = { 1 => "a", 2 => "b", 3 => "c" }
01033  *     h.shift   #=> [1, "a"]
01034  *     h         #=> {2=>"b", 3=>"c"}
01035  */
01036 
01037 static VALUE
01038 rb_hash_shift(VALUE hash)
01039 {
01040     struct shift_var var;
01041 
01042     rb_hash_modify_check(hash);
01043     if (RHASH(hash)->ntbl) {
01044         var.key = Qundef;
01045         if (RHASH_ITER_LEV(hash) == 0) {
01046             if (st_shift(RHASH(hash)->ntbl, &var.key, &var.val)) {
01047                 return rb_assoc_new(var.key, var.val);
01048             }
01049         }
01050         else {
01051             rb_hash_foreach(hash, shift_i_safe, (VALUE)&var);
01052             if (var.key != Qundef) {
01053                 rb_hash_delete_key(hash, var.key);
01054                 return rb_assoc_new(var.key, var.val);
01055             }
01056         }
01057     }
01058     return hash_default_value(hash, Qnil);
01059 }
01060 
01061 static int
01062 delete_if_i(VALUE key, VALUE value, VALUE hash)
01063 {
01064     if (RTEST(rb_yield_values(2, key, value))) {
01065         return ST_DELETE;
01066     }
01067     return ST_CONTINUE;
01068 }
01069 
01070 static VALUE rb_hash_size(VALUE hash);
01071 
01072 static VALUE
01073 hash_enum_size(VALUE hash, VALUE args, VALUE eobj)
01074 {
01075     return rb_hash_size(hash);
01076 }
01077 
01078 /*
01079  *  call-seq:
01080  *     hsh.delete_if {| key, value | block }  -> hsh
01081  *     hsh.delete_if                          -> an_enumerator
01082  *
01083  *  Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
01084  *  evaluates to <code>true</code>.
01085  *
01086  *  If no block is given, an enumerator is returned instead.
01087  *
01088  *     h = { "a" => 100, "b" => 200, "c" => 300 }
01089  *     h.delete_if {|key, value| key >= "b" }   #=> {"a"=>100}
01090  *
01091  */
01092 
01093 VALUE
01094 rb_hash_delete_if(VALUE hash)
01095 {
01096     RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
01097     rb_hash_modify_check(hash);
01098     if (RHASH(hash)->ntbl)
01099         rb_hash_foreach(hash, delete_if_i, hash);
01100     return hash;
01101 }
01102 
01103 /*
01104  *  call-seq:
01105  *     hsh.reject! {| key, value | block }  -> hsh or nil
01106  *     hsh.reject!                          -> an_enumerator
01107  *
01108  *  Equivalent to <code>Hash#delete_if</code>, but returns
01109  *  <code>nil</code> if no changes were made.
01110  */
01111 
01112 VALUE
01113 rb_hash_reject_bang(VALUE hash)
01114 {
01115     st_index_t n;
01116 
01117     RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
01118     rb_hash_modify(hash);
01119     n = RHASH_SIZE(hash);
01120     if (!n) return Qnil;
01121     rb_hash_foreach(hash, delete_if_i, hash);
01122     if (n == RHASH(hash)->ntbl->num_entries) return Qnil;
01123     return hash;
01124 }
01125 
01126 static int
01127 reject_i(VALUE key, VALUE value, VALUE result)
01128 {
01129     if (!RTEST(rb_yield_values(2, key, value))) {
01130         rb_hash_aset(result, key, value);
01131     }
01132     return ST_CONTINUE;
01133 }
01134 
01135 /*
01136  *  call-seq:
01137  *     hsh.reject {|key, value| block}   -> a_hash
01138  *     hsh.reject                        -> an_enumerator
01139  *
01140  *  Returns a new hash consisting of entries for which the block returns false.
01141  *
01142  *  If no block is given, an enumerator is returned instead.
01143  *
01144  *     h = { "a" => 100, "b" => 200, "c" => 300 }
01145  *     h.reject {|k,v| k < "b"}  #=> {"b" => 200, "c" => 300}
01146  *     h.reject {|k,v| v > 100}  #=> {"a" => 100}
01147  */
01148 
01149 VALUE
01150 rb_hash_reject(VALUE hash)
01151 {
01152     VALUE result;
01153 
01154     RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
01155     if (RTEST(ruby_verbose)) {
01156         VALUE klass;
01157         if (HAS_EXTRA_STATES(hash, klass)) {
01158 #if HASH_REJECT_COPY_EXTRA_STATES
01159             rb_warn("copying extra states: %+"PRIsVALUE, hash);
01160             rb_warn("following states will not be copied in the future version:");
01161             if (klass) {
01162                 rb_warn("  subclass: %+"PRIsVALUE, klass);
01163             }
01164             if (FL_TEST(hash, FL_EXIVAR)) {
01165                 rb_warn("  instance variables: %+"PRIsVALUE,
01166                         rb_obj_instance_variables(hash));
01167             }
01168             if (FL_TEST(hash, FL_TAINT)) {
01169                 rb_warn("  taintedness");
01170             }
01171             if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
01172                 rb_warn("  default proc: %+"PRIsVALUE, RHASH_IFNONE(hash));
01173             }
01174             else if (!NIL_P(RHASH_IFNONE(hash)))
01175                 rb_warn("  default value: %+"PRIsVALUE, RHASH_IFNONE(hash));
01176 #else
01177             rb_warn("extra states are no longer copied: %+"PRIsVALUE, hash);
01178 #endif
01179         }
01180     }
01181 #if HASH_REJECT_COPY_EXTRA_STATES
01182     result = rb_hash_dup_empty(hash);
01183 #else
01184     result = rb_hash_new();
01185 #endif
01186     if (!RHASH_EMPTY_P(hash)) {
01187         rb_hash_foreach(hash, reject_i, result);
01188     }
01189     return result;
01190 }
01191 
01192 /*
01193  * call-seq:
01194  *   hsh.values_at(key, ...)   -> array
01195  *
01196  * Return an array containing the values associated with the given keys.
01197  * Also see <code>Hash.select</code>.
01198  *
01199  *   h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
01200  *   h.values_at("cow", "cat")  #=> ["bovine", "feline"]
01201  */
01202 
01203 VALUE
01204 rb_hash_values_at(int argc, VALUE *argv, VALUE hash)
01205 {
01206     VALUE result = rb_ary_new2(argc);
01207     long i;
01208 
01209     for (i=0; i<argc; i++) {
01210         rb_ary_push(result, rb_hash_aref(hash, argv[i]));
01211     }
01212     return result;
01213 }
01214 
01215 static int
01216 select_i(VALUE key, VALUE value, VALUE result)
01217 {
01218     if (RTEST(rb_yield_values(2, key, value))) {
01219         rb_hash_aset(result, key, value);
01220     }
01221     return ST_CONTINUE;
01222 }
01223 
01224 /*
01225  *  call-seq:
01226  *     hsh.select {|key, value| block}   -> a_hash
01227  *     hsh.select                        -> an_enumerator
01228  *
01229  *  Returns a new hash consisting of entries for which the block returns true.
01230  *
01231  *  If no block is given, an enumerator is returned instead.
01232  *
01233  *     h = { "a" => 100, "b" => 200, "c" => 300 }
01234  *     h.select {|k,v| k > "a"}  #=> {"b" => 200, "c" => 300}
01235  *     h.select {|k,v| v < 200}  #=> {"a" => 100}
01236  */
01237 
01238 VALUE
01239 rb_hash_select(VALUE hash)
01240 {
01241     VALUE result;
01242 
01243     RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
01244     result = rb_hash_new();
01245     if (!RHASH_EMPTY_P(hash)) {
01246         rb_hash_foreach(hash, select_i, result);
01247     }
01248     return result;
01249 }
01250 
01251 static int
01252 keep_if_i(VALUE key, VALUE value, VALUE hash)
01253 {
01254     if (!RTEST(rb_yield_values(2, key, value))) {
01255         return ST_DELETE;
01256     }
01257     return ST_CONTINUE;
01258 }
01259 
01260 /*
01261  *  call-seq:
01262  *     hsh.select! {| key, value | block }  -> hsh or nil
01263  *     hsh.select!                          -> an_enumerator
01264  *
01265  *  Equivalent to <code>Hash#keep_if</code>, but returns
01266  *  <code>nil</code> if no changes were made.
01267  */
01268 
01269 VALUE
01270 rb_hash_select_bang(VALUE hash)
01271 {
01272     st_index_t n;
01273 
01274     RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
01275     rb_hash_modify_check(hash);
01276     if (!RHASH(hash)->ntbl)
01277         return Qnil;
01278     n = RHASH(hash)->ntbl->num_entries;
01279     rb_hash_foreach(hash, keep_if_i, hash);
01280     if (n == RHASH(hash)->ntbl->num_entries) return Qnil;
01281     return hash;
01282 }
01283 
01284 /*
01285  *  call-seq:
01286  *     hsh.keep_if {| key, value | block }  -> hsh
01287  *     hsh.keep_if                          -> an_enumerator
01288  *
01289  *  Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
01290  *  evaluates to false.
01291  *
01292  *  If no block is given, an enumerator is returned instead.
01293  *
01294  */
01295 
01296 VALUE
01297 rb_hash_keep_if(VALUE hash)
01298 {
01299     RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
01300     rb_hash_modify_check(hash);
01301     if (RHASH(hash)->ntbl)
01302         rb_hash_foreach(hash, keep_if_i, hash);
01303     return hash;
01304 }
01305 
01306 static int
01307 clear_i(VALUE key, VALUE value, VALUE dummy)
01308 {
01309     return ST_DELETE;
01310 }
01311 
01312 /*
01313  *  call-seq:
01314  *     hsh.clear -> hsh
01315  *
01316  *  Removes all key-value pairs from <i>hsh</i>.
01317  *
01318  *     h = { "a" => 100, "b" => 200 }   #=> {"a"=>100, "b"=>200}
01319  *     h.clear                          #=> {}
01320  *
01321  */
01322 
01323 VALUE
01324 rb_hash_clear(VALUE hash)
01325 {
01326     rb_hash_modify_check(hash);
01327     if (!RHASH(hash)->ntbl)
01328         return hash;
01329     if (RHASH(hash)->ntbl->num_entries > 0) {
01330         if (RHASH_ITER_LEV(hash) > 0)
01331             rb_hash_foreach(hash, clear_i, 0);
01332         else
01333             st_clear(RHASH(hash)->ntbl);
01334     }
01335 
01336     return hash;
01337 }
01338 
01339 static int
01340 hash_aset(st_data_t *key, st_data_t *val, struct update_arg *arg, int existing)
01341 {
01342     if (existing) {
01343         arg->new_value = arg->arg;
01344         arg->old_value = *val;
01345     }
01346     else {
01347         arg->new_key = *key;
01348         arg->new_value = arg->arg;
01349     }
01350     *val = arg->arg;
01351     return ST_CONTINUE;
01352 }
01353 
01354 static int
01355 hash_aset_str(st_data_t *key, st_data_t *val, struct update_arg *arg, int existing)
01356 {
01357     if (!existing) {
01358         *key = rb_str_new_frozen(*key);
01359     }
01360     return hash_aset(key, val, arg, existing);
01361 }
01362 
01363 NOINSERT_UPDATE_CALLBACK(hash_aset);
01364 NOINSERT_UPDATE_CALLBACK(hash_aset_str);
01365 
01366 /*
01367  *  call-seq:
01368  *     hsh[key] = value        -> value
01369  *     hsh.store(key, value)   -> value
01370  *
01371  *  == Element Assignment
01372  *
01373  *  Associates the value given by +value+ with the key given by +key+.
01374  *
01375  *     h = { "a" => 100, "b" => 200 }
01376  *     h["a"] = 9
01377  *     h["c"] = 4
01378  *     h   #=> {"a"=>9, "b"=>200, "c"=>4}
01379  *     h.store("d", 42) #=> {"a"=>9, "b"=>200, "c"=>4, "d"=>42}
01380  *
01381  *  +key+ should not have its value changed while it is in use as a key (an
01382  *  <tt>unfrozen String</tt> passed as a key will be duplicated and frozen).
01383  *
01384  *     a = "a"
01385  *     b = "b".freeze
01386  *     h = { a => 100, b => 200 }
01387  *     h.key(100).equal? a #=> false
01388  *     h.key(200).equal? b #=> true
01389  *
01390  */
01391 
01392 VALUE
01393 rb_hash_aset(VALUE hash, VALUE key, VALUE val)
01394 {
01395     int iter_lev = RHASH_ITER_LEV(hash);
01396     st_table *tbl = RHASH(hash)->ntbl;
01397 
01398     rb_hash_modify(hash);
01399     if (!tbl) {
01400         if (iter_lev > 0) no_new_key();
01401         tbl = hash_tbl(hash);
01402     }
01403     if (tbl->type == &identhash || rb_obj_class(key) != rb_cString) {
01404         RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset, val);
01405     }
01406     else {
01407         RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset_str, val);
01408     }
01409     return val;
01410 }
01411 
01412 static int
01413 replace_i(VALUE key, VALUE val, VALUE hash)
01414 {
01415     rb_hash_aset(hash, key, val);
01416 
01417     return ST_CONTINUE;
01418 }
01419 
01420 /* :nodoc: */
01421 static VALUE
01422 rb_hash_initialize_copy(VALUE hash, VALUE hash2)
01423 {
01424     st_table *ntbl;
01425 
01426     rb_hash_modify_check(hash);
01427     hash2 = to_hash(hash2);
01428 
01429     Check_Type(hash2, T_HASH);
01430 
01431     if (hash == hash2) return hash;
01432 
01433     ntbl = RHASH(hash)->ntbl;
01434     if (RHASH(hash2)->ntbl) {
01435         if (ntbl) st_free_table(ntbl);
01436         RHASH(hash)->ntbl = st_copy(RHASH(hash2)->ntbl);
01437         if (RHASH(hash)->ntbl->num_entries)
01438             rb_hash_rehash(hash);
01439     }
01440     else if (ntbl) {
01441         st_clear(ntbl);
01442     }
01443 
01444     if (FL_TEST(hash2, HASH_PROC_DEFAULT)) {
01445         FL_SET(hash, HASH_PROC_DEFAULT);
01446     }
01447     else {
01448         FL_UNSET(hash, HASH_PROC_DEFAULT);
01449     }
01450     RHASH_SET_IFNONE(hash, RHASH_IFNONE(hash2));
01451 
01452     return hash;
01453 }
01454 
01455 /*
01456  *  call-seq:
01457  *     hsh.replace(other_hash) -> hsh
01458  *
01459  *  Replaces the contents of <i>hsh</i> with the contents of
01460  *  <i>other_hash</i>.
01461  *
01462  *     h = { "a" => 100, "b" => 200 }
01463  *     h.replace({ "c" => 300, "d" => 400 })   #=> {"c"=>300, "d"=>400}
01464  *
01465  */
01466 
01467 static VALUE
01468 rb_hash_replace(VALUE hash, VALUE hash2)
01469 {
01470     st_table *table2;
01471 
01472     rb_hash_modify_check(hash);
01473     if (hash == hash2) return hash;
01474     hash2 = to_hash(hash2);
01475 
01476     RHASH_SET_IFNONE(hash, RHASH_IFNONE(hash2));
01477     if (FL_TEST(hash2, HASH_PROC_DEFAULT))
01478         FL_SET(hash, HASH_PROC_DEFAULT);
01479     else
01480         FL_UNSET(hash, HASH_PROC_DEFAULT);
01481 
01482     table2 = RHASH(hash2)->ntbl;
01483 
01484     rb_hash_clear(hash);
01485     if (table2) hash_tbl(hash)->type = table2->type;
01486     rb_hash_foreach(hash2, replace_i, hash);
01487 
01488     return hash;
01489 }
01490 
01491 /*
01492  *  call-seq:
01493  *     hsh.length    ->  fixnum
01494  *     hsh.size      ->  fixnum
01495  *
01496  *  Returns the number of key-value pairs in the hash.
01497  *
01498  *     h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
01499  *     h.length        #=> 4
01500  *     h.delete("a")   #=> 200
01501  *     h.length        #=> 3
01502  */
01503 
01504 static VALUE
01505 rb_hash_size(VALUE hash)
01506 {
01507     return INT2FIX(RHASH_SIZE(hash));
01508 }
01509 
01510 
01511 /*
01512  *  call-seq:
01513  *     hsh.empty?    -> true or false
01514  *
01515  *  Returns <code>true</code> if <i>hsh</i> contains no key-value pairs.
01516  *
01517  *     {}.empty?   #=> true
01518  *
01519  */
01520 
01521 static VALUE
01522 rb_hash_empty_p(VALUE hash)
01523 {
01524     return RHASH_EMPTY_P(hash) ? Qtrue : Qfalse;
01525 }
01526 
01527 static int
01528 each_value_i(VALUE key, VALUE value)
01529 {
01530     rb_yield(value);
01531     return ST_CONTINUE;
01532 }
01533 
01534 /*
01535  *  call-seq:
01536  *     hsh.each_value {| value | block } -> hsh
01537  *     hsh.each_value                    -> an_enumerator
01538  *
01539  *  Calls <i>block</i> once for each key in <i>hsh</i>, passing the
01540  *  value as a parameter.
01541  *
01542  *  If no block is given, an enumerator is returned instead.
01543  *
01544  *     h = { "a" => 100, "b" => 200 }
01545  *     h.each_value {|value| puts value }
01546  *
01547  *  <em>produces:</em>
01548  *
01549  *     100
01550  *     200
01551  */
01552 
01553 static VALUE
01554 rb_hash_each_value(VALUE hash)
01555 {
01556     RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
01557     rb_hash_foreach(hash, each_value_i, 0);
01558     return hash;
01559 }
01560 
01561 static int
01562 each_key_i(VALUE key, VALUE value)
01563 {
01564     rb_yield(key);
01565     return ST_CONTINUE;
01566 }
01567 
01568 /*
01569  *  call-seq:
01570  *     hsh.each_key {| key | block } -> hsh
01571  *     hsh.each_key                  -> an_enumerator
01572  *
01573  *  Calls <i>block</i> once for each key in <i>hsh</i>, passing the key
01574  *  as a parameter.
01575  *
01576  *  If no block is given, an enumerator is returned instead.
01577  *
01578  *     h = { "a" => 100, "b" => 200 }
01579  *     h.each_key {|key| puts key }
01580  *
01581  *  <em>produces:</em>
01582  *
01583  *     a
01584  *     b
01585  */
01586 static VALUE
01587 rb_hash_each_key(VALUE hash)
01588 {
01589     RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
01590     rb_hash_foreach(hash, each_key_i, 0);
01591     return hash;
01592 }
01593 
01594 static int
01595 each_pair_i(VALUE key, VALUE value)
01596 {
01597     rb_yield(rb_assoc_new(key, value));
01598     return ST_CONTINUE;
01599 }
01600 
01601 static int
01602 each_pair_i_fast(VALUE key, VALUE value)
01603 {
01604     rb_yield_values(2, key, value);
01605     return ST_CONTINUE;
01606 }
01607 
01608 /*
01609  *  call-seq:
01610  *     hsh.each      {| key, value | block } -> hsh
01611  *     hsh.each_pair {| key, value | block } -> hsh
01612  *     hsh.each                              -> an_enumerator
01613  *     hsh.each_pair                         -> an_enumerator
01614  *
01615  *  Calls <i>block</i> once for each key in <i>hsh</i>, passing the key-value
01616  *  pair as parameters.
01617  *
01618  *  If no block is given, an enumerator is returned instead.
01619  *
01620  *     h = { "a" => 100, "b" => 200 }
01621  *     h.each {|key, value| puts "#{key} is #{value}" }
01622  *
01623  *  <em>produces:</em>
01624  *
01625  *     a is 100
01626  *     b is 200
01627  *
01628  */
01629 
01630 static VALUE
01631 rb_hash_each_pair(VALUE hash)
01632 {
01633     RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
01634     if (rb_block_arity() > 1)
01635         rb_hash_foreach(hash, each_pair_i_fast, 0);
01636     else
01637         rb_hash_foreach(hash, each_pair_i, 0);
01638     return hash;
01639 }
01640 
01641 static int
01642 to_a_i(VALUE key, VALUE value, VALUE ary)
01643 {
01644     rb_ary_push(ary, rb_assoc_new(key, value));
01645     return ST_CONTINUE;
01646 }
01647 
01648 /*
01649  *  call-seq:
01650  *     hsh.to_a -> array
01651  *
01652  *  Converts <i>hsh</i> to a nested array of <code>[</code> <i>key,
01653  *  value</i> <code>]</code> arrays.
01654  *
01655  *     h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300  }
01656  *     h.to_a   #=> [["c", 300], ["a", 100], ["d", 400]]
01657  */
01658 
01659 static VALUE
01660 rb_hash_to_a(VALUE hash)
01661 {
01662     VALUE ary;
01663 
01664     ary = rb_ary_new_capa(RHASH_SIZE(hash));
01665     rb_hash_foreach(hash, to_a_i, ary);
01666     OBJ_INFECT(ary, hash);
01667 
01668     return ary;
01669 }
01670 
01671 static int
01672 inspect_i(VALUE key, VALUE value, VALUE str)
01673 {
01674     VALUE str2;
01675 
01676     str2 = rb_inspect(key);
01677     if (RSTRING_LEN(str) > 1) {
01678         rb_str_buf_cat_ascii(str, ", ");
01679     }
01680     else {
01681         rb_enc_copy(str, str2);
01682     }
01683     rb_str_buf_append(str, str2);
01684     OBJ_INFECT(str, str2);
01685     rb_str_buf_cat_ascii(str, "=>");
01686     str2 = rb_inspect(value);
01687     rb_str_buf_append(str, str2);
01688     OBJ_INFECT(str, str2);
01689 
01690     return ST_CONTINUE;
01691 }
01692 
01693 static VALUE
01694 inspect_hash(VALUE hash, VALUE dummy, int recur)
01695 {
01696     VALUE str;
01697 
01698     if (recur) return rb_usascii_str_new2("{...}");
01699     str = rb_str_buf_new2("{");
01700     rb_hash_foreach(hash, inspect_i, str);
01701     rb_str_buf_cat2(str, "}");
01702     OBJ_INFECT(str, hash);
01703 
01704     return str;
01705 }
01706 
01707 /*
01708  * call-seq:
01709  *   hsh.to_s     -> string
01710  *   hsh.inspect  -> string
01711  *
01712  * Return the contents of this hash as a string.
01713  *
01714  *     h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300  }
01715  *     h.to_s   #=> "{\"c\"=>300, \"a\"=>100, \"d\"=>400}"
01716  */
01717 
01718 static VALUE
01719 rb_hash_inspect(VALUE hash)
01720 {
01721     if (RHASH_EMPTY_P(hash))
01722         return rb_usascii_str_new2("{}");
01723     return rb_exec_recursive(inspect_hash, hash, 0);
01724 }
01725 
01726 /*
01727  * call-seq:
01728  *    hsh.to_hash   => hsh
01729  *
01730  * Returns +self+.
01731  */
01732 
01733 static VALUE
01734 rb_hash_to_hash(VALUE hash)
01735 {
01736     return hash;
01737 }
01738 
01739 /*
01740  *  call-seq:
01741  *     hsh.to_h     -> hsh or new_hash
01742  *
01743  *  Returns +self+. If called on a subclass of Hash, converts
01744  *  the receiver to a Hash object.
01745  */
01746 
01747 static VALUE
01748 rb_hash_to_h(VALUE hash)
01749 {
01750     if (rb_obj_class(hash) != rb_cHash) {
01751         VALUE ret = rb_hash_new();
01752         if (!RHASH_EMPTY_P(hash))
01753             RHASH(ret)->ntbl = st_copy(RHASH(hash)->ntbl);
01754         if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
01755             FL_SET(ret, HASH_PROC_DEFAULT);
01756         }
01757         RHASH_SET_IFNONE(ret, RHASH_IFNONE(hash));
01758         return ret;
01759     }
01760     return hash;
01761 }
01762 
01763 static int
01764 keys_i(VALUE key, VALUE value, VALUE ary)
01765 {
01766     rb_ary_push(ary, key);
01767     return ST_CONTINUE;
01768 }
01769 
01770 /*
01771  *  call-seq:
01772  *     hsh.keys    -> array
01773  *
01774  *  Returns a new array populated with the keys from this hash. See also
01775  *  <code>Hash#values</code>.
01776  *
01777  *     h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 }
01778  *     h.keys   #=> ["a", "b", "c", "d"]
01779  *
01780  */
01781 
01782 VALUE
01783 rb_hash_keys(VALUE hash)
01784 {
01785     VALUE keys;
01786     st_index_t size = RHASH_SIZE(hash);
01787 
01788     keys = rb_ary_new_capa(size);
01789     if (size == 0) return keys;
01790 
01791     if (ST_DATA_COMPATIBLE_P(VALUE)) {
01792         st_table *table = RHASH(hash)->ntbl;
01793 
01794         if (OBJ_PROMOTED(keys)) rb_gc_writebarrier_remember_promoted(keys);
01795         RARRAY_PTR_USE(keys, ptr, {
01796             size = st_keys_check(table, ptr, size, Qundef);
01797         });
01798         rb_ary_set_len(keys, size);
01799     }
01800     else {
01801         rb_hash_foreach(hash, keys_i, keys);
01802     }
01803 
01804     return keys;
01805 }
01806 
01807 static int
01808 values_i(VALUE key, VALUE value, VALUE ary)
01809 {
01810     rb_ary_push(ary, value);
01811     return ST_CONTINUE;
01812 }
01813 
01814 /*
01815  *  call-seq:
01816  *     hsh.values    -> array
01817  *
01818  *  Returns a new array populated with the values from <i>hsh</i>. See
01819  *  also <code>Hash#keys</code>.
01820  *
01821  *     h = { "a" => 100, "b" => 200, "c" => 300 }
01822  *     h.values   #=> [100, 200, 300]
01823  *
01824  */
01825 
01826 VALUE
01827 rb_hash_values(VALUE hash)
01828 {
01829     VALUE values;
01830     st_index_t size = RHASH_SIZE(hash);
01831 
01832     values = rb_ary_new_capa(size);
01833     if (size == 0) return values;
01834 
01835     if (ST_DATA_COMPATIBLE_P(VALUE)) {
01836         st_table *table = RHASH(hash)->ntbl;
01837 
01838         if (OBJ_PROMOTED(values)) rb_gc_writebarrier_remember_promoted(values);
01839         RARRAY_PTR_USE(values, ptr, {
01840             size = st_values_check(table, ptr, size, Qundef);
01841         });
01842         rb_ary_set_len(values, size);
01843     }
01844     else {
01845         rb_hash_foreach(hash, values_i, values);
01846     }
01847 
01848     return values;
01849 }
01850 
01851 /*
01852  *  call-seq:
01853  *     hsh.has_key?(key)    -> true or false
01854  *     hsh.include?(key)    -> true or false
01855  *     hsh.key?(key)        -> true or false
01856  *     hsh.member?(key)     -> true or false
01857  *
01858  *  Returns <code>true</code> if the given key is present in <i>hsh</i>.
01859  *
01860  *     h = { "a" => 100, "b" => 200 }
01861  *     h.has_key?("a")   #=> true
01862  *     h.has_key?("z")   #=> false
01863  *
01864  */
01865 
01866 static VALUE
01867 rb_hash_has_key(VALUE hash, VALUE key)
01868 {
01869     if (!RHASH(hash)->ntbl)
01870         return Qfalse;
01871     if (st_lookup(RHASH(hash)->ntbl, key, 0)) {
01872         return Qtrue;
01873     }
01874     return Qfalse;
01875 }
01876 
01877 static int
01878 rb_hash_search_value(VALUE key, VALUE value, VALUE arg)
01879 {
01880     VALUE *data = (VALUE *)arg;
01881 
01882     if (rb_equal(value, data[1])) {
01883         data[0] = Qtrue;
01884         return ST_STOP;
01885     }
01886     return ST_CONTINUE;
01887 }
01888 
01889 /*
01890  *  call-seq:
01891  *     hsh.has_value?(value)    -> true or false
01892  *     hsh.value?(value)        -> true or false
01893  *
01894  *  Returns <code>true</code> if the given value is present for some key
01895  *  in <i>hsh</i>.
01896  *
01897  *     h = { "a" => 100, "b" => 200 }
01898  *     h.has_value?(100)   #=> true
01899  *     h.has_value?(999)   #=> false
01900  */
01901 
01902 static VALUE
01903 rb_hash_has_value(VALUE hash, VALUE val)
01904 {
01905     VALUE data[2];
01906 
01907     data[0] = Qfalse;
01908     data[1] = val;
01909     rb_hash_foreach(hash, rb_hash_search_value, (VALUE)data);
01910     return data[0];
01911 }
01912 
01913 struct equal_data {
01914     VALUE result;
01915     st_table *tbl;
01916     int eql;
01917 };
01918 
01919 static int
01920 eql_i(VALUE key, VALUE val1, VALUE arg)
01921 {
01922     struct equal_data *data = (struct equal_data *)arg;
01923     st_data_t val2;
01924 
01925     if (!st_lookup(data->tbl, key, &val2)) {
01926         data->result = Qfalse;
01927         return ST_STOP;
01928     }
01929     if (!(data->eql ? rb_eql(val1, (VALUE)val2) : (int)rb_equal(val1, (VALUE)val2))) {
01930         data->result = Qfalse;
01931         return ST_STOP;
01932     }
01933     return ST_CONTINUE;
01934 }
01935 
01936 static VALUE
01937 recursive_eql(VALUE hash, VALUE dt, int recur)
01938 {
01939     struct equal_data *data;
01940 
01941     if (recur) return Qtrue;    /* Subtle! */
01942     data = (struct equal_data*)dt;
01943     data->result = Qtrue;
01944     rb_hash_foreach(hash, eql_i, dt);
01945 
01946     return data->result;
01947 }
01948 
01949 static VALUE
01950 hash_equal(VALUE hash1, VALUE hash2, int eql)
01951 {
01952     struct equal_data data;
01953 
01954     if (hash1 == hash2) return Qtrue;
01955     if (!RB_TYPE_P(hash2, T_HASH)) {
01956         if (!rb_respond_to(hash2, rb_intern("to_hash"))) {
01957             return Qfalse;
01958         }
01959         if (eql)
01960             return rb_eql(hash2, hash1);
01961         else
01962             return rb_equal(hash2, hash1);
01963     }
01964     if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2))
01965         return Qfalse;
01966     if (!RHASH(hash1)->ntbl || !RHASH(hash2)->ntbl)
01967         return Qtrue;
01968     if (RHASH(hash1)->ntbl->type != RHASH(hash2)->ntbl->type)
01969         return Qfalse;
01970 #if 0
01971     if (!(rb_equal(RHASH_IFNONE(hash1), RHASH_IFNONE(hash2)) &&
01972           FL_TEST(hash1, HASH_PROC_DEFAULT) == FL_TEST(hash2, HASH_PROC_DEFAULT)))
01973         return Qfalse;
01974 #endif
01975 
01976     data.tbl = RHASH(hash2)->ntbl;
01977     data.eql = eql;
01978     return rb_exec_recursive_paired(recursive_eql, hash1, hash2, (VALUE)&data);
01979 }
01980 
01981 /*
01982  *  call-seq:
01983  *     hsh == other_hash    -> true or false
01984  *
01985  *  Equality---Two hashes are equal if they each contain the same number
01986  *  of keys and if each key-value pair is equal to (according to
01987  *  <code>Object#==</code>) the corresponding elements in the other
01988  *  hash.
01989  *
01990  *     h1 = { "a" => 1, "c" => 2 }
01991  *     h2 = { 7 => 35, "c" => 2, "a" => 1 }
01992  *     h3 = { "a" => 1, "c" => 2, 7 => 35 }
01993  *     h4 = { "a" => 1, "d" => 2, "f" => 35 }
01994  *     h1 == h2   #=> false
01995  *     h2 == h3   #=> true
01996  *     h3 == h4   #=> false
01997  *
01998  */
01999 
02000 static VALUE
02001 rb_hash_equal(VALUE hash1, VALUE hash2)
02002 {
02003     return hash_equal(hash1, hash2, FALSE);
02004 }
02005 
02006 /*
02007  *  call-seq:
02008  *     hash.eql?(other)  -> true or false
02009  *
02010  *  Returns <code>true</code> if <i>hash</i> and <i>other</i> are
02011  *  both hashes with the same content.
02012  */
02013 
02014 static VALUE
02015 rb_hash_eql(VALUE hash1, VALUE hash2)
02016 {
02017     return hash_equal(hash1, hash2, TRUE);
02018 }
02019 
02020 static int
02021 hash_i(VALUE key, VALUE val, VALUE arg)
02022 {
02023     st_index_t *hval = (st_index_t *)arg;
02024     st_index_t hdata[2];
02025 
02026     hdata[0] = rb_hash(key);
02027     hdata[1] = rb_hash(val);
02028     *hval ^= st_hash(hdata, sizeof(hdata), 0);
02029     return ST_CONTINUE;
02030 }
02031 
02032 /*
02033  *  call-seq:
02034  *     hsh.hash   -> fixnum
02035  *
02036  *  Compute a hash-code for this hash. Two hashes with the same content
02037  *  will have the same hash code (and will compare using <code>eql?</code>).
02038  */
02039 
02040 static VALUE
02041 rb_hash_hash(VALUE hash)
02042 {
02043     st_index_t size = RHASH_SIZE(hash);
02044     st_index_t hval = rb_hash_start(size);
02045     hval = rb_hash_uint(hval, (st_index_t)rb_hash_hash);
02046     if (size) {
02047         rb_hash_foreach(hash, hash_i, (VALUE)&hval);
02048     }
02049     hval = rb_hash_end(hval);
02050     return INT2FIX(hval);
02051 }
02052 
02053 static int
02054 rb_hash_invert_i(VALUE key, VALUE value, VALUE hash)
02055 {
02056     rb_hash_aset(hash, value, key);
02057     return ST_CONTINUE;
02058 }
02059 
02060 /*
02061  *  call-seq:
02062  *     hsh.invert -> new_hash
02063  *
02064  *  Returns a new hash created by using <i>hsh</i>'s values as keys, and
02065  *  the keys as values.
02066  *
02067  *     h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 }
02068  *     h.invert   #=> {0=>"a", 100=>"m", 200=>"d", 300=>"y"}
02069  *
02070  */
02071 
02072 static VALUE
02073 rb_hash_invert(VALUE hash)
02074 {
02075     VALUE h = rb_hash_new();
02076 
02077     rb_hash_foreach(hash, rb_hash_invert_i, h);
02078     return h;
02079 }
02080 
02081 static int
02082 rb_hash_update_callback(st_data_t *key, st_data_t *value, struct update_arg *arg, int existing)
02083 {
02084     if (existing) {
02085         arg->old_value = *value;
02086         arg->new_value = arg->arg;
02087     }
02088     else {
02089         arg->new_key = *key;
02090         arg->new_value = arg->arg;
02091     }
02092     *value = arg->arg;
02093     return ST_CONTINUE;
02094 }
02095 
02096 NOINSERT_UPDATE_CALLBACK(rb_hash_update_callback);
02097 
02098 static int
02099 rb_hash_update_i(VALUE key, VALUE value, VALUE hash)
02100 {
02101     RHASH_UPDATE(hash, key, rb_hash_update_callback, value);
02102     return ST_CONTINUE;
02103 }
02104 
02105 static int
02106 rb_hash_update_block_callback(st_data_t *key, st_data_t *value, struct update_arg *arg, int existing)
02107 {
02108     VALUE newvalue = (VALUE)arg->arg;
02109 
02110     if (existing) {
02111         newvalue = rb_yield_values(3, (VALUE)*key, (VALUE)*value, newvalue);
02112         arg->old_value = *value;
02113         arg->new_value = newvalue;
02114     }
02115     else {
02116         arg->new_key = *key;
02117         arg->new_value = newvalue;
02118     }
02119     *value = newvalue;
02120     return ST_CONTINUE;
02121 }
02122 
02123 NOINSERT_UPDATE_CALLBACK(rb_hash_update_block_callback);
02124 
02125 static int
02126 rb_hash_update_block_i(VALUE key, VALUE value, VALUE hash)
02127 {
02128     RHASH_UPDATE(hash, key, rb_hash_update_block_callback, value);
02129     return ST_CONTINUE;
02130 }
02131 
02132 /*
02133  *  call-seq:
02134  *     hsh.merge!(other_hash)                                 -> hsh
02135  *     hsh.update(other_hash)                                 -> hsh
02136  *     hsh.merge!(other_hash){|key, oldval, newval| block}    -> hsh
02137  *     hsh.update(other_hash){|key, oldval, newval| block}    -> hsh
02138  *
02139  *  Adds the contents of _other_hash_ to _hsh_.  If no block is specified,
02140  *  entries with duplicate keys are overwritten with the values from
02141  *  _other_hash_, otherwise the value of each duplicate key is determined by
02142  *  calling the block with the key, its value in _hsh_ and its value in
02143  *  _other_hash_.
02144  *
02145  *     h1 = { "a" => 100, "b" => 200 }
02146  *     h2 = { "b" => 254, "c" => 300 }
02147  *     h1.merge!(h2)   #=> {"a"=>100, "b"=>254, "c"=>300}
02148  *
02149  *     h1 = { "a" => 100, "b" => 200 }
02150  *     h2 = { "b" => 254, "c" => 300 }
02151  *     h1.merge!(h2) { |key, v1, v2| v1 }
02152  *                     #=> {"a"=>100, "b"=>200, "c"=>300}
02153  */
02154 
02155 static VALUE
02156 rb_hash_update(VALUE hash1, VALUE hash2)
02157 {
02158     rb_hash_modify(hash1);
02159     hash2 = to_hash(hash2);
02160     if (rb_block_given_p()) {
02161         rb_hash_foreach(hash2, rb_hash_update_block_i, hash1);
02162     }
02163     else {
02164         rb_hash_foreach(hash2, rb_hash_update_i, hash1);
02165     }
02166     return hash1;
02167 }
02168 
02169 struct update_func_arg {
02170     VALUE hash;
02171     VALUE value;
02172     rb_hash_update_func *func;
02173 };
02174 
02175 static int
02176 rb_hash_update_func_callback(st_data_t *key, st_data_t *value, struct update_arg *arg, int existing)
02177 {
02178     struct update_func_arg *uf_arg = (struct update_func_arg *)arg->arg;
02179     VALUE newvalue = uf_arg->value;
02180 
02181     if (existing) {
02182         newvalue = (*uf_arg->func)((VALUE)*key, (VALUE)*value, newvalue);
02183         arg->old_value = *value;
02184         arg->new_value = newvalue;
02185     }
02186     else {
02187         arg->new_key = *key;
02188         arg->new_value = newvalue;
02189     }
02190     *value = newvalue;
02191     return ST_CONTINUE;
02192 }
02193 
02194 NOINSERT_UPDATE_CALLBACK(rb_hash_update_func_callback);
02195 
02196 static int
02197 rb_hash_update_func_i(VALUE key, VALUE value, VALUE arg0)
02198 {
02199     struct update_func_arg *arg = (struct update_func_arg *)arg0;
02200     VALUE hash = arg->hash;
02201 
02202     arg->value = value;
02203     RHASH_UPDATE(hash, key, rb_hash_update_func_callback, (VALUE)arg);
02204     return ST_CONTINUE;
02205 }
02206 
02207 VALUE
02208 rb_hash_update_by(VALUE hash1, VALUE hash2, rb_hash_update_func *func)
02209 {
02210     rb_hash_modify(hash1);
02211     hash2 = to_hash(hash2);
02212     if (func) {
02213         struct update_func_arg arg;
02214         arg.hash = hash1;
02215         arg.func = func;
02216         rb_hash_foreach(hash2, rb_hash_update_func_i, (VALUE)&arg);
02217     }
02218     else {
02219         rb_hash_foreach(hash2, rb_hash_update_i, hash1);
02220     }
02221     return hash1;
02222 }
02223 
02224 /*
02225  *  call-seq:
02226  *     hsh.merge(other_hash)                              -> new_hash
02227  *     hsh.merge(other_hash){|key, oldval, newval| block} -> new_hash
02228  *
02229  *  Returns a new hash containing the contents of <i>other_hash</i> and
02230  *  the contents of <i>hsh</i>. If no block is specified, the value for
02231  *  entries with duplicate keys will be that of <i>other_hash</i>. Otherwise
02232  *  the value for each duplicate key is determined by calling the block
02233  *  with the key, its value in <i>hsh</i> and its value in <i>other_hash</i>.
02234  *
02235  *     h1 = { "a" => 100, "b" => 200 }
02236  *     h2 = { "b" => 254, "c" => 300 }
02237  *     h1.merge(h2)   #=> {"a"=>100, "b"=>254, "c"=>300}
02238  *     h1.merge(h2){|key, oldval, newval| newval - oldval}
02239  *                    #=> {"a"=>100, "b"=>54,  "c"=>300}
02240  *     h1             #=> {"a"=>100, "b"=>200}
02241  *
02242  */
02243 
02244 static VALUE
02245 rb_hash_merge(VALUE hash1, VALUE hash2)
02246 {
02247     return rb_hash_update(rb_obj_dup(hash1), hash2);
02248 }
02249 
02250 static int
02251 assoc_cmp(VALUE a, VALUE b)
02252 {
02253     return !RTEST(rb_equal(a, b));
02254 }
02255 
02256 static VALUE
02257 lookup2_call(VALUE arg)
02258 {
02259     VALUE *args = (VALUE *)arg;
02260     return rb_hash_lookup2(args[0], args[1], Qundef);
02261 }
02262 
02263 struct reset_hash_type_arg {
02264     VALUE hash;
02265     const struct st_hash_type *orighash;
02266 };
02267 
02268 static VALUE
02269 reset_hash_type(VALUE arg)
02270 {
02271     struct reset_hash_type_arg *p = (struct reset_hash_type_arg *)arg;
02272     RHASH(p->hash)->ntbl->type = p->orighash;
02273     return Qundef;
02274 }
02275 
02276 static int
02277 assoc_i(VALUE key, VALUE val, VALUE arg)
02278 {
02279     VALUE *args = (VALUE *)arg;
02280 
02281     if (RTEST(rb_equal(args[0], key))) {
02282         args[1] = rb_assoc_new(key, val);
02283         return ST_STOP;
02284     }
02285     return ST_CONTINUE;
02286 }
02287 
02288 /*
02289  *  call-seq:
02290  *     hash.assoc(obj)   ->  an_array  or  nil
02291  *
02292  *  Searches through the hash comparing _obj_ with the key using <code>==</code>.
02293  *  Returns the key-value pair (two elements array) or +nil+
02294  *  if no match is found.  See <code>Array#assoc</code>.
02295  *
02296  *     h = {"colors"  => ["red", "blue", "green"],
02297  *          "letters" => ["a", "b", "c" ]}
02298  *     h.assoc("letters")  #=> ["letters", ["a", "b", "c"]]
02299  *     h.assoc("foo")      #=> nil
02300  */
02301 
02302 VALUE
02303 rb_hash_assoc(VALUE hash, VALUE key)
02304 {
02305     st_table *table;
02306     const struct st_hash_type *orighash;
02307     VALUE args[2];
02308 
02309     if (RHASH_EMPTY_P(hash)) return Qnil;
02310     table = RHASH(hash)->ntbl;
02311     orighash = table->type;
02312 
02313     if (orighash != &identhash) {
02314         VALUE value;
02315         struct reset_hash_type_arg ensure_arg;
02316         struct st_hash_type assochash;
02317 
02318         assochash.compare = assoc_cmp;
02319         assochash.hash = orighash->hash;
02320         table->type = &assochash;
02321         args[0] = hash;
02322         args[1] = key;
02323         ensure_arg.hash = hash;
02324         ensure_arg.orighash = orighash;
02325         value = rb_ensure(lookup2_call, (VALUE)&args, reset_hash_type, (VALUE)&ensure_arg);
02326         if (value != Qundef) return rb_assoc_new(key, value);
02327     }
02328 
02329     args[0] = key;
02330     args[1] = Qnil;
02331     rb_hash_foreach(hash, assoc_i, (VALUE)args);
02332     return args[1];
02333 }
02334 
02335 static int
02336 rassoc_i(VALUE key, VALUE val, VALUE arg)
02337 {
02338     VALUE *args = (VALUE *)arg;
02339 
02340     if (RTEST(rb_equal(args[0], val))) {
02341         args[1] = rb_assoc_new(key, val);
02342         return ST_STOP;
02343     }
02344     return ST_CONTINUE;
02345 }
02346 
02347 /*
02348  *  call-seq:
02349  *     hash.rassoc(obj) -> an_array or nil
02350  *
02351  *  Searches through the hash comparing _obj_ with the value using <code>==</code>.
02352  *  Returns the first key-value pair (two-element array) that matches. See
02353  *  also <code>Array#rassoc</code>.
02354  *
02355  *     a = {1=> "one", 2 => "two", 3 => "three", "ii" => "two"}
02356  *     a.rassoc("two")    #=> [2, "two"]
02357  *     a.rassoc("four")   #=> nil
02358  */
02359 
02360 VALUE
02361 rb_hash_rassoc(VALUE hash, VALUE obj)
02362 {
02363     VALUE args[2];
02364 
02365     args[0] = obj;
02366     args[1] = Qnil;
02367     rb_hash_foreach(hash, rassoc_i, (VALUE)args);
02368     return args[1];
02369 }
02370 
02371 static int
02372 flatten_i(VALUE key, VALUE val, VALUE ary)
02373 {
02374     VALUE pair[2];
02375 
02376     pair[0] = key;
02377     pair[1] = val;
02378     rb_ary_cat(ary, pair, 2);
02379 
02380     return ST_CONTINUE;
02381 }
02382 
02383 /*
02384  *  call-seq:
02385  *     hash.flatten -> an_array
02386  *     hash.flatten(level) -> an_array
02387  *
02388  *  Returns a new array that is a one-dimensional flattening of this
02389  *  hash. That is, for every key or value that is an array, extract
02390  *  its elements into the new array.  Unlike Array#flatten, this
02391  *  method does not flatten recursively by default.  The optional
02392  *  <i>level</i> argument determines the level of recursion to flatten.
02393  *
02394  *     a =  {1=> "one", 2 => [2,"two"], 3 => "three"}
02395  *     a.flatten    # => [1, "one", 2, [2, "two"], 3, "three"]
02396  *     a.flatten(2) # => [1, "one", 2, 2, "two", 3, "three"]
02397  */
02398 
02399 static VALUE
02400 rb_hash_flatten(int argc, VALUE *argv, VALUE hash)
02401 {
02402     VALUE ary;
02403 
02404     if (argc) {
02405         int level = NUM2INT(*argv);
02406         if (level == 0) return rb_hash_to_a(hash);
02407 
02408         ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2);
02409         rb_hash_foreach(hash, flatten_i, ary);
02410         if (level - 1 > 0) {
02411             *argv = INT2FIX(level - 1);
02412             rb_funcall2(ary, id_flatten_bang, argc, argv);
02413         }
02414         else if (level < 0) {
02415             rb_funcall2(ary, id_flatten_bang, 0, 0);
02416         }
02417     }
02418     else {
02419         ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2);
02420         rb_hash_foreach(hash, flatten_i, ary);
02421     }
02422 
02423     return ary;
02424 }
02425 
02426 static VALUE rb_hash_compare_by_id_p(VALUE hash);
02427 
02428 /*
02429  *  call-seq:
02430  *     hsh.compare_by_identity -> hsh
02431  *
02432  *  Makes <i>hsh</i> compare its keys by their identity, i.e. it
02433  *  will consider exact same objects as same keys.
02434  *
02435  *     h1 = { "a" => 100, "b" => 200, :c => "c" }
02436  *     h1["a"]        #=> 100
02437  *     h1.compare_by_identity
02438  *     h1.compare_by_identity? #=> true
02439  *     h1["a"]        #=> nil  # different objects.
02440  *     h1[:c]         #=> "c"  # same symbols are all same.
02441  *
02442  */
02443 
02444 static VALUE
02445 rb_hash_compare_by_id(VALUE hash)
02446 {
02447     if (rb_hash_compare_by_id_p(hash)) return hash;
02448     rb_hash_modify(hash);
02449     RHASH(hash)->ntbl->type = &identhash;
02450     rb_hash_rehash(hash);
02451     return hash;
02452 }
02453 
02454 /*
02455  *  call-seq:
02456  *     hsh.compare_by_identity? -> true or false
02457  *
02458  *  Returns <code>true</code> if <i>hsh</i> will compare its keys by
02459  *  their identity.  Also see <code>Hash#compare_by_identity</code>.
02460  *
02461  */
02462 
02463 static VALUE
02464 rb_hash_compare_by_id_p(VALUE hash)
02465 {
02466     if (!RHASH(hash)->ntbl)
02467         return Qfalse;
02468     if (RHASH(hash)->ntbl->type == &identhash) {
02469         return Qtrue;
02470     }
02471     return Qfalse;
02472 }
02473 
02474 static int path_tainted = -1;
02475 
02476 static char **origenviron;
02477 #ifdef _WIN32
02478 #define GET_ENVIRON(e) ((e) = rb_w32_get_environ())
02479 #define FREE_ENVIRON(e) rb_w32_free_environ(e)
02480 static char **my_environ;
02481 #undef environ
02482 #define environ my_environ
02483 #undef getenv
02484 static inline char *
02485 w32_getenv(const char *name)
02486 {
02487     static int binary = -1;
02488     static int locale = -1;
02489     if (binary < 0) {
02490         binary = rb_ascii8bit_encindex();
02491         locale = rb_locale_encindex();
02492     }
02493     return locale == binary ? rb_w32_getenv(name) : rb_w32_ugetenv(name);
02494 }
02495 #define getenv(n) w32_getenv(n)
02496 #elif defined(__APPLE__)
02497 #undef environ
02498 #define environ (*_NSGetEnviron())
02499 #define GET_ENVIRON(e) (e)
02500 #define FREE_ENVIRON(e)
02501 #else
02502 extern char **environ;
02503 #define GET_ENVIRON(e) (e)
02504 #define FREE_ENVIRON(e)
02505 #endif
02506 #ifdef ENV_IGNORECASE
02507 #define ENVMATCH(s1, s2) (STRCASECMP((s1), (s2)) == 0)
02508 #define ENVNMATCH(s1, s2, n) (STRNCASECMP((s1), (s2), (n)) == 0)
02509 #else
02510 #define ENVMATCH(n1, n2) (strcmp((n1), (n2)) == 0)
02511 #define ENVNMATCH(s1, s2, n) (memcmp((s1), (s2), (n)) == 0)
02512 #endif
02513 
02514 static VALUE
02515 env_str_new(const char *ptr, long len)
02516 {
02517 #ifdef _WIN32
02518     VALUE str = rb_str_conv_enc(rb_str_new(ptr, len), rb_utf8_encoding(), rb_locale_encoding());
02519 #else
02520     VALUE str = rb_locale_str_new(ptr, len);
02521 #endif
02522 
02523     rb_obj_freeze(str);
02524     return str;
02525 }
02526 
02527 static VALUE
02528 env_str_new2(const char *ptr)
02529 {
02530     if (!ptr) return Qnil;
02531     return env_str_new(ptr, strlen(ptr));
02532 }
02533 
02534 static VALUE
02535 env_delete(VALUE obj, VALUE name)
02536 {
02537     char *nam, *val;
02538 
02539     SafeStringValue(name);
02540     nam = RSTRING_PTR(name);
02541     if (memchr(nam, '\0', RSTRING_LEN(name))) {
02542         rb_raise(rb_eArgError, "bad environment variable name");
02543     }
02544     val = getenv(nam);
02545     if (val) {
02546         VALUE value = env_str_new2(val);
02547 
02548         ruby_setenv(nam, 0);
02549         if (ENVMATCH(nam, PATH_ENV)) {
02550             path_tainted = 0;
02551         }
02552         return value;
02553     }
02554     return Qnil;
02555 }
02556 
02557 /*
02558  * call-seq:
02559  *   ENV.delete(name)            -> value
02560  *   ENV.delete(name) { |name| } -> value
02561  *
02562  * Deletes the environment variable with +name+ and returns the value of the
02563  * variable.  If a block is given it will be called when the named environment
02564  * does not exist.
02565  */
02566 static VALUE
02567 env_delete_m(VALUE obj, VALUE name)
02568 {
02569     VALUE val;
02570 
02571     val = env_delete(obj, name);
02572     if (NIL_P(val) && rb_block_given_p()) rb_yield(name);
02573     return val;
02574 }
02575 
02576 static int env_path_tainted(const char *);
02577 
02578 /*
02579  * call-seq:
02580  *   ENV[name] -> value
02581  *
02582  * Retrieves the +value+ for environment variable +name+ as a String.  Returns
02583  * +nil+ if the named variable does not exist.
02584  */
02585 static VALUE
02586 rb_f_getenv(VALUE obj, VALUE name)
02587 {
02588     char *nam, *env;
02589 
02590     SafeStringValue(name);
02591     nam = RSTRING_PTR(name);
02592     if (memchr(nam, '\0', RSTRING_LEN(name))) {
02593         rb_raise(rb_eArgError, "bad environment variable name");
02594     }
02595     env = getenv(nam);
02596     if (env) {
02597         if (ENVMATCH(nam, PATH_ENV) && !env_path_tainted(env)) {
02598 #ifdef _WIN32
02599             VALUE str = rb_str_conv_enc(rb_str_new(env, strlen(env)), rb_utf8_encoding(), rb_filesystem_encoding());
02600 #else
02601             VALUE str = rb_filesystem_str_new_cstr(env);
02602 #endif
02603 
02604             rb_obj_freeze(str);
02605             return str;
02606         }
02607         return env_str_new2(env);
02608     }
02609     return Qnil;
02610 }
02611 
02612 /*
02613  * :yield: missing_name
02614  * call-seq:
02615  *   ENV.fetch(name)                        -> value
02616  *   ENV.fetch(name, default)               -> value
02617  *   ENV.fetch(name) { |missing_name| ... } -> value
02618  *
02619  * Retrieves the environment variable +name+.
02620  *
02621  * If the given name does not exist and neither +default+ nor a block a
02622  * provided an IndexError is raised.  If a block is given it is called with
02623  * the missing name to provide a value.  If a default value is given it will
02624  * be returned when no block is given.
02625  */
02626 static VALUE
02627 env_fetch(int argc, VALUE *argv)
02628 {
02629     VALUE key, if_none;
02630     long block_given;
02631     char *nam, *env;
02632 
02633     rb_scan_args(argc, argv, "11", &key, &if_none);
02634     block_given = rb_block_given_p();
02635     if (block_given && argc == 2) {
02636         rb_warn("block supersedes default value argument");
02637     }
02638     SafeStringValue(key);
02639     nam = RSTRING_PTR(key);
02640     if (memchr(nam, '\0', RSTRING_LEN(key))) {
02641         rb_raise(rb_eArgError, "bad environment variable name");
02642     }
02643     env = getenv(nam);
02644     if (!env) {
02645         if (block_given) return rb_yield(key);
02646         if (argc == 1) {
02647             rb_raise(rb_eKeyError, "key not found: \"%"PRIsVALUE"\"", key);
02648         }
02649         return if_none;
02650     }
02651     if (ENVMATCH(nam, PATH_ENV) && !env_path_tainted(env))
02652 #ifdef _WIN32
02653         return rb_str_conv_enc(rb_str_new(env, strlen(env)), rb_utf8_encoding(), rb_filesystem_encoding());
02654 #else
02655         return rb_filesystem_str_new_cstr(env);
02656 #endif
02657     return env_str_new2(env);
02658 }
02659 
02660 static void
02661 path_tainted_p(const char *path)
02662 {
02663     path_tainted = rb_path_check(path)?0:1;
02664 }
02665 
02666 static int
02667 env_path_tainted(const char *path)
02668 {
02669     if (path_tainted < 0) {
02670         path_tainted_p(path);
02671     }
02672     return path_tainted;
02673 }
02674 
02675 int
02676 rb_env_path_tainted(void)
02677 {
02678     if (path_tainted < 0) {
02679         path_tainted_p(getenv(PATH_ENV));
02680     }
02681     return path_tainted;
02682 }
02683 
02684 #if defined(_WIN32) || (defined(HAVE_SETENV) && defined(HAVE_UNSETENV))
02685 #elif defined __sun
02686 static int
02687 in_origenv(const char *str)
02688 {
02689     char **env;
02690     for (env = origenviron; *env; ++env) {
02691         if (*env == str) return 1;
02692     }
02693     return 0;
02694 }
02695 #else
02696 static int
02697 envix(const char *nam)
02698 {
02699     register int i, len = strlen(nam);
02700     char **env;
02701 
02702     env = GET_ENVIRON(environ);
02703     for (i = 0; env[i]; i++) {
02704         if (ENVNMATCH(env[i],nam,len) && env[i][len] == '=')
02705             break;                      /* memcmp must come first to avoid */
02706     }                                   /* potential SEGV's */
02707     FREE_ENVIRON(environ);
02708     return i;
02709 }
02710 #endif
02711 
02712 #if defined(_WIN32)
02713 static size_t
02714 getenvsize(const char* p)
02715 {
02716     const char* porg = p;
02717     while (*p++) p += strlen(p) + 1;
02718     return p - porg + 1;
02719 }
02720 static size_t
02721 getenvblocksize()
02722 {
02723     return (rb_w32_osver() >= 5) ? 32767 : 5120;
02724 }
02725 #endif
02726 
02727 #if !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV)
02728 NORETURN(static void invalid_envname(const char *name));
02729 
02730 static void
02731 invalid_envname(const char *name)
02732 {
02733     rb_syserr_fail_str(EINVAL, rb_sprintf("ruby_setenv(%s)", name));
02734 }
02735 
02736 static const char *
02737 check_envname(const char *name)
02738 {
02739     if (strchr(name, '=')) {
02740         invalid_envname(name);
02741     }
02742     return name;
02743 }
02744 #endif
02745 
02746 void
02747 ruby_setenv(const char *name, const char *value)
02748 {
02749 #if defined(_WIN32)
02750     VALUE buf;
02751     int failed = 0;
02752     check_envname(name);
02753     if (value) {
02754         char* p = GetEnvironmentStringsA();
02755         size_t n;
02756         if (!p) goto fail; /* never happen */
02757         n = strlen(name) + 2 + strlen(value) + getenvsize(p);
02758         FreeEnvironmentStringsA(p);
02759         if (n >= getenvblocksize()) {
02760             goto fail;  /* 2 for '=' & '\0' */
02761         }
02762         buf = rb_sprintf("%s=%s", name, value);
02763     }
02764     else {
02765         buf = rb_sprintf("%s=", name);
02766     }
02767     failed = putenv(RSTRING_PTR(buf));
02768     /* even if putenv() failed, clean up and try to delete the
02769      * variable from the system area. */
02770     rb_str_resize(buf, 0);
02771     if (!value || !*value) {
02772         /* putenv() doesn't handle empty value */
02773         if (!SetEnvironmentVariable(name, value) &&
02774             GetLastError() != ERROR_ENVVAR_NOT_FOUND) goto fail;
02775     }
02776     if (failed) {
02777       fail:
02778         invalid_envname(name);
02779     }
02780 #elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)
02781 #undef setenv
02782 #undef unsetenv
02783     if (value) {
02784         if (setenv(name, value, 1))
02785             rb_sys_fail_str(rb_sprintf("setenv(%s)", name));
02786     }
02787     else {
02788 #ifdef VOID_UNSETENV
02789         unsetenv(name);
02790 #else
02791         if (unsetenv(name))
02792             rb_sys_fail_str(rb_sprintf("unsetenv(%s)", name));
02793 #endif
02794     }
02795 #elif defined __sun
02796     size_t len;
02797     char **env_ptr, *str;
02798 
02799     len = strlen(name);
02800     for (env_ptr = GET_ENVIRON(environ); (str = *env_ptr) != 0; ++env_ptr) {
02801         if (!strncmp(str, name, len) && str[len] == '=') {
02802             if (!in_origenv(str)) free(str);
02803             while ((env_ptr[0] = env_ptr[1]) != 0) env_ptr++;
02804             break;
02805         }
02806     }
02807     if (value) {
02808         str = malloc(len += strlen(value) + 2);
02809         snprintf(str, len, "%s=%s", name, value);
02810         if (putenv(str))
02811             rb_sys_fail_str(rb_sprintf("putenv(%s)", name));
02812     }
02813 #else  /* WIN32 */
02814     size_t len;
02815     int i;
02816 
02817     i=envix(name);                      /* where does it go? */
02818 
02819     if (environ == origenviron) {       /* need we copy environment? */
02820         int j;
02821         int max;
02822         char **tmpenv;
02823 
02824         for (max = i; environ[max]; max++) ;
02825         tmpenv = ALLOC_N(char*, max+2);
02826         for (j=0; j<max; j++)           /* copy environment */
02827             tmpenv[j] = ruby_strdup(environ[j]);
02828         tmpenv[max] = 0;
02829         environ = tmpenv;               /* tell exec where it is now */
02830     }
02831     if (environ[i]) {
02832         char **envp = origenviron;
02833         while (*envp && *envp != environ[i]) envp++;
02834         if (!*envp)
02835             xfree(environ[i]);
02836         if (!value) {
02837             while (environ[i]) {
02838                 environ[i] = environ[i+1];
02839                 i++;
02840             }
02841             return;
02842         }
02843     }
02844     else {                      /* does not exist yet */
02845         if (!value) return;
02846         REALLOC_N(environ, char*, i+2); /* just expand it a bit */
02847         environ[i+1] = 0;       /* make sure it's null terminated */
02848     }
02849     len = strlen(name) + strlen(value) + 2;
02850     environ[i] = ALLOC_N(char, len);
02851     snprintf(environ[i],len,"%s=%s",name,value); /* all that work just for this */
02852 #endif /* WIN32 */
02853 }
02854 
02855 void
02856 ruby_unsetenv(const char *name)
02857 {
02858     ruby_setenv(name, 0);
02859 }
02860 
02861 /*
02862  * call-seq:
02863  *   ENV[name] = value
02864  *   ENV.store(name, value) -> value
02865  *
02866  * Sets the environment variable +name+ to +value+.  If the value given is
02867  * +nil+ the environment variable is deleted.
02868  *
02869  */
02870 static VALUE
02871 env_aset(VALUE obj, VALUE nm, VALUE val)
02872 {
02873     char *name, *value;
02874 
02875     if (NIL_P(val)) {
02876         env_delete(obj, nm);
02877         return Qnil;
02878     }
02879     SafeStringValue(nm);
02880     SafeStringValue(val);
02881     name = RSTRING_PTR(nm);
02882     value = RSTRING_PTR(val);
02883     if (memchr(name, '\0', RSTRING_LEN(nm)))
02884         rb_raise(rb_eArgError, "bad environment variable name");
02885     if (memchr(value, '\0', RSTRING_LEN(val)))
02886         rb_raise(rb_eArgError, "bad environment variable value");
02887 
02888     ruby_setenv(name, value);
02889     if (ENVMATCH(name, PATH_ENV)) {
02890         if (OBJ_TAINTED(val)) {
02891             /* already tainted, no check */
02892             path_tainted = 1;
02893             return val;
02894         }
02895         else {
02896             path_tainted_p(value);
02897         }
02898     }
02899     return val;
02900 }
02901 
02902 /*
02903  * call-seq:
02904  *   ENV.keys -> Array
02905  *
02906  * Returns every environment variable name in an Array
02907  */
02908 static VALUE
02909 env_keys(void)
02910 {
02911     char **env;
02912     VALUE ary;
02913 
02914     ary = rb_ary_new();
02915     env = GET_ENVIRON(environ);
02916     while (*env) {
02917         char *s = strchr(*env, '=');
02918         if (s) {
02919             rb_ary_push(ary, env_str_new(*env, s-*env));
02920         }
02921         env++;
02922     }
02923     FREE_ENVIRON(environ);
02924     return ary;
02925 }
02926 
02927 static VALUE
02928 rb_env_size(VALUE ehash, VALUE args, VALUE eobj)
02929 {
02930     char **env;
02931     long cnt = 0;
02932 
02933     env = GET_ENVIRON(environ);
02934     for (; *env ; ++env) {
02935         if (strchr(*env, '=')) {
02936             cnt++;
02937         }
02938     }
02939     FREE_ENVIRON(environ);
02940     return LONG2FIX(cnt);
02941 }
02942 
02943 /*
02944  * call-seq:
02945  *   ENV.each_key { |name| } -> Hash
02946  *   ENV.each_key            -> Enumerator
02947  *
02948  * Yields each environment variable name.
02949  *
02950  * An Enumerator is returned if no block is given.
02951  */
02952 static VALUE
02953 env_each_key(VALUE ehash)
02954 {
02955     VALUE keys;
02956     long i;
02957 
02958     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
02959     keys = env_keys();
02960     for (i=0; i<RARRAY_LEN(keys); i++) {
02961         rb_yield(RARRAY_AREF(keys, i));
02962     }
02963     return ehash;
02964 }
02965 
02966 /*
02967  * call-seq:
02968  *   ENV.values -> Array
02969  *
02970  * Returns every environment variable value as an Array
02971  */
02972 static VALUE
02973 env_values(void)
02974 {
02975     VALUE ary;
02976     char **env;
02977 
02978     ary = rb_ary_new();
02979     env = GET_ENVIRON(environ);
02980     while (*env) {
02981         char *s = strchr(*env, '=');
02982         if (s) {
02983             rb_ary_push(ary, env_str_new2(s+1));
02984         }
02985         env++;
02986     }
02987     FREE_ENVIRON(environ);
02988     return ary;
02989 }
02990 
02991 /*
02992  * call-seq:
02993  *   ENV.each_value { |value| } -> Hash
02994  *   ENV.each_value             -> Enumerator
02995  *
02996  * Yields each environment variable +value+.
02997  *
02998  * An Enumerator is returned if no block was given.
02999  */
03000 static VALUE
03001 env_each_value(VALUE ehash)
03002 {
03003     VALUE values;
03004     long i;
03005 
03006     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
03007     values = env_values();
03008     for (i=0; i<RARRAY_LEN(values); i++) {
03009         rb_yield(RARRAY_AREF(values, i));
03010     }
03011     return ehash;
03012 }
03013 
03014 /*
03015  * call-seq:
03016  *   ENV.each      { |name, value| } -> Hash
03017  *   ENV.each                        -> Enumerator
03018  *   ENV.each_pair { |name, value| } -> Hash
03019  *   ENV.each_pair                   -> Enumerator
03020  *
03021  * Yields each environment variable +name+ and +value+.
03022  *
03023  * If no block is given an Enumerator is returned.
03024  */
03025 static VALUE
03026 env_each_pair(VALUE ehash)
03027 {
03028     char **env;
03029     VALUE ary;
03030     long i;
03031 
03032     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
03033 
03034     ary = rb_ary_new();
03035     env = GET_ENVIRON(environ);
03036     while (*env) {
03037         char *s = strchr(*env, '=');
03038         if (s) {
03039             rb_ary_push(ary, env_str_new(*env, s-*env));
03040             rb_ary_push(ary, env_str_new2(s+1));
03041         }
03042         env++;
03043     }
03044     FREE_ENVIRON(environ);
03045 
03046     if (rb_block_arity() > 1) {
03047         for (i=0; i<RARRAY_LEN(ary); i+=2) {
03048             rb_yield_values(2, RARRAY_AREF(ary, i), RARRAY_AREF(ary, i+1));
03049         }
03050     }
03051     else {
03052         for (i=0; i<RARRAY_LEN(ary); i+=2) {
03053             rb_yield(rb_assoc_new(RARRAY_AREF(ary, i), RARRAY_AREF(ary, i+1)));
03054         }
03055     }
03056     return ehash;
03057 }
03058 
03059 /*
03060  * call-seq:
03061  *   ENV.reject! { |name, value| } -> ENV or nil
03062  *   ENV.reject!                   -> Enumerator
03063  *
03064  * Equivalent to ENV#delete_if but returns +nil+ if no changes were made.
03065  *
03066  * Returns an Enumerator if no block was given.
03067  */
03068 static VALUE
03069 env_reject_bang(VALUE ehash)
03070 {
03071     volatile VALUE keys;
03072     long i;
03073     int del = 0;
03074 
03075     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
03076     keys = env_keys();
03077     RBASIC_CLEAR_CLASS(keys);
03078     for (i=0; i<RARRAY_LEN(keys); i++) {
03079         VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
03080         if (!NIL_P(val)) {
03081             if (RTEST(rb_yield_values(2, RARRAY_AREF(keys, i), val))) {
03082                 FL_UNSET(RARRAY_AREF(keys, i), FL_TAINT);
03083                 env_delete(Qnil, RARRAY_AREF(keys, i));
03084                 del++;
03085             }
03086         }
03087     }
03088     if (del == 0) return Qnil;
03089     return envtbl;
03090 }
03091 
03092 /*
03093  * call-seq:
03094  *   ENV.delete_if { |name, value| } -> Hash
03095  *   ENV.delete_if                   -> Enumerator
03096  *
03097  * Deletes every environment variable for which the block evaluates to +true+.
03098  *
03099  * If no block is given an enumerator is returned instead.
03100  */
03101 static VALUE
03102 env_delete_if(VALUE ehash)
03103 {
03104     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
03105     env_reject_bang(ehash);
03106     return envtbl;
03107 }
03108 
03109 /*
03110  * call-seq:
03111  *   ENV.values_at(name, ...) -> Array
03112  *
03113  * Returns an array containing the environment variable values associated with
03114  * the given names.  See also ENV.select.
03115  */
03116 static VALUE
03117 env_values_at(int argc, VALUE *argv)
03118 {
03119     VALUE result;
03120     long i;
03121 
03122     result = rb_ary_new();
03123     for (i=0; i<argc; i++) {
03124         rb_ary_push(result, rb_f_getenv(Qnil, argv[i]));
03125     }
03126     return result;
03127 }
03128 
03129 /*
03130  * call-seq:
03131  *   ENV.select { |name, value| } -> Hash
03132  *   ENV.select                   -> Enumerator
03133  *
03134  * Returns a copy of the environment for entries where the block returns true.
03135  *
03136  * Returns an Enumerator if no block was given.
03137  */
03138 static VALUE
03139 env_select(VALUE ehash)
03140 {
03141     VALUE result;
03142     VALUE keys;
03143     long i;
03144 
03145     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
03146     result = rb_hash_new();
03147     keys = env_keys();
03148     for (i = 0; i < RARRAY_LEN(keys); ++i) {
03149         VALUE key = RARRAY_AREF(keys, i);
03150         VALUE val = rb_f_getenv(Qnil, key);
03151         if (!NIL_P(val)) {
03152             if (RTEST(rb_yield_values(2, key, val))) {
03153                 rb_hash_aset(result, key, val);
03154             }
03155         }
03156     }
03157 
03158     return result;
03159 }
03160 
03161 /*
03162  * call-seq:
03163  *   ENV.select! { |name, value| } -> ENV or nil
03164  *   ENV.select!                   -> Enumerator
03165  *
03166  * Equivalent to ENV#keep_if but returns +nil+ if no changes were made.
03167  */
03168 static VALUE
03169 env_select_bang(VALUE ehash)
03170 {
03171     volatile VALUE keys;
03172     long i;
03173     int del = 0;
03174 
03175     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
03176     keys = env_keys();
03177     RBASIC_CLEAR_CLASS(keys);
03178     for (i=0; i<RARRAY_LEN(keys); i++) {
03179         VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
03180         if (!NIL_P(val)) {
03181             if (!RTEST(rb_yield_values(2, RARRAY_AREF(keys, i), val))) {
03182                 FL_UNSET(RARRAY_AREF(keys, i), FL_TAINT);
03183                 env_delete(Qnil, RARRAY_AREF(keys, i));
03184                 del++;
03185             }
03186         }
03187     }
03188     if (del == 0) return Qnil;
03189     return envtbl;
03190 }
03191 
03192 /*
03193  * call-seq:
03194  *   ENV.keep_if { |name, value| } -> Hash
03195  *   ENV.keep_if                   -> Enumerator
03196  *
03197  * Deletes every environment variable where the block evaluates to +false+.
03198  *
03199  * Returns an enumerator if no block was given.
03200  */
03201 static VALUE
03202 env_keep_if(VALUE ehash)
03203 {
03204     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
03205     env_select_bang(ehash);
03206     return envtbl;
03207 }
03208 
03209 /*
03210  * call-seq:
03211  *   ENV.clear
03212  *
03213  * Removes every environment variable.
03214  */
03215 VALUE
03216 rb_env_clear(void)
03217 {
03218     volatile VALUE keys;
03219     long i;
03220 
03221     keys = env_keys();
03222     for (i=0; i<RARRAY_LEN(keys); i++) {
03223         VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
03224         if (!NIL_P(val)) {
03225             env_delete(Qnil, RARRAY_AREF(keys, i));
03226         }
03227     }
03228     return envtbl;
03229 }
03230 
03231 /*
03232  * call-seq:
03233  *   ENV.to_s -> "ENV"
03234  *
03235  * Returns "ENV"
03236  */
03237 static VALUE
03238 env_to_s(void)
03239 {
03240     return rb_usascii_str_new2("ENV");
03241 }
03242 
03243 /*
03244  * call-seq:
03245  *   ENV.inspect -> string
03246  *
03247  * Returns the contents of the environment as a String.
03248  */
03249 static VALUE
03250 env_inspect(void)
03251 {
03252     char **env;
03253     VALUE str, i;
03254 
03255     str = rb_str_buf_new2("{");
03256     env = GET_ENVIRON(environ);
03257     while (*env) {
03258         char *s = strchr(*env, '=');
03259 
03260         if (env != environ) {
03261             rb_str_buf_cat2(str, ", ");
03262         }
03263         if (s) {
03264             rb_str_buf_cat2(str, "\"");
03265             rb_str_buf_cat(str, *env, s-*env);
03266             rb_str_buf_cat2(str, "\"=>");
03267             i = rb_inspect(rb_str_new2(s+1));
03268             rb_str_buf_append(str, i);
03269         }
03270         env++;
03271     }
03272     FREE_ENVIRON(environ);
03273     rb_str_buf_cat2(str, "}");
03274     OBJ_TAINT(str);
03275 
03276     return str;
03277 }
03278 
03279 /*
03280  * call-seq:
03281  *   ENV.to_a -> Array
03282  *
03283  * Converts the environment variables into an array of names and value arrays.
03284  *
03285  *   ENV.to_a # => [["TERM", "xterm-color"], ["SHELL", "/bin/bash"], ...]
03286  *
03287  */
03288 static VALUE
03289 env_to_a(void)
03290 {
03291     char **env;
03292     VALUE ary;
03293 
03294     ary = rb_ary_new();
03295     env = GET_ENVIRON(environ);
03296     while (*env) {
03297         char *s = strchr(*env, '=');
03298         if (s) {
03299             rb_ary_push(ary, rb_assoc_new(env_str_new(*env, s-*env),
03300                                           env_str_new2(s+1)));
03301         }
03302         env++;
03303     }
03304     FREE_ENVIRON(environ);
03305     return ary;
03306 }
03307 
03308 /*
03309  * call-seq:
03310  *   ENV.rehash
03311  *
03312  * Re-hashing the environment variables does nothing.  It is provided for
03313  * compatibility with Hash.
03314  */
03315 static VALUE
03316 env_none(void)
03317 {
03318     return Qnil;
03319 }
03320 
03321 /*
03322  * call-seq:
03323  *   ENV.length
03324  *   ENV.size
03325  *
03326  * Returns the number of environment variables.
03327  */
03328 static VALUE
03329 env_size(void)
03330 {
03331     int i;
03332     char **env;
03333 
03334     env = GET_ENVIRON(environ);
03335     for (i=0; env[i]; i++)
03336         ;
03337     FREE_ENVIRON(environ);
03338     return INT2FIX(i);
03339 }
03340 
03341 /*
03342  * call-seq:
03343  *   ENV.empty? -> true or false
03344  *
03345  * Returns true when there are no environment variables
03346  */
03347 static VALUE
03348 env_empty_p(void)
03349 {
03350     char **env;
03351 
03352     env = GET_ENVIRON(environ);
03353     if (env[0] == 0) {
03354         FREE_ENVIRON(environ);
03355         return Qtrue;
03356     }
03357     FREE_ENVIRON(environ);
03358     return Qfalse;
03359 }
03360 
03361 /*
03362  * call-seq:
03363  *   ENV.key?(name)     -> true or false
03364  *   ENV.include?(name) -> true or false
03365  *   ENV.has_key?(name) -> true or false
03366  *   ENV.member?(name)  -> true or false
03367  *
03368  * Returns +true+ if there is an environment variable with the given +name+.
03369  */
03370 static VALUE
03371 env_has_key(VALUE env, VALUE key)
03372 {
03373     char *s;
03374 
03375     SafeStringValue(key);
03376     s = RSTRING_PTR(key);
03377     if (memchr(s, '\0', RSTRING_LEN(key)))
03378         rb_raise(rb_eArgError, "bad environment variable name");
03379     if (getenv(s)) return Qtrue;
03380     return Qfalse;
03381 }
03382 
03383 /*
03384  * call-seq:
03385  *   ENV.assoc(name) -> Array or nil
03386  *
03387  * Returns an Array of the name and value of the environment variable with
03388  * +name+ or +nil+ if the name cannot be found.
03389  */
03390 static VALUE
03391 env_assoc(VALUE env, VALUE key)
03392 {
03393     char *s, *e;
03394 
03395     SafeStringValue(key);
03396     s = RSTRING_PTR(key);
03397     if (memchr(s, '\0', RSTRING_LEN(key)))
03398         rb_raise(rb_eArgError, "bad environment variable name");
03399     e = getenv(s);
03400     if (e) return rb_assoc_new(key, rb_tainted_str_new2(e));
03401     return Qnil;
03402 }
03403 
03404 /*
03405  * call-seq:
03406  *   ENV.value?(value) -> true or false
03407  *   ENV.has_value?(value) -> true or false
03408  *
03409  * Returns +true+ if there is an environment variable with the given +value+.
03410  */
03411 static VALUE
03412 env_has_value(VALUE dmy, VALUE obj)
03413 {
03414     char **env;
03415 
03416     obj = rb_check_string_type(obj);
03417     if (NIL_P(obj)) return Qnil;
03418     rb_check_safe_obj(obj);
03419     env = GET_ENVIRON(environ);
03420     while (*env) {
03421         char *s = strchr(*env, '=');
03422         if (s++) {
03423             long len = strlen(s);
03424             if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
03425                 FREE_ENVIRON(environ);
03426                 return Qtrue;
03427             }
03428         }
03429         env++;
03430     }
03431     FREE_ENVIRON(environ);
03432     return Qfalse;
03433 }
03434 
03435 /*
03436  * call-seq:
03437  *   ENV.rassoc(value)
03438  *
03439  * Returns an Array of the name and value of the environment variable with
03440  * +value+ or +nil+ if the value cannot be found.
03441  */
03442 static VALUE
03443 env_rassoc(VALUE dmy, VALUE obj)
03444 {
03445     char **env;
03446 
03447     obj = rb_check_string_type(obj);
03448     if (NIL_P(obj)) return Qnil;
03449     rb_check_safe_obj(obj);
03450     env = GET_ENVIRON(environ);
03451     while (*env) {
03452         char *s = strchr(*env, '=');
03453         if (s++) {
03454             long len = strlen(s);
03455             if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
03456                 VALUE result = rb_assoc_new(rb_tainted_str_new(*env, s-*env-1), obj);
03457                 FREE_ENVIRON(environ);
03458                 return result;
03459             }
03460         }
03461         env++;
03462     }
03463     FREE_ENVIRON(environ);
03464     return Qnil;
03465 }
03466 
03467 /*
03468  * call-seq:
03469  *   ENV.key(value) -> name
03470  *
03471  * Returns the name of the environment variable with +value+.  If the value is
03472  * not found +nil+ is returned.
03473  */
03474 static VALUE
03475 env_key(VALUE dmy, VALUE value)
03476 {
03477     char **env;
03478     VALUE str;
03479 
03480     SafeStringValue(value);
03481     env = GET_ENVIRON(environ);
03482     while (*env) {
03483         char *s = strchr(*env, '=');
03484         if (s++) {
03485             long len = strlen(s);
03486             if (RSTRING_LEN(value) == len && strncmp(s, RSTRING_PTR(value), len) == 0) {
03487                 str = env_str_new(*env, s-*env-1);
03488                 FREE_ENVIRON(environ);
03489                 return str;
03490             }
03491         }
03492         env++;
03493     }
03494     FREE_ENVIRON(environ);
03495     return Qnil;
03496 }
03497 
03498 /*
03499  * call-seq:
03500  *   ENV.index(value) -> key
03501  *
03502  * Deprecated method that is equivalent to ENV.key
03503  */
03504 static VALUE
03505 env_index(VALUE dmy, VALUE value)
03506 {
03507     rb_warn("ENV.index is deprecated; use ENV.key");
03508     return env_key(dmy, value);
03509 }
03510 
03511 /*
03512  * call-seq:
03513  *   ENV.to_hash -> hash
03514  *   ENV.to_h    -> hash
03515  *
03516  * Creates a hash with a copy of the environment variables.
03517  *
03518  */
03519 static VALUE
03520 env_to_hash(void)
03521 {
03522     char **env;
03523     VALUE hash;
03524 
03525     hash = rb_hash_new();
03526     env = GET_ENVIRON(environ);
03527     while (*env) {
03528         char *s = strchr(*env, '=');
03529         if (s) {
03530             rb_hash_aset(hash, env_str_new(*env, s-*env),
03531                                env_str_new2(s+1));
03532         }
03533         env++;
03534     }
03535     FREE_ENVIRON(environ);
03536     return hash;
03537 }
03538 
03539 /*
03540  * call-seq:
03541  *   ENV.reject { |name, value| } -> Hash
03542  *   ENV.reject                   -> Enumerator
03543  *
03544  * Same as ENV#delete_if, but works on (and returns) a copy of the
03545  * environment.
03546  */
03547 static VALUE
03548 env_reject(void)
03549 {
03550     return rb_hash_delete_if(env_to_hash());
03551 }
03552 
03553 /*
03554  * call-seq:
03555  *   ENV.shift -> Array or nil
03556  *
03557  * Removes an environment variable name-value pair from ENV and returns it as
03558  * an Array.  Returns +nil+ if when the environment is empty.
03559  */
03560 static VALUE
03561 env_shift(void)
03562 {
03563     char **env;
03564     VALUE result = Qnil;
03565 
03566     env = GET_ENVIRON(environ);
03567     if (*env) {
03568         char *s = strchr(*env, '=');
03569         if (s) {
03570             VALUE key = env_str_new(*env, s-*env);
03571             VALUE val = env_str_new2(getenv(RSTRING_PTR(key)));
03572             env_delete(Qnil, key);
03573             result = rb_assoc_new(key, val);
03574         }
03575     }
03576     FREE_ENVIRON(environ);
03577     return result;
03578 }
03579 
03580 /*
03581  * call-seq:
03582  *   ENV.invert -> Hash
03583  *
03584  * Returns a new hash created by using environment variable names as values
03585  * and values as names.
03586  */
03587 static VALUE
03588 env_invert(void)
03589 {
03590     return rb_hash_invert(env_to_hash());
03591 }
03592 
03593 static int
03594 env_replace_i(VALUE key, VALUE val, VALUE keys)
03595 {
03596     env_aset(Qnil, key, val);
03597     if (rb_ary_includes(keys, key)) {
03598         rb_ary_delete(keys, key);
03599     }
03600     return ST_CONTINUE;
03601 }
03602 
03603 /*
03604  * call-seq:
03605  *   ENV.replace(hash) -> env
03606  *
03607  * Replaces the contents of the environment variables with the contents of
03608  * +hash+.
03609  */
03610 static VALUE
03611 env_replace(VALUE env, VALUE hash)
03612 {
03613     volatile VALUE keys;
03614     long i;
03615 
03616     keys = env_keys();
03617     if (env == hash) return env;
03618     hash = to_hash(hash);
03619     rb_hash_foreach(hash, env_replace_i, keys);
03620 
03621     for (i=0; i<RARRAY_LEN(keys); i++) {
03622         env_delete(env, RARRAY_AREF(keys, i));
03623     }
03624     return env;
03625 }
03626 
03627 static int
03628 env_update_i(VALUE key, VALUE val)
03629 {
03630     if (rb_block_given_p()) {
03631         val = rb_yield_values(3, key, rb_f_getenv(Qnil, key), val);
03632     }
03633     env_aset(Qnil, key, val);
03634     return ST_CONTINUE;
03635 }
03636 
03637 /*
03638  * call-seq:
03639  *   ENV.update(hash)                                  -> Hash
03640  *   ENV.update(hash) { |name, old_value, new_value| } -> Hash
03641  *
03642  * Adds the contents of +hash+ to the environment variables.  If no block is
03643  * specified entries with duplicate keys are overwritten, otherwise the value
03644  * of each duplicate name is determined by calling the block with the key, its
03645  * value from the environment and its value from the hash.
03646  */
03647 static VALUE
03648 env_update(VALUE env, VALUE hash)
03649 {
03650     if (env == hash) return env;
03651     hash = to_hash(hash);
03652     rb_hash_foreach(hash, env_update_i, 0);
03653     return env;
03654 }
03655 
03656 /*
03657  *  A Hash is a dictionary-like collection of unique keys and their values.
03658  *  Also called associative arrays, they are similar to Arrays, but where an
03659  *  Array uses integers as its index, a Hash allows you to use any object
03660  *  type.
03661  *
03662  *  Hashes enumerate their values in the order that the corresponding keys
03663  *  were inserted.
03664  *
03665  *  A Hash can be easily created by using its implicit form:
03666  *
03667  *    grades = { "Jane Doe" => 10, "Jim Doe" => 6 }
03668  *
03669  *  Hashes allow an alternate syntax form when your keys are always symbols.
03670  *  Instead of
03671  *
03672  *    options = { :font_size => 10, :font_family => "Arial" }
03673  *
03674  *  You could write it as:
03675  *
03676  *    options = { font_size: 10, font_family: "Arial" }
03677  *
03678  *  Each named key is a symbol you can access in hash:
03679  *
03680  *    options[:font_size]  # => 10
03681  *
03682  *  A Hash can also be created through its ::new method:
03683  *
03684  *    grades = Hash.new
03685  *    grades["Dorothy Doe"] = 9
03686  *
03687  *  Hashes have a <em>default value</em> that is returned when accessing
03688  *  keys that do not exist in the hash. If no default is set +nil+ is used.
03689  *  You can set the default value by sending it as an argument to Hash.new:
03690  *
03691  *    grades = Hash.new(0)
03692  *
03693  *  Or by using the #default= method:
03694  *
03695  *    grades = {"Timmy Doe" => 8}
03696  *    grades.default = 0
03697  *
03698  *  Accessing a value in a Hash requires using its key:
03699  *
03700  *    puts grades["Jane Doe"] # => 0
03701  *
03702  *  === Common Uses
03703  *
03704  *  Hashes are an easy way to represent data structures, such as
03705  *
03706  *    books         = {}
03707  *    books[:matz]  = "The Ruby Language"
03708  *    books[:black] = "The Well-Grounded Rubyist"
03709  *
03710  *  Hashes are also commonly used as a way to have named parameters in
03711  *  functions. Note that no brackets are used below. If a hash is the last
03712  *  argument on a method call, no braces are needed, thus creating a really
03713  *  clean interface:
03714  *
03715  *    Person.create(name: "John Doe", age: 27)
03716  *
03717  *    def self.create(params)
03718  *      @name = params[:name]
03719  *      @age  = params[:age]
03720  *    end
03721  *
03722  *  === Hash Keys
03723  *
03724  *  Two objects refer to the same hash key when their <code>hash</code> value
03725  *  is identical and the two objects are <code>eql?</code> to each other.
03726  *
03727  *  A user-defined class may be used as a hash key if the <code>hash</code>
03728  *  and <code>eql?</code> methods are overridden to provide meaningful
03729  *  behavior.  By default, separate instances refer to separate hash keys.
03730  *
03731  *  A typical implementation of <code>hash</code> is based on the
03732  *  object's data while <code>eql?</code> is usually aliased to the overridden
03733  *  <code>==</code> method:
03734  *
03735  *    class Book
03736  *      attr_reader :author, :title
03737  *
03738  *      def initialize(author, title)
03739  *        @author = author
03740  *        @title = title
03741  *      end
03742  *
03743  *      def ==(other)
03744  *        self.class === other and
03745  *          other.author == @author and
03746  *          other.title == @title
03747  *      end
03748  *
03749  *      alias eql? ==
03750  *
03751  *      def hash
03752  *        @author.hash ^ @title.hash # XOR
03753  *      end
03754  *    end
03755  *
03756  *    book1 = Book.new 'matz', 'Ruby in a Nutshell'
03757  *    book2 = Book.new 'matz', 'Ruby in a Nutshell'
03758  *
03759  *    reviews = {}
03760  *
03761  *    reviews[book1] = 'Great reference!'
03762  *    reviews[book2] = 'Nice and compact!'
03763  *
03764  *    reviews.length #=> 1
03765  *
03766  *  See also Object#hash and Object#eql?
03767  */
03768 
03769 void
03770 Init_Hash(void)
03771 {
03772 #undef rb_intern
03773 #define rb_intern(str) rb_intern_const(str)
03774 
03775     id_hash = rb_intern("hash");
03776     id_yield = rb_intern("yield");
03777     id_default = rb_intern("default");
03778     id_flatten_bang = rb_intern("flatten!");
03779 
03780     rb_cHash = rb_define_class("Hash", rb_cObject);
03781 
03782     rb_include_module(rb_cHash, rb_mEnumerable);
03783 
03784     rb_define_alloc_func(rb_cHash, empty_hash_alloc);
03785     rb_define_singleton_method(rb_cHash, "[]", rb_hash_s_create, -1);
03786     rb_define_singleton_method(rb_cHash, "try_convert", rb_hash_s_try_convert, 1);
03787     rb_define_method(rb_cHash,"initialize", rb_hash_initialize, -1);
03788     rb_define_method(rb_cHash,"initialize_copy", rb_hash_initialize_copy, 1);
03789     rb_define_method(rb_cHash,"rehash", rb_hash_rehash, 0);
03790 
03791     rb_define_method(rb_cHash,"to_hash", rb_hash_to_hash, 0);
03792     rb_define_method(rb_cHash,"to_h", rb_hash_to_h, 0);
03793     rb_define_method(rb_cHash,"to_a", rb_hash_to_a, 0);
03794     rb_define_method(rb_cHash,"inspect", rb_hash_inspect, 0);
03795     rb_define_alias(rb_cHash, "to_s", "inspect");
03796 
03797     rb_define_method(rb_cHash,"==", rb_hash_equal, 1);
03798     rb_define_method(rb_cHash,"[]", rb_hash_aref, 1);
03799     rb_define_method(rb_cHash,"hash", rb_hash_hash, 0);
03800     rb_define_method(rb_cHash,"eql?", rb_hash_eql, 1);
03801     rb_define_method(rb_cHash,"fetch", rb_hash_fetch_m, -1);
03802     rb_define_method(rb_cHash,"[]=", rb_hash_aset, 2);
03803     rb_define_method(rb_cHash,"store", rb_hash_aset, 2);
03804     rb_define_method(rb_cHash,"default", rb_hash_default, -1);
03805     rb_define_method(rb_cHash,"default=", rb_hash_set_default, 1);
03806     rb_define_method(rb_cHash,"default_proc", rb_hash_default_proc, 0);
03807     rb_define_method(rb_cHash,"default_proc=", rb_hash_set_default_proc, 1);
03808     rb_define_method(rb_cHash,"key", rb_hash_key, 1);
03809     rb_define_method(rb_cHash,"index", rb_hash_index, 1);
03810     rb_define_method(rb_cHash,"size", rb_hash_size, 0);
03811     rb_define_method(rb_cHash,"length", rb_hash_size, 0);
03812     rb_define_method(rb_cHash,"empty?", rb_hash_empty_p, 0);
03813 
03814     rb_define_method(rb_cHash,"each_value", rb_hash_each_value, 0);
03815     rb_define_method(rb_cHash,"each_key", rb_hash_each_key, 0);
03816     rb_define_method(rb_cHash,"each_pair", rb_hash_each_pair, 0);
03817     rb_define_method(rb_cHash,"each", rb_hash_each_pair, 0);
03818 
03819     rb_define_method(rb_cHash,"keys", rb_hash_keys, 0);
03820     rb_define_method(rb_cHash,"values", rb_hash_values, 0);
03821     rb_define_method(rb_cHash,"values_at", rb_hash_values_at, -1);
03822 
03823     rb_define_method(rb_cHash,"shift", rb_hash_shift, 0);
03824     rb_define_method(rb_cHash,"delete", rb_hash_delete, 1);
03825     rb_define_method(rb_cHash,"delete_if", rb_hash_delete_if, 0);
03826     rb_define_method(rb_cHash,"keep_if", rb_hash_keep_if, 0);
03827     rb_define_method(rb_cHash,"select", rb_hash_select, 0);
03828     rb_define_method(rb_cHash,"select!", rb_hash_select_bang, 0);
03829     rb_define_method(rb_cHash,"reject", rb_hash_reject, 0);
03830     rb_define_method(rb_cHash,"reject!", rb_hash_reject_bang, 0);
03831     rb_define_method(rb_cHash,"clear", rb_hash_clear, 0);
03832     rb_define_method(rb_cHash,"invert", rb_hash_invert, 0);
03833     rb_define_method(rb_cHash,"update", rb_hash_update, 1);
03834     rb_define_method(rb_cHash,"replace", rb_hash_replace, 1);
03835     rb_define_method(rb_cHash,"merge!", rb_hash_update, 1);
03836     rb_define_method(rb_cHash,"merge", rb_hash_merge, 1);
03837     rb_define_method(rb_cHash, "assoc", rb_hash_assoc, 1);
03838     rb_define_method(rb_cHash, "rassoc", rb_hash_rassoc, 1);
03839     rb_define_method(rb_cHash, "flatten", rb_hash_flatten, -1);
03840 
03841     rb_define_method(rb_cHash,"include?", rb_hash_has_key, 1);
03842     rb_define_method(rb_cHash,"member?", rb_hash_has_key, 1);
03843     rb_define_method(rb_cHash,"has_key?", rb_hash_has_key, 1);
03844     rb_define_method(rb_cHash,"has_value?", rb_hash_has_value, 1);
03845     rb_define_method(rb_cHash,"key?", rb_hash_has_key, 1);
03846     rb_define_method(rb_cHash,"value?", rb_hash_has_value, 1);
03847 
03848     rb_define_method(rb_cHash,"compare_by_identity", rb_hash_compare_by_id, 0);
03849     rb_define_method(rb_cHash,"compare_by_identity?", rb_hash_compare_by_id_p, 0);
03850 
03851     /* Document-class: ENV
03852      *
03853      * ENV is a hash-like accessor for environment variables.
03854      */
03855 
03856     /*
03857      * Hack to get RDoc to regard ENV as a class:
03858      * envtbl = rb_define_class("ENV", rb_cObject);
03859      */
03860     origenviron = environ;
03861     envtbl = rb_obj_alloc(rb_cObject);
03862     rb_extend_object(envtbl, rb_mEnumerable);
03863 
03864     rb_define_singleton_method(envtbl,"[]", rb_f_getenv, 1);
03865     rb_define_singleton_method(envtbl,"fetch", env_fetch, -1);
03866     rb_define_singleton_method(envtbl,"[]=", env_aset, 2);
03867     rb_define_singleton_method(envtbl,"store", env_aset, 2);
03868     rb_define_singleton_method(envtbl,"each", env_each_pair, 0);
03869     rb_define_singleton_method(envtbl,"each_pair", env_each_pair, 0);
03870     rb_define_singleton_method(envtbl,"each_key", env_each_key, 0);
03871     rb_define_singleton_method(envtbl,"each_value", env_each_value, 0);
03872     rb_define_singleton_method(envtbl,"delete", env_delete_m, 1);
03873     rb_define_singleton_method(envtbl,"delete_if", env_delete_if, 0);
03874     rb_define_singleton_method(envtbl,"keep_if", env_keep_if, 0);
03875     rb_define_singleton_method(envtbl,"clear", rb_env_clear, 0);
03876     rb_define_singleton_method(envtbl,"reject", env_reject, 0);
03877     rb_define_singleton_method(envtbl,"reject!", env_reject_bang, 0);
03878     rb_define_singleton_method(envtbl,"select", env_select, 0);
03879     rb_define_singleton_method(envtbl,"select!", env_select_bang, 0);
03880     rb_define_singleton_method(envtbl,"shift", env_shift, 0);
03881     rb_define_singleton_method(envtbl,"invert", env_invert, 0);
03882     rb_define_singleton_method(envtbl,"replace", env_replace, 1);
03883     rb_define_singleton_method(envtbl,"update", env_update, 1);
03884     rb_define_singleton_method(envtbl,"inspect", env_inspect, 0);
03885     rb_define_singleton_method(envtbl,"rehash", env_none, 0);
03886     rb_define_singleton_method(envtbl,"to_a", env_to_a, 0);
03887     rb_define_singleton_method(envtbl,"to_s", env_to_s, 0);
03888     rb_define_singleton_method(envtbl,"key", env_key, 1);
03889     rb_define_singleton_method(envtbl,"index", env_index, 1);
03890     rb_define_singleton_method(envtbl,"size", env_size, 0);
03891     rb_define_singleton_method(envtbl,"length", env_size, 0);
03892     rb_define_singleton_method(envtbl,"empty?", env_empty_p, 0);
03893     rb_define_singleton_method(envtbl,"keys", env_keys, 0);
03894     rb_define_singleton_method(envtbl,"values", env_values, 0);
03895     rb_define_singleton_method(envtbl,"values_at", env_values_at, -1);
03896     rb_define_singleton_method(envtbl,"include?", env_has_key, 1);
03897     rb_define_singleton_method(envtbl,"member?", env_has_key, 1);
03898     rb_define_singleton_method(envtbl,"has_key?", env_has_key, 1);
03899     rb_define_singleton_method(envtbl,"has_value?", env_has_value, 1);
03900     rb_define_singleton_method(envtbl,"key?", env_has_key, 1);
03901     rb_define_singleton_method(envtbl,"value?", env_has_value, 1);
03902     rb_define_singleton_method(envtbl,"to_hash", env_to_hash, 0);
03903     rb_define_singleton_method(envtbl,"to_h", env_to_hash, 0);
03904     rb_define_singleton_method(envtbl,"assoc", env_assoc, 1);
03905     rb_define_singleton_method(envtbl,"rassoc", env_rassoc, 1);
03906 
03907     /*
03908      * ENV is a Hash-like accessor for environment variables.
03909      *
03910      * See ENV (the class) for more details.
03911      */
03912     rb_define_global_const("ENV", envtbl);
03913 
03914     /* for callcc */
03915     ruby_register_rollback_func_for_ensure(hash_foreach_ensure, hash_foreach_ensure_rollback);
03916 }
03917 

Generated on 19 Jul 2016 for Ruby by  doxygen 1.4.7