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