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