1/********************************************************************** 2 3 hash.c - 4 5 $Author: nagachika $ 6 created at: Mon Nov 22 18:51:18 JST 1993 7 8 Copyright (C) 1993-2007 Yukihiro Matsumoto 9 Copyright (C) 2000 Network Applied Communication Laboratory, Inc. 10 Copyright (C) 2000 Information-technology Promotion Agency, Japan 11 12**********************************************************************/ 13 14#include "ruby/ruby.h" 15#include "ruby/st.h" 16#include "ruby/util.h" 17#include "ruby/encoding.h" 18#include "internal.h" 19#include <errno.h> 20#include "probes.h" 21 22#ifdef __APPLE__ 23# ifdef HAVE_CRT_EXTERNS_H 24# include <crt_externs.h> 25# else 26# include "missing/crt_externs.h" 27# endif 28#endif 29 30static VALUE rb_hash_s_try_convert(VALUE, VALUE); 31 32#define HASH_DELETED FL_USER1 33#define HASH_PROC_DEFAULT FL_USER2 34 35VALUE 36rb_hash_freeze(VALUE hash) 37{ 38 return rb_obj_freeze(hash); 39} 40 41VALUE rb_cHash; 42 43static VALUE envtbl; 44static ID id_hash, id_yield, id_default; 45 46static int 47rb_any_cmp(VALUE a, VALUE b) 48{ 49 if (a == b) return 0; 50 if (FIXNUM_P(a) && FIXNUM_P(b)) { 51 return a != b; 52 } 53 if (RB_TYPE_P(a, T_STRING) && RBASIC(a)->klass == rb_cString && 54 RB_TYPE_P(b, T_STRING) && RBASIC(b)->klass == rb_cString) { 55 return rb_str_hash_cmp(a, b); 56 } 57 if (a == Qundef || b == Qundef) return -1; 58 if (SYMBOL_P(a) && SYMBOL_P(b)) { 59 return a != b; 60 } 61 62 return !rb_eql(a, b); 63} 64 65VALUE 66rb_hash(VALUE obj) 67{ 68 VALUE hval = rb_funcall(obj, id_hash, 0); 69 retry: 70 switch (TYPE(hval)) { 71 case T_FIXNUM: 72 return hval; 73 74 case T_BIGNUM: 75 return LONG2FIX(((long*)(RBIGNUM_DIGITS(hval)))[0]); 76 77 default: 78 hval = rb_to_int(hval); 79 goto retry; 80 } 81} 82 83static st_index_t 84rb_any_hash(VALUE a) 85{ 86 VALUE hval; 87 st_index_t hnum; 88 89 if (SPECIAL_CONST_P(a)) { 90 if (a == Qundef) return 0; 91 hnum = rb_hash_end(rb_hash_start((st_index_t)a)); 92 } 93 else if (BUILTIN_TYPE(a) == T_STRING) { 94 hnum = rb_str_hash(a); 95 } 96 else { 97 hval = rb_hash(a); 98 hnum = FIX2LONG(hval); 99 } 100 hnum <<= 1; 101 return (st_index_t)RSHIFT(hnum, 1); 102} 103 104static const struct st_hash_type objhash = { 105 rb_any_cmp, 106 rb_any_hash, 107}; 108 109extern const struct st_hash_type st_hashtype_num; 110#define identhash st_hashtype_num 111 112typedef int st_foreach_func(st_data_t, st_data_t, st_data_t); 113 114struct foreach_safe_arg { 115 st_table *tbl; 116 st_foreach_func *func; 117 st_data_t arg; 118}; 119 120static int 121foreach_safe_i(st_data_t key, st_data_t value, struct foreach_safe_arg *arg) 122{ 123 int status; 124 125 status = (*arg->func)(key, value, arg->arg); 126 if (status == ST_CONTINUE) { 127 return ST_CHECK; 128 } 129 return status; 130} 131 132void 133st_foreach_safe(st_table *table, int (*func)(ANYARGS), st_data_t a) 134{ 135 struct foreach_safe_arg arg; 136 137 arg.tbl = table; 138 arg.func = (st_foreach_func *)func; 139 arg.arg = a; 140 if (st_foreach_check(table, foreach_safe_i, (st_data_t)&arg, 0)) { 141 rb_raise(rb_eRuntimeError, "hash modified during iteration"); 142 } 143} 144 145typedef int rb_foreach_func(VALUE, VALUE, VALUE); 146 147struct hash_foreach_arg { 148 VALUE hash; 149 rb_foreach_func *func; 150 VALUE arg; 151}; 152 153static int 154hash_foreach_iter(st_data_t key, st_data_t value, st_data_t argp) 155{ 156 struct hash_foreach_arg *arg = (struct hash_foreach_arg *)argp; 157 int status; 158 st_table *tbl; 159 160 tbl = RHASH(arg->hash)->ntbl; 161 status = (*arg->func)((VALUE)key, (VALUE)value, arg->arg); 162 if (RHASH(arg->hash)->ntbl != tbl) { 163 rb_raise(rb_eRuntimeError, "rehash occurred during iteration"); 164 } 165 switch (status) { 166 case ST_DELETE: 167 FL_SET(arg->hash, HASH_DELETED); 168 return ST_DELETE; 169 case ST_CONTINUE: 170 break; 171 case ST_STOP: 172 return ST_STOP; 173 } 174 return ST_CHECK; 175} 176 177static VALUE 178hash_foreach_ensure(VALUE hash) 179{ 180 if (--RHASH_ITER_LEV(hash) == 0) { 181 if (FL_TEST(hash, HASH_DELETED)) { 182 st_cleanup_safe(RHASH(hash)->ntbl, (st_data_t)Qundef); 183 FL_UNSET(hash, HASH_DELETED); 184 } 185 } 186 return 0; 187} 188 189static VALUE 190hash_foreach_call(VALUE arg) 191{ 192 VALUE hash = ((struct hash_foreach_arg *)arg)->hash; 193 if (st_foreach_check(RHASH(hash)->ntbl, hash_foreach_iter, (st_data_t)arg, (st_data_t)Qundef)) { 194 rb_raise(rb_eRuntimeError, "hash modified during iteration"); 195 } 196 return Qnil; 197} 198 199void 200rb_hash_foreach(VALUE hash, int (*func)(ANYARGS), VALUE farg) 201{ 202 struct hash_foreach_arg arg; 203 204 if (!RHASH(hash)->ntbl) 205 return; 206 RHASH_ITER_LEV(hash)++; 207 arg.hash = hash; 208 arg.func = (rb_foreach_func *)func; 209 arg.arg = farg; 210 rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash); 211} 212 213static VALUE 214hash_alloc(VALUE klass) 215{ 216 NEWOBJ_OF(hash, struct RHash, klass, T_HASH); 217 218 RHASH_IFNONE(hash) = Qnil; 219 220 return (VALUE)hash; 221} 222 223static VALUE 224empty_hash_alloc(VALUE klass) 225{ 226 if (RUBY_DTRACE_HASH_CREATE_ENABLED()) { 227 RUBY_DTRACE_HASH_CREATE(0, rb_sourcefile(), rb_sourceline()); 228 } 229 230 return hash_alloc(klass); 231} 232 233VALUE 234rb_hash_new(void) 235{ 236 return hash_alloc(rb_cHash); 237} 238 239VALUE 240rb_hash_dup(VALUE hash) 241{ 242 NEWOBJ_OF(ret, struct RHash, 243 rb_obj_class(hash), 244 (RBASIC(hash)->flags)&(T_MASK|FL_EXIVAR|FL_TAINT|FL_UNTRUSTED)); 245 if (FL_TEST((hash), FL_EXIVAR)) 246 rb_copy_generic_ivar((VALUE)(ret),(VALUE)(hash)); 247 248 if (!RHASH_EMPTY_P(hash)) 249 ret->ntbl = st_copy(RHASH(hash)->ntbl); 250 if (FL_TEST(hash, HASH_PROC_DEFAULT)) { 251 FL_SET(ret, HASH_PROC_DEFAULT); 252 } 253 RHASH_IFNONE(ret) = RHASH_IFNONE(hash); 254 return (VALUE)ret; 255} 256 257static void 258rb_hash_modify_check(VALUE hash) 259{ 260 rb_check_frozen(hash); 261 if (!OBJ_UNTRUSTED(hash) && rb_safe_level() >= 4) 262 rb_raise(rb_eSecurityError, "Insecure: can't modify hash"); 263} 264 265struct st_table * 266rb_hash_tbl(VALUE hash) 267{ 268 if (!RHASH(hash)->ntbl) { 269 RHASH(hash)->ntbl = st_init_table(&objhash); 270 } 271 return RHASH(hash)->ntbl; 272} 273 274static void 275rb_hash_modify(VALUE hash) 276{ 277 rb_hash_modify_check(hash); 278 rb_hash_tbl(hash); 279} 280 281NORETURN(static void no_new_key(void)); 282static void 283no_new_key(void) 284{ 285 rb_raise(rb_eRuntimeError, "can't add a new key into hash during iteration"); 286} 287 288#define NOINSERT_UPDATE_CALLBACK(func) \ 289int \ 290func##_noinsert(st_data_t *key, st_data_t *val, st_data_t arg, int existing) \ 291{ \ 292 if (!existing) no_new_key(); \ 293 return func(key, val, arg, existing); \ 294} 295 296#define UPDATE_CALLBACK(iter_lev, func) ((iter_lev) > 0 ? func##_noinsert : func) 297 298#define RHASH_UPDATE_ITER(hash, iter_lev, key, func, arg) \ 299 st_update(RHASH(hash)->ntbl, (st_data_t)(key), \ 300 UPDATE_CALLBACK((iter_lev), func), \ 301 (st_data_t)(arg)) 302#define RHASH_UPDATE(hash, key, func, arg) \ 303 RHASH_UPDATE_ITER(hash, RHASH_ITER_LEV(hash), key, func, arg) 304 305static void 306default_proc_arity_check(VALUE proc) 307{ 308 int n = rb_proc_arity(proc); 309 310 if (rb_proc_lambda_p(proc) && n != 2 && (n >= 0 || n < -3)) { 311 if (n < 0) n = -n-1; 312 rb_raise(rb_eTypeError, "default_proc takes two arguments (2 for %d)", n); 313 } 314} 315 316/* 317 * call-seq: 318 * Hash.new -> new_hash 319 * Hash.new(obj) -> new_hash 320 * Hash.new {|hash, key| block } -> new_hash 321 * 322 * Returns a new, empty hash. If this hash is subsequently accessed by 323 * a key that doesn't correspond to a hash entry, the value returned 324 * depends on the style of <code>new</code> used to create the hash. In 325 * the first form, the access returns <code>nil</code>. If 326 * <i>obj</i> is specified, this single object will be used for 327 * all <em>default values</em>. If a block is specified, it will be 328 * called with the hash object and the key, and should return the 329 * default value. It is the block's responsibility to store the value 330 * in the hash if required. 331 * 332 * h = Hash.new("Go Fish") 333 * h["a"] = 100 334 * h["b"] = 200 335 * h["a"] #=> 100 336 * h["c"] #=> "Go Fish" 337 * # The following alters the single default object 338 * h["c"].upcase! #=> "GO FISH" 339 * h["d"] #=> "GO FISH" 340 * h.keys #=> ["a", "b"] 341 * 342 * # While this creates a new default object each time 343 * h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" } 344 * h["c"] #=> "Go Fish: c" 345 * h["c"].upcase! #=> "GO FISH: C" 346 * h["d"] #=> "Go Fish: d" 347 * h.keys #=> ["c", "d"] 348 * 349 */ 350 351static VALUE 352rb_hash_initialize(int argc, VALUE *argv, VALUE hash) 353{ 354 VALUE ifnone; 355 356 rb_hash_modify(hash); 357 if (rb_block_given_p()) { 358 rb_check_arity(argc, 0, 0); 359 ifnone = rb_block_proc(); 360 default_proc_arity_check(ifnone); 361 RHASH_IFNONE(hash) = ifnone; 362 FL_SET(hash, HASH_PROC_DEFAULT); 363 } 364 else { 365 rb_scan_args(argc, argv, "01", &ifnone); 366 RHASH_IFNONE(hash) = ifnone; 367 } 368 369 return hash; 370} 371 372/* 373 * call-seq: 374 * Hash[ key, value, ... ] -> new_hash 375 * Hash[ [ [key, value], ... ] ] -> new_hash 376 * Hash[ object ] -> new_hash 377 * 378 * Creates a new hash populated with the given objects. Equivalent to 379 * the literal <code>{ <i>key</i> => <i>value</i>, ... }</code>. In the first 380 * form, keys and values occur in pairs, so there must be an even number of arguments. 381 * The second and third form take a single argument which is either 382 * an array of key-value pairs or an object convertible to a hash. 383 * 384 * Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200} 385 * Hash[ [ ["a", 100], ["b", 200] ] ] #=> {"a"=>100, "b"=>200} 386 * Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200} 387 */ 388 389static VALUE 390rb_hash_s_create(int argc, VALUE *argv, VALUE klass) 391{ 392 VALUE hash, tmp; 393 int i; 394 395 if (argc == 1) { 396 tmp = rb_hash_s_try_convert(Qnil, argv[0]); 397 if (!NIL_P(tmp)) { 398 hash = hash_alloc(klass); 399 if (RHASH(tmp)->ntbl) { 400 RHASH(hash)->ntbl = st_copy(RHASH(tmp)->ntbl); 401 } 402 return hash; 403 } 404 405 tmp = rb_check_array_type(argv[0]); 406 if (!NIL_P(tmp)) { 407 long i; 408 409 hash = hash_alloc(klass); 410 for (i = 0; i < RARRAY_LEN(tmp); ++i) { 411 VALUE e = RARRAY_PTR(tmp)[i]; 412 VALUE v = rb_check_array_type(e); 413 VALUE key, val = Qnil; 414 415 if (NIL_P(v)) { 416#if 0 /* refix in the next release */ 417 rb_raise(rb_eArgError, "wrong element type %s at %ld (expected array)", 418 rb_builtin_class_name(e), i); 419 420#else 421 rb_warn("wrong element type %s at %ld (expected array)", 422 rb_builtin_class_name(e), i); 423 rb_warn("ignoring wrong elements is deprecated, remove them explicitly"); 424 rb_warn("this causes ArgumentError in the next release"); 425 continue; 426#endif 427 } 428 switch (RARRAY_LEN(v)) { 429 default: 430 rb_raise(rb_eArgError, "invalid number of elements (%ld for 1..2)", 431 RARRAY_LEN(v)); 432 case 2: 433 val = RARRAY_PTR(v)[1]; 434 case 1: 435 key = RARRAY_PTR(v)[0]; 436 rb_hash_aset(hash, key, val); 437 } 438 } 439 return hash; 440 } 441 } 442 if (argc % 2 != 0) { 443 rb_raise(rb_eArgError, "odd number of arguments for Hash"); 444 } 445 446 hash = hash_alloc(klass); 447 for (i=0; i<argc; i+=2) { 448 rb_hash_aset(hash, argv[i], argv[i + 1]); 449 } 450 451 return hash; 452} 453 454static VALUE 455to_hash(VALUE hash) 456{ 457 return rb_convert_type(hash, T_HASH, "Hash", "to_hash"); 458} 459 460VALUE 461rb_check_hash_type(VALUE hash) 462{ 463 return rb_check_convert_type(hash, T_HASH, "Hash", "to_hash"); 464} 465 466/* 467 * call-seq: 468 * Hash.try_convert(obj) -> hash or nil 469 * 470 * Try to convert <i>obj</i> into a hash, using to_hash method. 471 * Returns converted hash or nil if <i>obj</i> cannot be converted 472 * for any reason. 473 * 474 * Hash.try_convert({1=>2}) # => {1=>2} 475 * Hash.try_convert("1=>2") # => nil 476 */ 477static VALUE 478rb_hash_s_try_convert(VALUE dummy, VALUE hash) 479{ 480 return rb_check_hash_type(hash); 481} 482 483struct rehash_arg { 484 VALUE hash; 485 st_table *tbl; 486}; 487 488static int 489rb_hash_rehash_i(VALUE key, VALUE value, VALUE arg) 490{ 491 st_table *tbl = (st_table *)arg; 492 493 st_insert(tbl, (st_data_t)key, (st_data_t)value); 494 return ST_CONTINUE; 495} 496 497/* 498 * call-seq: 499 * hsh.rehash -> hsh 500 * 501 * Rebuilds the hash based on the current hash values for each key. If 502 * values of key objects have changed since they were inserted, this 503 * method will reindex <i>hsh</i>. If <code>Hash#rehash</code> is 504 * called while an iterator is traversing the hash, an 505 * <code>RuntimeError</code> will be raised in the iterator. 506 * 507 * a = [ "a", "b" ] 508 * c = [ "c", "d" ] 509 * h = { a => 100, c => 300 } 510 * h[a] #=> 100 511 * a[0] = "z" 512 * h[a] #=> nil 513 * h.rehash #=> {["z", "b"]=>100, ["c", "d"]=>300} 514 * h[a] #=> 100 515 */ 516 517static VALUE 518rb_hash_rehash(VALUE hash) 519{ 520 VALUE tmp; 521 st_table *tbl; 522 523 if (RHASH_ITER_LEV(hash) > 0) { 524 rb_raise(rb_eRuntimeError, "rehash during iteration"); 525 } 526 rb_hash_modify_check(hash); 527 if (!RHASH(hash)->ntbl) 528 return hash; 529 tmp = hash_alloc(0); 530 tbl = st_init_table_with_size(RHASH(hash)->ntbl->type, RHASH(hash)->ntbl->num_entries); 531 RHASH(tmp)->ntbl = tbl; 532 533 rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tbl); 534 st_free_table(RHASH(hash)->ntbl); 535 RHASH(hash)->ntbl = tbl; 536 RHASH(tmp)->ntbl = 0; 537 538 return hash; 539} 540 541static VALUE 542hash_default_value(VALUE hash, VALUE key) 543{ 544 if (rb_method_basic_definition_p(CLASS_OF(hash), id_default)) { 545 VALUE ifnone = RHASH_IFNONE(hash); 546 if (!FL_TEST(hash, HASH_PROC_DEFAULT)) return ifnone; 547 if (key == Qundef) return Qnil; 548 return rb_funcall(ifnone, id_yield, 2, hash, key); 549 } 550 else { 551 return rb_funcall(hash, id_default, 1, key); 552 } 553} 554 555/* 556 * call-seq: 557 * hsh[key] -> value 558 * 559 * Element Reference---Retrieves the <i>value</i> object corresponding 560 * to the <i>key</i> object. If not found, returns the default value (see 561 * <code>Hash::new</code> for details). 562 * 563 * h = { "a" => 100, "b" => 200 } 564 * h["a"] #=> 100 565 * h["c"] #=> nil 566 * 567 */ 568 569VALUE 570rb_hash_aref(VALUE hash, VALUE key) 571{ 572 st_data_t val; 573 574 if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) { 575 return hash_default_value(hash, key); 576 } 577 return (VALUE)val; 578} 579 580VALUE 581rb_hash_lookup2(VALUE hash, VALUE key, VALUE def) 582{ 583 st_data_t val; 584 585 if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) { 586 return def; /* without Hash#default */ 587 } 588 return (VALUE)val; 589} 590 591VALUE 592rb_hash_lookup(VALUE hash, VALUE key) 593{ 594 return rb_hash_lookup2(hash, key, Qnil); 595} 596 597/* 598 * call-seq: 599 * hsh.fetch(key [, default] ) -> obj 600 * hsh.fetch(key) {| key | block } -> obj 601 * 602 * Returns a value from the hash for the given key. If the key can't be 603 * found, there are several options: With no other arguments, it will 604 * raise an <code>KeyError</code> exception; if <i>default</i> is 605 * given, then that will be returned; if the optional code block is 606 * specified, then that will be run and its result returned. 607 * 608 * h = { "a" => 100, "b" => 200 } 609 * h.fetch("a") #=> 100 610 * h.fetch("z", "go fish") #=> "go fish" 611 * h.fetch("z") { |el| "go fish, #{el}"} #=> "go fish, z" 612 * 613 * The following example shows that an exception is raised if the key 614 * is not found and a default value is not supplied. 615 * 616 * h = { "a" => 100, "b" => 200 } 617 * h.fetch("z") 618 * 619 * <em>produces:</em> 620 * 621 * prog.rb:2:in `fetch': key not found (KeyError) 622 * from prog.rb:2 623 * 624 */ 625 626static VALUE 627rb_hash_fetch_m(int argc, VALUE *argv, VALUE hash) 628{ 629 VALUE key, if_none; 630 st_data_t val; 631 long block_given; 632 633 rb_scan_args(argc, argv, "11", &key, &if_none); 634 635 block_given = rb_block_given_p(); 636 if (block_given && argc == 2) { 637 rb_warn("block supersedes default value argument"); 638 } 639 if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) { 640 if (block_given) return rb_yield(key); 641 if (argc == 1) { 642 volatile VALUE desc = rb_protect(rb_inspect, key, 0); 643 if (NIL_P(desc)) { 644 desc = rb_any_to_s(key); 645 } 646 desc = rb_str_ellipsize(desc, 65); 647 rb_raise(rb_eKeyError, "key not found: %s", RSTRING_PTR(desc)); 648 } 649 return if_none; 650 } 651 return (VALUE)val; 652} 653 654VALUE 655rb_hash_fetch(VALUE hash, VALUE key) 656{ 657 return rb_hash_fetch_m(1, &key, hash); 658} 659 660/* 661 * call-seq: 662 * hsh.default(key=nil) -> obj 663 * 664 * Returns the default value, the value that would be returned by 665 * <i>hsh</i>[<i>key</i>] if <i>key</i> did not exist in <i>hsh</i>. 666 * See also <code>Hash::new</code> and <code>Hash#default=</code>. 667 * 668 * h = Hash.new #=> {} 669 * h.default #=> nil 670 * h.default(2) #=> nil 671 * 672 * h = Hash.new("cat") #=> {} 673 * h.default #=> "cat" 674 * h.default(2) #=> "cat" 675 * 676 * h = Hash.new {|h,k| h[k] = k.to_i*10} #=> {} 677 * h.default #=> nil 678 * h.default(2) #=> 20 679 */ 680 681static VALUE 682rb_hash_default(int argc, VALUE *argv, VALUE hash) 683{ 684 VALUE key, ifnone; 685 686 rb_scan_args(argc, argv, "01", &key); 687 ifnone = RHASH_IFNONE(hash); 688 if (FL_TEST(hash, HASH_PROC_DEFAULT)) { 689 if (argc == 0) return Qnil; 690 return rb_funcall(ifnone, id_yield, 2, hash, key); 691 } 692 return ifnone; 693} 694 695/* 696 * call-seq: 697 * hsh.default = obj -> obj 698 * 699 * Sets the default value, the value returned for a key that does not 700 * exist in the hash. It is not possible to set the default to a 701 * <code>Proc</code> that will be executed on each key lookup. 702 * 703 * h = { "a" => 100, "b" => 200 } 704 * h.default = "Go fish" 705 * h["a"] #=> 100 706 * h["z"] #=> "Go fish" 707 * # This doesn't do what you might hope... 708 * h.default = proc do |hash, key| 709 * hash[key] = key + key 710 * end 711 * h[2] #=> #<Proc:0x401b3948@-:6> 712 * h["cat"] #=> #<Proc:0x401b3948@-:6> 713 */ 714 715static VALUE 716rb_hash_set_default(VALUE hash, VALUE ifnone) 717{ 718 rb_hash_modify_check(hash); 719 RHASH_IFNONE(hash) = ifnone; 720 FL_UNSET(hash, HASH_PROC_DEFAULT); 721 return ifnone; 722} 723 724/* 725 * call-seq: 726 * hsh.default_proc -> anObject 727 * 728 * If <code>Hash::new</code> was invoked with a block, return that 729 * block, otherwise return <code>nil</code>. 730 * 731 * h = Hash.new {|h,k| h[k] = k*k } #=> {} 732 * p = h.default_proc #=> #<Proc:0x401b3d08@-:1> 733 * a = [] #=> [] 734 * p.call(a, 2) 735 * a #=> [nil, nil, 4] 736 */ 737 738 739static VALUE 740rb_hash_default_proc(VALUE hash) 741{ 742 if (FL_TEST(hash, HASH_PROC_DEFAULT)) { 743 return RHASH_IFNONE(hash); 744 } 745 return Qnil; 746} 747 748/* 749 * call-seq: 750 * hsh.default_proc = proc_obj or nil 751 * 752 * Sets the default proc to be executed on each failed key lookup. 753 * 754 * h.default_proc = proc do |hash, key| 755 * hash[key] = key + key 756 * end 757 * h[2] #=> 4 758 * h["cat"] #=> "catcat" 759 */ 760 761static VALUE 762rb_hash_set_default_proc(VALUE hash, VALUE proc) 763{ 764 VALUE b; 765 766 rb_hash_modify_check(hash); 767 if (NIL_P(proc)) { 768 FL_UNSET(hash, HASH_PROC_DEFAULT); 769 RHASH_IFNONE(hash) = proc; 770 return proc; 771 } 772 b = rb_check_convert_type(proc, T_DATA, "Proc", "to_proc"); 773 if (NIL_P(b) || !rb_obj_is_proc(b)) { 774 rb_raise(rb_eTypeError, 775 "wrong default_proc type %s (expected Proc)", 776 rb_obj_classname(proc)); 777 } 778 proc = b; 779 default_proc_arity_check(proc); 780 RHASH_IFNONE(hash) = proc; 781 FL_SET(hash, HASH_PROC_DEFAULT); 782 return proc; 783} 784 785static int 786key_i(VALUE key, VALUE value, VALUE arg) 787{ 788 VALUE *args = (VALUE *)arg; 789 790 if (rb_equal(value, args[0])) { 791 args[1] = key; 792 return ST_STOP; 793 } 794 return ST_CONTINUE; 795} 796 797/* 798 * call-seq: 799 * hsh.key(value) -> key 800 * 801 * Returns the key of an occurrence of a given value. If the value is 802 * not found, returns <code>nil</code>. 803 * 804 * h = { "a" => 100, "b" => 200, "c" => 300, "d" => 300 } 805 * h.key(200) #=> "b" 806 * h.key(300) #=> "c" 807 * h.key(999) #=> nil 808 * 809 */ 810 811static VALUE 812rb_hash_key(VALUE hash, VALUE value) 813{ 814 VALUE args[2]; 815 816 args[0] = value; 817 args[1] = Qnil; 818 819 rb_hash_foreach(hash, key_i, (VALUE)args); 820 821 return args[1]; 822} 823 824/* :nodoc: */ 825static VALUE 826rb_hash_index(VALUE hash, VALUE value) 827{ 828 rb_warn("Hash#index is deprecated; use Hash#key"); 829 return rb_hash_key(hash, value); 830} 831 832static VALUE 833rb_hash_delete_key(VALUE hash, VALUE key) 834{ 835 st_data_t ktmp = (st_data_t)key, val; 836 837 if (!RHASH(hash)->ntbl) 838 return Qundef; 839 if (RHASH_ITER_LEV(hash) > 0) { 840 if (st_delete_safe(RHASH(hash)->ntbl, &ktmp, &val, (st_data_t)Qundef)) { 841 FL_SET(hash, HASH_DELETED); 842 return (VALUE)val; 843 } 844 } 845 else if (st_delete(RHASH(hash)->ntbl, &ktmp, &val)) 846 return (VALUE)val; 847 return Qundef; 848} 849 850/* 851 * call-seq: 852 * hsh.delete(key) -> value 853 * hsh.delete(key) {| key | block } -> value 854 * 855 * Deletes the key-value pair and returns the value from <i>hsh</i> whose 856 * key is equal to <i>key</i>. If the key is not found, returns the 857 * <em>default value</em>. If the optional code block is given and the 858 * key is not found, pass in the key and return the result of 859 * <i>block</i>. 860 * 861 * h = { "a" => 100, "b" => 200 } 862 * h.delete("a") #=> 100 863 * h.delete("z") #=> nil 864 * h.delete("z") { |el| "#{el} not found" } #=> "z not found" 865 * 866 */ 867 868VALUE 869rb_hash_delete(VALUE hash, VALUE key) 870{ 871 VALUE val; 872 873 rb_hash_modify_check(hash); 874 val = rb_hash_delete_key(hash, key); 875 if (val != Qundef) return val; 876 if (rb_block_given_p()) { 877 return rb_yield(key); 878 } 879 return Qnil; 880} 881 882struct shift_var { 883 VALUE key; 884 VALUE val; 885}; 886 887static int 888shift_i(VALUE key, VALUE value, VALUE arg) 889{ 890 struct shift_var *var = (struct shift_var *)arg; 891 892 if (var->key != Qundef) return ST_STOP; 893 var->key = key; 894 var->val = value; 895 return ST_DELETE; 896} 897 898static int 899shift_i_safe(VALUE key, VALUE value, VALUE arg) 900{ 901 struct shift_var *var = (struct shift_var *)arg; 902 903 var->key = key; 904 var->val = value; 905 return ST_STOP; 906} 907 908/* 909 * call-seq: 910 * hsh.shift -> anArray or obj 911 * 912 * Removes a key-value pair from <i>hsh</i> and returns it as the 913 * two-item array <code>[</code> <i>key, value</i> <code>]</code>, or 914 * the hash's default value if the hash is empty. 915 * 916 * h = { 1 => "a", 2 => "b", 3 => "c" } 917 * h.shift #=> [1, "a"] 918 * h #=> {2=>"b", 3=>"c"} 919 */ 920 921static VALUE 922rb_hash_shift(VALUE hash) 923{ 924 struct shift_var var; 925 926 rb_hash_modify_check(hash); 927 if (RHASH(hash)->ntbl) { 928 var.key = Qundef; 929 rb_hash_foreach(hash, RHASH_ITER_LEV(hash) > 0 ? shift_i_safe : shift_i, 930 (VALUE)&var); 931 932 if (var.key != Qundef) { 933 if (RHASH_ITER_LEV(hash) > 0) { 934 rb_hash_delete_key(hash, var.key); 935 } 936 return rb_assoc_new(var.key, var.val); 937 } 938 } 939 return hash_default_value(hash, Qnil); 940} 941 942static int 943delete_if_i(VALUE key, VALUE value, VALUE hash) 944{ 945 if (RTEST(rb_yield_values(2, key, value))) { 946 rb_hash_delete_key(hash, key); 947 } 948 return ST_CONTINUE; 949} 950 951static VALUE rb_hash_size(VALUE hash); 952 953/* 954 * call-seq: 955 * hsh.delete_if {| key, value | block } -> hsh 956 * hsh.delete_if -> an_enumerator 957 * 958 * Deletes every key-value pair from <i>hsh</i> for which <i>block</i> 959 * evaluates to <code>true</code>. 960 * 961 * If no block is given, an enumerator is returned instead. 962 * 963 * h = { "a" => 100, "b" => 200, "c" => 300 } 964 * h.delete_if {|key, value| key >= "b" } #=> {"a"=>100} 965 * 966 */ 967 968VALUE 969rb_hash_delete_if(VALUE hash) 970{ 971 RETURN_SIZED_ENUMERATOR(hash, 0, 0, rb_hash_size); 972 rb_hash_modify_check(hash); 973 if (RHASH(hash)->ntbl) 974 rb_hash_foreach(hash, delete_if_i, hash); 975 return hash; 976} 977 978/* 979 * call-seq: 980 * hsh.reject! {| key, value | block } -> hsh or nil 981 * hsh.reject! -> an_enumerator 982 * 983 * Equivalent to <code>Hash#delete_if</code>, but returns 984 * <code>nil</code> if no changes were made. 985 */ 986 987VALUE 988rb_hash_reject_bang(VALUE hash) 989{ 990 st_index_t n; 991 992 RETURN_SIZED_ENUMERATOR(hash, 0, 0, rb_hash_size); 993 rb_hash_modify(hash); 994 if (!RHASH(hash)->ntbl) 995 return Qnil; 996 n = RHASH(hash)->ntbl->num_entries; 997 rb_hash_foreach(hash, delete_if_i, hash); 998 if (n == RHASH(hash)->ntbl->num_entries) return Qnil; 999 return hash; 1000} 1001 1002/* 1003 * call-seq: 1004 * hsh.reject {| key, value | block } -> a_hash 1005 * hsh.reject -> an_enumerator 1006 * 1007 * Same as <code>Hash#delete_if</code>, but works on (and returns) a 1008 * copy of the <i>hsh</i>. Equivalent to 1009 * <code><i>hsh</i>.dup.delete_if</code>. 1010 * 1011 */ 1012 1013static VALUE 1014rb_hash_reject(VALUE hash) 1015{ 1016 return rb_hash_delete_if(rb_obj_dup(hash)); 1017} 1018 1019/* 1020 * call-seq: 1021 * hsh.values_at(key, ...) -> array 1022 * 1023 * Return an array containing the values associated with the given keys. 1024 * Also see <code>Hash.select</code>. 1025 * 1026 * h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" } 1027 * h.values_at("cow", "cat") #=> ["bovine", "feline"] 1028 */ 1029 1030VALUE 1031rb_hash_values_at(int argc, VALUE *argv, VALUE hash) 1032{ 1033 VALUE result = rb_ary_new2(argc); 1034 long i; 1035 1036 for (i=0; i<argc; i++) { 1037 rb_ary_push(result, rb_hash_aref(hash, argv[i])); 1038 } 1039 return result; 1040} 1041 1042static int 1043select_i(VALUE key, VALUE value, VALUE result) 1044{ 1045 if (RTEST(rb_yield_values(2, key, value))) 1046 rb_hash_aset(result, key, value); 1047 return ST_CONTINUE; 1048} 1049 1050/* 1051 * call-seq: 1052 * hsh.select {|key, value| block} -> a_hash 1053 * hsh.select -> an_enumerator 1054 * 1055 * Returns a new hash consisting of entries for which the block returns true. 1056 * 1057 * If no block is given, an enumerator is returned instead. 1058 * 1059 * h = { "a" => 100, "b" => 200, "c" => 300 } 1060 * h.select {|k,v| k > "a"} #=> {"b" => 200, "c" => 300} 1061 * h.select {|k,v| v < 200} #=> {"a" => 100} 1062 */ 1063 1064VALUE 1065rb_hash_select(VALUE hash) 1066{ 1067 VALUE result; 1068 1069 RETURN_SIZED_ENUMERATOR(hash, 0, 0, rb_hash_size); 1070 result = rb_hash_new(); 1071 rb_hash_foreach(hash, select_i, result); 1072 return result; 1073} 1074 1075static int 1076keep_if_i(VALUE key, VALUE value, VALUE hash) 1077{ 1078 if (!RTEST(rb_yield_values(2, key, value))) { 1079 return ST_DELETE; 1080 } 1081 return ST_CONTINUE; 1082} 1083 1084/* 1085 * call-seq: 1086 * hsh.select! {| key, value | block } -> hsh or nil 1087 * hsh.select! -> an_enumerator 1088 * 1089 * Equivalent to <code>Hash#keep_if</code>, but returns 1090 * <code>nil</code> if no changes were made. 1091 */ 1092 1093VALUE 1094rb_hash_select_bang(VALUE hash) 1095{ 1096 st_index_t n; 1097 1098 RETURN_SIZED_ENUMERATOR(hash, 0, 0, rb_hash_size); 1099 rb_hash_modify_check(hash); 1100 if (!RHASH(hash)->ntbl) 1101 return Qnil; 1102 n = RHASH(hash)->ntbl->num_entries; 1103 rb_hash_foreach(hash, keep_if_i, hash); 1104 if (n == RHASH(hash)->ntbl->num_entries) return Qnil; 1105 return hash; 1106} 1107 1108/* 1109 * call-seq: 1110 * hsh.keep_if {| key, value | block } -> hsh 1111 * hsh.keep_if -> an_enumerator 1112 * 1113 * Deletes every key-value pair from <i>hsh</i> for which <i>block</i> 1114 * evaluates to false. 1115 * 1116 * If no block is given, an enumerator is returned instead. 1117 * 1118 */ 1119 1120VALUE 1121rb_hash_keep_if(VALUE hash) 1122{ 1123 RETURN_SIZED_ENUMERATOR(hash, 0, 0, rb_hash_size); 1124 rb_hash_modify_check(hash); 1125 if (RHASH(hash)->ntbl) 1126 rb_hash_foreach(hash, keep_if_i, hash); 1127 return hash; 1128} 1129 1130static int 1131clear_i(VALUE key, VALUE value, VALUE dummy) 1132{ 1133 return ST_DELETE; 1134} 1135 1136/* 1137 * call-seq: 1138 * hsh.clear -> hsh 1139 * 1140 * Removes all key-value pairs from <i>hsh</i>. 1141 * 1142 * h = { "a" => 100, "b" => 200 } #=> {"a"=>100, "b"=>200} 1143 * h.clear #=> {} 1144 * 1145 */ 1146 1147VALUE 1148rb_hash_clear(VALUE hash) 1149{ 1150 rb_hash_modify_check(hash); 1151 if (!RHASH(hash)->ntbl) 1152 return hash; 1153 if (RHASH(hash)->ntbl->num_entries > 0) { 1154 if (RHASH_ITER_LEV(hash) > 0) 1155 rb_hash_foreach(hash, clear_i, 0); 1156 else 1157 st_clear(RHASH(hash)->ntbl); 1158 } 1159 1160 return hash; 1161} 1162 1163static int 1164hash_aset(st_data_t *key, st_data_t *val, st_data_t arg, int existing) 1165{ 1166 *val = arg; 1167 return ST_CONTINUE; 1168} 1169 1170static int 1171hash_aset_str(st_data_t *key, st_data_t *val, st_data_t arg, int existing) 1172{ 1173 *key = (st_data_t)rb_str_new_frozen((VALUE)*key); 1174 return hash_aset(key, val, arg, existing); 1175} 1176 1177static NOINSERT_UPDATE_CALLBACK(hash_aset) 1178static NOINSERT_UPDATE_CALLBACK(hash_aset_str) 1179 1180/* 1181 * call-seq: 1182 * hsh[key] = value -> value 1183 * hsh.store(key, value) -> value 1184 * 1185 * == Element Assignment 1186 * 1187 * Associates the value given by +value+ with the key given by +key+. 1188 * 1189 * h = { "a" => 100, "b" => 200 } 1190 * h["a"] = 9 1191 * h["c"] = 4 1192 * h #=> {"a"=>9, "b"=>200, "c"=>4} 1193 * 1194 * +key+ should not have its value changed while it is in use as a key (an 1195 * <tt>unfrozen String</tt> passed as a key will be duplicated and frozen). 1196 * 1197 * a = "a" 1198 * b = "b".freeze 1199 * h = { a => 100, b => 200 } 1200 * h.key(100).equal? a #=> false 1201 * h.key(200).equal? b #=> true 1202 * 1203 */ 1204 1205VALUE 1206rb_hash_aset(VALUE hash, VALUE key, VALUE val) 1207{ 1208 int iter_lev = RHASH_ITER_LEV(hash); 1209 st_table *tbl = RHASH(hash)->ntbl; 1210 1211 rb_hash_modify(hash); 1212 if (!tbl) { 1213 if (iter_lev > 0) no_new_key(); 1214 tbl = RHASH_TBL(hash); 1215 } 1216 if (tbl->type == &identhash || rb_obj_class(key) != rb_cString) { 1217 RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset, val); 1218 } 1219 else { 1220 RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset_str, val); 1221 } 1222 return val; 1223} 1224 1225static int 1226replace_i(VALUE key, VALUE val, VALUE hash) 1227{ 1228 rb_hash_aset(hash, key, val); 1229 1230 return ST_CONTINUE; 1231} 1232 1233static VALUE 1234rb_hash_initialize_copy(VALUE hash, VALUE hash2) 1235{ 1236 st_table *ntbl; 1237 1238 rb_hash_modify_check(hash); 1239 hash2 = to_hash(hash2); 1240 1241 Check_Type(hash2, T_HASH); 1242 1243 if (hash == hash2) return hash; 1244 1245 ntbl = RHASH(hash)->ntbl; 1246 if (RHASH(hash2)->ntbl) { 1247 if (ntbl) st_free_table(ntbl); 1248 RHASH(hash)->ntbl = st_copy(RHASH(hash2)->ntbl); 1249 if (RHASH(hash)->ntbl->num_entries) 1250 rb_hash_rehash(hash); 1251 } 1252 else if (ntbl) { 1253 st_clear(ntbl); 1254 } 1255 1256 if (FL_TEST(hash2, HASH_PROC_DEFAULT)) { 1257 FL_SET(hash, HASH_PROC_DEFAULT); 1258 } 1259 else { 1260 FL_UNSET(hash, HASH_PROC_DEFAULT); 1261 } 1262 RHASH_IFNONE(hash) = RHASH_IFNONE(hash2); 1263 1264 return hash; 1265} 1266 1267/* 1268 * call-seq: 1269 * hsh.replace(other_hash) -> hsh 1270 * 1271 * Replaces the contents of <i>hsh</i> with the contents of 1272 * <i>other_hash</i>. 1273 * 1274 * h = { "a" => 100, "b" => 200 } 1275 * h.replace({ "c" => 300, "d" => 400 }) #=> {"c"=>300, "d"=>400} 1276 * 1277 */ 1278 1279static VALUE 1280rb_hash_replace(VALUE hash, VALUE hash2) 1281{ 1282 rb_hash_modify_check(hash); 1283 hash2 = to_hash(hash2); 1284 if (hash == hash2) return hash; 1285 rb_hash_clear(hash); 1286 if (RHASH(hash2)->ntbl) { 1287 rb_hash_tbl(hash); 1288 RHASH(hash)->ntbl->type = RHASH(hash2)->ntbl->type; 1289 } 1290 rb_hash_foreach(hash2, replace_i, hash); 1291 RHASH_IFNONE(hash) = RHASH_IFNONE(hash2); 1292 if (FL_TEST(hash2, HASH_PROC_DEFAULT)) { 1293 FL_SET(hash, HASH_PROC_DEFAULT); 1294 } 1295 else { 1296 FL_UNSET(hash, HASH_PROC_DEFAULT); 1297 } 1298 1299 return hash; 1300} 1301 1302/* 1303 * call-seq: 1304 * hsh.length -> fixnum 1305 * hsh.size -> fixnum 1306 * 1307 * Returns the number of key-value pairs in the hash. 1308 * 1309 * h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 } 1310 * h.length #=> 4 1311 * h.delete("a") #=> 200 1312 * h.length #=> 3 1313 */ 1314 1315static VALUE 1316rb_hash_size(VALUE hash) 1317{ 1318 if (!RHASH(hash)->ntbl) 1319 return INT2FIX(0); 1320 return INT2FIX(RHASH(hash)->ntbl->num_entries); 1321} 1322 1323 1324/* 1325 * call-seq: 1326 * hsh.empty? -> true or false 1327 * 1328 * Returns <code>true</code> if <i>hsh</i> contains no key-value pairs. 1329 * 1330 * {}.empty? #=> true 1331 * 1332 */ 1333 1334static VALUE 1335rb_hash_empty_p(VALUE hash) 1336{ 1337 return RHASH_EMPTY_P(hash) ? Qtrue : Qfalse; 1338} 1339 1340static int 1341each_value_i(VALUE key, VALUE value) 1342{ 1343 rb_yield(value); 1344 return ST_CONTINUE; 1345} 1346 1347/* 1348 * call-seq: 1349 * hsh.each_value {| value | block } -> hsh 1350 * hsh.each_value -> an_enumerator 1351 * 1352 * Calls <i>block</i> once for each key in <i>hsh</i>, passing the 1353 * value as a parameter. 1354 * 1355 * If no block is given, an enumerator is returned instead. 1356 * 1357 * h = { "a" => 100, "b" => 200 } 1358 * h.each_value {|value| puts value } 1359 * 1360 * <em>produces:</em> 1361 * 1362 * 100 1363 * 200 1364 */ 1365 1366static VALUE 1367rb_hash_each_value(VALUE hash) 1368{ 1369 RETURN_SIZED_ENUMERATOR(hash, 0, 0, rb_hash_size); 1370 rb_hash_foreach(hash, each_value_i, 0); 1371 return hash; 1372} 1373 1374static int 1375each_key_i(VALUE key, VALUE value) 1376{ 1377 rb_yield(key); 1378 return ST_CONTINUE; 1379} 1380 1381/* 1382 * call-seq: 1383 * hsh.each_key {| key | block } -> hsh 1384 * hsh.each_key -> an_enumerator 1385 * 1386 * Calls <i>block</i> once for each key in <i>hsh</i>, passing the key 1387 * as a parameter. 1388 * 1389 * If no block is given, an enumerator is returned instead. 1390 * 1391 * h = { "a" => 100, "b" => 200 } 1392 * h.each_key {|key| puts key } 1393 * 1394 * <em>produces:</em> 1395 * 1396 * a 1397 * b 1398 */ 1399static VALUE 1400rb_hash_each_key(VALUE hash) 1401{ 1402 RETURN_SIZED_ENUMERATOR(hash, 0, 0, rb_hash_size); 1403 rb_hash_foreach(hash, each_key_i, 0); 1404 return hash; 1405} 1406 1407static int 1408each_pair_i(VALUE key, VALUE value) 1409{ 1410 rb_yield(rb_assoc_new(key, value)); 1411 return ST_CONTINUE; 1412} 1413 1414/* 1415 * call-seq: 1416 * hsh.each {| key, value | block } -> hsh 1417 * hsh.each_pair {| key, value | block } -> hsh 1418 * hsh.each -> an_enumerator 1419 * hsh.each_pair -> an_enumerator 1420 * 1421 * Calls <i>block</i> once for each key in <i>hsh</i>, passing the key-value 1422 * pair as parameters. 1423 * 1424 * If no block is given, an enumerator is returned instead. 1425 * 1426 * h = { "a" => 100, "b" => 200 } 1427 * h.each {|key, value| puts "#{key} is #{value}" } 1428 * 1429 * <em>produces:</em> 1430 * 1431 * a is 100 1432 * b is 200 1433 * 1434 */ 1435 1436static VALUE 1437rb_hash_each_pair(VALUE hash) 1438{ 1439 RETURN_SIZED_ENUMERATOR(hash, 0, 0, rb_hash_size); 1440 rb_hash_foreach(hash, each_pair_i, 0); 1441 return hash; 1442} 1443 1444static int 1445to_a_i(VALUE key, VALUE value, VALUE ary) 1446{ 1447 rb_ary_push(ary, rb_assoc_new(key, value)); 1448 return ST_CONTINUE; 1449} 1450 1451/* 1452 * call-seq: 1453 * hsh.to_a -> array 1454 * 1455 * Converts <i>hsh</i> to a nested array of <code>[</code> <i>key, 1456 * value</i> <code>]</code> arrays. 1457 * 1458 * h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 } 1459 * h.to_a #=> [["c", 300], ["a", 100], ["d", 400]] 1460 */ 1461 1462static VALUE 1463rb_hash_to_a(VALUE hash) 1464{ 1465 VALUE ary; 1466 1467 ary = rb_ary_new(); 1468 rb_hash_foreach(hash, to_a_i, ary); 1469 OBJ_INFECT(ary, hash); 1470 1471 return ary; 1472} 1473 1474static int 1475inspect_i(VALUE key, VALUE value, VALUE str) 1476{ 1477 VALUE str2; 1478 1479 str2 = rb_inspect(key); 1480 if (RSTRING_LEN(str) > 1) { 1481 rb_str_buf_cat_ascii(str, ", "); 1482 } 1483 else { 1484 rb_enc_copy(str, str2); 1485 } 1486 rb_str_buf_append(str, str2); 1487 OBJ_INFECT(str, str2); 1488 rb_str_buf_cat_ascii(str, "=>"); 1489 str2 = rb_inspect(value); 1490 rb_str_buf_append(str, str2); 1491 OBJ_INFECT(str, str2); 1492 1493 return ST_CONTINUE; 1494} 1495 1496static VALUE 1497inspect_hash(VALUE hash, VALUE dummy, int recur) 1498{ 1499 VALUE str; 1500 1501 if (recur) return rb_usascii_str_new2("{...}"); 1502 str = rb_str_buf_new2("{"); 1503 rb_hash_foreach(hash, inspect_i, str); 1504 rb_str_buf_cat2(str, "}"); 1505 OBJ_INFECT(str, hash); 1506 1507 return str; 1508} 1509 1510/* 1511 * call-seq: 1512 * hsh.to_s -> string 1513 * hsh.inspect -> string 1514 * 1515 * Return the contents of this hash as a string. 1516 * 1517 * h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 } 1518 * h.to_s #=> "{\"c\"=>300, \"a\"=>100, \"d\"=>400}" 1519 */ 1520 1521static VALUE 1522rb_hash_inspect(VALUE hash) 1523{ 1524 if (RHASH_EMPTY_P(hash)) 1525 return rb_usascii_str_new2("{}"); 1526 return rb_exec_recursive(inspect_hash, hash, 0); 1527} 1528 1529/* 1530 * call-seq: 1531 * hsh.to_hash => hsh 1532 * 1533 * Returns +self+. 1534 */ 1535 1536static VALUE 1537rb_hash_to_hash(VALUE hash) 1538{ 1539 return hash; 1540} 1541 1542/* 1543 * call-seq: 1544 * hsh.to_h -> hsh or new_hash 1545 * 1546 * Returns +self+. If called on a subclass of Hash, converts 1547 * the receiver to a Hash object. 1548 */ 1549 1550static VALUE 1551rb_hash_to_h(VALUE hash) 1552{ 1553 if (rb_obj_class(hash) != rb_cHash) { 1554 VALUE ret = rb_hash_new(); 1555 if (!RHASH_EMPTY_P(hash)) 1556 RHASH(ret)->ntbl = st_copy(RHASH(hash)->ntbl); 1557 if (FL_TEST(hash, HASH_PROC_DEFAULT)) { 1558 FL_SET(ret, HASH_PROC_DEFAULT); 1559 } 1560 RHASH_IFNONE(ret) = RHASH_IFNONE(hash); 1561 return ret; 1562 } 1563 return hash; 1564} 1565 1566static int 1567keys_i(VALUE key, VALUE value, VALUE ary) 1568{ 1569 rb_ary_push(ary, key); 1570 return ST_CONTINUE; 1571} 1572 1573/* 1574 * call-seq: 1575 * hsh.keys -> array 1576 * 1577 * Returns a new array populated with the keys from this hash. See also 1578 * <code>Hash#values</code>. 1579 * 1580 * h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 } 1581 * h.keys #=> ["a", "b", "c", "d"] 1582 * 1583 */ 1584 1585static VALUE 1586rb_hash_keys(VALUE hash) 1587{ 1588 VALUE ary; 1589 1590 ary = rb_ary_new(); 1591 rb_hash_foreach(hash, keys_i, ary); 1592 1593 return ary; 1594} 1595 1596static int 1597values_i(VALUE key, VALUE value, VALUE ary) 1598{ 1599 rb_ary_push(ary, value); 1600 return ST_CONTINUE; 1601} 1602 1603/* 1604 * call-seq: 1605 * hsh.values -> array 1606 * 1607 * Returns a new array populated with the values from <i>hsh</i>. See 1608 * also <code>Hash#keys</code>. 1609 * 1610 * h = { "a" => 100, "b" => 200, "c" => 300 } 1611 * h.values #=> [100, 200, 300] 1612 * 1613 */ 1614 1615static VALUE 1616rb_hash_values(VALUE hash) 1617{ 1618 VALUE ary; 1619 1620 ary = rb_ary_new(); 1621 rb_hash_foreach(hash, values_i, ary); 1622 1623 return ary; 1624} 1625 1626/* 1627 * call-seq: 1628 * hsh.has_key?(key) -> true or false 1629 * hsh.include?(key) -> true or false 1630 * hsh.key?(key) -> true or false 1631 * hsh.member?(key) -> true or false 1632 * 1633 * Returns <code>true</code> if the given key is present in <i>hsh</i>. 1634 * 1635 * h = { "a" => 100, "b" => 200 } 1636 * h.has_key?("a") #=> true 1637 * h.has_key?("z") #=> false 1638 * 1639 */ 1640 1641static VALUE 1642rb_hash_has_key(VALUE hash, VALUE key) 1643{ 1644 if (!RHASH(hash)->ntbl) 1645 return Qfalse; 1646 if (st_lookup(RHASH(hash)->ntbl, key, 0)) { 1647 return Qtrue; 1648 } 1649 return Qfalse; 1650} 1651 1652static int 1653rb_hash_search_value(VALUE key, VALUE value, VALUE arg) 1654{ 1655 VALUE *data = (VALUE *)arg; 1656 1657 if (rb_equal(value, data[1])) { 1658 data[0] = Qtrue; 1659 return ST_STOP; 1660 } 1661 return ST_CONTINUE; 1662} 1663 1664/* 1665 * call-seq: 1666 * hsh.has_value?(value) -> true or false 1667 * hsh.value?(value) -> true or false 1668 * 1669 * Returns <code>true</code> if the given value is present for some key 1670 * in <i>hsh</i>. 1671 * 1672 * h = { "a" => 100, "b" => 200 } 1673 * h.has_value?(100) #=> true 1674 * h.has_value?(999) #=> false 1675 */ 1676 1677static VALUE 1678rb_hash_has_value(VALUE hash, VALUE val) 1679{ 1680 VALUE data[2]; 1681 1682 data[0] = Qfalse; 1683 data[1] = val; 1684 rb_hash_foreach(hash, rb_hash_search_value, (VALUE)data); 1685 return data[0]; 1686} 1687 1688struct equal_data { 1689 VALUE result; 1690 st_table *tbl; 1691 int eql; 1692}; 1693 1694static int 1695eql_i(VALUE key, VALUE val1, VALUE arg) 1696{ 1697 struct equal_data *data = (struct equal_data *)arg; 1698 st_data_t val2; 1699 1700 if (!st_lookup(data->tbl, key, &val2)) { 1701 data->result = Qfalse; 1702 return ST_STOP; 1703 } 1704 if (!(data->eql ? rb_eql(val1, (VALUE)val2) : (int)rb_equal(val1, (VALUE)val2))) { 1705 data->result = Qfalse; 1706 return ST_STOP; 1707 } 1708 return ST_CONTINUE; 1709} 1710 1711static VALUE 1712recursive_eql(VALUE hash, VALUE dt, int recur) 1713{ 1714 struct equal_data *data; 1715 1716 if (recur) return Qtrue; /* Subtle! */ 1717 data = (struct equal_data*)dt; 1718 data->result = Qtrue; 1719 rb_hash_foreach(hash, eql_i, dt); 1720 1721 return data->result; 1722} 1723 1724static VALUE 1725hash_equal(VALUE hash1, VALUE hash2, int eql) 1726{ 1727 struct equal_data data; 1728 1729 if (hash1 == hash2) return Qtrue; 1730 if (!RB_TYPE_P(hash2, T_HASH)) { 1731 if (!rb_respond_to(hash2, rb_intern("to_hash"))) { 1732 return Qfalse; 1733 } 1734 if (eql) 1735 return rb_eql(hash2, hash1); 1736 else 1737 return rb_equal(hash2, hash1); 1738 } 1739 if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2)) 1740 return Qfalse; 1741 if (!RHASH(hash1)->ntbl || !RHASH(hash2)->ntbl) 1742 return Qtrue; 1743 if (RHASH(hash1)->ntbl->type != RHASH(hash2)->ntbl->type) 1744 return Qfalse; 1745#if 0 1746 if (!(rb_equal(RHASH_IFNONE(hash1), RHASH_IFNONE(hash2)) && 1747 FL_TEST(hash1, HASH_PROC_DEFAULT) == FL_TEST(hash2, HASH_PROC_DEFAULT))) 1748 return Qfalse; 1749#endif 1750 1751 data.tbl = RHASH(hash2)->ntbl; 1752 data.eql = eql; 1753 return rb_exec_recursive_paired(recursive_eql, hash1, hash2, (VALUE)&data); 1754} 1755 1756/* 1757 * call-seq: 1758 * hsh == other_hash -> true or false 1759 * 1760 * Equality---Two hashes are equal if they each contain the same number 1761 * of keys and if each key-value pair is equal to (according to 1762 * <code>Object#==</code>) the corresponding elements in the other 1763 * hash. 1764 * 1765 * h1 = { "a" => 1, "c" => 2 } 1766 * h2 = { 7 => 35, "c" => 2, "a" => 1 } 1767 * h3 = { "a" => 1, "c" => 2, 7 => 35 } 1768 * h4 = { "a" => 1, "d" => 2, "f" => 35 } 1769 * h1 == h2 #=> false 1770 * h2 == h3 #=> true 1771 * h3 == h4 #=> false 1772 * 1773 */ 1774 1775static VALUE 1776rb_hash_equal(VALUE hash1, VALUE hash2) 1777{ 1778 return hash_equal(hash1, hash2, FALSE); 1779} 1780 1781/* 1782 * call-seq: 1783 * hash.eql?(other) -> true or false 1784 * 1785 * Returns <code>true</code> if <i>hash</i> and <i>other</i> are 1786 * both hashes with the same content. 1787 */ 1788 1789static VALUE 1790rb_hash_eql(VALUE hash1, VALUE hash2) 1791{ 1792 return hash_equal(hash1, hash2, TRUE); 1793} 1794 1795static int 1796hash_i(VALUE key, VALUE val, VALUE arg) 1797{ 1798 st_index_t *hval = (st_index_t *)arg; 1799 st_index_t hdata[2]; 1800 1801 hdata[0] = rb_hash(key); 1802 hdata[1] = rb_hash(val); 1803 *hval ^= st_hash(hdata, sizeof(hdata), 0); 1804 return ST_CONTINUE; 1805} 1806 1807static VALUE 1808recursive_hash(VALUE hash, VALUE dummy, int recur) 1809{ 1810 st_index_t hval; 1811 1812 if (!RHASH(hash)->ntbl) 1813 return LONG2FIX(0); 1814 hval = RHASH(hash)->ntbl->num_entries; 1815 if (!hval) return LONG2FIX(0); 1816 if (recur) 1817 hval = rb_hash_uint(rb_hash_start(rb_hash(rb_cHash)), hval); 1818 else 1819 rb_hash_foreach(hash, hash_i, (VALUE)&hval); 1820 hval = rb_hash_end(hval); 1821 return INT2FIX(hval); 1822} 1823 1824/* 1825 * call-seq: 1826 * hsh.hash -> fixnum 1827 * 1828 * Compute a hash-code for this hash. Two hashes with the same content 1829 * will have the same hash code (and will compare using <code>eql?</code>). 1830 */ 1831 1832static VALUE 1833rb_hash_hash(VALUE hash) 1834{ 1835 return rb_exec_recursive_outer(recursive_hash, hash, 0); 1836} 1837 1838static int 1839rb_hash_invert_i(VALUE key, VALUE value, VALUE hash) 1840{ 1841 rb_hash_aset(hash, value, key); 1842 return ST_CONTINUE; 1843} 1844 1845/* 1846 * call-seq: 1847 * hsh.invert -> new_hash 1848 * 1849 * Returns a new hash created by using <i>hsh</i>'s values as keys, and 1850 * the keys as values. 1851 * 1852 * h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 } 1853 * h.invert #=> {0=>"a", 100=>"m", 200=>"d", 300=>"y"} 1854 * 1855 */ 1856 1857static VALUE 1858rb_hash_invert(VALUE hash) 1859{ 1860 VALUE h = rb_hash_new(); 1861 1862 rb_hash_foreach(hash, rb_hash_invert_i, h); 1863 return h; 1864} 1865 1866static int 1867rb_hash_update_callback(st_data_t *key, st_data_t *value, st_data_t arg, int existing) 1868{ 1869 *value = arg; 1870 return ST_CONTINUE; 1871} 1872 1873static NOINSERT_UPDATE_CALLBACK(rb_hash_update_callback) 1874 1875static int 1876rb_hash_update_i(VALUE key, VALUE value, VALUE hash) 1877{ 1878 RHASH_UPDATE(hash, key, rb_hash_update_callback, value); 1879 return ST_CONTINUE; 1880} 1881 1882static int 1883rb_hash_update_block_callback(st_data_t *key, st_data_t *value, st_data_t arg, int existing) 1884{ 1885 VALUE newvalue = (VALUE)arg; 1886 if (existing) { 1887 newvalue = rb_yield_values(3, (VALUE)*key, (VALUE)*value, newvalue); 1888 } 1889 *value = (st_data_t)newvalue; 1890 return ST_CONTINUE; 1891} 1892 1893static NOINSERT_UPDATE_CALLBACK(rb_hash_update_block_callback) 1894 1895static int 1896rb_hash_update_block_i(VALUE key, VALUE value, VALUE hash) 1897{ 1898 RHASH_UPDATE(hash, key, rb_hash_update_block_callback, value); 1899 return ST_CONTINUE; 1900} 1901 1902/* 1903 * call-seq: 1904 * hsh.merge!(other_hash) -> hsh 1905 * hsh.update(other_hash) -> hsh 1906 * hsh.merge!(other_hash){|key, oldval, newval| block} -> hsh 1907 * hsh.update(other_hash){|key, oldval, newval| block} -> hsh 1908 * 1909 * Adds the contents of _other_hash_ to _hsh_. If no block is specified, 1910 * entries with duplicate keys are overwritten with the values from 1911 * _other_hash_, otherwise the value of each duplicate key is determined by 1912 * calling the block with the key, its value in _hsh_ and its value in 1913 * _other_hash_. 1914 * 1915 * h1 = { "a" => 100, "b" => 200 } 1916 * h2 = { "b" => 254, "c" => 300 } 1917 * h1.merge!(h2) #=> {"a"=>100, "b"=>254, "c"=>300} 1918 * 1919 * h1 = { "a" => 100, "b" => 200 } 1920 * h2 = { "b" => 254, "c" => 300 } 1921 * h1.merge!(h2) { |key, v1, v2| v1 } 1922 * #=> {"a"=>100, "b"=>200, "c"=>300} 1923 */ 1924 1925static VALUE 1926rb_hash_update(VALUE hash1, VALUE hash2) 1927{ 1928 rb_hash_modify(hash1); 1929 hash2 = to_hash(hash2); 1930 if (rb_block_given_p()) { 1931 rb_hash_foreach(hash2, rb_hash_update_block_i, hash1); 1932 } 1933 else { 1934 rb_hash_foreach(hash2, rb_hash_update_i, hash1); 1935 } 1936 return hash1; 1937} 1938 1939struct update_arg { 1940 VALUE hash; 1941 VALUE value; 1942 rb_hash_update_func *func; 1943}; 1944 1945static int 1946rb_hash_update_func_callback(st_data_t *key, st_data_t *value, st_data_t arg0, int existing) 1947{ 1948 struct update_arg *arg = (struct update_arg *)arg0; 1949 VALUE newvalue = arg->value; 1950 if (existing) { 1951 newvalue = (*arg->func)((VALUE)*key, (VALUE)*value, newvalue); 1952 } 1953 *value = (st_data_t)newvalue; 1954 return ST_CONTINUE; 1955} 1956 1957static NOINSERT_UPDATE_CALLBACK(rb_hash_update_func_callback) 1958 1959static int 1960rb_hash_update_func_i(VALUE key, VALUE value, VALUE arg0) 1961{ 1962 struct update_arg *arg = (struct update_arg *)arg0; 1963 VALUE hash = arg->hash; 1964 1965 arg->value = value; 1966 RHASH_UPDATE(hash, key, rb_hash_update_func_callback, arg); 1967 return ST_CONTINUE; 1968} 1969 1970VALUE 1971rb_hash_update_by(VALUE hash1, VALUE hash2, rb_hash_update_func *func) 1972{ 1973 rb_hash_modify(hash1); 1974 hash2 = to_hash(hash2); 1975 if (func) { 1976 struct update_arg arg; 1977 arg.hash = hash1; 1978 arg.func = func; 1979 rb_hash_foreach(hash2, rb_hash_update_func_i, (VALUE)&arg); 1980 } 1981 else { 1982 rb_hash_foreach(hash2, rb_hash_update_i, hash1); 1983 } 1984 return hash1; 1985} 1986 1987/* 1988 * call-seq: 1989 * hsh.merge(other_hash) -> new_hash 1990 * hsh.merge(other_hash){|key, oldval, newval| block} -> new_hash 1991 * 1992 * Returns a new hash containing the contents of <i>other_hash</i> and 1993 * the contents of <i>hsh</i>. If no block is specified, the value for 1994 * entries with duplicate keys will be that of <i>other_hash</i>. Otherwise 1995 * the value for each duplicate key is determined by calling the block 1996 * with the key, its value in <i>hsh</i> and its value in <i>other_hash</i>. 1997 * 1998 * h1 = { "a" => 100, "b" => 200 } 1999 * h2 = { "b" => 254, "c" => 300 } 2000 * h1.merge(h2) #=> {"a"=>100, "b"=>254, "c"=>300} 2001 * h1.merge(h2){|key, oldval, newval| newval - oldval} 2002 * #=> {"a"=>100, "b"=>54, "c"=>300} 2003 * h1 #=> {"a"=>100, "b"=>200} 2004 * 2005 */ 2006 2007static VALUE 2008rb_hash_merge(VALUE hash1, VALUE hash2) 2009{ 2010 return rb_hash_update(rb_obj_dup(hash1), hash2); 2011} 2012 2013static int 2014assoc_i(VALUE key, VALUE val, VALUE arg) 2015{ 2016 VALUE *args = (VALUE *)arg; 2017 2018 if (RTEST(rb_equal(args[0], key))) { 2019 args[1] = rb_assoc_new(key, val); 2020 return ST_STOP; 2021 } 2022 return ST_CONTINUE; 2023} 2024 2025/* 2026 * call-seq: 2027 * hash.assoc(obj) -> an_array or nil 2028 * 2029 * Searches through the hash comparing _obj_ with the key using <code>==</code>. 2030 * Returns the key-value pair (two elements array) or +nil+ 2031 * if no match is found. See <code>Array#assoc</code>. 2032 * 2033 * h = {"colors" => ["red", "blue", "green"], 2034 * "letters" => ["a", "b", "c" ]} 2035 * h.assoc("letters") #=> ["letters", ["a", "b", "c"]] 2036 * h.assoc("foo") #=> nil 2037 */ 2038 2039VALUE 2040rb_hash_assoc(VALUE hash, VALUE obj) 2041{ 2042 VALUE args[2]; 2043 2044 args[0] = obj; 2045 args[1] = Qnil; 2046 rb_hash_foreach(hash, assoc_i, (VALUE)args); 2047 return args[1]; 2048} 2049 2050static int 2051rassoc_i(VALUE key, VALUE val, VALUE arg) 2052{ 2053 VALUE *args = (VALUE *)arg; 2054 2055 if (RTEST(rb_equal(args[0], val))) { 2056 args[1] = rb_assoc_new(key, val); 2057 return ST_STOP; 2058 } 2059 return ST_CONTINUE; 2060} 2061 2062/* 2063 * call-seq: 2064 * hash.rassoc(obj) -> an_array or nil 2065 * 2066 * Searches through the hash comparing _obj_ with the value using <code>==</code>. 2067 * Returns the first key-value pair (two-element array) that matches. See 2068 * also <code>Array#rassoc</code>. 2069 * 2070 * a = {1=> "one", 2 => "two", 3 => "three", "ii" => "two"} 2071 * a.rassoc("two") #=> [2, "two"] 2072 * a.rassoc("four") #=> nil 2073 */ 2074 2075VALUE 2076rb_hash_rassoc(VALUE hash, VALUE obj) 2077{ 2078 VALUE args[2]; 2079 2080 args[0] = obj; 2081 args[1] = Qnil; 2082 rb_hash_foreach(hash, rassoc_i, (VALUE)args); 2083 return args[1]; 2084} 2085 2086/* 2087 * call-seq: 2088 * hash.flatten -> an_array 2089 * hash.flatten(level) -> an_array 2090 * 2091 * Returns a new array that is a one-dimensional flattening of this 2092 * hash. That is, for every key or value that is an array, extract 2093 * its elements into the new array. Unlike Array#flatten, this 2094 * method does not flatten recursively by default. The optional 2095 * <i>level</i> argument determines the level of recursion to flatten. 2096 * 2097 * a = {1=> "one", 2 => [2,"two"], 3 => "three"} 2098 * a.flatten # => [1, "one", 2, [2, "two"], 3, "three"] 2099 * a.flatten(2) # => [1, "one", 2, 2, "two", 3, "three"] 2100 */ 2101 2102static VALUE 2103rb_hash_flatten(int argc, VALUE *argv, VALUE hash) 2104{ 2105 VALUE ary, tmp; 2106 2107 ary = rb_hash_to_a(hash); 2108 if (argc == 0) { 2109 argc = 1; 2110 tmp = INT2FIX(1); 2111 argv = &tmp; 2112 } 2113 rb_funcall2(ary, rb_intern("flatten!"), argc, argv); 2114 return ary; 2115} 2116 2117/* 2118 * call-seq: 2119 * hsh.compare_by_identity -> hsh 2120 * 2121 * Makes <i>hsh</i> compare its keys by their identity, i.e. it 2122 * will consider exact same objects as same keys. 2123 * 2124 * h1 = { "a" => 100, "b" => 200, :c => "c" } 2125 * h1["a"] #=> 100 2126 * h1.compare_by_identity 2127 * h1.compare_by_identity? #=> true 2128 * h1["a"] #=> nil # different objects. 2129 * h1[:c] #=> "c" # same symbols are all same. 2130 * 2131 */ 2132 2133static VALUE 2134rb_hash_compare_by_id(VALUE hash) 2135{ 2136 rb_hash_modify(hash); 2137 RHASH(hash)->ntbl->type = &identhash; 2138 rb_hash_rehash(hash); 2139 return hash; 2140} 2141 2142/* 2143 * call-seq: 2144 * hsh.compare_by_identity? -> true or false 2145 * 2146 * Returns <code>true</code> if <i>hsh</i> will compare its keys by 2147 * their identity. Also see <code>Hash#compare_by_identity</code>. 2148 * 2149 */ 2150 2151static VALUE 2152rb_hash_compare_by_id_p(VALUE hash) 2153{ 2154 if (!RHASH(hash)->ntbl) 2155 return Qfalse; 2156 if (RHASH(hash)->ntbl->type == &identhash) { 2157 return Qtrue; 2158 } 2159 return Qfalse; 2160} 2161 2162static int path_tainted = -1; 2163 2164static char **origenviron; 2165#ifdef _WIN32 2166#define GET_ENVIRON(e) ((e) = rb_w32_get_environ()) 2167#define FREE_ENVIRON(e) rb_w32_free_environ(e) 2168static char **my_environ; 2169#undef environ 2170#define environ my_environ 2171#undef getenv 2172#define getenv(n) rb_w32_ugetenv(n) 2173#elif defined(__APPLE__) 2174#undef environ 2175#define environ (*_NSGetEnviron()) 2176#define GET_ENVIRON(e) (e) 2177#define FREE_ENVIRON(e) 2178#else 2179extern char **environ; 2180#define GET_ENVIRON(e) (e) 2181#define FREE_ENVIRON(e) 2182#endif 2183#ifdef ENV_IGNORECASE 2184#define ENVMATCH(s1, s2) (STRCASECMP((s1), (s2)) == 0) 2185#define ENVNMATCH(s1, s2, n) (STRNCASECMP((s1), (s2), (n)) == 0) 2186#else 2187#define ENVMATCH(n1, n2) (strcmp((n1), (n2)) == 0) 2188#define ENVNMATCH(s1, s2, n) (memcmp((s1), (s2), (n)) == 0) 2189#endif 2190 2191static VALUE 2192env_str_new(const char *ptr, long len) 2193{ 2194#ifdef _WIN32 2195 VALUE str = rb_str_conv_enc(rb_str_new(ptr, len), rb_utf8_encoding(), rb_locale_encoding()); 2196#else 2197 VALUE str = rb_locale_str_new(ptr, len); 2198#endif 2199 2200 rb_obj_freeze(str); 2201 return str; 2202} 2203 2204static VALUE 2205env_str_new2(const char *ptr) 2206{ 2207 if (!ptr) return Qnil; 2208 return env_str_new(ptr, strlen(ptr)); 2209} 2210 2211static VALUE 2212env_delete(VALUE obj, VALUE name) 2213{ 2214 char *nam, *val; 2215 2216 rb_secure(4); 2217 SafeStringValue(name); 2218 nam = RSTRING_PTR(name); 2219 if (memchr(nam, '\0', RSTRING_LEN(name))) { 2220 rb_raise(rb_eArgError, "bad environment variable name"); 2221 } 2222 val = getenv(nam); 2223 if (val) { 2224 VALUE value = env_str_new2(val); 2225 2226 ruby_setenv(nam, 0); 2227 if (ENVMATCH(nam, PATH_ENV)) { 2228 path_tainted = 0; 2229 } 2230 return value; 2231 } 2232 return Qnil; 2233} 2234 2235/* 2236 * call-seq: 2237 * ENV.delete(name) -> value 2238 * ENV.delete(name) { |name| } -> value 2239 * 2240 * Deletes the environment variable with +name+ and returns the value of the 2241 * variable. If a block is given it will be called when the named environment 2242 * does not exist. 2243 */ 2244static VALUE 2245env_delete_m(VALUE obj, VALUE name) 2246{ 2247 VALUE val; 2248 2249 val = env_delete(obj, name); 2250 if (NIL_P(val) && rb_block_given_p()) rb_yield(name); 2251 return val; 2252} 2253 2254static int env_path_tainted(const char *); 2255 2256/* 2257 * call-seq: 2258 * ENV[name] -> value 2259 * 2260 * Retrieves the +value+ for environment variable +name+ as a String. Returns 2261 * +nil+ if the named variable does not exist. 2262 */ 2263static VALUE 2264rb_f_getenv(VALUE obj, VALUE name) 2265{ 2266 char *nam, *env; 2267 2268 rb_secure(4); 2269 SafeStringValue(name); 2270 nam = RSTRING_PTR(name); 2271 if (memchr(nam, '\0', RSTRING_LEN(name))) { 2272 rb_raise(rb_eArgError, "bad environment variable name"); 2273 } 2274 env = getenv(nam); 2275 if (env) { 2276 if (ENVMATCH(nam, PATH_ENV) && !env_path_tainted(env)) { 2277#ifdef _WIN32 2278 VALUE str = rb_str_conv_enc(rb_str_new(env, strlen(env)), rb_utf8_encoding(), rb_filesystem_encoding()); 2279#else 2280 VALUE str = rb_filesystem_str_new_cstr(env); 2281#endif 2282 2283 rb_obj_freeze(str); 2284 return str; 2285 } 2286 return env_str_new2(env); 2287 } 2288 return Qnil; 2289} 2290 2291/* 2292 * :yield: missing_name 2293 * call-seq: 2294 * ENV.fetch(name) -> value 2295 * ENV.fetch(name, default) -> value 2296 * ENV.fetch(name) { |missing_name| ... } -> value 2297 * 2298 * Retrieves the environment variable +name+. 2299 * 2300 * If the given name does not exist and neither +default+ nor a block a 2301 * provided an IndexError is raised. If a block is given it is called with 2302 * the missing name to provide a value. If a default value is given it will 2303 * be returned when no block is given. 2304 */ 2305static VALUE 2306env_fetch(int argc, VALUE *argv) 2307{ 2308 VALUE key, if_none; 2309 long block_given; 2310 char *nam, *env; 2311 2312 rb_secure(4); 2313 rb_scan_args(argc, argv, "11", &key, &if_none); 2314 block_given = rb_block_given_p(); 2315 if (block_given && argc == 2) { 2316 rb_warn("block supersedes default value argument"); 2317 } 2318 SafeStringValue(key); 2319 nam = RSTRING_PTR(key); 2320 if (memchr(nam, '\0', RSTRING_LEN(key))) { 2321 rb_raise(rb_eArgError, "bad environment variable name"); 2322 } 2323 env = getenv(nam); 2324 if (!env) { 2325 if (block_given) return rb_yield(key); 2326 if (argc == 1) { 2327 rb_raise(rb_eKeyError, "key not found"); 2328 } 2329 return if_none; 2330 } 2331 if (ENVMATCH(nam, PATH_ENV) && !env_path_tainted(env)) 2332#ifdef _WIN32 2333 return rb_str_conv_enc(rb_str_new(env, strlen(env)), rb_utf8_encoding(), rb_filesystem_encoding()); 2334#else 2335 return rb_filesystem_str_new_cstr(env); 2336#endif 2337 return env_str_new2(env); 2338} 2339 2340static void 2341path_tainted_p(const char *path) 2342{ 2343 path_tainted = rb_path_check(path)?0:1; 2344} 2345 2346static int 2347env_path_tainted(const char *path) 2348{ 2349 if (path_tainted < 0) { 2350 path_tainted_p(path); 2351 } 2352 return path_tainted; 2353} 2354 2355int 2356rb_env_path_tainted(void) 2357{ 2358 if (path_tainted < 0) { 2359 path_tainted_p(getenv(PATH_ENV)); 2360 } 2361 return path_tainted; 2362} 2363 2364#if defined(_WIN32) || (defined(HAVE_SETENV) && defined(HAVE_UNSETENV)) 2365#elif defined __sun 2366static int 2367in_origenv(const char *str) 2368{ 2369 char **env; 2370 for (env = origenviron; *env; ++env) { 2371 if (*env == str) return 1; 2372 } 2373 return 0; 2374} 2375#else 2376static int 2377envix(const char *nam) 2378{ 2379 register int i, len = strlen(nam); 2380 char **env; 2381 2382 env = GET_ENVIRON(environ); 2383 for (i = 0; env[i]; i++) { 2384 if (ENVNMATCH(env[i],nam,len) && env[i][len] == '=') 2385 break; /* memcmp must come first to avoid */ 2386 } /* potential SEGV's */ 2387 FREE_ENVIRON(environ); 2388 return i; 2389} 2390#endif 2391 2392#if defined(_WIN32) 2393static size_t 2394getenvsize(const char* p) 2395{ 2396 const char* porg = p; 2397 while (*p++) p += strlen(p) + 1; 2398 return p - porg + 1; 2399} 2400static size_t 2401getenvblocksize() 2402{ 2403 return (rb_w32_osver() >= 5) ? 32767 : 5120; 2404} 2405#endif 2406 2407void 2408ruby_setenv(const char *name, const char *value) 2409{ 2410#if defined(_WIN32) 2411 VALUE buf; 2412 int failed = 0; 2413 if (strchr(name, '=')) { 2414 fail: 2415 errno = EINVAL; 2416 rb_sys_fail("ruby_setenv"); 2417 } 2418 if (value) { 2419 const char* p = GetEnvironmentStringsA(); 2420 if (!p) goto fail; /* never happen */ 2421 if (strlen(name) + 2 + strlen(value) + getenvsize(p) >= getenvblocksize()) { 2422 goto fail; /* 2 for '=' & '\0' */ 2423 } 2424 buf = rb_sprintf("%s=%s", name, value); 2425 } 2426 else { 2427 buf = rb_sprintf("%s=", name); 2428 } 2429 failed = putenv(RSTRING_PTR(buf)); 2430 /* even if putenv() failed, clean up and try to delete the 2431 * variable from the system area. */ 2432 rb_str_resize(buf, 0); 2433 if (!value || !*value) { 2434 /* putenv() doesn't handle empty value */ 2435 if (!SetEnvironmentVariable(name, value) && 2436 GetLastError() != ERROR_ENVVAR_NOT_FOUND) goto fail; 2437 } 2438 if (failed) goto fail; 2439#elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV) 2440#undef setenv 2441#undef unsetenv 2442 if (value) { 2443 if (setenv(name, value, 1)) 2444 rb_sys_fail("setenv"); 2445 } else { 2446#ifdef VOID_UNSETENV 2447 unsetenv(name); 2448#else 2449 if (unsetenv(name)) 2450 rb_sys_fail("unsetenv"); 2451#endif 2452 } 2453#elif defined __sun 2454 size_t len; 2455 char **env_ptr, *str; 2456 if (strchr(name, '=')) { 2457 errno = EINVAL; 2458 rb_sys_fail("ruby_setenv"); 2459 } 2460 len = strlen(name); 2461 for (env_ptr = GET_ENVIRON(environ); (str = *env_ptr) != 0; ++env_ptr) { 2462 if (!strncmp(str, name, len) && str[len] == '=') { 2463 if (!in_origenv(str)) free(str); 2464 while ((env_ptr[0] = env_ptr[1]) != 0) env_ptr++; 2465 break; 2466 } 2467 } 2468 if (value) { 2469 str = malloc(len += strlen(value) + 2); 2470 snprintf(str, len, "%s=%s", name, value); 2471 if (putenv(str)) 2472 rb_sys_fail("putenv"); 2473 } 2474#else /* WIN32 */ 2475 size_t len; 2476 int i; 2477 if (strchr(name, '=')) { 2478 errno = EINVAL; 2479 rb_sys_fail("ruby_setenv"); 2480 } 2481 i=envix(name); /* where does it go? */ 2482 2483 if (environ == origenviron) { /* need we copy environment? */ 2484 int j; 2485 int max; 2486 char **tmpenv; 2487 2488 for (max = i; environ[max]; max++) ; 2489 tmpenv = ALLOC_N(char*, max+2); 2490 for (j=0; j<max; j++) /* copy environment */ 2491 tmpenv[j] = ruby_strdup(environ[j]); 2492 tmpenv[max] = 0; 2493 environ = tmpenv; /* tell exec where it is now */ 2494 } 2495 if (environ[i]) { 2496 char **envp = origenviron; 2497 while (*envp && *envp != environ[i]) envp++; 2498 if (!*envp) 2499 xfree(environ[i]); 2500 if (!value) { 2501 while (environ[i]) { 2502 environ[i] = environ[i+1]; 2503 i++; 2504 } 2505 return; 2506 } 2507 } 2508 else { /* does not exist yet */ 2509 if (!value) return; 2510 REALLOC_N(environ, char*, i+2); /* just expand it a bit */ 2511 environ[i+1] = 0; /* make sure it's null terminated */ 2512 } 2513 len = strlen(name) + strlen(value) + 2; 2514 environ[i] = ALLOC_N(char, len); 2515 snprintf(environ[i],len,"%s=%s",name,value); /* all that work just for this */ 2516#endif /* WIN32 */ 2517} 2518 2519void 2520ruby_unsetenv(const char *name) 2521{ 2522 ruby_setenv(name, 0); 2523} 2524 2525/* 2526 * call-seq: 2527 * ENV[name] = value 2528 * ENV.store(name, value) -> value 2529 * 2530 * Sets the environment variable +name+ to +value+. If the value given is 2531 * +nil+ the environment variable is deleted. 2532 * 2533 */ 2534static VALUE 2535env_aset(VALUE obj, VALUE nm, VALUE val) 2536{ 2537 char *name, *value; 2538 2539 if (rb_safe_level() >= 4) { 2540 rb_raise(rb_eSecurityError, "can't change environment variable"); 2541 } 2542 2543 if (NIL_P(val)) { 2544 env_delete(obj, nm); 2545 return Qnil; 2546 } 2547 StringValue(nm); 2548 StringValue(val); 2549 name = RSTRING_PTR(nm); 2550 value = RSTRING_PTR(val); 2551 if (memchr(name, '\0', RSTRING_LEN(nm))) 2552 rb_raise(rb_eArgError, "bad environment variable name"); 2553 if (memchr(value, '\0', RSTRING_LEN(val))) 2554 rb_raise(rb_eArgError, "bad environment variable value"); 2555 2556 ruby_setenv(name, value); 2557 if (ENVMATCH(name, PATH_ENV)) { 2558 if (OBJ_TAINTED(val)) { 2559 /* already tainted, no check */ 2560 path_tainted = 1; 2561 return val; 2562 } 2563 else { 2564 path_tainted_p(value); 2565 } 2566 } 2567 return val; 2568} 2569 2570/* 2571 * call-seq: 2572 * ENV.keys -> Array 2573 * 2574 * Returns every environment variable name in an Array 2575 */ 2576static VALUE 2577env_keys(void) 2578{ 2579 char **env; 2580 VALUE ary; 2581 2582 rb_secure(4); 2583 ary = rb_ary_new(); 2584 env = GET_ENVIRON(environ); 2585 while (*env) { 2586 char *s = strchr(*env, '='); 2587 if (s) { 2588 rb_ary_push(ary, env_str_new(*env, s-*env)); 2589 } 2590 env++; 2591 } 2592 FREE_ENVIRON(environ); 2593 return ary; 2594} 2595 2596static VALUE 2597rb_env_size(VALUE ehash) 2598{ 2599 char **env; 2600 long cnt = 0; 2601 2602 rb_secure(4); 2603 2604 env = GET_ENVIRON(environ); 2605 for (; *env ; ++env) { 2606 if (strchr(*env, '=')) { 2607 cnt++; 2608 } 2609 } 2610 FREE_ENVIRON(environ); 2611 return LONG2FIX(cnt); 2612} 2613 2614/* 2615 * call-seq: 2616 * ENV.each_key { |name| } -> Hash 2617 * ENV.each_key -> Enumerator 2618 * 2619 * Yields each environment variable name. 2620 * 2621 * An Enumerator is returned if no block is given. 2622 */ 2623static VALUE 2624env_each_key(VALUE ehash) 2625{ 2626 VALUE keys; 2627 long i; 2628 2629 RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size); 2630 keys = env_keys(); /* rb_secure(4); */ 2631 for (i=0; i<RARRAY_LEN(keys); i++) { 2632 rb_yield(RARRAY_PTR(keys)[i]); 2633 } 2634 return ehash; 2635} 2636 2637/* 2638 * call-seq: 2639 * ENV.values -> Array 2640 * 2641 * Returns every environment variable value as an Array 2642 */ 2643static VALUE 2644env_values(void) 2645{ 2646 VALUE ary; 2647 char **env; 2648 2649 rb_secure(4); 2650 ary = rb_ary_new(); 2651 env = GET_ENVIRON(environ); 2652 while (*env) { 2653 char *s = strchr(*env, '='); 2654 if (s) { 2655 rb_ary_push(ary, env_str_new2(s+1)); 2656 } 2657 env++; 2658 } 2659 FREE_ENVIRON(environ); 2660 return ary; 2661} 2662 2663/* 2664 * call-seq: 2665 * ENV.each_value { |value| } -> Hash 2666 * ENV.each_value -> Enumerator 2667 * 2668 * Yields each environment variable +value+. 2669 * 2670 * An Enumerator is returned if no block was given. 2671 */ 2672static VALUE 2673env_each_value(VALUE ehash) 2674{ 2675 VALUE values; 2676 long i; 2677 2678 RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size); 2679 values = env_values(); /* rb_secure(4); */ 2680 for (i=0; i<RARRAY_LEN(values); i++) { 2681 rb_yield(RARRAY_PTR(values)[i]); 2682 } 2683 return ehash; 2684} 2685 2686/* 2687 * call-seq: 2688 * ENV.each { |name, value| } -> Hash 2689 * ENV.each -> Enumerator 2690 * ENV.each_pair { |name, value| } -> Hash 2691 * ENV.each_pair -> Enumerator 2692 * 2693 * Yields each environment variable +name+ and +value+. 2694 * 2695 * If no block is given an Enumerator is returned. 2696 */ 2697static VALUE 2698env_each_pair(VALUE ehash) 2699{ 2700 char **env; 2701 VALUE ary; 2702 long i; 2703 2704 RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size); 2705 2706 rb_secure(4); 2707 ary = rb_ary_new(); 2708 env = GET_ENVIRON(environ); 2709 while (*env) { 2710 char *s = strchr(*env, '='); 2711 if (s) { 2712 rb_ary_push(ary, env_str_new(*env, s-*env)); 2713 rb_ary_push(ary, env_str_new2(s+1)); 2714 } 2715 env++; 2716 } 2717 FREE_ENVIRON(environ); 2718 2719 for (i=0; i<RARRAY_LEN(ary); i+=2) { 2720 rb_yield(rb_assoc_new(RARRAY_PTR(ary)[i], RARRAY_PTR(ary)[i+1])); 2721 } 2722 return ehash; 2723} 2724 2725/* 2726 * call-seq: 2727 * ENV.reject! { |name, value| } -> ENV or nil 2728 * ENV.reject! -> Enumerator 2729 * 2730 * Equivalent to ENV#delete_if but returns +nil+ if no changes were made. 2731 * 2732 * Returns an Enumerator if no block was given. 2733 */ 2734static VALUE 2735env_reject_bang(VALUE ehash) 2736{ 2737 volatile VALUE keys; 2738 long i; 2739 int del = 0; 2740 2741 RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size); 2742 keys = env_keys(); /* rb_secure(4); */ 2743 RBASIC(keys)->klass = 0; 2744 for (i=0; i<RARRAY_LEN(keys); i++) { 2745 VALUE val = rb_f_getenv(Qnil, RARRAY_PTR(keys)[i]); 2746 if (!NIL_P(val)) { 2747 if (RTEST(rb_yield_values(2, RARRAY_PTR(keys)[i], val))) { 2748 FL_UNSET(RARRAY_PTR(keys)[i], FL_TAINT); 2749 env_delete(Qnil, RARRAY_PTR(keys)[i]); 2750 del++; 2751 } 2752 } 2753 } 2754 if (del == 0) return Qnil; 2755 return envtbl; 2756} 2757 2758/* 2759 * call-seq: 2760 * ENV.delete_if { |name, value| } -> Hash 2761 * ENV.delete_if -> Enumerator 2762 * 2763 * Deletes every environment variable for which the block evaluates to +true+. 2764 * 2765 * If no block is given an enumerator is returned instead. 2766 */ 2767static VALUE 2768env_delete_if(VALUE ehash) 2769{ 2770 RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size); 2771 env_reject_bang(ehash); 2772 return envtbl; 2773} 2774 2775/* 2776 * call-seq: 2777 * ENV.values_at(name, ...) -> Array 2778 * 2779 * Returns an array containing the environment variable values associated with 2780 * the given names. See also ENV.select. 2781 */ 2782static VALUE 2783env_values_at(int argc, VALUE *argv) 2784{ 2785 VALUE result; 2786 long i; 2787 2788 rb_secure(4); 2789 result = rb_ary_new(); 2790 for (i=0; i<argc; i++) { 2791 rb_ary_push(result, rb_f_getenv(Qnil, argv[i])); 2792 } 2793 return result; 2794} 2795 2796/* 2797 * call-seq: 2798 * ENV.select { |name, value| } -> Hash 2799 * ENV.select -> Enumerator 2800 * 2801 * Returns a copy of the environment for entries where the block returns true. 2802 * 2803 * Returns an Enumerator if no block was given. 2804 */ 2805static VALUE 2806env_select(VALUE ehash) 2807{ 2808 VALUE result; 2809 char **env; 2810 2811 RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size); 2812 rb_secure(4); 2813 result = rb_hash_new(); 2814 env = GET_ENVIRON(environ); 2815 while (*env) { 2816 char *s = strchr(*env, '='); 2817 if (s) { 2818 VALUE k = env_str_new(*env, s-*env); 2819 VALUE v = env_str_new2(s+1); 2820 if (RTEST(rb_yield_values(2, k, v))) { 2821 rb_hash_aset(result, k, v); 2822 } 2823 } 2824 env++; 2825 } 2826 FREE_ENVIRON(environ); 2827 2828 return result; 2829} 2830 2831/* 2832 * call-seq: 2833 * ENV.select! { |name, value| } -> ENV or nil 2834 * ENV.select! -> Enumerator 2835 * 2836 * Equivalent to ENV#keep_if but returns +nil+ if no changes were made. 2837 */ 2838static VALUE 2839env_select_bang(VALUE ehash) 2840{ 2841 volatile VALUE keys; 2842 long i; 2843 int del = 0; 2844 2845 RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size); 2846 keys = env_keys(); /* rb_secure(4); */ 2847 RBASIC(keys)->klass = 0; 2848 for (i=0; i<RARRAY_LEN(keys); i++) { 2849 VALUE val = rb_f_getenv(Qnil, RARRAY_PTR(keys)[i]); 2850 if (!NIL_P(val)) { 2851 if (!RTEST(rb_yield_values(2, RARRAY_PTR(keys)[i], val))) { 2852 FL_UNSET(RARRAY_PTR(keys)[i], FL_TAINT); 2853 env_delete(Qnil, RARRAY_PTR(keys)[i]); 2854 del++; 2855 } 2856 } 2857 } 2858 if (del == 0) return Qnil; 2859 return envtbl; 2860} 2861 2862/* 2863 * call-seq: 2864 * ENV.keep_if { |name, value| } -> Hash 2865 * ENV.keep_if -> Enumerator 2866 * 2867 * Deletes every environment variable where the block evaluates to +false+. 2868 * 2869 * Returns an enumerator if no block was given. 2870 */ 2871static VALUE 2872env_keep_if(VALUE ehash) 2873{ 2874 RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size); 2875 env_select_bang(ehash); 2876 return envtbl; 2877} 2878 2879/* 2880 * call-seq: 2881 * ENV.clear 2882 * 2883 * Removes every environment variable. 2884 */ 2885VALUE 2886rb_env_clear(void) 2887{ 2888 volatile VALUE keys; 2889 long i; 2890 2891 keys = env_keys(); /* rb_secure(4); */ 2892 for (i=0; i<RARRAY_LEN(keys); i++) { 2893 VALUE val = rb_f_getenv(Qnil, RARRAY_PTR(keys)[i]); 2894 if (!NIL_P(val)) { 2895 env_delete(Qnil, RARRAY_PTR(keys)[i]); 2896 } 2897 } 2898 return envtbl; 2899} 2900 2901/* 2902 * call-seq: 2903 * ENV.to_s -> "ENV" 2904 * 2905 * Returns "ENV" 2906 */ 2907static VALUE 2908env_to_s(void) 2909{ 2910 return rb_usascii_str_new2("ENV"); 2911} 2912 2913/* 2914 * call-seq: 2915 * ENV.inspect -> string 2916 * 2917 * Returns the contents of the environment as a String. 2918 */ 2919static VALUE 2920env_inspect(void) 2921{ 2922 char **env; 2923 VALUE str, i; 2924 2925 rb_secure(4); 2926 str = rb_str_buf_new2("{"); 2927 env = GET_ENVIRON(environ); 2928 while (*env) { 2929 char *s = strchr(*env, '='); 2930 2931 if (env != environ) { 2932 rb_str_buf_cat2(str, ", "); 2933 } 2934 if (s) { 2935 rb_str_buf_cat2(str, "\""); 2936 rb_str_buf_cat(str, *env, s-*env); 2937 rb_str_buf_cat2(str, "\"=>"); 2938 i = rb_inspect(rb_str_new2(s+1)); 2939 rb_str_buf_append(str, i); 2940 } 2941 env++; 2942 } 2943 FREE_ENVIRON(environ); 2944 rb_str_buf_cat2(str, "}"); 2945 OBJ_TAINT(str); 2946 2947 return str; 2948} 2949 2950/* 2951 * call-seq: 2952 * ENV.to_a -> Array 2953 * 2954 * Converts the environment variables into an array of names and value arrays. 2955 * 2956 * ENV.to_a # => [["TERM", "xterm-color"], ["SHELL", "/bin/bash"], ...] 2957 * 2958 */ 2959static VALUE 2960env_to_a(void) 2961{ 2962 char **env; 2963 VALUE ary; 2964 2965 rb_secure(4); 2966 ary = rb_ary_new(); 2967 env = GET_ENVIRON(environ); 2968 while (*env) { 2969 char *s = strchr(*env, '='); 2970 if (s) { 2971 rb_ary_push(ary, rb_assoc_new(env_str_new(*env, s-*env), 2972 env_str_new2(s+1))); 2973 } 2974 env++; 2975 } 2976 FREE_ENVIRON(environ); 2977 return ary; 2978} 2979 2980/* 2981 * call-seq: 2982 * ENV.rehash 2983 * 2984 * Re-hashing the environment variables does nothing. It is provided for 2985 * compatibility with Hash. 2986 */ 2987static VALUE 2988env_none(void) 2989{ 2990 return Qnil; 2991} 2992 2993/* 2994 * call-seq: 2995 * ENV.length 2996 * ENV.size 2997 * 2998 * Returns the number of environment variables. 2999 */ 3000static VALUE 3001env_size(void) 3002{ 3003 int i; 3004 char **env; 3005 3006 rb_secure(4); 3007 env = GET_ENVIRON(environ); 3008 for (i=0; env[i]; i++) 3009 ; 3010 FREE_ENVIRON(environ); 3011 return INT2FIX(i); 3012} 3013 3014/* 3015 * call-seq: 3016 * ENV.empty? -> true or false 3017 * 3018 * Returns true when there are no environment variables 3019 */ 3020static VALUE 3021env_empty_p(void) 3022{ 3023 char **env; 3024 3025 rb_secure(4); 3026 env = GET_ENVIRON(environ); 3027 if (env[0] == 0) { 3028 FREE_ENVIRON(environ); 3029 return Qtrue; 3030 } 3031 FREE_ENVIRON(environ); 3032 return Qfalse; 3033} 3034 3035/* 3036 * call-seq: 3037 * ENV.key?(name) -> true or false 3038 * ENV.include?(name) -> true or false 3039 * ENV.has_key?(name) -> true or false 3040 * ENV.member?(name) -> true or false 3041 * 3042 * Returns +true+ if there is an environment variable with the given +name+. 3043 */ 3044static VALUE 3045env_has_key(VALUE env, VALUE key) 3046{ 3047 char *s; 3048 3049 rb_secure(4); 3050 s = StringValuePtr(key); 3051 if (memchr(s, '\0', RSTRING_LEN(key))) 3052 rb_raise(rb_eArgError, "bad environment variable name"); 3053 if (getenv(s)) return Qtrue; 3054 return Qfalse; 3055} 3056 3057/* 3058 * call-seq: 3059 * ENV.assoc(name) -> Array or nil 3060 * 3061 * Returns an Array of the name and value of the environment variable with 3062 * +name+ or +nil+ if the name cannot be found. 3063 */ 3064static VALUE 3065env_assoc(VALUE env, VALUE key) 3066{ 3067 char *s, *e; 3068 3069 rb_secure(4); 3070 s = StringValuePtr(key); 3071 if (memchr(s, '\0', RSTRING_LEN(key))) 3072 rb_raise(rb_eArgError, "bad environment variable name"); 3073 e = getenv(s); 3074 if (e) return rb_assoc_new(key, rb_tainted_str_new2(e)); 3075 return Qnil; 3076} 3077 3078/* 3079 * call-seq: 3080 * ENV.value?(value) -> true or false 3081 * ENV.has_value?(value) -> true or false 3082 * 3083 * Returns +true+ if there is an environment variable with the given +value+. 3084 */ 3085static VALUE 3086env_has_value(VALUE dmy, VALUE obj) 3087{ 3088 char **env; 3089 3090 rb_secure(4); 3091 obj = rb_check_string_type(obj); 3092 if (NIL_P(obj)) return Qnil; 3093 env = GET_ENVIRON(environ); 3094 while (*env) { 3095 char *s = strchr(*env, '='); 3096 if (s++) { 3097 long len = strlen(s); 3098 if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) { 3099 FREE_ENVIRON(environ); 3100 return Qtrue; 3101 } 3102 } 3103 env++; 3104 } 3105 FREE_ENVIRON(environ); 3106 return Qfalse; 3107} 3108 3109/* 3110 * call-seq: 3111 * ENV.rassoc(value) 3112 * 3113 * Returns an Array of the name and value of the environment variable with 3114 * +value+ or +nil+ if the value cannot be found. 3115 */ 3116static VALUE 3117env_rassoc(VALUE dmy, VALUE obj) 3118{ 3119 char **env; 3120 3121 rb_secure(4); 3122 obj = rb_check_string_type(obj); 3123 if (NIL_P(obj)) return Qnil; 3124 env = GET_ENVIRON(environ); 3125 while (*env) { 3126 char *s = strchr(*env, '='); 3127 if (s++) { 3128 long len = strlen(s); 3129 if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) { 3130 VALUE result = rb_assoc_new(rb_tainted_str_new(*env, s-*env-1), obj); 3131 FREE_ENVIRON(environ); 3132 return result; 3133 } 3134 } 3135 env++; 3136 } 3137 FREE_ENVIRON(environ); 3138 return Qnil; 3139} 3140 3141/* 3142 * call-seq: 3143 * ENV.key(value) -> name 3144 * 3145 * Returns the name of the environment variable with +value+. If the value is 3146 * not found +nil+ is returned. 3147 */ 3148static VALUE 3149env_key(VALUE dmy, VALUE value) 3150{ 3151 char **env; 3152 VALUE str; 3153 3154 rb_secure(4); 3155 StringValue(value); 3156 env = GET_ENVIRON(environ); 3157 while (*env) { 3158 char *s = strchr(*env, '='); 3159 if (s++) { 3160 long len = strlen(s); 3161 if (RSTRING_LEN(value) == len && strncmp(s, RSTRING_PTR(value), len) == 0) { 3162 str = env_str_new(*env, s-*env-1); 3163 FREE_ENVIRON(environ); 3164 return str; 3165 } 3166 } 3167 env++; 3168 } 3169 FREE_ENVIRON(environ); 3170 return Qnil; 3171} 3172 3173/* 3174 * call-seq: 3175 * ENV.index(value) -> key 3176 * 3177 * Deprecated method that is equivalent to ENV.key 3178 */ 3179static VALUE 3180env_index(VALUE dmy, VALUE value) 3181{ 3182 rb_warn("ENV.index is deprecated; use ENV.key"); 3183 return env_key(dmy, value); 3184} 3185 3186/* 3187 * call-seq: 3188 * ENV.to_hash -> hash 3189 * ENV.to_h -> hash 3190 * 3191 * Creates a hash with a copy of the environment variables. 3192 * 3193 */ 3194static VALUE 3195env_to_hash(void) 3196{ 3197 char **env; 3198 VALUE hash; 3199 3200 rb_secure(4); 3201 hash = rb_hash_new(); 3202 env = GET_ENVIRON(environ); 3203 while (*env) { 3204 char *s = strchr(*env, '='); 3205 if (s) { 3206 rb_hash_aset(hash, env_str_new(*env, s-*env), 3207 env_str_new2(s+1)); 3208 } 3209 env++; 3210 } 3211 FREE_ENVIRON(environ); 3212 return hash; 3213} 3214 3215/* 3216 * call-seq: 3217 * ENV.reject { |name, value| } -> Hash 3218 * ENV.reject -> Enumerator 3219 * 3220 * Same as ENV#delete_if, but works on (and returns) a copy of the 3221 * environment. 3222 */ 3223static VALUE 3224env_reject(void) 3225{ 3226 return rb_hash_delete_if(env_to_hash()); 3227} 3228 3229/* 3230 * call-seq: 3231 * ENV.shift -> Array or nil 3232 * 3233 * Removes an environment variable name-value pair from ENV and returns it as 3234 * an Array. Returns +nil+ if when the environment is empty. 3235 */ 3236static VALUE 3237env_shift(void) 3238{ 3239 char **env; 3240 3241 rb_secure(4); 3242 env = GET_ENVIRON(environ); 3243 if (*env) { 3244 char *s = strchr(*env, '='); 3245 if (s) { 3246 VALUE key = env_str_new(*env, s-*env); 3247 VALUE val = env_str_new2(getenv(RSTRING_PTR(key))); 3248 env_delete(Qnil, key); 3249 return rb_assoc_new(key, val); 3250 } 3251 } 3252 FREE_ENVIRON(environ); 3253 return Qnil; 3254} 3255 3256/* 3257 * call-seq: 3258 * ENV.invert -> Hash 3259 * 3260 * Returns a new hash created by using environment variable names as values 3261 * and values as names. 3262 */ 3263static VALUE 3264env_invert(void) 3265{ 3266 return rb_hash_invert(env_to_hash()); 3267} 3268 3269static int 3270env_replace_i(VALUE key, VALUE val, VALUE keys) 3271{ 3272 env_aset(Qnil, key, val); 3273 if (rb_ary_includes(keys, key)) { 3274 rb_ary_delete(keys, key); 3275 } 3276 return ST_CONTINUE; 3277} 3278 3279/* 3280 * call-seq: 3281 * ENV.replace(hash) -> env 3282 * 3283 * Replaces the contents of the environment variables with the contents of 3284 * +hash+. 3285 */ 3286static VALUE 3287env_replace(VALUE env, VALUE hash) 3288{ 3289 volatile VALUE keys; 3290 long i; 3291 3292 keys = env_keys(); /* rb_secure(4); */ 3293 if (env == hash) return env; 3294 hash = to_hash(hash); 3295 rb_hash_foreach(hash, env_replace_i, keys); 3296 3297 for (i=0; i<RARRAY_LEN(keys); i++) { 3298 env_delete(env, RARRAY_PTR(keys)[i]); 3299 } 3300 return env; 3301} 3302 3303static int 3304env_update_i(VALUE key, VALUE val) 3305{ 3306 if (rb_block_given_p()) { 3307 val = rb_yield_values(3, key, rb_f_getenv(Qnil, key), val); 3308 } 3309 env_aset(Qnil, key, val); 3310 return ST_CONTINUE; 3311} 3312 3313/* 3314 * call-seq: 3315 * ENV.update(hash) -> Hash 3316 * ENV.update(hash) { |name, old_value, new_value| } -> Hash 3317 * 3318 * Adds the contents of +hash+ to the environment variables. If no block is 3319 * specified entries with duplicate keys are overwritten, otherwise the value 3320 * of each duplicate name is determined by calling the block with the key, its 3321 * value from the environment and its value from the hash. 3322 */ 3323static VALUE 3324env_update(VALUE env, VALUE hash) 3325{ 3326 rb_secure(4); 3327 if (env == hash) return env; 3328 hash = to_hash(hash); 3329 rb_hash_foreach(hash, env_update_i, 0); 3330 return env; 3331} 3332 3333/* 3334 * A Hash is a dictionary-like collection of unique keys and their values. 3335 * Also called associative arrays, they are similar to Arrays, but where an 3336 * Array uses integers as its index, a Hash allows you to use any object 3337 * type. 3338 * 3339 * Hashes enumerate their values in the order that the corresponding keys 3340 * were inserted. 3341 * 3342 * A Hash can be easily created by using its implicit form: 3343 * 3344 * grades = { "Jane Doe" => 10, "Jim Doe" => 6 } 3345 * 3346 * Hashes allow an alternate syntax form when your keys are always symbols. 3347 * Instead of 3348 * 3349 * options = { :font_size => 10, :font_family => "Arial" } 3350 * 3351 * You could write it as: 3352 * 3353 * options = { font_size: 10, font_family: "Arial" } 3354 * 3355 * Each named key is a symbol you can access in hash: 3356 * 3357 * options[:font_size] # => 10 3358 * 3359 * A Hash can also be created through its ::new method: 3360 * 3361 * grades = Hash.new 3362 * grades["Dorothy Doe"] = 9 3363 * 3364 * Hashes have a <em>default value</em> that is returned when accessing 3365 * keys that do not exist in the hash. If no default is set +nil+ is used. 3366 * You can set the default value by sending it as an argument to Hash.new: 3367 * 3368 * grades = Hash.new(0) 3369 * 3370 * Or by using the #default= method: 3371 * 3372 * grades = {"Timmy Doe" => 8} 3373 * grades.default = 0 3374 * 3375 * Accessing a value in a Hash requires using its key: 3376 * 3377 * puts grades["Jane Doe"] # => 10 3378 * 3379 * === Common Uses 3380 * 3381 * Hashes are an easy way to represent data structures, such as 3382 * 3383 * books = {} 3384 * books[:matz] = "The Ruby Language" 3385 * books[:black] = "The Well-Grounded Rubyist" 3386 * 3387 * Hashes are also commonly used as a way to have named parameters in 3388 * functions. Note that no brackets are used below. If a hash is the last 3389 * argument on a method call, no braces are needed, thus creating a really 3390 * clean interface: 3391 * 3392 * Person.create(name: "John Doe", age: 27) 3393 * 3394 * def self.create(params) 3395 * @name = params[:name] 3396 * @age = params[:age] 3397 * end 3398 * 3399 * === Hash Keys 3400 * 3401 * Two objects refer to the same hash key when their <code>hash</code> value 3402 * is identical and the two objects are <code>eql?</code> to each other. 3403 * 3404 * A user-defined class may be used as a hash key if the <code>hash</code> 3405 * and <code>eql?</code> methods are overridden to provide meaningful 3406 * behavior. By default, separate instances refer to separate hash keys. 3407 * 3408 * A typical implementation of <code>hash</code> is based on the 3409 * object's data while <code>eql?</code> is usually aliased to the overridden 3410 * <code>==</code> method: 3411 * 3412 * class Book 3413 * attr_reader :author, :title 3414 * 3415 * def initialize(author, title) 3416 * @author = author 3417 * @title = title 3418 * end 3419 * 3420 * def ==(other) 3421 * self.class === other and 3422 * other.author == @author and 3423 * other.title == @title 3424 * end 3425 * 3426 * alias eql? == 3427 * 3428 * def hash 3429 * @author.hash ^ @title.hash # XOR 3430 * end 3431 * end 3432 * 3433 * book1 = Book.new 'matz', 'Ruby in a Nutshell' 3434 * book2 = Book.new 'matz', 'Ruby in a Nutshell' 3435 * 3436 * reviews = {} 3437 * 3438 * reviews[book1] = 'Great reference!' 3439 * reviews[book2] = 'Nice and compact!' 3440 * 3441 * reviews.length #=> 1 3442 * 3443 * See also Object#hash and Object#eql? 3444 */ 3445 3446void 3447Init_Hash(void) 3448{ 3449#undef rb_intern 3450#define rb_intern(str) rb_intern_const(str) 3451 3452 id_hash = rb_intern("hash"); 3453 id_yield = rb_intern("yield"); 3454 id_default = rb_intern("default"); 3455 3456 rb_cHash = rb_define_class("Hash", rb_cObject); 3457 3458 rb_include_module(rb_cHash, rb_mEnumerable); 3459 3460 rb_define_alloc_func(rb_cHash, empty_hash_alloc); 3461 rb_define_singleton_method(rb_cHash, "[]", rb_hash_s_create, -1); 3462 rb_define_singleton_method(rb_cHash, "try_convert", rb_hash_s_try_convert, 1); 3463 rb_define_method(rb_cHash,"initialize", rb_hash_initialize, -1); 3464 rb_define_method(rb_cHash,"initialize_copy", rb_hash_initialize_copy, 1); 3465 rb_define_method(rb_cHash,"rehash", rb_hash_rehash, 0); 3466 3467 rb_define_method(rb_cHash,"to_hash", rb_hash_to_hash, 0); 3468 rb_define_method(rb_cHash,"to_h", rb_hash_to_h, 0); 3469 rb_define_method(rb_cHash,"to_a", rb_hash_to_a, 0); 3470 rb_define_method(rb_cHash,"inspect", rb_hash_inspect, 0); 3471 rb_define_alias(rb_cHash, "to_s", "inspect"); 3472 3473 rb_define_method(rb_cHash,"==", rb_hash_equal, 1); 3474 rb_define_method(rb_cHash,"[]", rb_hash_aref, 1); 3475 rb_define_method(rb_cHash,"hash", rb_hash_hash, 0); 3476 rb_define_method(rb_cHash,"eql?", rb_hash_eql, 1); 3477 rb_define_method(rb_cHash,"fetch", rb_hash_fetch_m, -1); 3478 rb_define_method(rb_cHash,"[]=", rb_hash_aset, 2); 3479 rb_define_method(rb_cHash,"store", rb_hash_aset, 2); 3480 rb_define_method(rb_cHash,"default", rb_hash_default, -1); 3481 rb_define_method(rb_cHash,"default=", rb_hash_set_default, 1); 3482 rb_define_method(rb_cHash,"default_proc", rb_hash_default_proc, 0); 3483 rb_define_method(rb_cHash,"default_proc=", rb_hash_set_default_proc, 1); 3484 rb_define_method(rb_cHash,"key", rb_hash_key, 1); 3485 rb_define_method(rb_cHash,"index", rb_hash_index, 1); 3486 rb_define_method(rb_cHash,"size", rb_hash_size, 0); 3487 rb_define_method(rb_cHash,"length", rb_hash_size, 0); 3488 rb_define_method(rb_cHash,"empty?", rb_hash_empty_p, 0); 3489 3490 rb_define_method(rb_cHash,"each_value", rb_hash_each_value, 0); 3491 rb_define_method(rb_cHash,"each_key", rb_hash_each_key, 0); 3492 rb_define_method(rb_cHash,"each_pair", rb_hash_each_pair, 0); 3493 rb_define_method(rb_cHash,"each", rb_hash_each_pair, 0); 3494 3495 rb_define_method(rb_cHash,"keys", rb_hash_keys, 0); 3496 rb_define_method(rb_cHash,"values", rb_hash_values, 0); 3497 rb_define_method(rb_cHash,"values_at", rb_hash_values_at, -1); 3498 3499 rb_define_method(rb_cHash,"shift", rb_hash_shift, 0); 3500 rb_define_method(rb_cHash,"delete", rb_hash_delete, 1); 3501 rb_define_method(rb_cHash,"delete_if", rb_hash_delete_if, 0); 3502 rb_define_method(rb_cHash,"keep_if", rb_hash_keep_if, 0); 3503 rb_define_method(rb_cHash,"select", rb_hash_select, 0); 3504 rb_define_method(rb_cHash,"select!", rb_hash_select_bang, 0); 3505 rb_define_method(rb_cHash,"reject", rb_hash_reject, 0); 3506 rb_define_method(rb_cHash,"reject!", rb_hash_reject_bang, 0); 3507 rb_define_method(rb_cHash,"clear", rb_hash_clear, 0); 3508 rb_define_method(rb_cHash,"invert", rb_hash_invert, 0); 3509 rb_define_method(rb_cHash,"update", rb_hash_update, 1); 3510 rb_define_method(rb_cHash,"replace", rb_hash_replace, 1); 3511 rb_define_method(rb_cHash,"merge!", rb_hash_update, 1); 3512 rb_define_method(rb_cHash,"merge", rb_hash_merge, 1); 3513 rb_define_method(rb_cHash, "assoc", rb_hash_assoc, 1); 3514 rb_define_method(rb_cHash, "rassoc", rb_hash_rassoc, 1); 3515 rb_define_method(rb_cHash, "flatten", rb_hash_flatten, -1); 3516 3517 rb_define_method(rb_cHash,"include?", rb_hash_has_key, 1); 3518 rb_define_method(rb_cHash,"member?", rb_hash_has_key, 1); 3519 rb_define_method(rb_cHash,"has_key?", rb_hash_has_key, 1); 3520 rb_define_method(rb_cHash,"has_value?", rb_hash_has_value, 1); 3521 rb_define_method(rb_cHash,"key?", rb_hash_has_key, 1); 3522 rb_define_method(rb_cHash,"value?", rb_hash_has_value, 1); 3523 3524 rb_define_method(rb_cHash,"compare_by_identity", rb_hash_compare_by_id, 0); 3525 rb_define_method(rb_cHash,"compare_by_identity?", rb_hash_compare_by_id_p, 0); 3526 3527 /* Document-class: ENV 3528 * 3529 * ENV is a hash-like accessor for environment variables. 3530 */ 3531 3532 /* 3533 * Hack to get RDoc to regard ENV as a class: 3534 * envtbl = rb_define_class("ENV", rb_cObject); 3535 */ 3536 origenviron = environ; 3537 envtbl = rb_obj_alloc(rb_cObject); 3538 rb_extend_object(envtbl, rb_mEnumerable); 3539 3540 rb_define_singleton_method(envtbl,"[]", rb_f_getenv, 1); 3541 rb_define_singleton_method(envtbl,"fetch", env_fetch, -1); 3542 rb_define_singleton_method(envtbl,"[]=", env_aset, 2); 3543 rb_define_singleton_method(envtbl,"store", env_aset, 2); 3544 rb_define_singleton_method(envtbl,"each", env_each_pair, 0); 3545 rb_define_singleton_method(envtbl,"each_pair", env_each_pair, 0); 3546 rb_define_singleton_method(envtbl,"each_key", env_each_key, 0); 3547 rb_define_singleton_method(envtbl,"each_value", env_each_value, 0); 3548 rb_define_singleton_method(envtbl,"delete", env_delete_m, 1); 3549 rb_define_singleton_method(envtbl,"delete_if", env_delete_if, 0); 3550 rb_define_singleton_method(envtbl,"keep_if", env_keep_if, 0); 3551 rb_define_singleton_method(envtbl,"clear", rb_env_clear, 0); 3552 rb_define_singleton_method(envtbl,"reject", env_reject, 0); 3553 rb_define_singleton_method(envtbl,"reject!", env_reject_bang, 0); 3554 rb_define_singleton_method(envtbl,"select", env_select, 0); 3555 rb_define_singleton_method(envtbl,"select!", env_select_bang, 0); 3556 rb_define_singleton_method(envtbl,"shift", env_shift, 0); 3557 rb_define_singleton_method(envtbl,"invert", env_invert, 0); 3558 rb_define_singleton_method(envtbl,"replace", env_replace, 1); 3559 rb_define_singleton_method(envtbl,"update", env_update, 1); 3560 rb_define_singleton_method(envtbl,"inspect", env_inspect, 0); 3561 rb_define_singleton_method(envtbl,"rehash", env_none, 0); 3562 rb_define_singleton_method(envtbl,"to_a", env_to_a, 0); 3563 rb_define_singleton_method(envtbl,"to_s", env_to_s, 0); 3564 rb_define_singleton_method(envtbl,"key", env_key, 1); 3565 rb_define_singleton_method(envtbl,"index", env_index, 1); 3566 rb_define_singleton_method(envtbl,"size", env_size, 0); 3567 rb_define_singleton_method(envtbl,"length", env_size, 0); 3568 rb_define_singleton_method(envtbl,"empty?", env_empty_p, 0); 3569 rb_define_singleton_method(envtbl,"keys", env_keys, 0); 3570 rb_define_singleton_method(envtbl,"values", env_values, 0); 3571 rb_define_singleton_method(envtbl,"values_at", env_values_at, -1); 3572 rb_define_singleton_method(envtbl,"include?", env_has_key, 1); 3573 rb_define_singleton_method(envtbl,"member?", env_has_key, 1); 3574 rb_define_singleton_method(envtbl,"has_key?", env_has_key, 1); 3575 rb_define_singleton_method(envtbl,"has_value?", env_has_value, 1); 3576 rb_define_singleton_method(envtbl,"key?", env_has_key, 1); 3577 rb_define_singleton_method(envtbl,"value?", env_has_value, 1); 3578 rb_define_singleton_method(envtbl,"to_hash", env_to_hash, 0); 3579 rb_define_singleton_method(envtbl,"to_h", env_to_hash, 0); 3580 rb_define_singleton_method(envtbl,"assoc", env_assoc, 1); 3581 rb_define_singleton_method(envtbl,"rassoc", env_rassoc, 1); 3582 3583 /* 3584 * ENV is a Hash-like accessor for environment variables. 3585 * 3586 * See ENV (the class) for more details. 3587 */ 3588 rb_define_global_const("ENV", envtbl); 3589} 3590