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