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