Ruby 1.9.2p136(2010-12-25revision30365)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# hash.c

Go to the documentation of this file.

    00001 /**********************************************************************
    00002
    00003   hash.c -
    00004
    00005   $Author: yugui $
    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 <errno.h>
    00018
    00019 #ifdef __APPLE__
    00020 #include <crt_externs.h>
    00021 #endif
    00022
    00023 static VALUE rb_hash_s_try_convert(VALUE, VALUE);
    00024
    00025 #define HASH_DELETED  FL_USER1
    00026 #define HASH_PROC_DEFAULT FL_USER2
    00027
    00028 VALUE
    00029 rb_hash_freeze(VALUE hash)
    00030 {
    00031     return rb_obj_freeze(hash);
    00032 }
    00033
    00034 VALUE rb_cHash;
    00035
    00036 static VALUE envtbl;
    00037 static ID id_hash, id_yield, id_default;
    00038
    00039 static int
    00040 rb_any_cmp(VALUE a, VALUE b)
    00041 {
    00042     if (a == b) return 0;
    00043     if (FIXNUM_P(a) && FIXNUM_P(b)) {
    00044         return a != b;
    00045     }
    00046     if (TYPE(a) == T_STRING && RBASIC(a)->klass == rb_cString &&
    00047         TYPE(b) == T_STRING && RBASIC(b)->klass == rb_cString) {
    00048         return rb_str_hash_cmp(a, b);
    00049     }
    00050     if (a == Qundef || b == Qundef) return -1;
    00051     if (SYMBOL_P(a) && SYMBOL_P(b)) {
    00052         return a != b;
    00053     }
    00054
    00055     return !rb_eql(a, b);
    00056 }
    00057
    00058 VALUE
    00059 rb_hash(VALUE obj)
    00060 {
    00061     VALUE hval = rb_funcall(obj, id_hash, 0);
    00062   retry:
    00063     switch (TYPE(hval)) {
    00064       case T_FIXNUM:
    00065         return hval;
    00066
    00067       case T_BIGNUM:
    00068         return LONG2FIX(((long*)(RBIGNUM_DIGITS(hval)))[0]);
    00069
    00070       default:
    00071         hval = rb_to_int(hval);
    00072         goto retry;
    00073     }
    00074 }
    00075
    00076 static st_index_t
    00077 rb_any_hash(VALUE a)
    00078 {
    00079     VALUE hval;
    00080     st_index_t hnum;
    00081
    00082     switch (TYPE(a)) {
    00083       case T_FIXNUM:
    00084       case T_SYMBOL:
    00085       case T_NIL:
    00086       case T_FALSE:
    00087       case T_TRUE:
    00088         hnum = rb_hash_end(rb_hash_start((unsigned int)a));
    00089         break;
    00090
    00091       case T_STRING:
    00092         hnum = rb_str_hash(a);
    00093         break;
    00094
    00095       default:
    00096         hval = rb_hash(a);
    00097         hnum = FIX2LONG(hval);
    00098     }
    00099     hnum <<= 1;
    00100     return (st_index_t)RSHIFT(hnum, 1);
    00101 }
    00102
    00103 static const struct st_hash_type objhash = {
    00104     rb_any_cmp,
    00105     rb_any_hash,
    00106 };
    00107
    00108 static const struct st_hash_type identhash = {
    00109     st_numcmp,
    00110     st_numhash,
    00111 };
    00112
    00113 typedef int st_foreach_func(st_data_t, st_data_t, st_data_t);
    00114
    00115 struct foreach_safe_arg {
    00116     st_table *tbl;
    00117     st_foreach_func *func;
    00118     st_data_t arg;
    00119 };
    00120
    00121 static int
    00122 foreach_safe_i(st_data_t key, st_data_t value, struct foreach_safe_arg *arg)
    00123 {
    00124     int status;
    00125
    00126     if (key == Qundef) return ST_CONTINUE;
    00127     status = (*arg->func)(key, value, arg->arg);
    00128     if (status == ST_CONTINUE) {
    00129         return ST_CHECK;
    00130     }
    00131     return status;
    00132 }
    00133
    00134 void
    00135 st_foreach_safe(st_table *table, int (*func)(ANYARGS), st_data_t a)
    00136 {
    00137     struct foreach_safe_arg arg;
    00138
    00139     arg.tbl = table;
    00140     arg.func = (st_foreach_func *)func;
    00141     arg.arg = a;
    00142     if (st_foreach(table, foreach_safe_i, (st_data_t)&arg)) {
    00143         rb_raise(rb_eRuntimeError, "hash modified during iteration");
    00144     }
    00145 }
    00146
    00147 typedef int rb_foreach_func(VALUE, VALUE, VALUE);
    00148
    00149 struct hash_foreach_arg {
    00150     VALUE hash;
    00151     rb_foreach_func *func;
    00152     VALUE arg;
    00153 };
    00154
    00155 static int
    00156 hash_foreach_iter(st_data_t key, st_data_t value, struct hash_foreach_arg *arg)
    00157 {
    00158     int status;
    00159     st_table *tbl;
    00160
    00161     tbl = RHASH(arg->hash)->ntbl;
    00162     if ((VALUE)key == Qundef) return ST_CONTINUE;
    00163     status = (*arg->func)((VALUE)key, (VALUE)value, arg->arg);
    00164     if (RHASH(arg->hash)->ntbl != tbl) {
    00165         rb_raise(rb_eRuntimeError, "rehash occurred during iteration");
    00166     }
    00167     switch (status) {
    00168       case ST_DELETE:
    00169         st_delete_safe(tbl, &key, 0, Qundef);
    00170         FL_SET(arg->hash, HASH_DELETED);
    00171       case ST_CONTINUE:
    00172         break;
    00173       case ST_STOP:
    00174         return ST_STOP;
    00175     }
    00176     return ST_CHECK;
    00177 }
    00178
    00179 static VALUE
    00180 hash_foreach_ensure(VALUE hash)
    00181 {
    00182     RHASH(hash)->iter_lev--;
    00183
    00184     if (RHASH(hash)->iter_lev == 0) {
    00185         if (FL_TEST(hash, HASH_DELETED)) {
    00186             st_cleanup_safe(RHASH(hash)->ntbl, Qundef);
    00187             FL_UNSET(hash, HASH_DELETED);
    00188         }
    00189     }
    00190     return 0;
    00191 }
    00192
    00193 static VALUE
    00194 hash_foreach_call(struct hash_foreach_arg *arg)
    00195 {
    00196     if (st_foreach(RHASH(arg->hash)->ntbl, hash_foreach_iter, (st_data_t)arg)) {
    00197         rb_raise(rb_eRuntimeError, "hash modified during iteration");
    00198     }
    00199     return Qnil;
    00200 }
    00201
    00202 void
    00203 rb_hash_foreach(VALUE hash, int (*func)(ANYARGS), VALUE farg)
    00204 {
    00205     struct hash_foreach_arg arg;
    00206
    00207     if (!RHASH(hash)->ntbl)
    00208         return;
    00209     RHASH(hash)->iter_lev++;
    00210     arg.hash = hash;
    00211     arg.func = (rb_foreach_func *)func;
    00212     arg.arg  = farg;
    00213     rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash);
    00214 }
    00215
    00216 static VALUE
    00217 hash_alloc(VALUE klass)
    00218 {
    00219     NEWOBJ(hash, struct RHash);
    00220     OBJSETUP(hash, klass, T_HASH);
    00221
    00222     RHASH_IFNONE(hash) = Qnil;
    00223
    00224     return (VALUE)hash;
    00225 }
    00226
    00227 VALUE
    00228 rb_hash_new(void)
    00229 {
    00230     return hash_alloc(rb_cHash);
    00231 }
    00232
    00233 VALUE
    00234 rb_hash_dup(VALUE hash)
    00235 {
    00236     NEWOBJ(ret, struct RHash);
    00237     DUPSETUP(ret, hash);
    00238
    00239     if (!RHASH_EMPTY_P(hash))
    00240         ret->ntbl = st_copy(RHASH(hash)->ntbl);
    00241     if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
    00242         FL_SET(ret, HASH_PROC_DEFAULT);
    00243     }
    00244     RHASH_IFNONE(ret) = RHASH_IFNONE(hash);
    00245     return (VALUE)ret;
    00246 }
    00247
    00248 static void
    00249 rb_hash_modify_check(VALUE hash)
    00250 {
    00251     if (OBJ_FROZEN(hash)) rb_error_frozen("hash");
    00252     if (!OBJ_UNTRUSTED(hash) && rb_safe_level() >= 4)
    00253         rb_raise(rb_eSecurityError, "Insecure: can't modify hash");
    00254 }
    00255
    00256 struct st_table *
    00257 rb_hash_tbl(VALUE hash)
    00258 {
    00259     if (!RHASH(hash)->ntbl) {
    00260         RHASH(hash)->ntbl = st_init_table(&objhash);
    00261     }
    00262     return RHASH(hash)->ntbl;
    00263 }
    00264
    00265 static void
    00266 rb_hash_modify(VALUE hash)
    00267 {
    00268     rb_hash_modify_check(hash);
    00269     rb_hash_tbl(hash);
    00270 }
    00271
    00272 static void
    00273 hash_update(VALUE hash, VALUE key)
    00274 {
    00275     if (RHASH(hash)->iter_lev > 0 && !st_lookup(RHASH(hash)->ntbl, key, 0)) {
    00276         rb_raise(rb_eRuntimeError, "can't add a new key into hash during iteration");
    00277     }
    00278 }
    00279
    00280 static void
    00281 default_proc_arity_check(VALUE proc)
    00282 {
    00283     int n = rb_proc_arity(proc);
    00284
    00285     if (rb_proc_lambda_p(proc) && n != 2 && (n >= 0 || n < -3)) {
    00286         if (n < 0) n = -n-1;
    00287         rb_raise(rb_eTypeError, "default_proc takes two arguments (2 for %d)", n);
    00288     }
    00289 }
    00290
    00291 /*
    00292  *  call-seq:
    00293  *     Hash.new                          -> new_hash
    00294  *     Hash.new(obj)                     -> new_hash
    00295  *     Hash.new {|hash, key| block }     -> new_hash
    00296  *
    00297  *  Returns a new, empty hash. If this hash is subsequently accessed by
    00298  *  a key that doesn't correspond to a hash entry, the value returned
    00299  *  depends on the style of <code>new</code> used to create the hash. In
    00300  *  the first form, the access returns <code>nil</code>. If
    00301  *  <i>obj</i> is specified, this single object will be used for
    00302  *  all <em>default values</em>. If a block is specified, it will be
    00303  *  called with the hash object and the key, and should return the
    00304  *  default value. It is the block's responsibility to store the value
    00305  *  in the hash if required.
    00306  *
    00307  *     h = Hash.new("Go Fish")
    00308  *     h["a"] = 100
    00309  *     h["b"] = 200
    00310  *     h["a"]           #=> 100
    00311  *     h["c"]           #=> "Go Fish"
    00312  *     # The following alters the single default object
    00313  *     h["c"].upcase!   #=> "GO FISH"
    00314  *     h["d"]           #=> "GO FISH"
    00315  *     h.keys           #=> ["a", "b"]
    00316  *
    00317  *     # While this creates a new default object each time
    00318  *     h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }
    00319  *     h["c"]           #=> "Go Fish: c"
    00320  *     h["c"].upcase!   #=> "GO FISH: C"
    00321  *     h["d"]           #=> "Go Fish: d"
    00322  *     h.keys           #=> ["c", "d"]
    00323  *
    00324  */
    00325
    00326 static VALUE
    00327 rb_hash_initialize(int argc, VALUE *argv, VALUE hash)
    00328 {
    00329     VALUE ifnone;
    00330
    00331     rb_hash_modify(hash);
    00332     if (rb_block_given_p()) {
    00333         if (argc > 0) {
    00334             rb_raise(rb_eArgError, "wrong number of arguments");
    00335         }
    00336         ifnone = rb_block_proc();
    00337         default_proc_arity_check(ifnone);
    00338         RHASH_IFNONE(hash) = ifnone;
    00339         FL_SET(hash, HASH_PROC_DEFAULT);
    00340     }
    00341     else {
    00342         rb_scan_args(argc, argv, "01", &ifnone);
    00343         RHASH_IFNONE(hash) = ifnone;
    00344     }
    00345
    00346     return hash;
    00347 }
    00348
    00349 /*
    00350  *  call-seq:
    00351  *     Hash[ key, value, ... ]         -> new_hash
    00352  *     Hash[ [ [key, value], ... ] ]   -> new_hash
    00353  *     Hash[ object ]                  -> new_hash
    00354  *
    00355  *  Creates a new hash populated with the given objects. Equivalent to
    00356  *  the literal <code>{ <i>key</i> => <i>value</i>, ... }</code>. In the first
    00357  *  form, keys and values occur in pairs, so there must be an even number of arguments.
    00358  *  The second and third form take a single argument which is either
    00359  *  an array of key-value pairs or an object convertible to a hash.
    00360  *
    00361  *     Hash["a", 100, "b", 200]             #=> {"a"=>100, "b"=>200}
    00362  *     Hash[ [ ["a", 100], ["b", 200] ] ]   #=> {"a"=>100, "b"=>200}
    00363  *     Hash["a" => 100, "b" => 200]         #=> {"a"=>100, "b"=>200}
    00364  */
    00365
    00366 static VALUE
    00367 rb_hash_s_create(int argc, VALUE *argv, VALUE klass)
    00368 {
    00369     VALUE hash, tmp;
    00370     int i;
    00371
    00372     if (argc == 1) {
    00373         tmp = rb_hash_s_try_convert(Qnil, argv[0]);
    00374         if (!NIL_P(tmp)) {
    00375             hash = hash_alloc(klass);
    00376             if (RHASH(tmp)->ntbl) {
    00377                 RHASH(hash)->ntbl = st_copy(RHASH(tmp)->ntbl);
    00378             }
    00379             return hash;
    00380         }
    00381
    00382         tmp = rb_check_array_type(argv[0]);
    00383         if (!NIL_P(tmp)) {
    00384             long i;
    00385
    00386             hash = hash_alloc(klass);
    00387             for (i = 0; i < RARRAY_LEN(tmp); ++i) {
    00388                 VALUE v = rb_check_array_type(RARRAY_PTR(tmp)[i]);
    00389                 VALUE key, val = Qnil;
    00390
    00391                 if (NIL_P(v)) continue;
    00392                 switch (RARRAY_LEN(v)) {
    00393                   case 2:
    00394                     val = RARRAY_PTR(v)[1];
    00395                   case 1:
    00396                     key = RARRAY_PTR(v)[0];
    00397                     rb_hash_aset(hash, key, val);
    00398                 }
    00399             }
    00400             return hash;
    00401         }
    00402     }
    00403     if (argc % 2 != 0) {
    00404         rb_raise(rb_eArgError, "odd number of arguments for Hash");
    00405     }
    00406
    00407     hash = hash_alloc(klass);
    00408     for (i=0; i<argc; i+=2) {
    00409         rb_hash_aset(hash, argv[i], argv[i + 1]);
    00410     }
    00411
    00412     return hash;
    00413 }
    00414
    00415 static VALUE
    00416 to_hash(VALUE hash)
    00417 {
    00418     return rb_convert_type(hash, T_HASH, "Hash", "to_hash");
    00419 }
    00420
    00421 /*
    00422  *  call-seq:
    00423  *     Hash.try_convert(obj) -> hash or nil
    00424  *
    00425  *  Try to convert <i>obj</i> into a hash, using to_hash method.
    00426  *  Returns converted hash or nil if <i>obj</i> cannot be converted
    00427  *  for any reason.
    00428  *
    00429  *     Hash.try_convert({1=>2})   # => {1=>2}
    00430  *     Hash.try_convert("1=>2")   # => nil
    00431  */
    00432 static VALUE
    00433 rb_hash_s_try_convert(VALUE dummy, VALUE hash)
    00434 {
    00435     return rb_check_convert_type(hash, T_HASH, "Hash", "to_hash");
    00436 }
    00437
    00438 static int
    00439 rb_hash_rehash_i(VALUE key, VALUE value, VALUE arg)
    00440 {
    00441     st_table *tbl = (st_table *)arg;
    00442
    00443     if (key != Qundef) st_insert(tbl, key, value);
    00444     return ST_CONTINUE;
    00445 }
    00446
    00447 /*
    00448  *  call-seq:
    00449  *     hsh.rehash -> hsh
    00450  *
    00451  *  Rebuilds the hash based on the current hash values for each key. If
    00452  *  values of key objects have changed since they were inserted, this
    00453  *  method will reindex <i>hsh</i>. If <code>Hash#rehash</code> is
    00454  *  called while an iterator is traversing the hash, an
    00455  *  <code>RuntimeError</code> will be raised in the iterator.
    00456  *
    00457  *     a = [ "a", "b" ]
    00458  *     c = [ "c", "d" ]
    00459  *     h = { a => 100, c => 300 }
    00460  *     h[a]       #=> 100
    00461  *     a[0] = "z"
    00462  *     h[a]       #=> nil
    00463  *     h.rehash   #=> {["z", "b"]=>100, ["c", "d"]=>300}
    00464  *     h[a]       #=> 100
    00465  */
    00466
    00467 static VALUE
    00468 rb_hash_rehash(VALUE hash)
    00469 {
    00470     st_table *tbl;
    00471
    00472     if (RHASH(hash)->iter_lev > 0) {
    00473         rb_raise(rb_eRuntimeError, "rehash during iteration");
    00474     }
    00475     rb_hash_modify_check(hash);
    00476     if (!RHASH(hash)->ntbl)
    00477         return hash;
    00478     tbl = st_init_table_with_size(RHASH(hash)->ntbl->type, RHASH(hash)->ntbl->num_entries);
    00479     rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tbl);
    00480     st_free_table(RHASH(hash)->ntbl);
    00481     RHASH(hash)->ntbl = tbl;
    00482
    00483     return hash;
    00484 }
    00485
    00486 /*
    00487  *  call-seq:
    00488  *     hsh[key]    ->  value
    00489  *
    00490  *  Element Reference---Retrieves the <i>value</i> object corresponding
    00491  *  to the <i>key</i> object. If not found, returns the default value (see
    00492  *  <code>Hash::new</code> for details).
    00493  *
    00494  *     h = { "a" => 100, "b" => 200 }
    00495  *     h["a"]   #=> 100
    00496  *     h["c"]   #=> nil
    00497  *
    00498  */
    00499
    00500 VALUE
    00501 rb_hash_aref(VALUE hash, VALUE key)
    00502 {
    00503     VALUE val;
    00504
    00505     if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
    00506         return rb_funcall(hash, id_default, 1, key);
    00507     }
    00508     return val;
    00509 }
    00510
    00511 VALUE
    00512 rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
    00513 {
    00514     VALUE val;
    00515
    00516     if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
    00517         return def; /* without Hash#default */
    00518     }
    00519     return val;
    00520 }
    00521
    00522 VALUE
    00523 rb_hash_lookup(VALUE hash, VALUE key)
    00524 {
    00525     return rb_hash_lookup2(hash, key, Qnil);
    00526 }
    00527
    00528 /*
    00529  *  call-seq:
    00530  *     hsh.fetch(key [, default] )       -> obj
    00531  *     hsh.fetch(key) {| key | block }   -> obj
    00532  *
    00533  *  Returns a value from the hash for the given key. If the key can't be
    00534  *  found, there are several options: With no other arguments, it will
    00535  *  raise an <code>KeyError</code> exception; if <i>default</i> is
    00536  *  given, then that will be returned; if the optional code block is
    00537  *  specified, then that will be run and its result returned.
    00538  *
    00539  *     h = { "a" => 100, "b" => 200 }
    00540  *     h.fetch("a")                            #=> 100
    00541  *     h.fetch("z", "go fish")                 #=> "go fish"
    00542  *     h.fetch("z") { |el| "go fish, #{el}"}   #=> "go fish, z"
    00543  *
    00544  *  The following example shows that an exception is raised if the key
    00545  *  is not found and a default value is not supplied.
    00546  *
    00547  *     h = { "a" => 100, "b" => 200 }
    00548  *     h.fetch("z")
    00549  *
    00550  *  <em>produces:</em>
    00551  *
    00552  *     prog.rb:2:in `fetch': key not found (KeyError)
    00553  *      from prog.rb:2
    00554  *
    00555  */
    00556
    00557 static VALUE
    00558 rb_hash_fetch_m(int argc, VALUE *argv, VALUE hash)
    00559 {
    00560     VALUE key, if_none;
    00561     VALUE val;
    00562     long block_given;
    00563
    00564     rb_scan_args(argc, argv, "11", &key, &if_none);
    00565
    00566     block_given = rb_block_given_p();
    00567     if (block_given && argc == 2) {
    00568         rb_warn("block supersedes default value argument");
    00569     }
    00570     if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
    00571         if (block_given) return rb_yield(key);
    00572         if (argc == 1) {
    00573             VALUE desc = rb_protect(rb_inspect, key, 0);
    00574             if (NIL_P(desc) || RSTRING_LEN(desc) > 65) {
    00575                 desc = rb_any_to_s(key);
    00576             }
    00577             rb_raise(rb_eKeyError, "key not found: %s", RSTRING_PTR(desc));
    00578         }
    00579         return if_none;
    00580     }
    00581     return val;
    00582 }
    00583
    00584 VALUE
    00585 rb_hash_fetch(VALUE hash, VALUE key)
    00586 {
    00587     return rb_hash_fetch_m(1, &key, hash);
    00588 }
    00589
    00590 /*
    00591  *  call-seq:
    00592  *     hsh.default(key=nil)   -> obj
    00593  *
    00594  *  Returns the default value, the value that would be returned by
    00595  *  <i>hsh</i>[<i>key</i>] if <i>key</i> did not exist in <i>hsh</i>.
    00596  *  See also <code>Hash::new</code> and <code>Hash#default=</code>.
    00597  *
    00598  *     h = Hash.new                            #=> {}
    00599  *     h.default                               #=> nil
    00600  *     h.default(2)                            #=> nil
    00601  *
    00602  *     h = Hash.new("cat")                     #=> {}
    00603  *     h.default                               #=> "cat"
    00604  *     h.default(2)                            #=> "cat"
    00605  *
    00606  *     h = Hash.new {|h,k| h[k] = k.to_i*10}   #=> {}
    00607  *     h.default                               #=> nil
    00608  *     h.default(2)                            #=> 20
    00609  */
    00610
    00611 static VALUE
    00612 rb_hash_default(int argc, VALUE *argv, VALUE hash)
    00613 {
    00614     VALUE key, ifnone;
    00615
    00616     rb_scan_args(argc, argv, "01", &key);
    00617     ifnone = RHASH_IFNONE(hash);
    00618     if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
    00619         if (argc == 0) return Qnil;
    00620         return rb_funcall(ifnone, id_yield, 2, hash, key);
    00621     }
    00622     return ifnone;
    00623 }
    00624
    00625 /*
    00626  *  call-seq:
    00627  *     hsh.default = obj     -> obj
    00628  *
    00629  *  Sets the default value, the value returned for a key that does not
    00630  *  exist in the hash. It is not possible to set the default to a
    00631  *  <code>Proc</code> that will be executed on each key lookup.
    00632  *
    00633  *     h = { "a" => 100, "b" => 200 }
    00634  *     h.default = "Go fish"
    00635  *     h["a"]     #=> 100
    00636  *     h["z"]     #=> "Go fish"
    00637  *     # This doesn't do what you might hope...
    00638  *     h.default = proc do |hash, key|
    00639  *       hash[key] = key + key
    00640  *     end
    00641  *     h[2]       #=> #<Proc:0x401b3948@-:6>
    00642  *     h["cat"]   #=> #<Proc:0x401b3948@-:6>
    00643  */
    00644
    00645 static VALUE
    00646 rb_hash_set_default(VALUE hash, VALUE ifnone)
    00647 {
    00648     rb_hash_modify(hash);
    00649     RHASH_IFNONE(hash) = ifnone;
    00650     FL_UNSET(hash, HASH_PROC_DEFAULT);
    00651     return ifnone;
    00652 }
    00653
    00654 /*
    00655  *  call-seq:
    00656  *     hsh.default_proc -> anObject
    00657  *
    00658  *  If <code>Hash::new</code> was invoked with a block, return that
    00659  *  block, otherwise return <code>nil</code>.
    00660  *
    00661  *     h = Hash.new {|h,k| h[k] = k*k }   #=> {}
    00662  *     p = h.default_proc                 #=> #<Proc:0x401b3d08@-:1>
    00663  *     a = []                             #=> []
    00664  *     p.call(a, 2)
    00665  *     a                                  #=> [nil, nil, 4]
    00666  */
    00667
    00668
    00669 static VALUE
    00670 rb_hash_default_proc(VALUE hash)
    00671 {
    00672     if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
    00673         return RHASH_IFNONE(hash);
    00674     }
    00675     return Qnil;
    00676 }
    00677
    00678 VALUE rb_obj_is_proc(VALUE proc);
    00679
    00680 /*
    00681  *  call-seq:
    00682  *     hsh.default_proc = proc_obj     -> proc_obj
    00683  *
    00684  *  Sets the default proc to be executed on each key lookup.
    00685  *
    00686  *     h.default_proc = proc do |hash, key|
    00687  *       hash[key] = key + key
    00688  *     end
    00689  *     h[2]       #=> 4
    00690  *     h["cat"]   #=> "catcat"
    00691  */
    00692
    00693 static VALUE
    00694 rb_hash_set_default_proc(VALUE hash, VALUE proc)
    00695 {
    00696     VALUE b;
    00697
    00698     rb_hash_modify(hash);
    00699     b = rb_check_convert_type(proc, T_DATA, "Proc", "to_proc");
    00700     if (NIL_P(b) || !rb_obj_is_proc(b)) {
    00701         rb_raise(rb_eTypeError,
    00702                  "wrong default_proc type %s (expected Proc)",
    00703                  rb_obj_classname(proc));
    00704     }
    00705     proc = b;
    00706     default_proc_arity_check(proc);
    00707     RHASH_IFNONE(hash) = proc;
    00708     FL_SET(hash, HASH_PROC_DEFAULT);
    00709     return proc;
    00710 }
    00711
    00712 static int
    00713 key_i(VALUE key, VALUE value, VALUE arg)
    00714 {
    00715     VALUE *args = (VALUE *)arg;
    00716
    00717     if (rb_equal(value, args[0])) {
    00718         args[1] = key;
    00719         return ST_STOP;
    00720     }
    00721     return ST_CONTINUE;
    00722 }
    00723
    00724 /*
    00725  *  call-seq:
    00726  *     hsh.key(value)    -> key
    00727  *
    00728  *  Returns the key for a given value. If not found, returns <code>nil</code>.
    00729  *
    00730  *     h = { "a" => 100, "b" => 200 }
    00731  *     h.key(200)   #=> "b"
    00732  *     h.key(999)   #=> nil
    00733  *
    00734  */
    00735
    00736 static VALUE
    00737 rb_hash_key(VALUE hash, VALUE value)
    00738 {
    00739     VALUE args[2];
    00740
    00741     args[0] = value;
    00742     args[1] = Qnil;
    00743
    00744     rb_hash_foreach(hash, key_i, (VALUE)args);
    00745
    00746     return args[1];
    00747 }
    00748
    00749 /* :nodoc: */
    00750 static VALUE
    00751 rb_hash_index(VALUE hash, VALUE value)
    00752 {
    00753     rb_warn("Hash#index is deprecated; use Hash#key");
    00754     return rb_hash_key(hash, value);
    00755 }
    00756
    00757 static VALUE
    00758 rb_hash_delete_key(VALUE hash, VALUE key)
    00759 {
    00760     st_data_t ktmp = (st_data_t)key, val;
    00761
    00762     if (!RHASH(hash)->ntbl)
    00763         return Qundef;
    00764     if (RHASH(hash)->iter_lev > 0) {
    00765         if (st_delete_safe(RHASH(hash)->ntbl, &ktmp, &val, Qundef)) {
    00766             FL_SET(hash, HASH_DELETED);
    00767             return (VALUE)val;
    00768         }
    00769     }
    00770     else if (st_delete(RHASH(hash)->ntbl, &ktmp, &val))
    00771         return (VALUE)val;
    00772     return Qundef;
    00773 }
    00774
    00775 /*
    00776  *  call-seq:
    00777  *     hsh.delete(key)                   -> value
    00778  *     hsh.delete(key) {| key | block }  -> value
    00779  *
    00780  *  Deletes and returns a key-value pair from <i>hsh</i> whose key is
    00781  *  equal to <i>key</i>. If the key is not found, returns the
    00782  *  <em>default value</em>. If the optional code block is given and the
    00783  *  key is not found, pass in the key and return the result of
    00784  *  <i>block</i>.
    00785  *
    00786  *     h = { "a" => 100, "b" => 200 }
    00787  *     h.delete("a")                              #=> 100
    00788  *     h.delete("z")                              #=> nil
    00789  *     h.delete("z") { |el| "#{el} not found" }   #=> "z not found"
    00790  *
    00791  */
    00792
    00793 VALUE
    00794 rb_hash_delete(VALUE hash, VALUE key)
    00795 {
    00796     VALUE val;
    00797
    00798     rb_hash_modify(hash);
    00799     val = rb_hash_delete_key(hash, key);
    00800     if (val != Qundef) return val;
    00801     if (rb_block_given_p()) {
    00802         return rb_yield(key);
    00803     }
    00804     return Qnil;
    00805 }
    00806
    00807 struct shift_var {
    00808     VALUE key;
    00809     VALUE val;
    00810 };
    00811
    00812 static int
    00813 shift_i(VALUE key, VALUE value, VALUE arg)
    00814 {
    00815     struct shift_var *var = (struct shift_var *)arg;
    00816
    00817     if (key == Qundef) return ST_CONTINUE;
    00818     if (var->key != Qundef) return ST_STOP;
    00819     var->key = key;
    00820     var->val = value;
    00821     return ST_DELETE;
    00822 }
    00823
    00824 static int
    00825 shift_i_safe(VALUE key, VALUE value, VALUE arg)
    00826 {
    00827     struct shift_var *var = (struct shift_var *)arg;
    00828
    00829     if (key == Qundef) return ST_CONTINUE;
    00830     var->key = key;
    00831     var->val = value;
    00832     return ST_STOP;
    00833 }
    00834
    00835 /*
    00836  *  call-seq:
    00837  *     hsh.shift -> anArray or obj
    00838  *
    00839  *  Removes a key-value pair from <i>hsh</i> and returns it as the
    00840  *  two-item array <code>[</code> <i>key, value</i> <code>]</code>, or
    00841  *  the hash's default value if the hash is empty.
    00842  *
    00843  *     h = { 1 => "a", 2 => "b", 3 => "c" }
    00844  *     h.shift   #=> [1, "a"]
    00845  *     h         #=> {2=>"b", 3=>"c"}
    00846  */
    00847
    00848 static VALUE
    00849 rb_hash_shift(VALUE hash)
    00850 {
    00851     struct shift_var var;
    00852
    00853     rb_hash_modify(hash);
    00854     var.key = Qundef;
    00855     rb_hash_foreach(hash, RHASH(hash)->iter_lev > 0 ? shift_i_safe : shift_i,
    00856                     (VALUE)&var);
    00857
    00858     if (var.key != Qundef) {
    00859         if (RHASH(hash)->iter_lev > 0) {
    00860             rb_hash_delete_key(hash, var.key);
    00861         }
    00862         return rb_assoc_new(var.key, var.val);
    00863     }
    00864     else if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
    00865         return rb_funcall(RHASH_IFNONE(hash), id_yield, 2, hash, Qnil);
    00866     }
    00867     else {
    00868         return RHASH_IFNONE(hash);
    00869     }
    00870 }
    00871
    00872 static int
    00873 delete_if_i(VALUE key, VALUE value, VALUE hash)
    00874 {
    00875     if (key == Qundef) return ST_CONTINUE;
    00876     if (RTEST(rb_yield_values(2, key, value))) {
    00877         rb_hash_delete_key(hash, key);
    00878     }
    00879     return ST_CONTINUE;
    00880 }
    00881
    00882 /*
    00883  *  call-seq:
    00884  *     hsh.delete_if {| key, value | block }  -> hsh
    00885  *     hsh.delete_if                          -> an_enumerator
    00886  *
    00887  *  Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
    00888  *  evaluates to <code>true</code>.
    00889  *
    00890  *  If no block is given, an enumerator is returned instead.
    00891  *
    00892  *     h = { "a" => 100, "b" => 200, "c" => 300 }
    00893  *     h.delete_if {|key, value| key >= "b" }   #=> {"a"=>100}
    00894  *
    00895  */
    00896
    00897 VALUE
    00898 rb_hash_delete_if(VALUE hash)
    00899 {
    00900     RETURN_ENUMERATOR(hash, 0, 0);
    00901     rb_hash_modify(hash);
    00902     rb_hash_foreach(hash, delete_if_i, hash);
    00903     return hash;
    00904 }
    00905
    00906 /*
    00907  *  call-seq:
    00908  *     hsh.reject! {| key, value | block }  -> hsh or nil
    00909  *     hsh.reject!                          -> an_enumerator
    00910  *
    00911  *  Equivalent to <code>Hash#delete_if</code>, but returns
    00912  *  <code>nil</code> if no changes were made.
    00913  */
    00914
    00915 VALUE
    00916 rb_hash_reject_bang(VALUE hash)
    00917 {
    00918     st_index_t n;
    00919
    00920     RETURN_ENUMERATOR(hash, 0, 0);
    00921     rb_hash_modify(hash);
    00922     if (!RHASH(hash)->ntbl)
    00923         return Qnil;
    00924     n = RHASH(hash)->ntbl->num_entries;
    00925     rb_hash_foreach(hash, delete_if_i, hash);
    00926     if (n == RHASH(hash)->ntbl->num_entries) return Qnil;
    00927     return hash;
    00928 }
    00929
    00930 /*
    00931  *  call-seq:
    00932  *     hsh.reject {| key, value | block }  -> a_hash
    00933  *
    00934  *  Same as <code>Hash#delete_if</code>, but works on (and returns) a
    00935  *  copy of the <i>hsh</i>. Equivalent to
    00936  *  <code><i>hsh</i>.dup.delete_if</code>.
    00937  *
    00938  */
    00939
    00940 static VALUE
    00941 rb_hash_reject(VALUE hash)
    00942 {
    00943     return rb_hash_delete_if(rb_obj_dup(hash));
    00944 }
    00945
    00946 /*
    00947  * call-seq:
    00948  *   hsh.values_at(key, ...)   -> array
    00949  *
    00950  * Return an array containing the values associated with the given keys.
    00951  * Also see <code>Hash.select</code>.
    00952  *
    00953  *   h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
    00954  *   h.values_at("cow", "cat")  #=> ["bovine", "feline"]
    00955  */
    00956
    00957 VALUE
    00958 rb_hash_values_at(int argc, VALUE *argv, VALUE hash)
    00959 {
    00960     VALUE result = rb_ary_new2(argc);
    00961     long i;
    00962
    00963     for (i=0; i<argc; i++) {
    00964         rb_ary_push(result, rb_hash_aref(hash, argv[i]));
    00965     }
    00966     return result;
    00967 }
    00968
    00969 static int
    00970 select_i(VALUE key, VALUE value, VALUE result)
    00971 {
    00972     if (key == Qundef) return ST_CONTINUE;
    00973     if (RTEST(rb_yield_values(2, key, value)))
    00974         rb_hash_aset(result, key, value);
    00975     return ST_CONTINUE;
    00976 }
    00977
    00978 /*
    00979  *  call-seq:
    00980  *     hsh.select {|key, value| block}   -> a_hash
    00981  *     hsh.select                        -> an_enumerator
    00982  *
    00983  *  Returns a new hash consisting of entries for which the block returns true.
    00984  *
    00985  *  If no block is given, an enumerator is returned instead.
    00986  *
    00987  *     h = { "a" => 100, "b" => 200, "c" => 300 }
    00988  *     h.select {|k,v| k > "a"}  #=> {"b" => 200, "c" => 300}
    00989  *     h.select {|k,v| v < 200}  #=> {"a" => 100}
    00990  */
    00991
    00992 VALUE
    00993 rb_hash_select(VALUE hash)
    00994 {
    00995     VALUE result;
    00996
    00997     RETURN_ENUMERATOR(hash, 0, 0);
    00998     result = rb_hash_new();
    00999     rb_hash_foreach(hash, select_i, result);
    01000     return result;
    01001 }
    01002
    01003 static int
    01004 keep_if_i(VALUE key, VALUE value, VALUE hash)
    01005 {
    01006     if (key == Qundef) return ST_CONTINUE;
    01007     if (!RTEST(rb_yield_values(2, key, value))) {
    01008         return ST_DELETE;
    01009     }
    01010     return ST_CONTINUE;
    01011 }
    01012
    01013 /*
    01014  *  call-seq:
    01015  *     hsh.select! {| key, value | block }  -> hsh or nil
    01016  *     hsh.select!                          -> an_enumerator
    01017  *
    01018  *  Equivalent to <code>Hash#keep_if</code>, but returns
    01019  *  <code>nil</code> if no changes were made.
    01020  */
    01021
    01022 VALUE
    01023 rb_hash_select_bang(VALUE hash)
    01024 {
    01025     st_index_t n;
    01026
    01027     RETURN_ENUMERATOR(hash, 0, 0);
    01028     rb_hash_modify(hash);
    01029     if (!RHASH(hash)->ntbl)
    01030         return Qnil;
    01031     n = RHASH(hash)->ntbl->num_entries;
    01032     rb_hash_foreach(hash, keep_if_i, hash);
    01033     if (n == RHASH(hash)->ntbl->num_entries) return Qnil;
    01034     return hash;
    01035 }
    01036
    01037 /*
    01038  *  call-seq:
    01039  *     hsh.keep_if {| key, value | block }  -> hsh
    01040  *     hsh.keep_if                          -> an_enumerator
    01041  *
    01042  *  Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
    01043  *  evaluates to false.
    01044  *
    01045  *  If no block is given, an enumerator is returned instead.
    01046  *
    01047  */
    01048
    01049 VALUE
    01050 rb_hash_keep_if(VALUE hash)
    01051 {
    01052     RETURN_ENUMERATOR(hash, 0, 0);
    01053     rb_hash_modify(hash);
    01054     rb_hash_foreach(hash, keep_if_i, hash);
    01055     return hash;
    01056 }
    01057
    01058 static int
    01059 clear_i(VALUE key, VALUE value, VALUE dummy)
    01060 {
    01061     return ST_DELETE;
    01062 }
    01063
    01064 /*
    01065  *  call-seq:
    01066  *     hsh.clear -> hsh
    01067  *
    01068  *  Removes all key-value pairs from <i>hsh</i>.
    01069  *
    01070  *     h = { "a" => 100, "b" => 200 }   #=> {"a"=>100, "b"=>200}
    01071  *     h.clear                          #=> {}
    01072  *
    01073  */
    01074
    01075 static VALUE
    01076 rb_hash_clear(VALUE hash)
    01077 {
    01078     rb_hash_modify_check(hash);
    01079     if (!RHASH(hash)->ntbl)
    01080         return hash;
    01081     if (RHASH(hash)->ntbl->num_entries > 0) {
    01082         if (RHASH(hash)->iter_lev > 0)
    01083             rb_hash_foreach(hash, clear_i, 0);
    01084         else
    01085             st_clear(RHASH(hash)->ntbl);
    01086     }
    01087
    01088     return hash;
    01089 }
    01090
    01091 /*
    01092  *  call-seq:
    01093  *     hsh[key] = value        -> value
    01094  *     hsh.store(key, value)   -> value
    01095  *
    01096  *  Element Assignment---Associates the value given by
    01097  *  <i>value</i> with the key given by <i>key</i>.
    01098  *  <i>key</i> should not have its value changed while it is in
    01099  *  use as a key (a <code>String</code> passed as a key will be
    01100  *  duplicated and frozen).
    01101  *
    01102  *     h = { "a" => 100, "b" => 200 }
    01103  *     h["a"] = 9
    01104  *     h["c"] = 4
    01105  *     h   #=> {"a"=>9, "b"=>200, "c"=>4}
    01106  *
    01107  */
    01108
    01109 VALUE
    01110 rb_hash_aset(VALUE hash, VALUE key, VALUE val)
    01111 {
    01112     rb_hash_modify(hash);
    01113     hash_update(hash, key);
    01114     if (RHASH(hash)->ntbl->type == &identhash || rb_obj_class(key) != rb_cString) {
    01115         st_insert(RHASH(hash)->ntbl, key, val);
    01116     }
    01117     else {
    01118         st_insert2(RHASH(hash)->ntbl, key, val, rb_str_new4);
    01119     }
    01120     return val;
    01121 }
    01122
    01123 static int
    01124 replace_i(VALUE key, VALUE val, VALUE hash)
    01125 {
    01126     if (key != Qundef) {
    01127         rb_hash_aset(hash, key, val);
    01128     }
    01129
    01130     return ST_CONTINUE;
    01131 }
    01132
    01133 /*
    01134  *  call-seq:
    01135  *     hsh.replace(other_hash) -> hsh
    01136  *
    01137  *  Replaces the contents of <i>hsh</i> with the contents of
    01138  *  <i>other_hash</i>.
    01139  *
    01140  *     h = { "a" => 100, "b" => 200 }
    01141  *     h.replace({ "c" => 300, "d" => 400 })   #=> {"c"=>300, "d"=>400}
    01142  *
    01143  */
    01144
    01145 static VALUE
    01146 rb_hash_replace(VALUE hash, VALUE hash2)
    01147 {
    01148     rb_hash_modify_check(hash);
    01149     hash2 = to_hash(hash2);
    01150     if (hash == hash2) return hash;
    01151     rb_hash_clear(hash);
    01152     if (RHASH(hash2)->ntbl) {
    01153         rb_hash_tbl(hash);
    01154         RHASH(hash)->ntbl->type = RHASH(hash2)->ntbl->type;
    01155     }
    01156     rb_hash_foreach(hash2, replace_i, hash);
    01157     RHASH_IFNONE(hash) = RHASH_IFNONE(hash2);
    01158     if (FL_TEST(hash2, HASH_PROC_DEFAULT)) {
    01159         FL_SET(hash, HASH_PROC_DEFAULT);
    01160     }
    01161     else {
    01162         FL_UNSET(hash, HASH_PROC_DEFAULT);
    01163     }
    01164
    01165     return hash;
    01166 }
    01167
    01168 /*
    01169  *  call-seq:
    01170  *     hsh.length    ->  fixnum
    01171  *     hsh.size      ->  fixnum
    01172  *
    01173  *  Returns the number of key-value pairs in the hash.
    01174  *
    01175  *     h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
    01176  *     h.length        #=> 4
    01177  *     h.delete("a")   #=> 200
    01178  *     h.length        #=> 3
    01179  */
    01180
    01181 static VALUE
    01182 rb_hash_size(VALUE hash)
    01183 {
    01184     if (!RHASH(hash)->ntbl)
    01185         return INT2FIX(0);
    01186     return INT2FIX(RHASH(hash)->ntbl->num_entries);
    01187 }
    01188
    01189
    01190 /*
    01191  *  call-seq:
    01192  *     hsh.empty?    -> true or false
    01193  *
    01194  *  Returns <code>true</code> if <i>hsh</i> contains no key-value pairs.
    01195  *
    01196  *     {}.empty?   #=> true
    01197  *
    01198  */
    01199
    01200 static VALUE
    01201 rb_hash_empty_p(VALUE hash)
    01202 {
    01203     return RHASH_EMPTY_P(hash) ? Qtrue : Qfalse;
    01204 }
    01205
    01206 static int
    01207 each_value_i(VALUE key, VALUE value)
    01208 {
    01209     if (key == Qundef) return ST_CONTINUE;
    01210     rb_yield(value);
    01211     return ST_CONTINUE;
    01212 }
    01213
    01214 /*
    01215  *  call-seq:
    01216  *     hsh.each_value {| value | block } -> hsh
    01217  *     hsh.each_value                    -> an_enumerator
    01218  *
    01219  *  Calls <i>block</i> once for each key in <i>hsh</i>, passing the
    01220  *  value as a parameter.
    01221  *
    01222  *  If no block is given, an enumerator is returned instead.
    01223  *
    01224  *     h = { "a" => 100, "b" => 200 }
    01225  *     h.each_value {|value| puts value }
    01226  *
    01227  *  <em>produces:</em>
    01228  *
    01229  *     100
    01230  *     200
    01231  */
    01232
    01233 static VALUE
    01234 rb_hash_each_value(VALUE hash)
    01235 {
    01236     RETURN_ENUMERATOR(hash, 0, 0);
    01237     rb_hash_foreach(hash, each_value_i, 0);
    01238     return hash;
    01239 }
    01240
    01241 static int
    01242 each_key_i(VALUE key, VALUE value)
    01243 {
    01244     if (key == Qundef) return ST_CONTINUE;
    01245     rb_yield(key);
    01246     return ST_CONTINUE;
    01247 }
    01248
    01249 /*
    01250  *  call-seq:
    01251  *     hsh.each_key {| key | block } -> hsh
    01252  *     hsh.each_key                  -> an_enumerator
    01253  *
    01254  *  Calls <i>block</i> once for each key in <i>hsh</i>, passing the key
    01255  *  as a parameter.
    01256  *
    01257  *  If no block is given, an enumerator is returned instead.
    01258  *
    01259  *     h = { "a" => 100, "b" => 200 }
    01260  *     h.each_key {|key| puts key }
    01261  *
    01262  *  <em>produces:</em>
    01263  *
    01264  *     a
    01265  *     b
    01266  */
    01267 static VALUE
    01268 rb_hash_each_key(VALUE hash)
    01269 {
    01270     RETURN_ENUMERATOR(hash, 0, 0);
    01271     rb_hash_foreach(hash, each_key_i, 0);
    01272     return hash;
    01273 }
    01274
    01275 static int
    01276 each_pair_i(VALUE key, VALUE value)
    01277 {
    01278     if (key == Qundef) return ST_CONTINUE;
    01279     rb_yield(rb_assoc_new(key, value));
    01280     return ST_CONTINUE;
    01281 }
    01282
    01283 /*
    01284  *  call-seq:
    01285  *     hsh.each      {| key, value | block } -> hsh
    01286  *     hsh.each_pair {| key, value | block } -> hsh
    01287  *     hsh.each                              -> an_enumerator
    01288  *     hsh.each_pair                         -> an_enumerator
    01289  *
    01290  *  Calls <i>block</i> once for each key in <i>hsh</i>, passing the key-value
    01291  *  pair as parameters.
    01292  *
    01293  *  If no block is given, an enumerator is returned instead.
    01294  *
    01295  *     h = { "a" => 100, "b" => 200 }
    01296  *     h.each {|key, value| puts "#{key} is #{value}" }
    01297  *
    01298  *  <em>produces:</em>
    01299  *
    01300  *     a is 100
    01301  *     b is 200
    01302  *
    01303  */
    01304
    01305 static VALUE
    01306 rb_hash_each_pair(VALUE hash)
    01307 {
    01308     RETURN_ENUMERATOR(hash, 0, 0);
    01309     rb_hash_foreach(hash, each_pair_i, 0);
    01310     return hash;
    01311 }
    01312
    01313 static int
    01314 to_a_i(VALUE key, VALUE value, VALUE ary)
    01315 {
    01316     if (key == Qundef) return ST_CONTINUE;
    01317     rb_ary_push(ary, rb_assoc_new(key, value));
    01318     return ST_CONTINUE;
    01319 }
    01320
    01321 /*
    01322  *  call-seq:
    01323  *     hsh.to_a -> array
    01324  *
    01325  *  Converts <i>hsh</i> to a nested array of <code>[</code> <i>key,
    01326  *  value</i> <code>]</code> arrays.
    01327  *
    01328  *     h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300  }
    01329  *     h.to_a   #=> [["c", 300], ["a", 100], ["d", 400]]
    01330  */
    01331
    01332 static VALUE
    01333 rb_hash_to_a(VALUE hash)
    01334 {
    01335     VALUE ary;
    01336
    01337     ary = rb_ary_new();
    01338     rb_hash_foreach(hash, to_a_i, ary);
    01339     OBJ_INFECT(ary, hash);
    01340
    01341     return ary;
    01342 }
    01343
    01344 static int
    01345 inspect_i(VALUE key, VALUE value, VALUE str)
    01346 {
    01347     VALUE str2;
    01348
    01349     if (key == Qundef) return ST_CONTINUE;
    01350     if (RSTRING_LEN(str) > 1) {
    01351         rb_str_cat2(str, ", ");
    01352     }
    01353     str2 = rb_inspect(key);
    01354     rb_str_buf_append(str, str2);
    01355     OBJ_INFECT(str, str2);
    01356     rb_str_buf_cat2(str, "=>");
    01357     str2 = rb_inspect(value);
    01358     rb_str_buf_append(str, str2);
    01359     OBJ_INFECT(str, str2);
    01360
    01361     return ST_CONTINUE;
    01362 }
    01363
    01364 static VALUE
    01365 inspect_hash(VALUE hash, VALUE dummy, int recur)
    01366 {
    01367     VALUE str;
    01368
    01369     if (recur) return rb_usascii_str_new2("{...}");
    01370     str = rb_str_buf_new2("{");
    01371     rb_hash_foreach(hash, inspect_i, str);
    01372     rb_str_buf_cat2(str, "}");
    01373     OBJ_INFECT(str, hash);
    01374
    01375     return str;
    01376 }
    01377
    01378 /*
    01379  * call-seq:
    01380  *   hsh.to_s     -> string
    01381  *   hsh.inspect  -> string
    01382  *
    01383  * Return the contents of this hash as a string.
    01384  *
    01385  *     h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300  }
    01386  *     h.to_s   #=> "{\"c\"=>300, \"a\"=>100, \"d\"=>400}"
    01387  */
    01388
    01389 static VALUE
    01390 rb_hash_inspect(VALUE hash)
    01391 {
    01392     if (RHASH_EMPTY_P(hash))
    01393         return rb_usascii_str_new2("{}");
    01394     return rb_exec_recursive(inspect_hash, hash, 0);
    01395 }
    01396
    01397 /*
    01398  * call-seq:
    01399  *    hsh.to_hash   => hsh
    01400  *
    01401  * Returns +self+.
    01402  */
    01403
    01404 static VALUE
    01405 rb_hash_to_hash(VALUE hash)
    01406 {
    01407     return hash;
    01408 }
    01409
    01410 static int
    01411 keys_i(VALUE key, VALUE value, VALUE ary)
    01412 {
    01413     if (key == Qundef) return ST_CONTINUE;
    01414     rb_ary_push(ary, key);
    01415     return ST_CONTINUE;
    01416 }
    01417
    01418 /*
    01419  *  call-seq:
    01420  *     hsh.keys    -> array
    01421  *
    01422  *  Returns a new array populated with the keys from this hash. See also
    01423  *  <code>Hash#values</code>.
    01424  *
    01425  *     h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 }
    01426  *     h.keys   #=> ["a", "b", "c", "d"]
    01427  *
    01428  */
    01429
    01430 static VALUE
    01431 rb_hash_keys(VALUE hash)
    01432 {
    01433     VALUE ary;
    01434
    01435     ary = rb_ary_new();
    01436     rb_hash_foreach(hash, keys_i, ary);
    01437
    01438     return ary;
    01439 }
    01440
    01441 static int
    01442 values_i(VALUE key, VALUE value, VALUE ary)
    01443 {
    01444     if (key == Qundef) return ST_CONTINUE;
    01445     rb_ary_push(ary, value);
    01446     return ST_CONTINUE;
    01447 }
    01448
    01449 /*
    01450  *  call-seq:
    01451  *     hsh.values    -> array
    01452  *
    01453  *  Returns a new array populated with the values from <i>hsh</i>. See
    01454  *  also <code>Hash#keys</code>.
    01455  *
    01456  *     h = { "a" => 100, "b" => 200, "c" => 300 }
    01457  *     h.values   #=> [100, 200, 300]
    01458  *
    01459  */
    01460
    01461 static VALUE
    01462 rb_hash_values(VALUE hash)
    01463 {
    01464     VALUE ary;
    01465
    01466     ary = rb_ary_new();
    01467     rb_hash_foreach(hash, values_i, ary);
    01468
    01469     return ary;
    01470 }
    01471
    01472 /*
    01473  *  call-seq:
    01474  *     hsh.has_key?(key)    -> true or false
    01475  *     hsh.include?(key)    -> true or false
    01476  *     hsh.key?(key)        -> true or false
    01477  *     hsh.member?(key)     -> true or false
    01478  *
    01479  *  Returns <code>true</code> if the given key is present in <i>hsh</i>.
    01480  *
    01481  *     h = { "a" => 100, "b" => 200 }
    01482  *     h.has_key?("a")   #=> true
    01483  *     h.has_key?("z")   #=> false
    01484  *
    01485  */
    01486
    01487 static VALUE
    01488 rb_hash_has_key(VALUE hash, VALUE key)
    01489 {
    01490     if (!RHASH(hash)->ntbl)
    01491         return Qfalse;
    01492     if (st_lookup(RHASH(hash)->ntbl, key, 0)) {
    01493         return Qtrue;
    01494     }
    01495     return Qfalse;
    01496 }
    01497
    01498 static int
    01499 rb_hash_search_value(VALUE key, VALUE value, VALUE arg)
    01500 {
    01501     VALUE *data = (VALUE *)arg;
    01502
    01503     if (key == Qundef) return ST_CONTINUE;
    01504     if (rb_equal(value, data[1])) {
    01505         data[0] = Qtrue;
    01506         return ST_STOP;
    01507     }
    01508     return ST_CONTINUE;
    01509 }
    01510
    01511 /*
    01512  *  call-seq:
    01513  *     hsh.has_value?(value)    -> true or false
    01514  *     hsh.value?(value)        -> true or false
    01515  *
    01516  *  Returns <code>true</code> if the given value is present for some key
    01517  *  in <i>hsh</i>.
    01518  *
    01519  *     h = { "a" => 100, "b" => 200 }
    01520  *     h.has_value?(100)   #=> true
    01521  *     h.has_value?(999)   #=> false
    01522  */
    01523
    01524 static VALUE
    01525 rb_hash_has_value(VALUE hash, VALUE val)
    01526 {
    01527     VALUE data[2];
    01528
    01529     data[0] = Qfalse;
    01530     data[1] = val;
    01531     rb_hash_foreach(hash, rb_hash_search_value, (VALUE)data);
    01532     return data[0];
    01533 }
    01534
    01535 struct equal_data {
    01536     VALUE result;
    01537     st_table *tbl;
    01538     int eql;
    01539 };
    01540
    01541 static int
    01542 eql_i(VALUE key, VALUE val1, VALUE arg)
    01543 {
    01544     struct equal_data *data = (struct equal_data *)arg;
    01545     VALUE val2;
    01546
    01547     if (key == Qundef) return ST_CONTINUE;
    01548     if (!st_lookup(data->tbl, key, &val2)) {
    01549         data->result = Qfalse;
    01550         return ST_STOP;
    01551     }
    01552     if (!(data->eql ? rb_eql(val1, val2) : (int)rb_equal(val1, val2))) {
    01553         data->result = Qfalse;
    01554         return ST_STOP;
    01555     }
    01556     return ST_CONTINUE;
    01557 }
    01558
    01559 static VALUE
    01560 recursive_eql(VALUE hash, VALUE dt, int recur)
    01561 {
    01562     struct equal_data *data;
    01563
    01564     if (recur) return Qtrue;    /* Subtle! */
    01565     data = (struct equal_data*)dt;
    01566     data->result = Qtrue;
    01567     rb_hash_foreach(hash, eql_i, dt);
    01568
    01569     return data->result;
    01570 }
    01571
    01572 static VALUE
    01573 hash_equal(VALUE hash1, VALUE hash2, int eql)
    01574 {
    01575     struct equal_data data;
    01576
    01577     if (hash1 == hash2) return Qtrue;
    01578     if (TYPE(hash2) != T_HASH) {
    01579         if (!rb_respond_to(hash2, rb_intern("to_hash"))) {
    01580             return Qfalse;
    01581         }
    01582         if (eql)
    01583             return rb_eql(hash2, hash1);
    01584         else
    01585             return rb_equal(hash2, hash1);
    01586     }
    01587     if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2))
    01588         return Qfalse;
    01589     if (!RHASH(hash1)->ntbl || !RHASH(hash2)->ntbl)
    01590         return Qtrue;
    01591     if (RHASH(hash1)->ntbl->type != RHASH(hash2)->ntbl->type)
    01592         return Qfalse;
    01593 #if 0
    01594     if (!(rb_equal(RHASH_IFNONE(hash1), RHASH_IFNONE(hash2)) &&
    01595           FL_TEST(hash1, HASH_PROC_DEFAULT) == FL_TEST(hash2, HASH_PROC_DEFAULT)))
    01596         return Qfalse;
    01597 #endif
    01598
    01599     data.tbl = RHASH(hash2)->ntbl;
    01600     data.eql = eql;
    01601     return rb_exec_recursive_paired(recursive_eql, hash1, hash2, (VALUE)&data);
    01602 }
    01603
    01604 /*
    01605  *  call-seq:
    01606  *     hsh == other_hash    -> true or false
    01607  *
    01608  *  Equality---Two hashes are equal if they each contain the same number
    01609  *  of keys and if each key-value pair is equal to (according to
    01610  *  <code>Object#==</code>) the corresponding elements in the other
    01611  *  hash.
    01612  *
    01613  *     h1 = { "a" => 1, "c" => 2 }
    01614  *     h2 = { 7 => 35, "c" => 2, "a" => 1 }
    01615  *     h3 = { "a" => 1, "c" => 2, 7 => 35 }
    01616  *     h4 = { "a" => 1, "d" => 2, "f" => 35 }
    01617  *     h1 == h2   #=> false
    01618  *     h2 == h3   #=> true
    01619  *     h3 == h4   #=> false
    01620  *
    01621  */
    01622
    01623 static VALUE
    01624 rb_hash_equal(VALUE hash1, VALUE hash2)
    01625 {
    01626     return hash_equal(hash1, hash2, FALSE);
    01627 }
    01628
    01629 /*
    01630  *  call-seq:
    01631  *     hash.eql?(other)  -> true or false
    01632  *
    01633  *  Returns <code>true</code> if <i>hash</i> and <i>other</i> are
    01634  *  both hashes with the same content.
    01635  */
    01636
    01637 static VALUE
    01638 rb_hash_eql(VALUE hash1, VALUE hash2)
    01639 {
    01640     return hash_equal(hash1, hash2, TRUE);
    01641 }
    01642
    01643 static int
    01644 hash_i(VALUE key, VALUE val, VALUE arg)
    01645 {
    01646     st_index_t *hval = (st_index_t *)arg;
    01647
    01648     if (key == Qundef) return ST_CONTINUE;
    01649     *hval ^= rb_hash_end(rb_hash_uint(rb_hash_start(rb_hash(key)), rb_hash(val)));
    01650     return ST_CONTINUE;
    01651 }
    01652
    01653 static VALUE
    01654 recursive_hash(VALUE hash, VALUE dummy, int recur)
    01655 {
    01656     st_index_t hval;
    01657
    01658     if (!RHASH(hash)->ntbl)
    01659         return LONG2FIX(0);
    01660     hval = RHASH(hash)->ntbl->num_entries;
    01661     if (recur)
    01662         hval = rb_hash_end(rb_hash_uint(rb_hash_start(rb_hash(rb_cHash)), hval));
    01663     else
    01664         rb_hash_foreach(hash, hash_i, (VALUE)&hval);
    01665     return INT2FIX(hval);
    01666 }
    01667
    01668 /*
    01669  *  call-seq:
    01670  *     hsh.hash   -> fixnum
    01671  *
    01672  *  Compute a hash-code for this hash. Two hashes with the same content
    01673  *  will have the same hash code (and will compare using <code>eql?</code>).
    01674  */
    01675
    01676 static VALUE
    01677 rb_hash_hash(VALUE hash)
    01678 {
    01679     return rb_exec_recursive_outer(recursive_hash, hash, 0);
    01680 }
    01681
    01682 static int
    01683 rb_hash_invert_i(VALUE key, VALUE value, VALUE hash)
    01684 {
    01685     if (key == Qundef) return ST_CONTINUE;
    01686     rb_hash_aset(hash, value, key);
    01687     return ST_CONTINUE;
    01688 }
    01689
    01690 /*
    01691  *  call-seq:
    01692  *     hsh.invert -> new_hash
    01693  *
    01694  *  Returns a new hash created by using <i>hsh</i>'s values as keys, and
    01695  *  the keys as values.
    01696  *
    01697  *     h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 }
    01698  *     h.invert   #=> {0=>"a", 100=>"m", 200=>"d", 300=>"y"}
    01699  *
    01700  */
    01701
    01702 static VALUE
    01703 rb_hash_invert(VALUE hash)
    01704 {
    01705     VALUE h = rb_hash_new();
    01706
    01707     rb_hash_foreach(hash, rb_hash_invert_i, h);
    01708     return h;
    01709 }
    01710
    01711 static int
    01712 rb_hash_update_i(VALUE key, VALUE value, VALUE hash)
    01713 {
    01714     if (key == Qundef) return ST_CONTINUE;
    01715     hash_update(hash, key);
    01716     st_insert(RHASH(hash)->ntbl, key, value);
    01717     return ST_CONTINUE;
    01718 }
    01719
    01720 static int
    01721 rb_hash_update_block_i(VALUE key, VALUE value, VALUE hash)
    01722 {
    01723     if (key == Qundef) return ST_CONTINUE;
    01724     if (rb_hash_has_key(hash, key)) {
    01725         value = rb_yield_values(3, key, rb_hash_aref(hash, key), value);
    01726     }
    01727     hash_update(hash, key);
    01728     st_insert(RHASH(hash)->ntbl, key, value);
    01729     return ST_CONTINUE;
    01730 }
    01731
    01732 /*
    01733  *  call-seq:
    01734  *     hsh.merge!(other_hash)                                 -> hsh
    01735  *     hsh.update(other_hash)                                 -> hsh
    01736  *     hsh.merge!(other_hash){|key, oldval, newval| block}    -> hsh
    01737  *     hsh.update(other_hash){|key, oldval, newval| block}    -> hsh
    01738  *
    01739  *  Adds the contents of <i>other_hash</i> to <i>hsh</i>.  If no
    01740  *  block is specified, entries with duplicate keys are overwritten
    01741  *  with the values from <i>other_hash</i>, otherwise the value
    01742  *  of each duplicate key is determined by calling the block with
    01743  *  the key, its value in <i>hsh</i> and its value in <i>other_hash</i>.
    01744  *
    01745  *     h1 = { "a" => 100, "b" => 200 }
    01746  *     h2 = { "b" => 254, "c" => 300 }
    01747  *     h1.merge!(h2)   #=> {"a"=>100, "b"=>254, "c"=>300}
    01748  *
    01749  *     h1 = { "a" => 100, "b" => 200 }
    01750  *     h2 = { "b" => 254, "c" => 300 }
    01751  *     h1.merge!(h2) { |key, v1, v2| v1 }
    01752  *                     #=> {"a"=>100, "b"=>200, "c"=>300}
    01753  */
    01754
    01755 static VALUE
    01756 rb_hash_update(VALUE hash1, VALUE hash2)
    01757 {
    01758     rb_hash_modify(hash1);
    01759     hash2 = to_hash(hash2);
    01760     if (rb_block_given_p()) {
    01761         rb_hash_foreach(hash2, rb_hash_update_block_i, hash1);
    01762     }
    01763     else {
    01764         rb_hash_foreach(hash2, rb_hash_update_i, hash1);
    01765     }
    01766     return hash1;
    01767 }
    01768
    01769 /*
    01770  *  call-seq:
    01771  *     hsh.merge(other_hash)                              -> new_hash
    01772  *     hsh.merge(other_hash){|key, oldval, newval| block} -> new_hash
    01773  *
    01774  *  Returns a new hash containing the contents of <i>other_hash</i> and
    01775  *  the contents of <i>hsh</i>. If no block is specified, the value for
    01776  *  entries with duplicate keys will be that of <i>other_hash</i>. Otherwise
    01777  *  the value for each duplicate key is determined by calling the block
    01778  *  with the key, its value in <i>hsh</i> and its value in <i>other_hash</i>.
    01779  *
    01780  *     h1 = { "a" => 100, "b" => 200 }
    01781  *     h2 = { "b" => 254, "c" => 300 }
    01782  *     h1.merge(h2)   #=> {"a"=>100, "b"=>254, "c"=>300}
    01783  *     h1.merge(h2){|key, oldval, newval| newval - oldval}
    01784  *                    #=> {"a"=>100, "b"=>54,  "c"=>300}
    01785  *     h1             #=> {"a"=>100, "b"=>200}
    01786  *
    01787  */
    01788
    01789 static VALUE
    01790 rb_hash_merge(VALUE hash1, VALUE hash2)
    01791 {
    01792     return rb_hash_update(rb_obj_dup(hash1), hash2);
    01793 }
    01794
    01795 static int
    01796 assoc_i(VALUE key, VALUE val, VALUE arg)
    01797 {
    01798     VALUE *args = (VALUE *)arg;
    01799
    01800     if (key == Qundef) return ST_CONTINUE;
    01801     if (RTEST(rb_equal(args[0], key))) {
    01802         args[1] = rb_assoc_new(key, val);
    01803         return ST_STOP;
    01804     }
    01805     return ST_CONTINUE;
    01806 }
    01807
    01808 /*
    01809  *  call-seq:
    01810  *     hash.assoc(obj)   ->  an_array  or  nil
    01811  *
    01812  *  Searches through the hash comparing _obj_ with the key using <code>==</code>.
    01813  *  Returns the key-value pair (two elements array) or +nil+
    01814  *  if no match is found.  See <code>Array#assoc</code>.
    01815  *
    01816  *     h = {"colors"  => ["red", "blue", "green"],
    01817  *          "letters" => ["a", "b", "c" ]}
    01818  *     h.assoc("letters")  #=> ["letters", ["a", "b", "c"]]
    01819  *     h.assoc("foo")      #=> nil
    01820  */
    01821
    01822 VALUE
    01823 rb_hash_assoc(VALUE hash, VALUE obj)
    01824 {
    01825     VALUE args[2];
    01826
    01827     args[0] = obj;
    01828     args[1] = Qnil;
    01829     rb_hash_foreach(hash, assoc_i, (VALUE)args);
    01830     return args[1];
    01831 }
    01832
    01833 static int
    01834 rassoc_i(VALUE key, VALUE val, VALUE arg)
    01835 {
    01836     VALUE *args = (VALUE *)arg;
    01837
    01838     if (key == Qundef) return ST_CONTINUE;
    01839     if (RTEST(rb_equal(args[0], val))) {
    01840         args[1] = rb_assoc_new(key, val);
    01841         return ST_STOP;
    01842     }
    01843     return ST_CONTINUE;
    01844 }
    01845
    01846 /*
    01847  *  call-seq:
    01848  *     hash.rassoc(key) -> an_array or nil
    01849  *
    01850  *  Searches through the hash comparing _obj_ with the value using <code>==</code>.
    01851  *  Returns the first key-value pair (two-element array) that matches. See
    01852  *  also <code>Array#rassoc</code>.
    01853  *
    01854  *     a = {1=> "one", 2 => "two", 3 => "three", "ii" => "two"}
    01855  *     a.rassoc("two")    #=> [2, "two"]
    01856  *     a.rassoc("four")   #=> nil
    01857  */
    01858
    01859 VALUE
    01860 rb_hash_rassoc(VALUE hash, VALUE obj)
    01861 {
    01862     VALUE args[2];
    01863
    01864     args[0] = obj;
    01865     args[1] = Qnil;
    01866     rb_hash_foreach(hash, rassoc_i, (VALUE)args);
    01867     return args[1];
    01868 }
    01869
    01870 /*
    01871  *  call-seq:
    01872  *     hash.flatten -> an_array
    01873  *     hash.flatten(level) -> an_array
    01874  *
    01875  *  Returns a new array that is a one-dimensional flattening of this
    01876  *  hash. That is, for every key or value that is an array, extract
    01877  *  its elements into the new array.  Unlike Array#flatten, this
    01878  *  method does not flatten recursively by default.  The optional
    01879  *  <i>level</i> argument determines the level of recursion to flatten.
    01880  *
    01881  *     a =  {1=> "one", 2 => [2,"two"], 3 => "three"}
    01882  *     a.flatten    # => [1, "one", 2, [2, "two"], 3, "three"]
    01883  *     a.flatten(2) # => [1, "one", 2, 2, "two", 3, "three"]
    01884  */
    01885
    01886 static VALUE
    01887 rb_hash_flatten(int argc, VALUE *argv, VALUE hash)
    01888 {
    01889     VALUE ary, tmp;
    01890
    01891     ary = rb_hash_to_a(hash);
    01892     if (argc == 0) {
    01893         argc = 1;
    01894         tmp = INT2FIX(1);
    01895         argv = &tmp;
    01896     }
    01897     rb_funcall2(ary, rb_intern("flatten!"), argc, argv);
    01898     return ary;
    01899 }
    01900
    01901 /*
    01902  *  call-seq:
    01903  *     hsh.compare_by_identity -> hsh
    01904  *
    01905  *  Makes <i>hsh</i> compare its keys by their identity, i.e. it
    01906  *  will consider exact same objects as same keys.
    01907  *
    01908  *     h1 = { "a" => 100, "b" => 200, :c => "c" }
    01909  *     h1["a"]        #=> 100
    01910  *     h1.compare_by_identity
    01911  *     h1.compare_by_identity? #=> true
    01912  *     h1["a"]        #=> nil  # different objects.
    01913  *     h1[:c]         #=> "c"  # same symbols are all same.
    01914  *
    01915  */
    01916
    01917 static VALUE
    01918 rb_hash_compare_by_id(VALUE hash)
    01919 {
    01920     rb_hash_modify(hash);
    01921     RHASH(hash)->ntbl->type = &identhash;
    01922     rb_hash_rehash(hash);
    01923     return hash;
    01924 }
    01925
    01926 /*
    01927  *  call-seq:
    01928  *     hsh.compare_by_identity? -> true or false
    01929  *
    01930  *  Returns <code>true</code> if <i>hsh</i> will compare its keys by
    01931  *  their identity.  Also see <code>Hash#compare_by_identity</code>.
    01932  *
    01933  */
    01934
    01935 static VALUE
    01936 rb_hash_compare_by_id_p(VALUE hash)
    01937 {
    01938     if (!RHASH(hash)->ntbl)
    01939         return Qfalse;
    01940     if (RHASH(hash)->ntbl->type == &identhash) {
    01941         return Qtrue;
    01942     }
    01943     return Qfalse;
    01944 }
    01945
    01946 static int path_tainted = -1;
    01947
    01948 static char **origenviron;
    01949 #ifdef _WIN32
    01950 #define GET_ENVIRON(e) (e = rb_w32_get_environ())
    01951 #define FREE_ENVIRON(e) rb_w32_free_environ(e)
    01952 static char **my_environ;
    01953 #undef environ
    01954 #define environ my_environ
    01955 #elif defined(__APPLE__)
    01956 #undef environ
    01957 #define environ (*_NSGetEnviron())
    01958 #define GET_ENVIRON(e) (e)
    01959 #define FREE_ENVIRON(e)
    01960 #else
    01961 extern char **environ;
    01962 #define GET_ENVIRON(e) (e)
    01963 #define FREE_ENVIRON(e)
    01964 #endif
    01965 #ifdef ENV_IGNORECASE
    01966 #define ENVMATCH(s1, s2) (STRCASECMP(s1, s2) == 0)
    01967 #define ENVNMATCH(s1, s2, n) (STRNCASECMP(s1, s2, n) == 0)
    01968 #else
    01969 #define ENVMATCH(n1, n2) (strcmp(n1, n2) == 0)
    01970 #define ENVNMATCH(s1, s2, n) (memcmp(s1, s2, n) == 0)
    01971 #endif
    01972
    01973 static VALUE
    01974 env_str_new(const char *ptr, long len)
    01975 {
    01976     VALUE str = rb_locale_str_new(ptr, len);
    01977
    01978     rb_obj_freeze(str);
    01979     return str;
    01980 }
    01981
    01982 static VALUE
    01983 env_str_new2(const char *ptr)
    01984 {
    01985     if (!ptr) return Qnil;
    01986     return env_str_new(ptr, strlen(ptr));
    01987 }
    01988
    01989 static VALUE
    01990 env_delete(VALUE obj, VALUE name)
    01991 {
    01992     char *nam, *val;
    01993
    01994     rb_secure(4);
    01995     SafeStringValue(name);
    01996     nam = RSTRING_PTR(name);
    01997     if (memchr(nam, '\0', RSTRING_LEN(name))) {
    01998         rb_raise(rb_eArgError, "bad environment variable name");
    01999     }
    02000     val = getenv(nam);
    02001     if (val) {
    02002         VALUE value = env_str_new2(val);
    02003
    02004         ruby_setenv(nam, 0);
    02005         if (ENVMATCH(nam, PATH_ENV)) {
    02006             path_tainted = 0;
    02007         }
    02008         return value;
    02009     }
    02010     return Qnil;
    02011 }
    02012
    02013 static VALUE
    02014 env_delete_m(VALUE obj, VALUE name)
    02015 {
    02016     VALUE val;
    02017
    02018     val = env_delete(obj, name);
    02019     if (NIL_P(val) && rb_block_given_p()) rb_yield(name);
    02020     return val;
    02021 }
    02022
    02023 static int env_path_tainted(const char *);
    02024
    02025 static VALUE
    02026 rb_f_getenv(VALUE obj, VALUE name)
    02027 {
    02028     char *nam, *env;
    02029
    02030     rb_secure(4);
    02031     SafeStringValue(name);
    02032     nam = RSTRING_PTR(name);
    02033     if (memchr(nam, '\0', RSTRING_LEN(name))) {
    02034         rb_raise(rb_eArgError, "bad environment variable name");
    02035     }
    02036     env = getenv(nam);
    02037     if (env) {
    02038         if (ENVMATCH(nam, PATH_ENV) && !env_path_tainted(env)) {
    02039             VALUE str = rb_filesystem_str_new_cstr(env);
    02040
    02041             rb_obj_freeze(str);
    02042             return str;
    02043         }
    02044         return env_str_new2(env);
    02045     }
    02046     return Qnil;
    02047 }
    02048
    02049 static VALUE
    02050 env_fetch(int argc, VALUE *argv)
    02051 {
    02052     VALUE key, if_none;
    02053     long block_given;
    02054     char *nam, *env;
    02055
    02056     rb_secure(4);
    02057     rb_scan_args(argc, argv, "11", &key, &if_none);
    02058     block_given = rb_block_given_p();
    02059     if (block_given && argc == 2) {
    02060         rb_warn("block supersedes default value argument");
    02061     }
    02062     SafeStringValue(key);
    02063     nam = RSTRING_PTR(key);
    02064     if (memchr(nam, '\0', RSTRING_LEN(key))) {
    02065         rb_raise(rb_eArgError, "bad environment variable name");
    02066     }
    02067     env = getenv(nam);
    02068     if (!env) {
    02069         if (block_given) return rb_yield(key);
    02070         if (argc == 1) {
    02071             rb_raise(rb_eKeyError, "key not found");
    02072         }
    02073         return if_none;
    02074     }
    02075     if (ENVMATCH(nam, PATH_ENV) && !env_path_tainted(env))
    02076         return rb_filesystem_str_new_cstr(env);
    02077     return env_str_new2(env);
    02078 }
    02079
    02080 static void
    02081 path_tainted_p(const char *path)
    02082 {
    02083     path_tainted = rb_path_check(path)?0:1;
    02084 }
    02085
    02086 static int
    02087 env_path_tainted(const char *path)
    02088 {
    02089     if (path_tainted < 0) {
    02090         path_tainted_p(path);
    02091     }
    02092     return path_tainted;
    02093 }
    02094
    02095 int
    02096 rb_env_path_tainted(void)
    02097 {
    02098     if (path_tainted < 0) {
    02099         path_tainted_p(getenv(PATH_ENV));
    02100     }
    02101     return path_tainted;
    02102 }
    02103
    02104 #if defined(_WIN32) || (defined(HAVE_SETENV) && defined(HAVE_UNSETENV))
    02105 #elif defined __sun__
    02106 static int
    02107 in_origenv(const char *str)
    02108 {
    02109     char **env;
    02110     for (env = origenviron; *env; ++env) {
    02111         if (*env == str) return 1;
    02112     }
    02113     return 0;
    02114 }
    02115 #else
    02116 static int
    02117 envix(const char *nam)
    02118 {
    02119     register int i, len = strlen(nam);
    02120     char **env;
    02121
    02122     env = GET_ENVIRON(environ);
    02123     for (i = 0; env[i]; i++) {
    02124         if (ENVNMATCH(env[i],nam,len) && env[i][len] == '=')
    02125             break;                      /* memcmp must come first to avoid */
    02126     }                                   /* potential SEGV's */
    02127     FREE_ENVIRON(environ);
    02128     return i;
    02129 }
    02130 #endif
    02131
    02132 void
    02133 ruby_setenv(const char *name, const char *value)
    02134 {
    02135 #if defined(_WIN32)
    02136     int len;
    02137     char *buf;
    02138     int failed = 0;
    02139     if (strchr(name, '=')) {
    02140         errno = EINVAL;
    02141         rb_sys_fail("ruby_setenv");
    02142     }
    02143     if (value) {
    02144         len = strlen(name) + 1 + strlen(value) + 1;
    02145         buf = ALLOCA_N(char, len);
    02146         snprintf(buf, len, "%s=%s", name, value);
    02147         failed = putenv(buf);
    02148
    02149         /* putenv() doesn't handle empty value */
    02150         if (!*value)
    02151             failed = !SetEnvironmentVariable(name,value);
    02152     }
    02153     else {
    02154         len = strlen(name) + 1 + 1;
    02155         buf = ALLOCA_N(char, len);
    02156         snprintf(buf, len, "%s=", name);
    02157         putenv(buf);
    02158         failed = !SetEnvironmentVariable(name, 0);
    02159     }
    02160     if (failed) {
    02161         rb_warn("failed to set environment variable. Ruby 1.9.3 will raise SystemCallError in this case.");
    02162     }
    02163 #elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)
    02164 #undef setenv
    02165 #undef unsetenv
    02166     if (value) {
    02167         if (setenv(name, value, 1))
    02168             rb_sys_fail("setenv");
    02169     } else {
    02170 #ifdef VOID_UNSETENV
    02171         unsetenv(name);
    02172 #else
    02173         if (unsetenv(name))
    02174             rb_sys_fail("unsetenv");
    02175 #endif
    02176     }
    02177 #elif defined __sun__
    02178     size_t len;
    02179     char **env_ptr, *str;
    02180     if (strchr(name, '=')) {
    02181         errno = EINVAL;
    02182         rb_sys_fail("ruby_setenv");
    02183     }
    02184     len = strlen(name);
    02185     for (env_ptr = GET_ENVIRON(environ); (str = *env_ptr) != 0; ++env_ptr) {
    02186         if (!strncmp(str, name, len) && str[len] == '=') {
    02187             if (!in_origenv(str)) free(str);
    02188             while ((env_ptr[0] = env_ptr[1]) != 0) env_ptr++;
    02189             break;
    02190         }
    02191     }
    02192     if (value) {
    02193         str = malloc(len += strlen(value) + 2);
    02194         snprintf(str, len, "%s=%s", name, value);
    02195         if (putenv(str))
    02196             rb_sys_fail("putenv");
    02197     }
    02198 #else  /* WIN32 */
    02199     size_t len;
    02200     int i;
    02201     if (strchr(name, '=')) {
    02202         errno = EINVAL;
    02203         rb_sys_fail("ruby_setenv");
    02204     }
    02205     i=envix(name);                      /* where does it go? */
    02206
    02207     if (environ == origenviron) {       /* need we copy environment? */
    02208         int j;
    02209         int max;
    02210         char **tmpenv;
    02211
    02212         for (max = i; environ[max]; max++) ;
    02213         tmpenv = ALLOC_N(char*, max+2);
    02214         for (j=0; j<max; j++)           /* copy environment */
    02215             tmpenv[j] = ruby_strdup(environ[j]);
    02216         tmpenv[max] = 0;
    02217         environ = tmpenv;               /* tell exec where it is now */
    02218     }
    02219     if (environ[i]) {
    02220         char **envp = origenviron;
    02221         while (*envp && *envp != environ[i]) envp++;
    02222         if (!*envp)
    02223             xfree(environ[i]);
    02224         if (!value) {
    02225             while (environ[i]) {
    02226                 environ[i] = environ[i+1];
    02227                 i++;
    02228             }
    02229             return;
    02230         }
    02231     }
    02232     else {                      /* does not exist yet */
    02233         if (!value) return;
    02234         REALLOC_N(environ, char*, i+2); /* just expand it a bit */
    02235         environ[i+1] = 0;       /* make sure it's null terminated */
    02236     }
    02237     len = strlen(name) + strlen(value) + 2;
    02238     environ[i] = ALLOC_N(char, len);
    02239     snprintf(environ[i],len,"%s=%s",name,value); /* all that work just for this */
    02240 #endif /* WIN32 */
    02241 }
    02242
    02243 void
    02244 ruby_unsetenv(const char *name)
    02245 {
    02246     ruby_setenv(name, 0);
    02247 }
    02248
    02249 static VALUE
    02250 env_aset(VALUE obj, VALUE nm, VALUE val)
    02251 {
    02252     char *name, *value;
    02253
    02254     if (rb_safe_level() >= 4) {
    02255         rb_raise(rb_eSecurityError, "can't change environment variable");
    02256     }
    02257
    02258     if (NIL_P(val)) {
    02259         env_delete(obj, nm);
    02260         return Qnil;
    02261     }
    02262     StringValue(nm);
    02263     StringValue(val);
    02264     name = RSTRING_PTR(nm);
    02265     value = RSTRING_PTR(val);
    02266     if (memchr(name, '\0', RSTRING_LEN(nm)))
    02267         rb_raise(rb_eArgError, "bad environment variable name");
    02268     if (memchr(value, '\0', RSTRING_LEN(val)))
    02269         rb_raise(rb_eArgError, "bad environment variable value");
    02270
    02271     ruby_setenv(name, value);
    02272     if (ENVMATCH(name, PATH_ENV)) {
    02273         if (OBJ_TAINTED(val)) {
    02274             /* already tainted, no check */
    02275             path_tainted = 1;
    02276             return val;
    02277         }
    02278         else {
    02279             path_tainted_p(value);
    02280         }
    02281     }
    02282     return val;
    02283 }
    02284
    02285 static VALUE
    02286 env_keys(void)
    02287 {
    02288     char **env;
    02289     VALUE ary;
    02290
    02291     rb_secure(4);
    02292     ary = rb_ary_new();
    02293     env = GET_ENVIRON(environ);
    02294     while (*env) {
    02295         char *s = strchr(*env, '=');
    02296         if (s) {
    02297             rb_ary_push(ary, env_str_new(*env, s-*env));
    02298         }
    02299         env++;
    02300     }
    02301     FREE_ENVIRON(environ);
    02302     return ary;
    02303 }
    02304
    02305 static VALUE
    02306 env_each_key(VALUE ehash)
    02307 {
    02308     VALUE keys;
    02309     long i;
    02310
    02311     RETURN_ENUMERATOR(ehash, 0, 0);
    02312     keys = env_keys();  /* rb_secure(4); */
    02313     for (i=0; i<RARRAY_LEN(keys); i++) {
    02314         rb_yield(RARRAY_PTR(keys)[i]);
    02315     }
    02316     return ehash;
    02317 }
    02318
    02319 static VALUE
    02320 env_values(void)
    02321 {
    02322     VALUE ary;
    02323     char **env;
    02324
    02325     rb_secure(4);
    02326     ary = rb_ary_new();
    02327     env = GET_ENVIRON(environ);
    02328     while (*env) {
    02329         char *s = strchr(*env, '=');
    02330         if (s) {
    02331             rb_ary_push(ary, env_str_new2(s+1));
    02332         }
    02333         env++;
    02334     }
    02335     FREE_ENVIRON(environ);
    02336     return ary;
    02337 }
    02338
    02339 static VALUE
    02340 env_each_value(VALUE ehash)
    02341 {
    02342     VALUE values;
    02343     long i;
    02344
    02345     RETURN_ENUMERATOR(ehash, 0, 0);
    02346     values = env_values();      /* rb_secure(4); */
    02347     for (i=0; i<RARRAY_LEN(values); i++) {
    02348         rb_yield(RARRAY_PTR(values)[i]);
    02349     }
    02350     return ehash;
    02351 }
    02352
    02353 static VALUE
    02354 env_each_pair(VALUE ehash)
    02355 {
    02356     char **env;
    02357     VALUE ary;
    02358     long i;
    02359
    02360     RETURN_ENUMERATOR(ehash, 0, 0);
    02361
    02362     rb_secure(4);
    02363     ary = rb_ary_new();
    02364     env = GET_ENVIRON(environ);
    02365     while (*env) {
    02366         char *s = strchr(*env, '=');
    02367         if (s) {
    02368             rb_ary_push(ary, env_str_new(*env, s-*env));
    02369             rb_ary_push(ary, env_str_new2(s+1));
    02370         }
    02371         env++;
    02372     }
    02373     FREE_ENVIRON(environ);
    02374
    02375     for (i=0; i<RARRAY_LEN(ary); i+=2) {
    02376         rb_yield(rb_assoc_new(RARRAY_PTR(ary)[i], RARRAY_PTR(ary)[i+1]));
    02377     }
    02378     return ehash;
    02379 }
    02380
    02381 static VALUE
    02382 env_reject_bang(VALUE ehash)
    02383 {
    02384     volatile VALUE keys;
    02385     long i;
    02386     int del = 0;
    02387
    02388     RETURN_ENUMERATOR(ehash, 0, 0);
    02389     keys = env_keys();  /* rb_secure(4); */
    02390     for (i=0; i<RARRAY_LEN(keys); i++) {
    02391         VALUE val = rb_f_getenv(Qnil, RARRAY_PTR(keys)[i]);
    02392         if (!NIL_P(val)) {
    02393             if (RTEST(rb_yield_values(2, RARRAY_PTR(keys)[i], val))) {
    02394                 FL_UNSET(RARRAY_PTR(keys)[i], FL_TAINT);
    02395                 env_delete(Qnil, RARRAY_PTR(keys)[i]);
    02396                 del++;
    02397             }
    02398         }
    02399     }
    02400     if (del == 0) return Qnil;
    02401     return envtbl;
    02402 }
    02403
    02404 static VALUE
    02405 env_delete_if(VALUE ehash)
    02406 {
    02407     RETURN_ENUMERATOR(ehash, 0, 0);
    02408     env_reject_bang(ehash);
    02409     return envtbl;
    02410 }
    02411
    02412 static VALUE
    02413 env_values_at(int argc, VALUE *argv)
    02414 {
    02415     VALUE result;
    02416     long i;
    02417
    02418     rb_secure(4);
    02419     result = rb_ary_new();
    02420     for (i=0; i<argc; i++) {
    02421         rb_ary_push(result, rb_f_getenv(Qnil, argv[i]));
    02422     }
    02423     return result;
    02424 }
    02425
    02426 static VALUE
    02427 env_select(VALUE ehash)
    02428 {
    02429     VALUE result;
    02430     char **env;
    02431
    02432     RETURN_ENUMERATOR(ehash, 0, 0);
    02433     rb_secure(4);
    02434     result = rb_hash_new();
    02435     env = GET_ENVIRON(environ);
    02436     while (*env) {
    02437         char *s = strchr(*env, '=');
    02438         if (s) {
    02439             VALUE k = env_str_new(*env, s-*env);
    02440             VALUE v = env_str_new2(s+1);
    02441             if (RTEST(rb_yield_values(2, k, v))) {
    02442                 rb_hash_aset(result, k, v);
    02443             }
    02444         }
    02445         env++;
    02446     }
    02447     FREE_ENVIRON(environ);
    02448
    02449     return result;
    02450 }
    02451
    02452 static VALUE
    02453 env_select_bang(VALUE ehash)
    02454 {
    02455     volatile VALUE keys;
    02456     long i;
    02457     int del = 0;
    02458
    02459     RETURN_ENUMERATOR(ehash, 0, 0);
    02460     keys = env_keys();  /* rb_secure(4); */
    02461     for (i=0; i<RARRAY_LEN(keys); i++) {
    02462         VALUE val = rb_f_getenv(Qnil, RARRAY_PTR(keys)[i]);
    02463         if (!NIL_P(val)) {
    02464             if (!RTEST(rb_yield_values(2, RARRAY_PTR(keys)[i], val))) {
    02465                 FL_UNSET(RARRAY_PTR(keys)[i], FL_TAINT);
    02466                 env_delete(Qnil, RARRAY_PTR(keys)[i]);
    02467                 del++;
    02468             }
    02469         }
    02470     }
    02471     if (del == 0) return Qnil;
    02472     return envtbl;
    02473 }
    02474
    02475 static VALUE
    02476 env_keep_if(VALUE ehash)
    02477 {
    02478     RETURN_ENUMERATOR(ehash, 0, 0);
    02479     env_select_bang(ehash);
    02480     return envtbl;
    02481 }
    02482
    02483 VALUE
    02484 rb_env_clear(void)
    02485 {
    02486     volatile VALUE keys;
    02487     long i;
    02488
    02489     keys = env_keys();  /* rb_secure(4); */
    02490     for (i=0; i<RARRAY_LEN(keys); i++) {
    02491         VALUE val = rb_f_getenv(Qnil, RARRAY_PTR(keys)[i]);
    02492         if (!NIL_P(val)) {
    02493             env_delete(Qnil, RARRAY_PTR(keys)[i]);
    02494         }
    02495     }
    02496     return envtbl;
    02497 }
    02498
    02499 static VALUE
    02500 env_to_s(void)
    02501 {
    02502     return rb_usascii_str_new2("ENV");
    02503 }
    02504
    02505 static VALUE
    02506 env_inspect(void)
    02507 {
    02508     char **env;
    02509     VALUE str, i;
    02510
    02511     rb_secure(4);
    02512     str = rb_str_buf_new2("{");
    02513     env = GET_ENVIRON(environ);
    02514     while (*env) {
    02515         char *s = strchr(*env, '=');
    02516
    02517         if (env != environ) {
    02518             rb_str_buf_cat2(str, ", ");
    02519         }
    02520         if (s) {
    02521             rb_str_buf_cat2(str, "\"");
    02522             rb_str_buf_cat(str, *env, s-*env);
    02523             rb_str_buf_cat2(str, "\"=>");
    02524             i = rb_inspect(rb_str_new2(s+1));
    02525             rb_str_buf_append(str, i);
    02526         }
    02527         env++;
    02528     }
    02529     FREE_ENVIRON(environ);
    02530     rb_str_buf_cat2(str, "}");
    02531     OBJ_TAINT(str);
    02532
    02533     return str;
    02534 }
    02535
    02536 static VALUE
    02537 env_to_a(void)
    02538 {
    02539     char **env;
    02540     VALUE ary;
    02541
    02542     rb_secure(4);
    02543     ary = rb_ary_new();
    02544     env = GET_ENVIRON(environ);
    02545     while (*env) {
    02546         char *s = strchr(*env, '=');
    02547         if (s) {
    02548             rb_ary_push(ary, rb_assoc_new(env_str_new(*env, s-*env),
    02549                                           env_str_new2(s+1)));
    02550         }
    02551         env++;
    02552     }
    02553     FREE_ENVIRON(environ);
    02554     return ary;
    02555 }
    02556
    02557 static VALUE
    02558 env_none(void)
    02559 {
    02560     return Qnil;
    02561 }
    02562
    02563 static VALUE
    02564 env_size(void)
    02565 {
    02566     int i;
    02567     char **env;
    02568
    02569     rb_secure(4);
    02570     env = GET_ENVIRON(environ);
    02571     for(i=0; env[i]; i++)
    02572         ;
    02573     FREE_ENVIRON(environ);
    02574     return INT2FIX(i);
    02575 }
    02576
    02577 static VALUE
    02578 env_empty_p(void)
    02579 {
    02580     char **env;
    02581
    02582     rb_secure(4);
    02583     env = GET_ENVIRON(environ);
    02584     if (env[0] == 0) {
    02585         FREE_ENVIRON(environ);
    02586         return Qtrue;
    02587     }
    02588     FREE_ENVIRON(environ);
    02589     return Qfalse;
    02590 }
    02591
    02592 static VALUE
    02593 env_has_key(VALUE env, VALUE key)
    02594 {
    02595     char *s;
    02596
    02597     rb_secure(4);
    02598     s = StringValuePtr(key);
    02599     if (memchr(s, '\0', RSTRING_LEN(key)))
    02600         rb_raise(rb_eArgError, "bad environment variable name");
    02601     if (getenv(s)) return Qtrue;
    02602     return Qfalse;
    02603 }
    02604
    02605 static VALUE
    02606 env_assoc(VALUE env, VALUE key)
    02607 {
    02608     char *s, *e;
    02609
    02610     rb_secure(4);
    02611     s = StringValuePtr(key);
    02612     if (memchr(s, '\0', RSTRING_LEN(key)))
    02613         rb_raise(rb_eArgError, "bad environment variable name");
    02614     e = getenv(s);
    02615     if (e) return rb_assoc_new(key, rb_tainted_str_new2(e));
    02616     return Qnil;
    02617 }
    02618
    02619 static VALUE
    02620 env_has_value(VALUE dmy, VALUE obj)
    02621 {
    02622     char **env;
    02623
    02624     rb_secure(4);
    02625     obj = rb_check_string_type(obj);
    02626     if (NIL_P(obj)) return Qnil;
    02627     env = GET_ENVIRON(environ);
    02628     while (*env) {
    02629         char *s = strchr(*env, '=');
    02630         if (s++) {
    02631             long len = strlen(s);
    02632             if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
    02633                 FREE_ENVIRON(environ);
    02634                 return Qtrue;
    02635             }
    02636         }
    02637         env++;
    02638     }
    02639     FREE_ENVIRON(environ);
    02640     return Qfalse;
    02641 }
    02642
    02643 static VALUE
    02644 env_rassoc(VALUE dmy, VALUE obj)
    02645 {
    02646     char **env;
    02647
    02648     rb_secure(4);
    02649     obj = rb_check_string_type(obj);
    02650     if (NIL_P(obj)) return Qnil;
    02651     env = GET_ENVIRON(environ);
    02652     while (*env) {
    02653         char *s = strchr(*env, '=');
    02654         if (s++) {
    02655             long len = strlen(s);
    02656             if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
    02657                 VALUE result = rb_assoc_new(rb_tainted_str_new(*env, s-*env-1), obj);
    02658                 FREE_ENVIRON(environ);
    02659                 return result;
    02660             }
    02661         }
    02662         env++;
    02663     }
    02664     FREE_ENVIRON(environ);
    02665     return Qnil;
    02666 }
    02667
    02668 static VALUE
    02669 env_key(VALUE dmy, VALUE value)
    02670 {
    02671     char **env;
    02672     VALUE str;
    02673
    02674     rb_secure(4);
    02675     StringValue(value);
    02676     env = GET_ENVIRON(environ);
    02677     while (*env) {
    02678         char *s = strchr(*env, '=');
    02679         if (s++) {
    02680             long len = strlen(s);
    02681             if (RSTRING_LEN(value) == len && strncmp(s, RSTRING_PTR(value), len) == 0) {
    02682                 str = env_str_new(*env, s-*env-1);
    02683                 FREE_ENVIRON(environ);
    02684                 return str;
    02685             }
    02686         }
    02687         env++;
    02688     }
    02689     FREE_ENVIRON(environ);
    02690     return Qnil;
    02691 }
    02692
    02693 static VALUE
    02694 env_index(VALUE dmy, VALUE value)
    02695 {
    02696     rb_warn("ENV.index is deprecated; use ENV.key");
    02697     return env_key(dmy, value);
    02698 }
    02699
    02700 static VALUE
    02701 env_to_hash(void)
    02702 {
    02703     char **env;
    02704     VALUE hash;
    02705
    02706     rb_secure(4);
    02707     hash = rb_hash_new();
    02708     env = GET_ENVIRON(environ);
    02709     while (*env) {
    02710         char *s = strchr(*env, '=');
    02711         if (s) {
    02712             rb_hash_aset(hash, env_str_new(*env, s-*env),
    02713                                env_str_new2(s+1));
    02714         }
    02715         env++;
    02716     }
    02717     FREE_ENVIRON(environ);
    02718     return hash;
    02719 }
    02720
    02721 static VALUE
    02722 env_reject(void)
    02723 {
    02724     return rb_hash_delete_if(env_to_hash());
    02725 }
    02726
    02727 static VALUE
    02728 env_shift(void)
    02729 {
    02730     char **env;
    02731
    02732     rb_secure(4);
    02733     env = GET_ENVIRON(environ);
    02734     if (*env) {
    02735         char *s = strchr(*env, '=');
    02736         if (s) {
    02737             VALUE key = env_str_new(*env, s-*env);
    02738             VALUE val = env_str_new2(getenv(RSTRING_PTR(key)));
    02739             env_delete(Qnil, key);
    02740             return rb_assoc_new(key, val);
    02741         }
    02742     }
    02743     FREE_ENVIRON(environ);
    02744     return Qnil;
    02745 }
    02746
    02747 static VALUE
    02748 env_invert(void)
    02749 {
    02750     return rb_hash_invert(env_to_hash());
    02751 }
    02752
    02753 static int
    02754 env_replace_i(VALUE key, VALUE val, VALUE keys)
    02755 {
    02756     if (key != Qundef) {
    02757         env_aset(Qnil, key, val);
    02758         if (rb_ary_includes(keys, key)) {
    02759             rb_ary_delete(keys, key);
    02760         }
    02761     }
    02762     return ST_CONTINUE;
    02763 }
    02764
    02765 static VALUE
    02766 env_replace(VALUE env, VALUE hash)
    02767 {
    02768     volatile VALUE keys;
    02769     long i;
    02770
    02771     keys = env_keys();  /* rb_secure(4); */
    02772     if (env == hash) return env;
    02773     hash = to_hash(hash);
    02774     rb_hash_foreach(hash, env_replace_i, keys);
    02775
    02776     for (i=0; i<RARRAY_LEN(keys); i++) {
    02777         env_delete(env, RARRAY_PTR(keys)[i]);
    02778     }
    02779     return env;
    02780 }
    02781
    02782 static int
    02783 env_update_i(VALUE key, VALUE val)
    02784 {
    02785     if (key != Qundef) {
    02786         if (rb_block_given_p()) {
    02787             val = rb_yield_values(3, key, rb_f_getenv(Qnil, key), val);
    02788         }
    02789         env_aset(Qnil, key, val);
    02790     }
    02791     return ST_CONTINUE;
    02792 }
    02793
    02794 static VALUE
    02795 env_update(VALUE env, VALUE hash)
    02796 {
    02797     rb_secure(4);
    02798     if (env == hash) return env;
    02799     hash = to_hash(hash);
    02800     rb_hash_foreach(hash, env_update_i, 0);
    02801     return env;
    02802 }
    02803
    02804 /*
    02805  *  A <code>Hash</code> is a collection of key-value pairs. It is
    02806  *  similar to an <code>Array</code>, except that indexing is done via
    02807  *  arbitrary keys of any object type, not an integer index. Hashes enumerate
    02808  *  their values in the order that the corresponding keys were inserted.
    02809  *
    02810  *  Hashes have a <em>default value</em> that is returned when accessing
    02811  *  keys that do not exist in the hash. By default, that value is
    02812  *  <code>nil</code>.
    02813  *
    02814  */
    02815
    02816 void
    02817 Init_Hash(void)
    02818 {
    02819 #undef rb_intern
    02820 #define rb_intern(str) rb_intern_const(str)
    02821
    02822     id_hash = rb_intern("hash");
    02823     id_yield = rb_intern("yield");
    02824     id_default = rb_intern("default");
    02825
    02826     rb_cHash = rb_define_class("Hash", rb_cObject);
    02827
    02828     rb_include_module(rb_cHash, rb_mEnumerable);
    02829
    02830     rb_define_alloc_func(rb_cHash, hash_alloc);
    02831     rb_define_singleton_method(rb_cHash, "[]", rb_hash_s_create, -1);
    02832     rb_define_singleton_method(rb_cHash, "try_convert", rb_hash_s_try_convert, 1);
    02833     rb_define_method(rb_cHash,"initialize", rb_hash_initialize, -1);
    02834     rb_define_method(rb_cHash,"initialize_copy", rb_hash_replace, 1);
    02835     rb_define_method(rb_cHash,"rehash", rb_hash_rehash, 0);
    02836
    02837     rb_define_method(rb_cHash,"to_hash", rb_hash_to_hash, 0);
    02838     rb_define_method(rb_cHash,"to_a", rb_hash_to_a, 0);
    02839     rb_define_method(rb_cHash,"inspect", rb_hash_inspect, 0);
    02840     rb_define_alias(rb_cHash, "to_s", "inspect");
    02841
    02842     rb_define_method(rb_cHash,"==", rb_hash_equal, 1);
    02843     rb_define_method(rb_cHash,"[]", rb_hash_aref, 1);
    02844     rb_define_method(rb_cHash,"hash", rb_hash_hash, 0);
    02845     rb_define_method(rb_cHash,"eql?", rb_hash_eql, 1);
    02846     rb_define_method(rb_cHash,"fetch", rb_hash_fetch_m, -1);
    02847     rb_define_method(rb_cHash,"[]=", rb_hash_aset, 2);
    02848     rb_define_method(rb_cHash,"store", rb_hash_aset, 2);
    02849     rb_define_method(rb_cHash,"default", rb_hash_default, -1);
    02850     rb_define_method(rb_cHash,"default=", rb_hash_set_default, 1);
    02851     rb_define_method(rb_cHash,"default_proc", rb_hash_default_proc, 0);
    02852     rb_define_method(rb_cHash,"default_proc=", rb_hash_set_default_proc, 1);
    02853     rb_define_method(rb_cHash,"key", rb_hash_key, 1);
    02854     rb_define_method(rb_cHash,"index", rb_hash_index, 1);
    02855     rb_define_method(rb_cHash,"size", rb_hash_size, 0);
    02856     rb_define_method(rb_cHash,"length", rb_hash_size, 0);
    02857     rb_define_method(rb_cHash,"empty?", rb_hash_empty_p, 0);
    02858
    02859     rb_define_method(rb_cHash,"each_value", rb_hash_each_value, 0);
    02860     rb_define_method(rb_cHash,"each_key", rb_hash_each_key, 0);
    02861     rb_define_method(rb_cHash,"each_pair", rb_hash_each_pair, 0);
    02862     rb_define_method(rb_cHash,"each", rb_hash_each_pair, 0);
    02863
    02864     rb_define_method(rb_cHash,"keys", rb_hash_keys, 0);
    02865     rb_define_method(rb_cHash,"values", rb_hash_values, 0);
    02866     rb_define_method(rb_cHash,"values_at", rb_hash_values_at, -1);
    02867
    02868     rb_define_method(rb_cHash,"shift", rb_hash_shift, 0);
    02869     rb_define_method(rb_cHash,"delete", rb_hash_delete, 1);
    02870     rb_define_method(rb_cHash,"delete_if", rb_hash_delete_if, 0);
    02871     rb_define_method(rb_cHash,"keep_if", rb_hash_keep_if, 0);
    02872     rb_define_method(rb_cHash,"select", rb_hash_select, 0);
    02873     rb_define_method(rb_cHash,"select!", rb_hash_select_bang, 0);
    02874     rb_define_method(rb_cHash,"reject", rb_hash_reject, 0);
    02875     rb_define_method(rb_cHash,"reject!", rb_hash_reject_bang, 0);
    02876     rb_define_method(rb_cHash,"clear", rb_hash_clear, 0);
    02877     rb_define_method(rb_cHash,"invert", rb_hash_invert, 0);
    02878     rb_define_method(rb_cHash,"update", rb_hash_update, 1);
    02879     rb_define_method(rb_cHash,"replace", rb_hash_replace, 1);
    02880     rb_define_method(rb_cHash,"merge!", rb_hash_update, 1);
    02881     rb_define_method(rb_cHash,"merge", rb_hash_merge, 1);
    02882     rb_define_method(rb_cHash, "assoc", rb_hash_assoc, 1);
    02883     rb_define_method(rb_cHash, "rassoc", rb_hash_rassoc, 1);
    02884     rb_define_method(rb_cHash, "flatten", rb_hash_flatten, -1);
    02885
    02886     rb_define_method(rb_cHash,"include?", rb_hash_has_key, 1);
    02887     rb_define_method(rb_cHash,"member?", rb_hash_has_key, 1);
    02888     rb_define_method(rb_cHash,"has_key?", rb_hash_has_key, 1);
    02889     rb_define_method(rb_cHash,"has_value?", rb_hash_has_value, 1);
    02890     rb_define_method(rb_cHash,"key?", rb_hash_has_key, 1);
    02891     rb_define_method(rb_cHash,"value?", rb_hash_has_value, 1);
    02892
    02893     rb_define_method(rb_cHash,"compare_by_identity", rb_hash_compare_by_id, 0);
    02894     rb_define_method(rb_cHash,"compare_by_identity?", rb_hash_compare_by_id_p, 0);
    02895
    02896     origenviron = environ;
    02897     envtbl = rb_obj_alloc(rb_cObject);
    02898     rb_extend_object(envtbl, rb_mEnumerable);
    02899
    02900     rb_define_singleton_method(envtbl,"[]", rb_f_getenv, 1);
    02901     rb_define_singleton_method(envtbl,"fetch", env_fetch, -1);
    02902     rb_define_singleton_method(envtbl,"[]=", env_aset, 2);
    02903     rb_define_singleton_method(envtbl,"store", env_aset, 2);
    02904     rb_define_singleton_method(envtbl,"each", env_each_pair, 0);
    02905     rb_define_singleton_method(envtbl,"each_pair", env_each_pair, 0);
    02906     rb_define_singleton_method(envtbl,"each_key", env_each_key, 0);
    02907     rb_define_singleton_method(envtbl,"each_value", env_each_value, 0);
    02908     rb_define_singleton_method(envtbl,"delete", env_delete_m, 1);
    02909     rb_define_singleton_method(envtbl,"delete_if", env_delete_if, 0);
    02910     rb_define_singleton_method(envtbl,"keep_if", env_keep_if, 0);
    02911     rb_define_singleton_method(envtbl,"clear", rb_env_clear, 0);
    02912     rb_define_singleton_method(envtbl,"reject", env_reject, 0);
    02913     rb_define_singleton_method(envtbl,"reject!", env_reject_bang, 0);
    02914     rb_define_singleton_method(envtbl,"select", env_select, 0);
    02915     rb_define_singleton_method(envtbl,"select!", env_select_bang, 0);
    02916     rb_define_singleton_method(envtbl,"shift", env_shift, 0);
    02917     rb_define_singleton_method(envtbl,"invert", env_invert, 0);
    02918     rb_define_singleton_method(envtbl,"replace", env_replace, 1);
    02919     rb_define_singleton_method(envtbl,"update", env_update, 1);
    02920     rb_define_singleton_method(envtbl,"inspect", env_inspect, 0);
    02921     rb_define_singleton_method(envtbl,"rehash", env_none, 0);
    02922     rb_define_singleton_method(envtbl,"to_a", env_to_a, 0);
    02923     rb_define_singleton_method(envtbl,"to_s", env_to_s, 0);
    02924     rb_define_singleton_method(envtbl,"key", env_key, 1);
    02925     rb_define_singleton_method(envtbl,"index", env_index, 1);
    02926     rb_define_singleton_method(envtbl,"size", env_size, 0);
    02927     rb_define_singleton_method(envtbl,"length", env_size, 0);
    02928     rb_define_singleton_method(envtbl,"empty?", env_empty_p, 0);
    02929     rb_define_singleton_method(envtbl,"keys", env_keys, 0);
    02930     rb_define_singleton_method(envtbl,"values", env_values, 0);
    02931     rb_define_singleton_method(envtbl,"values_at", env_values_at, -1);
    02932     rb_define_singleton_method(envtbl,"include?", env_has_key, 1);
    02933     rb_define_singleton_method(envtbl,"member?", env_has_key, 1);
    02934     rb_define_singleton_method(envtbl,"has_key?", env_has_key, 1);
    02935     rb_define_singleton_method(envtbl,"has_value?", env_has_value, 1);
    02936     rb_define_singleton_method(envtbl,"key?", env_has_key, 1);
    02937     rb_define_singleton_method(envtbl,"value?", env_has_value, 1);
    02938     rb_define_singleton_method(envtbl,"to_hash", env_to_hash, 0);
    02939     rb_define_singleton_method(envtbl,"assoc", env_assoc, 1);
    02940     rb_define_singleton_method(envtbl,"rassoc", env_rassoc, 1);
    02941
    02942     rb_define_global_const("ENV", envtbl);
    02943 }
    02944