Ruby  2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)
hash.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  hash.c -
4 
5  $Author$
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/encoding.h"
15 #include "ruby/st.h"
16 #include "ruby/util.h"
17 #include "internal.h"
18 #include <errno.h>
19 #include "probes.h"
20 #include "id.h"
21 #include "symbol.h"
22 #include "debug_counter.h"
23 #include "transient_heap.h"
24 #include "ruby_assert.h"
25 #ifdef __APPLE__
26 # ifdef HAVE_CRT_EXTERNS_H
27 # include <crt_externs.h>
28 # else
29 # include "missing/crt_externs.h"
30 # endif
31 #endif
32 
33 #ifndef HASH_DEBUG
34 #define HASH_DEBUG 0
35 #endif
36 
37 #if HASH_DEBUG
38 #include "gc.h"
39 #endif
40 
41 #define HAS_EXTRA_STATES(hash, klass) ( \
42  ((klass = has_extra_methods(rb_obj_class(hash))) != 0) || \
43  FL_TEST((hash), FL_EXIVAR|RHASH_PROC_DEFAULT) || \
44  !NIL_P(RHASH_IFNONE(hash)))
45 
46 #define SET_DEFAULT(hash, ifnone) ( \
47  FL_UNSET_RAW(hash, RHASH_PROC_DEFAULT), \
48  RHASH_SET_IFNONE(hash, ifnone))
49 
50 #define SET_PROC_DEFAULT(hash, proc) set_proc_default(hash, proc)
51 
52 #define COPY_DEFAULT(hash, hash2) copy_default(RHASH(hash), RHASH(hash2))
53 
54 static inline void
55 copy_default(struct RHash *hash, const struct RHash *hash2)
56 {
57  hash->basic.flags &= ~RHASH_PROC_DEFAULT;
58  hash->basic.flags |= hash2->basic.flags & RHASH_PROC_DEFAULT;
59  RHASH_SET_IFNONE(hash, RHASH_IFNONE(hash2));
60 }
61 
62 static VALUE
63 has_extra_methods(VALUE klass)
64 {
65  const VALUE base = rb_cHash;
66  VALUE c = klass;
67  while (c != base) {
68  if (rb_class_has_methods(c)) return klass;
69  c = RCLASS_SUPER(c);
70  }
71  return 0;
72 }
73 
74 static VALUE rb_hash_s_try_convert(VALUE, VALUE);
75 
76 /*
77  * Hash WB strategy:
78  * 1. Check mutate st_* functions
79  * * st_insert()
80  * * st_insert2()
81  * * st_update()
82  * * st_add_direct()
83  * 2. Insert WBs
84  */
85 
86 VALUE
88 {
89  return rb_obj_freeze(hash);
90 }
91 
93 
94 static VALUE envtbl;
95 static ID id_hash, id_yield, id_default, id_flatten_bang;
96 static ID id_hash_iter_lev;
97 
98 VALUE
100 {
101  RB_OBJ_WRITE(hash, (&RHASH(hash)->ifnone), ifnone);
102  return hash;
103 }
104 
105 static int
106 rb_any_cmp(VALUE a, VALUE b)
107 {
108  if (a == b) return 0;
109  if (RB_TYPE_P(a, T_STRING) && RBASIC(a)->klass == rb_cString &&
110  RB_TYPE_P(b, T_STRING) && RBASIC(b)->klass == rb_cString) {
111  return rb_str_hash_cmp(a, b);
112  }
113  if (a == Qundef || b == Qundef) return -1;
114  if (SYMBOL_P(a) && SYMBOL_P(b)) {
115  return a != b;
116  }
117 
118  return !rb_eql(a, b);
119 }
120 
121 static VALUE
122 hash_recursive(VALUE obj, VALUE arg, int recurse)
123 {
124  if (recurse) return INT2FIX(0);
125  return rb_funcallv(obj, id_hash, 0, 0);
126 }
127 
128 VALUE
130 {
131  VALUE hval = rb_exec_recursive_outer(hash_recursive, obj, 0);
132 
133  while (!FIXNUM_P(hval)) {
134  if (RB_TYPE_P(hval, T_BIGNUM)) {
135  int sign;
136  unsigned long ul;
137  sign = rb_integer_pack(hval, &ul, 1, sizeof(ul), 0,
139  ul &= (1UL << (sizeof(long)*CHAR_BIT-1)) - 1;
140  if (sign < 0)
141  return LONG2FIX(-(long)ul);
142  return LONG2FIX((long)ul);
143  }
144  hval = rb_to_int(hval);
145  }
146  return hval;
147 }
148 
149 static long rb_objid_hash(st_index_t index);
150 
151 static st_index_t
152 dbl_to_index(double d)
153 {
154  union {double d; st_index_t i;} u;
155  u.d = d;
156  return u.i;
157 }
158 
159 long
161 {
162  /* normalize -0.0 to 0.0 */
163  if (d == 0.0) d = 0.0;
164 #if SIZEOF_INT == SIZEOF_VOIDP
165  return rb_memhash(&d, sizeof(d));
166 #else
167  return rb_objid_hash(dbl_to_index(d));
168 #endif
169 }
170 
171 static inline long
172 any_hash(VALUE a, st_index_t (*other_func)(VALUE))
173 {
174  VALUE hval;
175  st_index_t hnum;
176 
177  if (SPECIAL_CONST_P(a)) {
178  if (STATIC_SYM_P(a)) {
179  hnum = a >> (RUBY_SPECIAL_SHIFT + ID_SCOPE_SHIFT);
180  hnum = rb_hash_start(hnum);
181  goto out;
182  }
183  else if (FLONUM_P(a)) {
184  /* prevent pathological behavior: [Bug #10761] */
185  goto flt;
186  }
187  hnum = rb_objid_hash((st_index_t)a);
188  }
189  else if (BUILTIN_TYPE(a) == T_STRING) {
190  hnum = rb_str_hash(a);
191  }
192  else if (BUILTIN_TYPE(a) == T_SYMBOL) {
193  hnum = RSYMBOL(a)->hashval;
194  }
195  else if (BUILTIN_TYPE(a) == T_BIGNUM) {
196  hval = rb_big_hash(a);
197  hnum = FIX2LONG(hval);
198  }
199  else if (BUILTIN_TYPE(a) == T_FLOAT) {
200  flt:
201  hnum = rb_dbl_long_hash(rb_float_value(a));
202  }
203  else {
204  hnum = other_func(a);
205  }
206  out:
207 #if SIZEOF_LONG < SIZEOF_ST_INDEX_T
208  if (hnum > 0)
209  hnum &= (unsigned long)-1 >> 2;
210  else
211  hnum |= ~((unsigned long)-1 >> 2);
212 #else
213  hnum <<= 1;
214  hnum = RSHIFT(hnum, 1);
215 #endif
216  return (long)hnum;
217 }
218 
219 static st_index_t
220 obj_any_hash(VALUE obj)
221 {
222  obj = rb_hash(obj);
223  return FIX2LONG(obj);
224 }
225 
226 static st_index_t
227 rb_any_hash(VALUE a)
228 {
229  return any_hash(a, obj_any_hash);
230 }
231 
232 /* Here is a hash function for 64-bit key. It is about 5 times faster
233  (2 times faster when uint128 type is absent) on Haswell than
234  tailored Spooky or City hash function can be. */
235 
236 /* Here we two primes with random bit generation. */
237 static const uint64_t prime1 = ((uint64_t)0x2e0bb864 << 32) | 0xe9ea7df5;
238 static const uint32_t prime2 = 0x830fcab9;
239 
240 
241 static inline uint64_t
242 mult_and_mix(uint64_t m1, uint64_t m2)
243 {
244 #if defined HAVE_UINT128_T
245  uint128_t r = (uint128_t) m1 * (uint128_t) m2;
246  return (uint64_t) (r >> 64) ^ (uint64_t) r;
247 #else
248  uint64_t hm1 = m1 >> 32, hm2 = m2 >> 32;
249  uint64_t lm1 = m1, lm2 = m2;
250  uint64_t v64_128 = hm1 * hm2;
251  uint64_t v32_96 = hm1 * lm2 + lm1 * hm2;
252  uint64_t v1_32 = lm1 * lm2;
253 
254  return (v64_128 + (v32_96 >> 32)) ^ ((v32_96 << 32) + v1_32);
255 #endif
256 }
257 
258 static inline uint64_t
259 key64_hash(uint64_t key, uint32_t seed)
260 {
261  return mult_and_mix(key + seed, prime1);
262 }
263 
264 /* Should cast down the result for each purpose */
265 #define st_index_hash(index) key64_hash(rb_hash_start(index), prime2)
266 
267 static long
268 rb_objid_hash(st_index_t index)
269 {
270  return (long)st_index_hash(index);
271 }
272 
273 static st_index_t
274 objid_hash(VALUE obj)
275 {
277  if (!FIXNUM_P(object_id))
279 
280 #if SIZEOF_LONG == SIZEOF_VOIDP
282 #elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
284 #endif
285 }
286 
290 VALUE
292 {
293  long hnum = any_hash(obj, objid_hash);
294  return ST2FIX(hnum);
295 }
296 
297 static const struct st_hash_type objhash = {
298  rb_any_cmp,
299  rb_any_hash,
300 };
301 
302 #define rb_ident_cmp st_numcmp
303 
304 static st_index_t
305 rb_ident_hash(st_data_t n)
306 {
307 #ifdef USE_FLONUM /* RUBY */
308  /*
309  * - flonum (on 64-bit) is pathologically bad, mix the actual
310  * float value in, but do not use the float value as-is since
311  * many integers get interpreted as 2.0 or -2.0 [Bug #10761]
312  */
313  if (FLONUM_P(n)) {
314  n ^= dbl_to_index(rb_float_value(n));
315  }
316 #endif
317 
319 }
320 
321 #define identhash rb_hashtype_ident
323  rb_ident_cmp,
324  rb_ident_hash,
325 };
326 
328 
329 /*
330  * RHASH_AR_TABLE_P(h):
331  * * as.ar == NULL or
332  * as.ar points ar_table.
333  * * as.ar is allocated by transient heap or xmalloc.
334  *
335  * !RHASH_AR_TABLE_P(h):
336  * * as.st points st_table.
337  */
338 
339 #define RHASH_AR_TABLE_MAX_BOUND RHASH_AR_TABLE_MAX_SIZE
340 
341 #define RHASH_AR_TABLE_REF(hash, n) (&RHASH_AR_TABLE(hash)->pairs[n])
342 #define RHASH_AR_CLEARED_HINT 0xff
343 
344 typedef struct ar_table_pair_struct {
347 } ar_table_pair;
348 
349 typedef struct ar_table_struct {
350  /* 64bit CPU: 8B * 2 * 8 = 128B */
352 } ar_table;
353 
354 size_t
356 {
357  return sizeof(ar_table);
358 }
359 
360 static inline st_hash_t
361 ar_do_hash(st_data_t key)
362 {
363  return (st_hash_t)rb_any_hash(key);
364 }
365 
366 static inline ar_hint_t
367 ar_do_hash_hint(st_hash_t hash_value)
368 {
369  return (ar_hint_t)hash_value;
370 }
371 
372 static inline ar_hint_t
373 ar_hint(VALUE hash, unsigned int index)
374 {
375  return RHASH(hash)->ar_hint.ary[index];
376 }
377 
378 static inline void
379 ar_hint_set_hint(VALUE hash, unsigned int index, ar_hint_t hint)
380 {
381  RHASH(hash)->ar_hint.ary[index] = hint;
382 }
383 
384 static inline void
385 ar_hint_set(VALUE hash, unsigned int index, st_hash_t hash_value)
386 {
387  ar_hint_set_hint(hash, index, ar_do_hash_hint(hash_value));
388 }
389 
390 static inline void
391 ar_clear_entry(VALUE hash, unsigned int index)
392 {
393  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, index);
394  pair->key = Qundef;
395  ar_hint_set_hint(hash, index, RHASH_AR_CLEARED_HINT);
396 }
397 
398 static inline int
399 ar_cleared_entry(VALUE hash, unsigned int index)
400 {
401  if (ar_hint(hash, index) == RHASH_AR_CLEARED_HINT) {
402  /* RHASH_AR_CLEARED_HINT is only a hint, not mean cleared entry,
403  * so you need to check key == Qundef
404  */
405  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, index);
406  return pair->key == Qundef;
407  }
408  else {
409  return FALSE;
410  }
411 }
412 
413 static inline void
414 ar_set_entry(VALUE hash, unsigned int index, st_data_t key, st_data_t val, st_hash_t hash_value)
415 {
416  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, index);
417  pair->key = key;
418  pair->val = val;
419  ar_hint_set(hash, index, hash_value);
420 }
421 
422 #define RHASH_AR_TABLE_SIZE(h) (HASH_ASSERT(RHASH_AR_TABLE_P(h)), \
423  RHASH_AR_TABLE_SIZE_RAW(h))
424 
425 #define RHASH_AR_TABLE_BOUND_RAW(h) \
426  ((unsigned int)((RBASIC(h)->flags >> RHASH_AR_TABLE_BOUND_SHIFT) & \
427  (RHASH_AR_TABLE_BOUND_MASK >> RHASH_AR_TABLE_BOUND_SHIFT)))
428 
429 #define RHASH_AR_TABLE_BOUND(h) (HASH_ASSERT(RHASH_AR_TABLE_P(h)), \
430  RHASH_AR_TABLE_BOUND_RAW(h))
431 
432 #define RHASH_ST_TABLE_SET(h, s) rb_hash_st_table_set(h, s)
433 #define RHASH_TYPE(hash) (RHASH_AR_TABLE_P(hash) ? &objhash : RHASH_ST_TABLE(hash)->type)
434 
435 #define HASH_ASSERT(expr) RUBY_ASSERT_MESG_WHEN(HASH_DEBUG, expr, #expr)
436 
437 #if HASH_DEBUG
438 #define hash_verify(hash) hash_verify_(hash, __FILE__, __LINE__)
439 
440 void
441 rb_hash_dump(VALUE hash)
442 {
443  rb_obj_info_dump(hash);
444 
445  if (RHASH_AR_TABLE_P(hash)) {
446  unsigned i, n = 0, bound = RHASH_AR_TABLE_BOUND(hash);
447 
448  fprintf(stderr, " size:%u bound:%u\n",
450 
451  for (i=0; i<bound; i++) {
452  st_data_t k, v;
453 
454  if (!ar_cleared_entry(hash, i)) {
455  char b1[0x100], b2[0x100];
456  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
457  k = pair->key;
458  v = pair->val;
459  fprintf(stderr, " %d key:%s val:%s hint:%02x\n", i,
460  rb_raw_obj_info(b1, 0x100, k),
461  rb_raw_obj_info(b2, 0x100, v),
462  ar_hint(hash, i));
463  n++;
464  }
465  else {
466  fprintf(stderr, " %d empty\n", i);
467  }
468  }
469  }
470 }
471 
472 static VALUE
473 hash_verify_(VALUE hash, const char *file, int line)
474 {
475  HASH_ASSERT(RB_TYPE_P(hash, T_HASH));
476 
477  if (RHASH_AR_TABLE_P(hash)) {
478  unsigned i, n = 0, bound = RHASH_AR_TABLE_BOUND(hash);
479 
480  for (i=0; i<bound; i++) {
481  st_data_t k, v;
482  if (!ar_cleared_entry(hash, i)) {
483  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
484  k = pair->key;
485  v = pair->val;
486  HASH_ASSERT(k != Qundef);
487  HASH_ASSERT(v != Qundef);
488  n++;
489  }
490  }
491  if (n != RHASH_AR_TABLE_SIZE(hash)) {
492  rb_bug("n:%u, RHASH_AR_TABLE_SIZE:%u", n, RHASH_AR_TABLE_SIZE(hash));
493  }
494  }
495  else {
496  HASH_ASSERT(RHASH_ST_TABLE(hash) != NULL);
499  }
500 
501  if (RHASH_TRANSIENT_P(hash)) {
502  volatile st_data_t MAYBE_UNUSED(key) = RHASH_AR_TABLE_REF(hash, 0)->key; /* read */
503  HASH_ASSERT(RHASH_AR_TABLE(hash) != NULL);
505  }
506  return hash;
507 }
508 
509 #else
510 #define hash_verify(h) ((void)0)
511 #endif
512 
513 static inline int
514 RHASH_TABLE_NULL_P(VALUE hash)
515 {
516  if (RHASH(hash)->as.ar == NULL) {
518  return TRUE;
519  }
520  else {
521  return FALSE;
522  }
523 }
524 
525 static inline int
526 RHASH_TABLE_EMPTY_P(VALUE hash)
527 {
528  return RHASH_SIZE(hash) == 0;
529 }
530 
531 int
533 {
534  if (FL_TEST_RAW((hash), RHASH_ST_TABLE_FLAG)) {
535  HASH_ASSERT(RHASH(hash)->as.st != NULL);
536  return FALSE;
537  }
538  else {
539  return TRUE;
540  }
541 }
542 
543 ar_table *
545 {
547  return RHASH(hash)->as.ar;
548 }
549 
550 st_table *
552 {
554  return RHASH(hash)->as.st;
555 }
556 
557 void
559 {
560  HASH_ASSERT(st != NULL);
562  RHASH(hash)->as.st = st;
563 }
564 
565 static void
566 hash_ar_table_set(VALUE hash, ar_table *ar)
567 {
569  HASH_ASSERT((RHASH_TRANSIENT_P(hash) && ar == NULL) ? FALSE : TRUE);
570  RHASH(hash)->as.ar = ar;
571  hash_verify(hash);
572 }
573 
574 #define RHASH_SET_ST_FLAG(h) FL_SET_RAW(h, RHASH_ST_TABLE_FLAG)
575 #define RHASH_UNSET_ST_FLAG(h) FL_UNSET_RAW(h, RHASH_ST_TABLE_FLAG)
576 
577 static inline void
578 RHASH_AR_TABLE_BOUND_SET(VALUE h, st_index_t n)
579 {
582 
583  RBASIC(h)->flags &= ~RHASH_AR_TABLE_BOUND_MASK;
584  RBASIC(h)->flags |= n << RHASH_AR_TABLE_BOUND_SHIFT;
585 }
586 
587 static inline void
588 RHASH_AR_TABLE_SIZE_SET(VALUE h, st_index_t n)
589 {
592 
593  RBASIC(h)->flags &= ~RHASH_AR_TABLE_SIZE_MASK;
594  RBASIC(h)->flags |= n << RHASH_AR_TABLE_SIZE_SHIFT;
595 }
596 
597 static inline void
598 HASH_AR_TABLE_SIZE_ADD(VALUE h, st_index_t n)
599 {
601 
602  RHASH_AR_TABLE_SIZE_SET(h, RHASH_AR_TABLE_SIZE(h) + n);
603 
604  hash_verify(h);
605 }
606 
607 #define RHASH_AR_TABLE_SIZE_INC(h) HASH_AR_TABLE_SIZE_ADD(h, 1)
608 
609 static inline void
610 RHASH_AR_TABLE_SIZE_DEC(VALUE h)
611 {
613  int new_size = RHASH_AR_TABLE_SIZE(h) - 1;
614 
615  if (new_size != 0) {
616  RHASH_AR_TABLE_SIZE_SET(h, new_size);
617  }
618  else {
619  RHASH_AR_TABLE_SIZE_SET(h, 0);
620  RHASH_AR_TABLE_BOUND_SET(h, 0);
621  }
622  hash_verify(h);
623 }
624 
625 static inline void
626 RHASH_AR_TABLE_CLEAR(VALUE h)
627 {
628  RBASIC(h)->flags &= ~RHASH_AR_TABLE_SIZE_MASK;
629  RBASIC(h)->flags &= ~RHASH_AR_TABLE_BOUND_MASK;
630 
631  hash_ar_table_set(h, NULL);
632 }
633 
634 static ar_table*
635 ar_alloc_table(VALUE hash)
636 {
637  ar_table *tab = (ar_table*)rb_transient_heap_alloc(hash, sizeof(ar_table));
638 
639  if (tab != NULL) {
641  }
642  else {
644  tab = (ar_table*)ruby_xmalloc(sizeof(ar_table));
645  }
646 
647  RHASH_AR_TABLE_SIZE_SET(hash, 0);
648  RHASH_AR_TABLE_BOUND_SET(hash, 0);
649  hash_ar_table_set(hash, tab);
650 
651  return tab;
652 }
653 
654 NOINLINE(static int ar_equal(VALUE x, VALUE y));
655 
656 static int
657 ar_equal(VALUE x, VALUE y)
658 {
659  return rb_any_cmp(x, y) == 0;
660 }
661 
662 static unsigned
663 ar_find_entry_hint(VALUE hash, ar_hint_t hint, st_data_t key)
664 {
665  unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
666  const ar_hint_t *hints = RHASH(hash)->ar_hint.ary;
667 
668  /* if table is NULL, then bound also should be 0 */
669 
670  for (i = 0; i < bound; i++) {
671  if (hints[i] == hint) {
672  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
673  if (ar_equal(key, pair->key)) {
674  RB_DEBUG_COUNTER_INC(artable_hint_hit);
675  return i;
676  }
677  else {
678 #if 0
679  static int pid;
680  static char fname[256];
681  static FILE *fp;
682 
683  if (pid != getpid()) {
684  snprintf(fname, sizeof(fname), "/tmp/ruby-armiss.%d", pid = getpid());
685  if ((fp = fopen(fname, "w")) == NULL) rb_bug("fopen");
686  }
687 
688  st_hash_t h1 = ar_do_hash(key);
689  st_hash_t h2 = ar_do_hash(pair->key);
690 
691  fprintf(fp, "miss: hash_eq:%d hints[%d]:%02x hint:%02x\n"
692  " key :%016lx %s\n"
693  " pair->key:%016lx %s\n",
694  h1 == h2, i, hints[i], hint,
695  h1, rb_obj_info(key), h2, rb_obj_info(pair->key));
696 #endif
697  RB_DEBUG_COUNTER_INC(artable_hint_miss);
698  }
699  }
700  }
701  RB_DEBUG_COUNTER_INC(artable_hint_notfound);
703 }
704 
705 static unsigned
706 ar_find_entry(VALUE hash, st_hash_t hash_value, st_data_t key)
707 {
708  ar_hint_t hint = ar_do_hash_hint(hash_value);
709  return ar_find_entry_hint(hash, hint, key);
710 }
711 
712 static inline void
713 ar_free_and_clear_table(VALUE hash)
714 {
715  ar_table *tab = RHASH_AR_TABLE(hash);
716 
717  if (tab) {
718  if (RHASH_TRANSIENT_P(hash)) {
720  }
721  else {
722  ruby_xfree(RHASH_AR_TABLE(hash));
723  }
724  RHASH_AR_TABLE_CLEAR(hash);
725  }
726  HASH_ASSERT(RHASH_AR_TABLE_SIZE(hash) == 0);
727  HASH_ASSERT(RHASH_AR_TABLE_BOUND(hash) == 0);
728  HASH_ASSERT(RHASH_TRANSIENT_P(hash) == 0);
729 }
730 
731 static void
732 ar_try_convert_table(VALUE hash)
733 {
734  st_table *new_tab;
735  const unsigned size = RHASH_AR_TABLE_SIZE(hash);
736  st_index_t i;
737 
739  return;
740  }
741 
742  new_tab = st_init_table_with_size(&objhash, size * 2);
743 
744  for (i = 0; i < RHASH_AR_TABLE_MAX_BOUND; i++) {
745  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
746  st_add_direct(new_tab, pair->key, pair->val);
747  }
748  ar_free_and_clear_table(hash);
749  RHASH_ST_TABLE_SET(hash, new_tab);
750  return;
751 }
752 
753 static st_table *
754 ar_force_convert_table(VALUE hash, const char *file, int line)
755 {
756  st_table *new_tab;
757 
758  if (RHASH_ST_TABLE_P(hash)) {
759  return RHASH_ST_TABLE(hash);
760  }
761 
762  if (RHASH_AR_TABLE(hash)) {
763  unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
764 
765 #if RHASH_CONVERT_TABLE_DEBUG
766  rb_obj_info_dump(hash);
767  fprintf(stderr, "force_convert: %s:%d\n", file, line);
768  RB_DEBUG_COUNTER_INC(obj_hash_force_convert);
769 #endif
770 
771  new_tab = st_init_table_with_size(&objhash, RHASH_AR_TABLE_SIZE(hash));
772 
773  for (i = 0; i < bound; i++) {
774  if (ar_cleared_entry(hash, i)) continue;
775 
776  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
777  st_add_direct(new_tab, pair->key, pair->val);
778  }
779  ar_free_and_clear_table(hash);
780  }
781  else {
782  new_tab = st_init_table(&objhash);
783  }
784  RHASH_ST_TABLE_SET(hash, new_tab);
785 
786  return new_tab;
787 }
788 
789 static ar_table *
790 hash_ar_table(VALUE hash)
791 {
792  if (RHASH_TABLE_NULL_P(hash)) {
793  ar_alloc_table(hash);
794  }
795  return RHASH_AR_TABLE(hash);
796 }
797 
798 static int
799 ar_compact_table(VALUE hash)
800 {
801  const unsigned bound = RHASH_AR_TABLE_BOUND(hash);
802  const unsigned size = RHASH_AR_TABLE_SIZE(hash);
803 
804  if (size == bound) {
805  return size;
806  }
807  else {
808  unsigned i, j=0;
809  ar_table_pair *pairs = RHASH_AR_TABLE(hash)->pairs;
810 
811  for (i=0; i<bound; i++) {
812  if (ar_cleared_entry(hash, i)) {
813  if (j <= i) j = i+1;
814  for (; j<bound; j++) {
815  if (!ar_cleared_entry(hash, j)) {
816  pairs[i] = pairs[j];
817  ar_hint_set_hint(hash, i, (st_hash_t)ar_hint(hash, j));
818  ar_clear_entry(hash, j);
819  j++;
820  goto found;
821  }
822  }
823  /* non-empty is not found */
824  goto done;
825  found:;
826  }
827  }
828  done:
829  HASH_ASSERT(i<=bound);
830 
831  RHASH_AR_TABLE_BOUND_SET(hash, size);
832  hash_verify(hash);
833  return size;
834  }
835 }
836 
837 static int
838 ar_add_direct_with_hash(VALUE hash, st_data_t key, st_data_t val, st_hash_t hash_value)
839 {
840  unsigned bin = RHASH_AR_TABLE_BOUND(hash);
841 
843  return 1;
844  }
845  else {
847  bin = ar_compact_table(hash);
848  hash_ar_table(hash);
849  }
851 
852  ar_set_entry(hash, bin, key, val, hash_value);
853  RHASH_AR_TABLE_BOUND_SET(hash, bin+1);
855  return 0;
856  }
857 }
858 
859 static int
860 ar_general_foreach(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
861 {
862  if (RHASH_AR_TABLE_SIZE(hash) > 0) {
863  unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
864 
865  for (i = 0; i < bound; i++) {
866  if (ar_cleared_entry(hash, i)) continue;
867 
868  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
869  enum st_retval retval = (*func)(pair->key, pair->val, arg, 0);
870  /* pair may be not valid here because of theap */
871 
872  switch (retval) {
873  case ST_CONTINUE:
874  break;
875  case ST_CHECK:
876  case ST_STOP:
877  return 0;
878  case ST_REPLACE:
879  if (replace) {
880  VALUE key = pair->key;
881  VALUE val = pair->val;
882  retval = (*replace)(&key, &val, arg, TRUE);
883 
884  // TODO: pair should be same as pair before.
885  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
886  pair->key = key;
887  pair->val = val;
888  }
889  break;
890  case ST_DELETE:
891  ar_clear_entry(hash, i);
892  RHASH_AR_TABLE_SIZE_DEC(hash);
893  break;
894  }
895  }
896  }
897  return 0;
898 }
899 
900 static int
901 ar_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
902 {
903  return ar_general_foreach(hash, func, replace, arg);
904 }
905 
906 struct functor {
909 };
910 
911 static int
912 apply_functor(st_data_t k, st_data_t v, st_data_t d, int _)
913 {
914  const struct functor *f = (void *)d;
915  return f->func(k, v, f->arg);
916 }
917 
918 static int
919 ar_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg)
920 {
921  const struct functor f = { func, arg };
922  return ar_general_foreach(hash, apply_functor, NULL, (st_data_t)&f);
923 }
924 
925 static int
926 ar_foreach_check(VALUE hash, st_foreach_check_callback_func *func, st_data_t arg,
927  st_data_t never)
928 {
929  if (RHASH_AR_TABLE_SIZE(hash) > 0) {
930  unsigned i, ret = 0, bound = RHASH_AR_TABLE_BOUND(hash);
931  enum st_retval retval;
932  st_data_t key;
933  ar_table_pair *pair;
934  ar_hint_t hint;
935 
936  for (i = 0; i < bound; i++) {
937  if (ar_cleared_entry(hash, i)) continue;
938 
939  pair = RHASH_AR_TABLE_REF(hash, i);
940  key = pair->key;
941  hint = ar_hint(hash, i);
942 
943  retval = (*func)(key, pair->val, arg, 0);
944  hash_verify(hash);
945 
946  switch (retval) {
947  case ST_CHECK: {
948  if (pair->key == never) break;
949  ret = ar_find_entry_hint(hash, hint, key);
950  if (ret == RHASH_AR_TABLE_MAX_BOUND) {
951  retval = (*func)(0, 0, arg, 1);
952  return 2;
953  }
954  }
955  case ST_CONTINUE:
956  break;
957  case ST_STOP:
958  case ST_REPLACE:
959  return 0;
960  case ST_DELETE: {
961  if (!ar_cleared_entry(hash, i)) {
962  ar_clear_entry(hash, i);
963  RHASH_AR_TABLE_SIZE_DEC(hash);
964  }
965  break;
966  }
967  }
968  }
969  }
970  return 0;
971 }
972 
973 static int
974 ar_update(VALUE hash, st_data_t key,
976 {
977  int retval, existing;
978  unsigned bin = RHASH_AR_TABLE_MAX_BOUND;
979  st_data_t value = 0, old_key;
980  st_hash_t hash_value = ar_do_hash(key);
981 
982  if (RHASH_AR_TABLE_SIZE(hash) > 0) {
983  bin = ar_find_entry(hash, hash_value, key);
984  existing = (bin != RHASH_AR_TABLE_MAX_BOUND) ? TRUE : FALSE;
985  }
986  else {
987  hash_ar_table(hash); /* allocate ltbl if needed */
988  existing = FALSE;
989  }
990 
991  if (existing) {
992  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, bin);
993  key = pair->key;
994  value = pair->val;
995  }
996  old_key = key;
997  retval = (*func)(&key, &value, arg, existing);
998  /* pair can be invalid here because of theap */
999 
1000  switch (retval) {
1001  case ST_CONTINUE:
1002  if (!existing) {
1003  if (ar_add_direct_with_hash(hash, key, value, hash_value)) {
1004  return -1;
1005  }
1006  }
1007  else {
1008  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, bin);
1009  if (old_key != key) {
1010  pair->key = key;
1011  }
1012  pair->val = value;
1013  }
1014  break;
1015  case ST_DELETE:
1016  if (existing) {
1017  ar_clear_entry(hash, bin);
1018  RHASH_AR_TABLE_SIZE_DEC(hash);
1019  }
1020  break;
1021  }
1022  return existing;
1023 }
1024 
1025 static int
1026 ar_insert(VALUE hash, st_data_t key, st_data_t value)
1027 {
1028  unsigned bin = RHASH_AR_TABLE_BOUND(hash);
1029  st_hash_t hash_value = ar_do_hash(key);
1030 
1031  hash_ar_table(hash); /* prepare ltbl */
1032 
1033  bin = ar_find_entry(hash, hash_value, key);
1034  if (bin == RHASH_AR_TABLE_MAX_BOUND) {
1036  return -1;
1037  }
1038  else if (bin >= RHASH_AR_TABLE_MAX_BOUND) {
1039  bin = ar_compact_table(hash);
1040  hash_ar_table(hash);
1041  }
1043 
1044  ar_set_entry(hash, bin, key, value, hash_value);
1045  RHASH_AR_TABLE_BOUND_SET(hash, bin+1);
1047  return 0;
1048  }
1049  else {
1050  RHASH_AR_TABLE_REF(hash, bin)->val = value;
1051  return 1;
1052  }
1053 }
1054 
1055 static int
1056 ar_lookup(VALUE hash, st_data_t key, st_data_t *value)
1057 {
1058  if (RHASH_AR_TABLE_SIZE(hash) == 0) {
1059  return 0;
1060  }
1061  else {
1062  st_hash_t hash_value = ar_do_hash(key);
1063  unsigned bin = ar_find_entry(hash, hash_value, key);
1064 
1065  if (bin == RHASH_AR_TABLE_MAX_BOUND) {
1066  return 0;
1067  }
1068  else {
1070  if (value != NULL) {
1071  *value = RHASH_AR_TABLE_REF(hash, bin)->val;
1072  }
1073  return 1;
1074  }
1075  }
1076 }
1077 
1078 static int
1079 ar_delete(VALUE hash, st_data_t *key, st_data_t *value)
1080 {
1081  unsigned bin;
1082  st_hash_t hash_value = ar_do_hash(*key);
1083 
1084 
1085  bin = ar_find_entry(hash, hash_value, *key);
1086 
1087  if (bin == RHASH_AR_TABLE_MAX_BOUND) {
1088  if (value != 0) *value = 0;
1089  return 0;
1090  }
1091  else {
1092  if (value != 0) {
1093  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, bin);
1094  *value = pair->val;
1095  }
1096  ar_clear_entry(hash, bin);
1097  RHASH_AR_TABLE_SIZE_DEC(hash);
1098  return 1;
1099  }
1100 }
1101 
1102 static int
1103 ar_shift(VALUE hash, st_data_t *key, st_data_t *value)
1104 {
1105  if (RHASH_AR_TABLE_SIZE(hash) > 0) {
1106  unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
1107 
1108  for (i = 0; i < bound; i++) {
1109  if (!ar_cleared_entry(hash, i)) {
1110  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
1111  if (value != 0) *value = pair->val;
1112  *key = pair->key;
1113  ar_clear_entry(hash, i);
1114  RHASH_AR_TABLE_SIZE_DEC(hash);
1115  return 1;
1116  }
1117  }
1118  }
1119  if (value != NULL) *value = 0;
1120  return 0;
1121 }
1122 
1123 static long
1124 ar_keys(VALUE hash, st_data_t *keys, st_index_t size)
1125 {
1126  unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
1127  st_data_t *keys_start = keys, *keys_end = keys + size;
1128 
1129  for (i = 0; i < bound; i++) {
1130  if (keys == keys_end) {
1131  break;
1132  }
1133  else {
1134  if (!ar_cleared_entry(hash, i)) {
1135  *keys++ = RHASH_AR_TABLE_REF(hash, i)->key;
1136  }
1137  }
1138  }
1139 
1140  return keys - keys_start;
1141 }
1142 
1143 static long
1144 ar_values(VALUE hash, st_data_t *values, st_index_t size)
1145 {
1146  unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
1147  st_data_t *values_start = values, *values_end = values + size;
1148 
1149  for (i = 0; i < bound; i++) {
1150  if (values == values_end) {
1151  break;
1152  }
1153  else {
1154  if (!ar_cleared_entry(hash, i)) {
1155  *values++ = RHASH_AR_TABLE_REF(hash, i)->val;
1156  }
1157  }
1158  }
1159 
1160  return values - values_start;
1161 }
1162 
1163 static ar_table*
1164 ar_copy(VALUE hash1, VALUE hash2)
1165 {
1166  ar_table *old_tab = RHASH_AR_TABLE(hash2);
1167 
1168  if (old_tab != NULL) {
1169  ar_table *new_tab = RHASH_AR_TABLE(hash1);
1170  if (new_tab == NULL) {
1171  new_tab = (ar_table*) rb_transient_heap_alloc(hash1, sizeof(ar_table));
1172  if (new_tab != NULL) {
1173  RHASH_SET_TRANSIENT_FLAG(hash1);
1174  }
1175  else {
1177  new_tab = (ar_table*)ruby_xmalloc(sizeof(ar_table));
1178  }
1179  }
1180  *new_tab = *old_tab;
1181  RHASH(hash1)->ar_hint.word = RHASH(hash2)->ar_hint.word;
1182  RHASH_AR_TABLE_BOUND_SET(hash1, RHASH_AR_TABLE_BOUND(hash2));
1183  RHASH_AR_TABLE_SIZE_SET(hash1, RHASH_AR_TABLE_SIZE(hash2));
1184  hash_ar_table_set(hash1, new_tab);
1185 
1187  return new_tab;
1188  }
1189  else {
1190  RHASH_AR_TABLE_BOUND_SET(hash1, RHASH_AR_TABLE_BOUND(hash2));
1191  RHASH_AR_TABLE_SIZE_SET(hash1, RHASH_AR_TABLE_SIZE(hash2));
1192 
1193  if (RHASH_TRANSIENT_P(hash1)) {
1195  }
1196  else if (RHASH_AR_TABLE(hash1)) {
1197  ruby_xfree(RHASH_AR_TABLE(hash1));
1198  }
1199 
1200  hash_ar_table_set(hash1, NULL);
1201 
1203  return old_tab;
1204  }
1205 }
1206 
1207 static void
1208 ar_clear(VALUE hash)
1209 {
1210  if (RHASH_AR_TABLE(hash) != NULL) {
1211  RHASH_AR_TABLE_SIZE_SET(hash, 0);
1212  RHASH_AR_TABLE_BOUND_SET(hash, 0);
1213  }
1214  else {
1215  HASH_ASSERT(RHASH_AR_TABLE_SIZE(hash) == 0);
1216  HASH_ASSERT(RHASH_AR_TABLE_BOUND(hash) == 0);
1217  }
1218 }
1219 
1220 #if USE_TRANSIENT_HEAP
1221 void
1223 {
1224  if (RHASH_TRANSIENT_P(hash)) {
1225  ar_table *new_tab;
1226  ar_table *old_tab = RHASH_AR_TABLE(hash);
1227 
1228  if (UNLIKELY(old_tab == NULL)) {
1229  rb_gc_force_recycle(hash);
1230  return;
1231  }
1232  HASH_ASSERT(old_tab != NULL);
1233  if (promote) {
1234  promote:
1235  new_tab = ruby_xmalloc(sizeof(ar_table));
1237  }
1238  else {
1239  new_tab = rb_transient_heap_alloc(hash, sizeof(ar_table));
1240  if (new_tab == NULL) goto promote;
1241  }
1242  *new_tab = *old_tab;
1243  hash_ar_table_set(hash, new_tab);
1244  }
1245  hash_verify(hash);
1246 }
1247 #endif
1248 
1250 
1255 };
1256 
1257 static int
1258 foreach_safe_i(st_data_t key, st_data_t value, st_data_t args, int error)
1259 {
1260  int status;
1261  struct foreach_safe_arg *arg = (void *)args;
1262 
1263  if (error) return ST_STOP;
1264  status = (*arg->func)(key, value, arg->arg);
1265  if (status == ST_CONTINUE) {
1266  return ST_CHECK;
1267  }
1268  return status;
1269 }
1270 
1271 void
1273 {
1274  struct foreach_safe_arg arg;
1275 
1276  arg.tbl = table;
1277  arg.func = (st_foreach_func *)func;
1278  arg.arg = a;
1279  if (st_foreach_check(table, foreach_safe_i, (st_data_t)&arg, 0)) {
1280  rb_raise(rb_eRuntimeError, "hash modified during iteration");
1281  }
1282 }
1283 
1285 
1286 struct hash_foreach_arg {
1290 };
1291 
1292 static int
1293 hash_ar_foreach_iter(st_data_t key, st_data_t value, st_data_t argp, int error)
1294 {
1295  struct hash_foreach_arg *arg = (struct hash_foreach_arg *)argp;
1296  int status;
1297 
1298  if (error) return ST_STOP;
1299  status = (*arg->func)((VALUE)key, (VALUE)value, arg->arg);
1300  /* TODO: rehash check? rb_raise(rb_eRuntimeError, "rehash occurred during iteration"); */
1301 
1302  switch (status) {
1303  case ST_DELETE:
1304  return ST_DELETE;
1305  case ST_CONTINUE:
1306  break;
1307  case ST_STOP:
1308  return ST_STOP;
1309  }
1310  return ST_CHECK;
1311 }
1312 
1313 static int
1314 hash_foreach_iter(st_data_t key, st_data_t value, st_data_t argp, int error)
1315 {
1316  struct hash_foreach_arg *arg = (struct hash_foreach_arg *)argp;
1317  int status;
1318  st_table *tbl;
1319 
1320  if (error) return ST_STOP;
1321  tbl = RHASH_ST_TABLE(arg->hash);
1322  status = (*arg->func)((VALUE)key, (VALUE)value, arg->arg);
1323  if (RHASH_ST_TABLE(arg->hash) != tbl) {
1324  rb_raise(rb_eRuntimeError, "rehash occurred during iteration");
1325  }
1326  switch (status) {
1327  case ST_DELETE:
1328  return ST_DELETE;
1329  case ST_CONTINUE:
1330  break;
1331  case ST_STOP:
1332  return ST_STOP;
1333  }
1334  return ST_CHECK;
1335 }
1336 
1337 static int
1338 iter_lev_in_ivar(VALUE hash)
1339 {
1340  VALUE levval = rb_ivar_get(hash, id_hash_iter_lev);
1341  HASH_ASSERT(FIXNUM_P(levval));
1342  return FIX2INT(levval);
1343 }
1344 
1345 void rb_ivar_set_internal(VALUE obj, ID id, VALUE val);
1346 
1347 static void
1348 iter_lev_in_ivar_set(VALUE hash, int lev)
1349 {
1350  rb_ivar_set_internal(hash, id_hash_iter_lev, INT2FIX(lev));
1351 }
1352 
1353 static int
1354 iter_lev_in_flags(VALUE hash)
1355 {
1356  unsigned int u = (unsigned int)((RBASIC(hash)->flags >> RHASH_LEV_SHIFT) & RHASH_LEV_MAX);
1357  return (int)u;
1358 }
1359 
1360 static int
1362 {
1363  int lev = iter_lev_in_flags(hash);
1364 
1365  if (lev == RHASH_LEV_MAX) {
1366  return iter_lev_in_ivar(hash);
1367  }
1368  else {
1369  return lev;
1370  }
1371 }
1372 
1373 static void
1374 hash_iter_lev_inc(VALUE hash)
1375 {
1376  int lev = iter_lev_in_flags(hash);
1377  if (lev == RHASH_LEV_MAX) {
1378  lev = iter_lev_in_ivar(hash);
1379  iter_lev_in_ivar_set(hash, lev+1);
1380  }
1381  else {
1382  lev += 1;
1383  RBASIC(hash)->flags = ((RBASIC(hash)->flags & ~RHASH_LEV_MASK) | (lev << RHASH_LEV_SHIFT));
1384  if (lev == RHASH_LEV_MAX) {
1385  iter_lev_in_ivar_set(hash, lev);
1386  }
1387  }
1388 }
1389 
1390 static void
1391 hash_iter_lev_dec(VALUE hash)
1392 {
1393  int lev = iter_lev_in_flags(hash);
1394  if (lev == RHASH_LEV_MAX) {
1395  lev = iter_lev_in_ivar(hash);
1396  HASH_ASSERT(lev > 0);
1397  iter_lev_in_ivar_set(hash, lev-1);
1398  }
1399  else {
1400  HASH_ASSERT(lev > 0);
1401  RBASIC(hash)->flags = ((RBASIC(hash)->flags & ~RHASH_LEV_MASK) | ((lev-1) << RHASH_LEV_SHIFT));
1402  }
1403 }
1404 
1405 static VALUE
1406 hash_foreach_ensure_rollback(VALUE hash)
1407 {
1408  hash_iter_lev_inc(hash);
1409  return 0;
1410 }
1411 
1412 static VALUE
1413 hash_foreach_ensure(VALUE hash)
1414 {
1415  hash_iter_lev_dec(hash);
1416  return 0;
1417 }
1418 
1419 int
1421 {
1422  if (RHASH_AR_TABLE_P(hash)) {
1423  return ar_foreach(hash, func, arg);
1424  }
1425  else {
1426  return st_foreach(RHASH_ST_TABLE(hash), func, arg);
1427  }
1428 }
1429 
1430 int
1432 {
1433  if (RHASH_AR_TABLE_P(hash)) {
1434  return ar_foreach_with_replace(hash, func, replace, arg);
1435  }
1436  else {
1437  return st_foreach_with_replace(RHASH_ST_TABLE(hash), func, replace, arg);
1438  }
1439 }
1440 
1441 static VALUE
1442 hash_foreach_call(VALUE arg)
1443 {
1444  VALUE hash = ((struct hash_foreach_arg *)arg)->hash;
1445  int ret = 0;
1446  if (RHASH_AR_TABLE_P(hash)) {
1447  ret = ar_foreach_check(hash, hash_ar_foreach_iter,
1449  }
1450  else if (RHASH_ST_TABLE_P(hash)) {
1451  ret = st_foreach_check(RHASH_ST_TABLE(hash), hash_foreach_iter,
1453  }
1454  if (ret) {
1455  rb_raise(rb_eRuntimeError, "ret: %d, hash modified during iteration", ret);
1456  }
1457  return Qnil;
1458 }
1459 
1460 void
1462 {
1463  struct hash_foreach_arg arg;
1464 
1465  if (RHASH_TABLE_EMPTY_P(hash))
1466  return;
1467  hash_iter_lev_inc(hash);
1468  arg.hash = hash;
1469  arg.func = (rb_foreach_func *)func;
1470  arg.arg = farg;
1471  rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash);
1472  hash_verify(hash);
1473 }
1474 
1475 static VALUE
1476 hash_alloc_flags(VALUE klass, VALUE flags, VALUE ifnone)
1477 {
1478  const VALUE wb = (RGENGC_WB_PROTECTED_HASH ? FL_WB_PROTECTED : 0);
1479  NEWOBJ_OF(hash, struct RHash, klass, T_HASH | wb | flags);
1480 
1481  RHASH_SET_IFNONE((VALUE)hash, ifnone);
1482 
1483  return (VALUE)hash;
1484 }
1485 
1486 static VALUE
1487 hash_alloc(VALUE klass)
1488 {
1489  return hash_alloc_flags(klass, 0, Qnil);
1490 }
1491 
1492 static VALUE
1493 empty_hash_alloc(VALUE klass)
1494 {
1495  RUBY_DTRACE_CREATE_HOOK(HASH, 0);
1496 
1497  return hash_alloc(klass);
1498 }
1499 
1500 VALUE
1502 {
1503  return hash_alloc(rb_cHash);
1504 }
1505 
1508 {
1509  VALUE ret = rb_hash_new();
1510  if (size == 0) {
1511  /* do nothing */
1512  }
1513  else if (size <= RHASH_AR_TABLE_MAX_SIZE) {
1514  ar_alloc_table(ret);
1515  }
1516  else {
1518  }
1519  return ret;
1520 }
1521 
1522 static VALUE
1523 hash_dup(VALUE hash, VALUE klass, VALUE flags)
1524 {
1525  VALUE ret = hash_alloc_flags(klass, flags,
1526  RHASH_IFNONE(hash));
1527  if (!RHASH_EMPTY_P(hash)) {
1528  if (RHASH_AR_TABLE_P(hash))
1529  ar_copy(ret, hash);
1530  else if (RHASH_ST_TABLE_P(hash))
1532  }
1533  return ret;
1534 }
1535 
1536 VALUE
1538 {
1539  const VALUE flags = RBASIC(hash)->flags;
1540  VALUE ret = hash_dup(hash, rb_obj_class(hash),
1541  flags & (FL_EXIVAR|RHASH_PROC_DEFAULT));
1542  if (flags & FL_EXIVAR)
1543  rb_copy_generic_ivar(ret, hash);
1544  return ret;
1545 }
1546 
1549 {
1550  VALUE ret = hash_dup(hash, rb_cHash, 0);
1551  return ret;
1552 }
1553 
1554 static void
1555 rb_hash_modify_check(VALUE hash)
1556 {
1558 }
1559 
1561 #if RHASH_CONVERT_TABLE_DEBUG
1562 rb_hash_tbl_raw(VALUE hash, const char *file, int line)
1563 {
1564  return ar_force_convert_table(hash, file, line);
1565 }
1566 #else
1568 {
1569  return ar_force_convert_table(hash, NULL, 0);
1570 }
1571 #endif
1572 
1573 struct st_table *
1574 rb_hash_tbl(VALUE hash, const char *file, int line)
1575 {
1576  OBJ_WB_UNPROTECT(hash);
1577  return RHASH_TBL_RAW(hash);
1578 }
1579 
1580 static void
1581 rb_hash_modify(VALUE hash)
1582 {
1583  rb_hash_modify_check(hash);
1584 }
1585 
1586 NORETURN(static void no_new_key(void));
1587 static void
1588 no_new_key(void)
1589 {
1590  rb_raise(rb_eRuntimeError, "can't add a new key into hash during iteration");
1591 }
1592 
1596 };
1597 
1598 #define NOINSERT_UPDATE_CALLBACK(func) \
1599 static int \
1600 func##_noinsert(st_data_t *key, st_data_t *val, st_data_t arg, int existing) \
1601 { \
1602  if (!existing) no_new_key(); \
1603  return func(key, val, (struct update_arg *)arg, existing); \
1604 } \
1605  \
1606 static int \
1607 func##_insert(st_data_t *key, st_data_t *val, st_data_t arg, int existing) \
1608 { \
1609  return func(key, val, (struct update_arg *)arg, existing); \
1610 }
1611 
1612 struct update_arg {
1619 };
1620 
1622 
1623 int
1625 {
1626  if (RHASH_AR_TABLE_P(hash)) {
1627  int result = ar_update(hash, (st_data_t)key, func, arg);
1628  if (result == -1) {
1629  ar_try_convert_table(hash);
1630  }
1631  else {
1632  return result;
1633  }
1634  }
1635 
1636  return st_update(RHASH_ST_TABLE(hash), (st_data_t)key, func, arg);
1637 }
1638 
1639 static int
1640 tbl_update(VALUE hash, VALUE key, tbl_update_func func, st_data_t optional_arg)
1641 {
1642  struct update_arg arg;
1643  int result;
1644 
1645  arg.arg = optional_arg;
1646  arg.hash = hash;
1647  arg.new_key = 0;
1648  arg.old_key = Qundef;
1649  arg.new_value = 0;
1650  arg.old_value = Qundef;
1651 
1652  result = rb_hash_stlike_update(hash, key, func, (st_data_t)&arg);
1653 
1654  /* write barrier */
1655  if (arg.new_key) RB_OBJ_WRITTEN(hash, arg.old_key, arg.new_key);
1656  if (arg.new_value) RB_OBJ_WRITTEN(hash, arg.old_value, arg.new_value);
1657 
1658  return result;
1659 }
1660 
1661 #define UPDATE_CALLBACK(iter_lev, func) ((iter_lev) > 0 ? func##_noinsert : func##_insert)
1662 
1663 #define RHASH_UPDATE_ITER(h, iter_lev, key, func, a) do { \
1664  tbl_update((h), (key), UPDATE_CALLBACK((iter_lev), func), (st_data_t)(a)); \
1665 } while (0)
1666 
1667 #define RHASH_UPDATE(hash, key, func, arg) \
1668  RHASH_UPDATE_ITER(hash, RHASH_ITER_LEV(hash), key, func, arg)
1669 
1670 static void
1671 set_proc_default(VALUE hash, VALUE proc)
1672 {
1673  if (rb_proc_lambda_p(proc)) {
1674  int n = rb_proc_arity(proc);
1675 
1676  if (n != 2 && (n >= 0 || n < -3)) {
1677  if (n < 0) n = -n-1;
1678  rb_raise(rb_eTypeError, "default_proc takes two arguments (2 for %d)", n);
1679  }
1680  }
1681 
1683  RHASH_SET_IFNONE(hash, proc);
1684 }
1685 
1686 /*
1687  * call-seq:
1688  * Hash.new -> new_hash
1689  * Hash.new(obj) -> new_hash
1690  * Hash.new {|hash, key| block } -> new_hash
1691  *
1692  * Returns a new, empty hash. If this hash is subsequently accessed by
1693  * a key that doesn't correspond to a hash entry, the value returned
1694  * depends on the style of <code>new</code> used to create the hash. In
1695  * the first form, the access returns <code>nil</code>. If
1696  * <i>obj</i> is specified, this single object will be used for
1697  * all <em>default values</em>. If a block is specified, it will be
1698  * called with the hash object and the key, and should return the
1699  * default value. It is the block's responsibility to store the value
1700  * in the hash if required.
1701  *
1702  * h = Hash.new("Go Fish")
1703  * h["a"] = 100
1704  * h["b"] = 200
1705  * h["a"] #=> 100
1706  * h["c"] #=> "Go Fish"
1707  * # The following alters the single default object
1708  * h["c"].upcase! #=> "GO FISH"
1709  * h["d"] #=> "GO FISH"
1710  * h.keys #=> ["a", "b"]
1711  *
1712  * # While this creates a new default object each time
1713  * h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }
1714  * h["c"] #=> "Go Fish: c"
1715  * h["c"].upcase! #=> "GO FISH: C"
1716  * h["d"] #=> "Go Fish: d"
1717  * h.keys #=> ["c", "d"]
1718  *
1719  */
1720 
1721 static VALUE
1722 rb_hash_initialize(int argc, VALUE *argv, VALUE hash)
1723 {
1724  VALUE ifnone;
1725 
1726  rb_hash_modify(hash);
1727  if (rb_block_given_p()) {
1728  rb_check_arity(argc, 0, 0);
1729  ifnone = rb_block_proc();
1730  SET_PROC_DEFAULT(hash, ifnone);
1731  }
1732  else {
1733  rb_check_arity(argc, 0, 1);
1734  ifnone = argc == 0 ? Qnil : argv[0];
1735  RHASH_SET_IFNONE(hash, ifnone);
1736  }
1737 
1738  return hash;
1739 }
1740 
1741 /*
1742  * call-seq:
1743  * Hash[ key, value, ... ] -> new_hash
1744  * Hash[ [ [key, value], ... ] ] -> new_hash
1745  * Hash[ object ] -> new_hash
1746  *
1747  * Creates a new hash populated with the given objects.
1748  *
1749  * Similar to the literal <code>{ _key_ => _value_, ... }</code>. In the first
1750  * form, keys and values occur in pairs, so there must be an even number of
1751  * arguments.
1752  *
1753  * The second and third form take a single argument which is either an array
1754  * of key-value pairs or an object convertible to a hash.
1755  *
1756  * Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200}
1757  * Hash[ [ ["a", 100], ["b", 200] ] ] #=> {"a"=>100, "b"=>200}
1758  * Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200}
1759  */
1760 
1761 static VALUE
1762 rb_hash_s_create(int argc, VALUE *argv, VALUE klass)
1763 {
1764  VALUE hash, tmp;
1765 
1766  if (argc == 1) {
1767  tmp = rb_hash_s_try_convert(Qnil, argv[0]);
1768  if (!NIL_P(tmp)) {
1769  hash = hash_alloc(klass);
1770  if (RHASH_AR_TABLE_P(tmp)) {
1771  ar_copy(hash, tmp);
1772  }
1773  else {
1775  }
1776  return hash;
1777  }
1778 
1779  tmp = rb_check_array_type(argv[0]);
1780  if (!NIL_P(tmp)) {
1781  long i;
1782 
1783  hash = hash_alloc(klass);
1784  for (i = 0; i < RARRAY_LEN(tmp); ++i) {
1785  VALUE e = RARRAY_AREF(tmp, i);
1787  VALUE key, val = Qnil;
1788 
1789  if (NIL_P(v)) {
1790  rb_raise(rb_eArgError, "wrong element type %s at %ld (expected array)",
1791  rb_builtin_class_name(e), i);
1792  }
1793  switch (RARRAY_LEN(v)) {
1794  default:
1795  rb_raise(rb_eArgError, "invalid number of elements (%ld for 1..2)",
1796  RARRAY_LEN(v));
1797  case 2:
1798  val = RARRAY_AREF(v, 1);
1799  case 1:
1800  key = RARRAY_AREF(v, 0);
1801  rb_hash_aset(hash, key, val);
1802  }
1803  }
1804  return hash;
1805  }
1806  }
1807  if (argc % 2 != 0) {
1808  rb_raise(rb_eArgError, "odd number of arguments for Hash");
1809  }
1810 
1811  hash = hash_alloc(klass);
1813  hash_verify(hash);
1814  return hash;
1815 }
1816 
1817 VALUE
1819 {
1820  return rb_convert_type_with_id(hash, T_HASH, "Hash", idTo_hash);
1821 }
1822 #define to_hash rb_to_hash_type
1823 
1824 VALUE
1826 {
1828 }
1829 
1830 /*
1831  * call-seq:
1832  * Hash.try_convert(obj) -> hash or nil
1833  *
1834  * Try to convert <i>obj</i> into a hash, using to_hash method.
1835  * Returns converted hash or nil if <i>obj</i> cannot be converted
1836  * for any reason.
1837  *
1838  * Hash.try_convert({1=>2}) # => {1=>2}
1839  * Hash.try_convert("1=>2") # => nil
1840  */
1841 static VALUE
1842 rb_hash_s_try_convert(VALUE dummy, VALUE hash)
1843 {
1844  return rb_check_hash_type(hash);
1845 }
1846 
1847 struct rehash_arg {
1850 };
1851 
1852 static int
1853 rb_hash_rehash_i(VALUE key, VALUE value, VALUE arg)
1854 {
1855  if (RHASH_AR_TABLE_P(arg)) {
1856  ar_insert(arg, (st_data_t)key, (st_data_t)value);
1857  }
1858  else {
1860  }
1861  return ST_CONTINUE;
1862 }
1863 
1864 /*
1865  * call-seq:
1866  * hsh.rehash -> hsh
1867  *
1868  * Rebuilds the hash based on the current hash values for each key. If
1869  * values of key objects have changed since they were inserted, this
1870  * method will reindex <i>hsh</i>. If Hash#rehash is
1871  * called while an iterator is traversing the hash, a
1872  * RuntimeError will be raised in the iterator.
1873  *
1874  * a = [ "a", "b" ]
1875  * c = [ "c", "d" ]
1876  * h = { a => 100, c => 300 }
1877  * h[a] #=> 100
1878  * a[0] = "z"
1879  * h[a] #=> nil
1880  * h.rehash #=> {["z", "b"]=>100, ["c", "d"]=>300}
1881  * h[a] #=> 100
1882  */
1883 
1884 VALUE
1886 {
1887  VALUE tmp;
1888  st_table *tbl;
1889 
1890  if (RHASH_ITER_LEV(hash) > 0) {
1891  rb_raise(rb_eRuntimeError, "rehash during iteration");
1892  }
1893  rb_hash_modify_check(hash);
1894  if (RHASH_AR_TABLE_P(hash)) {
1895  tmp = hash_alloc(0);
1896  ar_alloc_table(tmp);
1897  rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
1898  ar_free_and_clear_table(hash);
1899  ar_copy(hash, tmp);
1900  ar_free_and_clear_table(tmp);
1901  }
1902  else if (RHASH_ST_TABLE_P(hash)) {
1903  st_table *old_tab = RHASH_ST_TABLE(hash);
1904  tmp = hash_alloc(0);
1905  tbl = st_init_table_with_size(old_tab->type, old_tab->num_entries);
1906  RHASH_ST_TABLE_SET(tmp, tbl);
1907  rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
1908  st_free_table(old_tab);
1909  RHASH_ST_TABLE_SET(hash, tbl);
1910  RHASH_ST_CLEAR(tmp);
1911  }
1912  hash_verify(hash);
1913  return hash;
1914 }
1915 
1916 VALUE
1918 {
1919  if (rb_method_basic_definition_p(CLASS_OF(hash), id_default)) {
1920  VALUE ifnone = RHASH_IFNONE(hash);
1921  if (!FL_TEST(hash, RHASH_PROC_DEFAULT)) return ifnone;
1922  if (key == Qundef) return Qnil;
1923  return rb_funcall(ifnone, id_yield, 2, hash, key);
1924  }
1925  else {
1926  return rb_funcall(hash, id_default, 1, key);
1927  }
1928 }
1929 
1930 static inline int
1931 hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval)
1932 {
1933  hash_verify(hash);
1934 
1935  if (RHASH_AR_TABLE_P(hash)) {
1936  return ar_lookup(hash, key, pval);
1937  }
1938  else {
1939  return st_lookup(RHASH_ST_TABLE(hash), key, pval);
1940  }
1941 }
1942 
1945 {
1946  return hash_stlike_lookup(hash, key, pval);
1947 }
1948 
1949 /*
1950  * call-seq:
1951  * hsh[key] -> value
1952  *
1953  * Element Reference---Retrieves the <i>value</i> object corresponding
1954  * to the <i>key</i> object. If not found, returns the default value (see
1955  * Hash::new for details).
1956  *
1957  * h = { "a" => 100, "b" => 200 }
1958  * h["a"] #=> 100
1959  * h["c"] #=> nil
1960  *
1961  */
1962 
1963 VALUE
1965 {
1966  st_data_t val;
1967 
1968  if (hash_stlike_lookup(hash, key, &val)) {
1969  return (VALUE)val;
1970  }
1971  else {
1972  return rb_hash_default_value(hash, key);
1973  }
1974 }
1975 
1976 VALUE
1978 {
1979  st_data_t val;
1980 
1981  if (hash_stlike_lookup(hash, key, &val)) {
1982  return (VALUE)val;
1983  }
1984  else {
1985  return def; /* without Hash#default */
1986  }
1987 }
1988 
1989 VALUE
1991 {
1992  return rb_hash_lookup2(hash, key, Qnil);
1993 }
1994 
1995 /*
1996  * call-seq:
1997  * hsh.fetch(key [, default] ) -> obj
1998  * hsh.fetch(key) {| key | block } -> obj
1999  *
2000  * Returns a value from the hash for the given key. If the key can't be
2001  * found, there are several options: With no other arguments, it will
2002  * raise a KeyError exception; if <i>default</i> is given,
2003  * then that will be returned; if the optional code block is specified,
2004  * then that will be run and its result returned.
2005  *
2006  * h = { "a" => 100, "b" => 200 }
2007  * h.fetch("a") #=> 100
2008  * h.fetch("z", "go fish") #=> "go fish"
2009  * h.fetch("z") { |el| "go fish, #{el}"} #=> "go fish, z"
2010  *
2011  * The following example shows that an exception is raised if the key
2012  * is not found and a default value is not supplied.
2013  *
2014  * h = { "a" => 100, "b" => 200 }
2015  * h.fetch("z")
2016  *
2017  * <em>produces:</em>
2018  *
2019  * prog.rb:2:in `fetch': key not found (KeyError)
2020  * from prog.rb:2
2021  *
2022  */
2023 
2024 static VALUE
2025 rb_hash_fetch_m(int argc, VALUE *argv, VALUE hash)
2026 {
2027  VALUE key;
2028  st_data_t val;
2029  long block_given;
2030 
2031  rb_check_arity(argc, 1, 2);
2032  key = argv[0];
2033 
2034  block_given = rb_block_given_p();
2035  if (block_given && argc == 2) {
2036  rb_warn("block supersedes default value argument");
2037  }
2038 
2039  if (hash_stlike_lookup(hash, key, &val)) {
2040  return (VALUE)val;
2041  }
2042  else {
2043  if (block_given) {
2044  return rb_yield(key);
2045  }
2046  else if (argc == 1) {
2047  VALUE desc = rb_protect(rb_inspect, key, 0);
2048  if (NIL_P(desc)) {
2049  desc = rb_any_to_s(key);
2050  }
2051  desc = rb_str_ellipsize(desc, 65);
2052  rb_key_err_raise(rb_sprintf("key not found: %"PRIsVALUE, desc), hash, key);
2053  }
2054  else {
2055  return argv[1];
2056  }
2057  }
2058 }
2059 
2060 VALUE
2062 {
2063  return rb_hash_fetch_m(1, &key, hash);
2064 }
2065 
2066 /*
2067  * call-seq:
2068  * hsh.default(key=nil) -> obj
2069  *
2070  * Returns the default value, the value that would be returned by
2071  * <i>hsh</i>[<i>key</i>] if <i>key</i> did not exist in <i>hsh</i>.
2072  * See also Hash::new and Hash#default=.
2073  *
2074  * h = Hash.new #=> {}
2075  * h.default #=> nil
2076  * h.default(2) #=> nil
2077  *
2078  * h = Hash.new("cat") #=> {}
2079  * h.default #=> "cat"
2080  * h.default(2) #=> "cat"
2081  *
2082  * h = Hash.new {|h,k| h[k] = k.to_i*10} #=> {}
2083  * h.default #=> nil
2084  * h.default(2) #=> 20
2085  */
2086 
2087 static VALUE
2088 rb_hash_default(int argc, VALUE *argv, VALUE hash)
2089 {
2090  VALUE args[2], ifnone;
2091 
2092  rb_check_arity(argc, 0, 1);
2093  ifnone = RHASH_IFNONE(hash);
2094  if (FL_TEST(hash, RHASH_PROC_DEFAULT)) {
2095  if (argc == 0) return Qnil;
2096  args[0] = hash;
2097  args[1] = argv[0];
2098  return rb_funcallv(ifnone, id_yield, 2, args);
2099  }
2100  return ifnone;
2101 }
2102 
2103 /*
2104  * call-seq:
2105  * hsh.default = obj -> obj
2106  *
2107  * Sets the default value, the value returned for a key that does not
2108  * exist in the hash. It is not possible to set the default to a
2109  * Proc that will be executed on each key lookup.
2110  *
2111  * h = { "a" => 100, "b" => 200 }
2112  * h.default = "Go fish"
2113  * h["a"] #=> 100
2114  * h["z"] #=> "Go fish"
2115  * # This doesn't do what you might hope...
2116  * h.default = proc do |hash, key|
2117  * hash[key] = key + key
2118  * end
2119  * h[2] #=> #<Proc:0x401b3948@-:6>
2120  * h["cat"] #=> #<Proc:0x401b3948@-:6>
2121  */
2122 
2123 static VALUE
2124 rb_hash_set_default(VALUE hash, VALUE ifnone)
2125 {
2126  rb_hash_modify_check(hash);
2127  SET_DEFAULT(hash, ifnone);
2128  return ifnone;
2129 }
2130 
2131 /*
2132  * call-seq:
2133  * hsh.default_proc -> anObject
2134  *
2135  * If Hash::new was invoked with a block, return that
2136  * block, otherwise return <code>nil</code>.
2137  *
2138  * h = Hash.new {|h,k| h[k] = k*k } #=> {}
2139  * p = h.default_proc #=> #<Proc:0x401b3d08@-:1>
2140  * a = [] #=> []
2141  * p.call(a, 2)
2142  * a #=> [nil, nil, 4]
2143  */
2144 
2145 
2146 static VALUE
2147 rb_hash_default_proc(VALUE hash)
2148 {
2149  if (FL_TEST(hash, RHASH_PROC_DEFAULT)) {
2150  return RHASH_IFNONE(hash);
2151  }
2152  return Qnil;
2153 }
2154 
2155 /*
2156  * call-seq:
2157  * hsh.default_proc = proc_obj or nil
2158  *
2159  * Sets the default proc to be executed on each failed key lookup.
2160  *
2161  * h.default_proc = proc do |hash, key|
2162  * hash[key] = key + key
2163  * end
2164  * h[2] #=> 4
2165  * h["cat"] #=> "catcat"
2166  */
2167 
2168 VALUE
2170 {
2171  VALUE b;
2172 
2173  rb_hash_modify_check(hash);
2174  if (NIL_P(proc)) {
2175  SET_DEFAULT(hash, proc);
2176  return proc;
2177  }
2178  b = rb_check_convert_type_with_id(proc, T_DATA, "Proc", idTo_proc);
2179  if (NIL_P(b) || !rb_obj_is_proc(b)) {
2181  "wrong default_proc type %s (expected Proc)",
2182  rb_obj_classname(proc));
2183  }
2184  proc = b;
2185  SET_PROC_DEFAULT(hash, proc);
2186  return proc;
2187 }
2188 
2189 static int
2190 key_i(VALUE key, VALUE value, VALUE arg)
2191 {
2192  VALUE *args = (VALUE *)arg;
2193 
2194  if (rb_equal(value, args[0])) {
2195  args[1] = key;
2196  return ST_STOP;
2197  }
2198  return ST_CONTINUE;
2199 }
2200 
2201 /*
2202  * call-seq:
2203  * hsh.key(value) -> key
2204  *
2205  * Returns the key of an occurrence of a given value. If the value is
2206  * not found, returns <code>nil</code>.
2207  *
2208  * h = { "a" => 100, "b" => 200, "c" => 300, "d" => 300 }
2209  * h.key(200) #=> "b"
2210  * h.key(300) #=> "c"
2211  * h.key(999) #=> nil
2212  *
2213  */
2214 
2215 static VALUE
2216 rb_hash_key(VALUE hash, VALUE value)
2217 {
2218  VALUE args[2];
2219 
2220  args[0] = value;
2221  args[1] = Qnil;
2222 
2223  rb_hash_foreach(hash, key_i, (VALUE)args);
2224 
2225  return args[1];
2226 }
2227 
2228 /* :nodoc: */
2229 static VALUE
2230 rb_hash_index(VALUE hash, VALUE value)
2231 {
2232  rb_warn_deprecated("Hash#index", "Hash#key");
2233  return rb_hash_key(hash, value);
2234 }
2235 
2236 int
2238 {
2239  if (RHASH_AR_TABLE_P(hash)) {
2240  return ar_delete(hash, pkey, pval);
2241  }
2242  else {
2243  return st_delete(RHASH_ST_TABLE(hash), pkey, pval);
2244  }
2245 }
2246 
2247 /*
2248  * delete a specified entry a given key.
2249  * if there is the corresponding entry, return a value of the entry.
2250  * if there is no corresponding entry, return Qundef.
2251  */
2252 VALUE
2254 {
2255  st_data_t ktmp = (st_data_t)key, val;
2256 
2257  if (rb_hash_stlike_delete(hash, &ktmp, &val)) {
2258  return (VALUE)val;
2259  }
2260  else {
2261  return Qundef;
2262  }
2263 }
2264 
2265 /*
2266  * delete a specified entry by a given key.
2267  * if there is the corresponding entry, return a value of the entry.
2268  * if there is no corresponding entry, return Qnil.
2269  */
2270 VALUE
2272 {
2273  VALUE deleted_value = rb_hash_delete_entry(hash, key);
2274 
2275  if (deleted_value != Qundef) { /* likely pass */
2276  return deleted_value;
2277  }
2278  else {
2279  return Qnil;
2280  }
2281 }
2282 
2283 /*
2284  * call-seq:
2285  * hsh.delete(key) -> value
2286  * hsh.delete(key) {| key | block } -> value
2287  *
2288  * Deletes the key-value pair and returns the value from <i>hsh</i> whose
2289  * key is equal to <i>key</i>. If the key is not found, it returns
2290  * <em>nil</em>. If the optional code block is given and the
2291  * key is not found, pass in the key and return the result of
2292  * <i>block</i>.
2293  *
2294  * h = { "a" => 100, "b" => 200 }
2295  * h.delete("a") #=> 100
2296  * h.delete("z") #=> nil
2297  * h.delete("z") { |el| "#{el} not found" } #=> "z not found"
2298  *
2299  */
2300 
2301 static VALUE
2302 rb_hash_delete_m(VALUE hash, VALUE key)
2303 {
2304  VALUE val;
2305 
2306  rb_hash_modify_check(hash);
2307  val = rb_hash_delete_entry(hash, key);
2308 
2309  if (val != Qundef) {
2310  return val;
2311  }
2312  else {
2313  if (rb_block_given_p()) {
2314  return rb_yield(key);
2315  }
2316  else {
2317  return Qnil;
2318  }
2319  }
2320 }
2321 
2322 struct shift_var {
2325 };
2326 
2327 static int
2328 shift_i_safe(VALUE key, VALUE value, VALUE arg)
2329 {
2330  struct shift_var *var = (struct shift_var *)arg;
2331 
2332  var->key = key;
2333  var->val = value;
2334  return ST_STOP;
2335 }
2336 
2337 /*
2338  * call-seq:
2339  * hsh.shift -> anArray or obj
2340  *
2341  * Removes a key-value pair from <i>hsh</i> and returns it as the
2342  * two-item array <code>[</code> <i>key, value</i> <code>]</code>, or
2343  * the hash's default value if the hash is empty.
2344  *
2345  * h = { 1 => "a", 2 => "b", 3 => "c" }
2346  * h.shift #=> [1, "a"]
2347  * h #=> {2=>"b", 3=>"c"}
2348  */
2349 
2350 static VALUE
2351 rb_hash_shift(VALUE hash)
2352 {
2353  struct shift_var var;
2354 
2355  rb_hash_modify_check(hash);
2356  if (RHASH_AR_TABLE_P(hash)) {
2357  var.key = Qundef;
2358  if (RHASH_ITER_LEV(hash) == 0) {
2359  if (ar_shift(hash, &var.key, &var.val)) {
2360  return rb_assoc_new(var.key, var.val);
2361  }
2362  }
2363  else {
2364  rb_hash_foreach(hash, shift_i_safe, (VALUE)&var);
2365  if (var.key != Qundef) {
2366  rb_hash_delete_entry(hash, var.key);
2367  return rb_assoc_new(var.key, var.val);
2368  }
2369  }
2370  }
2371  if (RHASH_ST_TABLE_P(hash)) {
2372  var.key = Qundef;
2373  if (RHASH_ITER_LEV(hash) == 0) {
2374  if (st_shift(RHASH_ST_TABLE(hash), &var.key, &var.val)) {
2375  return rb_assoc_new(var.key, var.val);
2376  }
2377  }
2378  else {
2379  rb_hash_foreach(hash, shift_i_safe, (VALUE)&var);
2380  if (var.key != Qundef) {
2381  rb_hash_delete_entry(hash, var.key);
2382  return rb_assoc_new(var.key, var.val);
2383  }
2384  }
2385  }
2386  return rb_hash_default_value(hash, Qnil);
2387 }
2388 
2389 static int
2390 delete_if_i(VALUE key, VALUE value, VALUE hash)
2391 {
2392  if (RTEST(rb_yield_values(2, key, value))) {
2393  return ST_DELETE;
2394  }
2395  return ST_CONTINUE;
2396 }
2397 
2398 static VALUE
2399 hash_enum_size(VALUE hash, VALUE args, VALUE eobj)
2400 {
2401  return rb_hash_size(hash);
2402 }
2403 
2404 /*
2405  * call-seq:
2406  * hsh.delete_if {| key, value | block } -> hsh
2407  * hsh.delete_if -> an_enumerator
2408  *
2409  * Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
2410  * evaluates to <code>true</code>.
2411  *
2412  * If no block is given, an enumerator is returned instead.
2413  *
2414  * h = { "a" => 100, "b" => 200, "c" => 300 }
2415  * h.delete_if {|key, value| key >= "b" } #=> {"a"=>100}
2416  *
2417  */
2418 
2419 VALUE
2421 {
2422  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2423  rb_hash_modify_check(hash);
2424  if (!RHASH_TABLE_EMPTY_P(hash)) {
2425  rb_hash_foreach(hash, delete_if_i, hash);
2426  }
2427  return hash;
2428 }
2429 
2430 /*
2431  * call-seq:
2432  * hsh.reject! {| key, value | block } -> hsh or nil
2433  * hsh.reject! -> an_enumerator
2434  *
2435  * Equivalent to Hash#delete_if, but returns
2436  * <code>nil</code> if no changes were made.
2437  */
2438 
2439 VALUE
2441 {
2442  st_index_t n;
2443 
2444  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2445  rb_hash_modify(hash);
2446  n = RHASH_SIZE(hash);
2447  if (!n) return Qnil;
2448  rb_hash_foreach(hash, delete_if_i, hash);
2449  if (n == RHASH_SIZE(hash)) return Qnil;
2450  return hash;
2451 }
2452 
2453 static int
2454 reject_i(VALUE key, VALUE value, VALUE result)
2455 {
2456  if (!RTEST(rb_yield_values(2, key, value))) {
2457  rb_hash_aset(result, key, value);
2458  }
2459  return ST_CONTINUE;
2460 }
2461 
2462 /*
2463  * call-seq:
2464  * hsh.reject {|key, value| block} -> a_hash
2465  * hsh.reject -> an_enumerator
2466  *
2467  * Returns a new hash consisting of entries for which the block returns false.
2468  *
2469  * If no block is given, an enumerator is returned instead.
2470  *
2471  * h = { "a" => 100, "b" => 200, "c" => 300 }
2472  * h.reject {|k,v| k < "b"} #=> {"b" => 200, "c" => 300}
2473  * h.reject {|k,v| v > 100} #=> {"a" => 100}
2474  */
2475 
2476 VALUE
2478 {
2479  VALUE result;
2480 
2481  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2482  if (RTEST(ruby_verbose)) {
2483  VALUE klass;
2484  if (HAS_EXTRA_STATES(hash, klass)) {
2485  rb_warn("extra states are no longer copied: %+"PRIsVALUE, hash);
2486  }
2487  }
2488  result = rb_hash_new();
2489  if (!RHASH_EMPTY_P(hash)) {
2490  rb_hash_foreach(hash, reject_i, result);
2491  }
2492  return result;
2493 }
2494 
2495 /*
2496  * call-seq:
2497  * hsh.slice(*keys) -> a_hash
2498  *
2499  * Returns a hash containing only the given keys and their values.
2500  *
2501  * h = { a: 100, b: 200, c: 300 }
2502  * h.slice(:a) #=> {:a=>100}
2503  * h.slice(:b, :c, :d) #=> {:b=>200, :c=>300}
2504  */
2505 
2506 static VALUE
2507 rb_hash_slice(int argc, VALUE *argv, VALUE hash)
2508 {
2509  int i;
2510  VALUE key, value, result;
2511 
2512  if (argc == 0 || RHASH_EMPTY_P(hash)) {
2513  return rb_hash_new();
2514  }
2515  result = rb_hash_new_with_size(argc);
2516 
2517  for (i = 0; i < argc; i++) {
2518  key = argv[i];
2519  value = rb_hash_lookup2(hash, key, Qundef);
2520  if (value != Qundef)
2521  rb_hash_aset(result, key, value);
2522  }
2523 
2524  return result;
2525 }
2526 
2527 /*
2528  * call-seq:
2529  * hsh.values_at(key, ...) -> array
2530  *
2531  * Return an array containing the values associated with the given keys.
2532  * Also see Hash.select.
2533  *
2534  * h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
2535  * h.values_at("cow", "cat") #=> ["bovine", "feline"]
2536  */
2537 
2538 VALUE
2540 {
2541  VALUE result = rb_ary_new2(argc);
2542  long i;
2543 
2544  for (i=0; i<argc; i++) {
2545  rb_ary_push(result, rb_hash_aref(hash, argv[i]));
2546  }
2547  return result;
2548 }
2549 
2550 /*
2551  * call-seq:
2552  * hsh.fetch_values(key, ...) -> array
2553  * hsh.fetch_values(key, ...) { |key| block } -> array
2554  *
2555  * Returns an array containing the values associated with the given keys
2556  * but also raises KeyError when one of keys can't be found.
2557  * Also see Hash#values_at and Hash#fetch.
2558  *
2559  * h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
2560  *
2561  * h.fetch_values("cow", "cat") #=> ["bovine", "feline"]
2562  * h.fetch_values("cow", "bird") # raises KeyError
2563  * h.fetch_values("cow", "bird") { |k| k.upcase } #=> ["bovine", "BIRD"]
2564  */
2565 
2566 VALUE
2568 {
2569  VALUE result = rb_ary_new2(argc);
2570  long i;
2571 
2572  for (i=0; i<argc; i++) {
2573  rb_ary_push(result, rb_hash_fetch(hash, argv[i]));
2574  }
2575  return result;
2576 }
2577 
2578 static int
2579 select_i(VALUE key, VALUE value, VALUE result)
2580 {
2581  if (RTEST(rb_yield_values(2, key, value))) {
2582  rb_hash_aset(result, key, value);
2583  }
2584  return ST_CONTINUE;
2585 }
2586 
2587 /*
2588  * call-seq:
2589  * hsh.select {|key, value| block} -> a_hash
2590  * hsh.select -> an_enumerator
2591  * hsh.filter {|key, value| block} -> a_hash
2592  * hsh.filter -> an_enumerator
2593  *
2594  * Returns a new hash consisting of entries for which the block returns true.
2595  *
2596  * If no block is given, an enumerator is returned instead.
2597  *
2598  * h = { "a" => 100, "b" => 200, "c" => 300 }
2599  * h.select {|k,v| k > "a"} #=> {"b" => 200, "c" => 300}
2600  * h.select {|k,v| v < 200} #=> {"a" => 100}
2601  *
2602  * Hash#filter is an alias for Hash#select.
2603  */
2604 
2605 VALUE
2607 {
2608  VALUE result;
2609 
2610  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2611  result = rb_hash_new();
2612  if (!RHASH_EMPTY_P(hash)) {
2613  rb_hash_foreach(hash, select_i, result);
2614  }
2615  return result;
2616 }
2617 
2618 static int
2619 keep_if_i(VALUE key, VALUE value, VALUE hash)
2620 {
2621  if (!RTEST(rb_yield_values(2, key, value))) {
2622  return ST_DELETE;
2623  }
2624  return ST_CONTINUE;
2625 }
2626 
2627 /*
2628  * call-seq:
2629  * hsh.select! {| key, value | block } -> hsh or nil
2630  * hsh.select! -> an_enumerator
2631  * hsh.filter! {| key, value | block } -> hsh or nil
2632  * hsh.filter! -> an_enumerator
2633  *
2634  * Equivalent to Hash#keep_if, but returns
2635  * +nil+ if no changes were made.
2636  *
2637  * Hash#filter! is an alias for Hash#select!.
2638  */
2639 
2640 VALUE
2642 {
2643  st_index_t n;
2644 
2645  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2646  rb_hash_modify_check(hash);
2647  n = RHASH_SIZE(hash);
2648  if (!n) return Qnil;
2649  rb_hash_foreach(hash, keep_if_i, hash);
2650  if (n == RHASH_SIZE(hash)) return Qnil;
2651  return hash;
2652 }
2653 
2654 /*
2655  * call-seq:
2656  * hsh.keep_if {| key, value | block } -> hsh
2657  * hsh.keep_if -> an_enumerator
2658  *
2659  * Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
2660  * evaluates to +false+.
2661  *
2662  * If no block is given, an enumerator is returned instead.
2663  *
2664  * See also Hash#select!.
2665  */
2666 
2667 VALUE
2669 {
2670  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2671  rb_hash_modify_check(hash);
2672  if (!RHASH_TABLE_EMPTY_P(hash)) {
2673  rb_hash_foreach(hash, keep_if_i, hash);
2674  }
2675  return hash;
2676 }
2677 
2678 static int
2679 clear_i(VALUE key, VALUE value, VALUE dummy)
2680 {
2681  return ST_DELETE;
2682 }
2683 
2684 /*
2685  * call-seq:
2686  * hsh.clear -> hsh
2687  *
2688  * Removes all key-value pairs from <i>hsh</i>.
2689  *
2690  * h = { "a" => 100, "b" => 200 } #=> {"a"=>100, "b"=>200}
2691  * h.clear #=> {}
2692  *
2693  */
2694 
2695 VALUE
2697 {
2698  rb_hash_modify_check(hash);
2699 
2700  if (RHASH_ITER_LEV(hash) > 0) {
2701  rb_hash_foreach(hash, clear_i, 0);
2702  }
2703  else if (RHASH_AR_TABLE_P(hash)) {
2704  ar_clear(hash);
2705  }
2706  else {
2707  st_clear(RHASH_ST_TABLE(hash));
2708  }
2709 
2710  return hash;
2711 }
2712 
2713 static int
2714 hash_aset(st_data_t *key, st_data_t *val, struct update_arg *arg, int existing)
2715 {
2716  if (existing) {
2717  arg->new_value = arg->arg;
2718  arg->old_value = *val;
2719  }
2720  else {
2721  arg->new_key = *key;
2722  arg->new_value = arg->arg;
2723  }
2724  *val = arg->arg;
2725  return ST_CONTINUE;
2726 }
2727 
2728 VALUE
2730 {
2732  return rb_fstring(key);
2733  }
2734  else {
2735  return rb_str_new_frozen(key);
2736  }
2737 }
2738 
2739 static int
2740 hash_aset_str(st_data_t *key, st_data_t *val, struct update_arg *arg, int existing)
2741 {
2742  if (!existing && !RB_OBJ_FROZEN(*key)) {
2743  *key = rb_hash_key_str(*key);
2744  }
2745  return hash_aset(key, val, arg, existing);
2746 }
2747 
2748 NOINSERT_UPDATE_CALLBACK(hash_aset)
2749 NOINSERT_UPDATE_CALLBACK(hash_aset_str)
2750 
2751 /*
2752  * call-seq:
2753  * hsh[key] = value -> value
2754  * hsh.store(key, value) -> value
2755  *
2756  * == Element Assignment
2757  *
2758  * Associates the value given by +value+ with the key given by +key+.
2759  *
2760  * h = { "a" => 100, "b" => 200 }
2761  * h["a"] = 9
2762  * h["c"] = 4
2763  * h #=> {"a"=>9, "b"=>200, "c"=>4}
2764  * h.store("d", 42) #=> 42
2765  * h #=> {"a"=>9, "b"=>200, "c"=>4, "d"=>42}
2766  *
2767  * +key+ should not have its value changed while it is in use as a key (an
2768  * <tt>unfrozen String</tt> passed as a key will be duplicated and frozen).
2769  *
2770  * a = "a"
2771  * b = "b".freeze
2772  * h = { a => 100, b => 200 }
2773  * h.key(100).equal? a #=> false
2774  * h.key(200).equal? b #=> true
2775  *
2776  */
2777 
2778 VALUE
2780 {
2781  int iter_lev = RHASH_ITER_LEV(hash);
2782 
2783  rb_hash_modify(hash);
2784 
2785  if (RHASH_TABLE_NULL_P(hash)) {
2786  if (iter_lev > 0) no_new_key();
2787  ar_alloc_table(hash);
2788  }
2789 
2790  if (RHASH_TYPE(hash) == &identhash || rb_obj_class(key) != rb_cString) {
2791  RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset, val);
2792  }
2793  else {
2794  RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset_str, val);
2795  }
2796  return val;
2797 }
2798 
2799 /*
2800  * call-seq:
2801  * hsh.replace(other_hash) -> hsh
2802  *
2803  * Replaces the contents of <i>hsh</i> with the contents of
2804  * <i>other_hash</i>.
2805  *
2806  * h = { "a" => 100, "b" => 200 }
2807  * h.replace({ "c" => 300, "d" => 400 }) #=> {"c"=>300, "d"=>400}
2808  *
2809  */
2810 
2811 static VALUE
2812 rb_hash_replace(VALUE hash, VALUE hash2)
2813 {
2814  rb_hash_modify_check(hash);
2815  if (hash == hash2) return hash;
2816  if (RHASH_ITER_LEV(hash) > 0) {
2817  rb_raise(rb_eRuntimeError, "can't replace hash during iteration");
2818  }
2819  hash2 = to_hash(hash2);
2820 
2821  COPY_DEFAULT(hash, hash2);
2822 
2823  if (RHASH_AR_TABLE_P(hash)) {
2824  if (RHASH_AR_TABLE_P(hash2)) {
2825  ar_clear(hash);
2826  }
2827  else {
2828  ar_free_and_clear_table(hash);
2830  }
2831  }
2832  else {
2833  if (RHASH_AR_TABLE_P(hash2)) {
2835  RHASH_ST_CLEAR(hash);
2836  }
2837  else {
2838  st_clear(RHASH_ST_TABLE(hash));
2839  RHASH_TBL_RAW(hash)->type = RHASH_ST_TABLE(hash2)->type;
2840  }
2841  }
2842  rb_hash_foreach(hash2, rb_hash_rehash_i, (VALUE)hash);
2843 
2845 
2846  return hash;
2847 }
2848 
2849 /*
2850  * call-seq:
2851  * hsh.length -> integer
2852  * hsh.size -> integer
2853  *
2854  * Returns the number of key-value pairs in the hash.
2855  *
2856  * h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
2857  * h.size #=> 4
2858  * h.delete("a") #=> 200
2859  * h.size #=> 3
2860  * h.length #=> 3
2861  *
2862  * Hash#length is an alias for Hash#size.
2863  */
2864 
2865 VALUE
2867 {
2868  return INT2FIX(RHASH_SIZE(hash));
2869 }
2870 
2871 size_t
2873 {
2874  return (long)RHASH_SIZE(hash);
2875 }
2876 
2877 /*
2878  * call-seq:
2879  * hsh.empty? -> true or false
2880  *
2881  * Returns <code>true</code> if <i>hsh</i> contains no key-value pairs.
2882  *
2883  * {}.empty? #=> true
2884  *
2885  */
2886 
2887 static VALUE
2888 rb_hash_empty_p(VALUE hash)
2889 {
2890  return RHASH_EMPTY_P(hash) ? Qtrue : Qfalse;
2891 }
2892 
2893 static int
2894 each_value_i(VALUE key, VALUE value, VALUE _)
2895 {
2896  rb_yield(value);
2897  return ST_CONTINUE;
2898 }
2899 
2900 /*
2901  * call-seq:
2902  * hsh.each_value {| value | block } -> hsh
2903  * hsh.each_value -> an_enumerator
2904  *
2905  * Calls <i>block</i> once for each key in <i>hsh</i>, passing the
2906  * value as a parameter.
2907  *
2908  * If no block is given, an enumerator is returned instead.
2909  *
2910  * h = { "a" => 100, "b" => 200 }
2911  * h.each_value {|value| puts value }
2912  *
2913  * <em>produces:</em>
2914  *
2915  * 100
2916  * 200
2917  */
2918 
2919 static VALUE
2920 rb_hash_each_value(VALUE hash)
2921 {
2922  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2923  rb_hash_foreach(hash, each_value_i, 0);
2924  return hash;
2925 }
2926 
2927 static int
2928 each_key_i(VALUE key, VALUE value, VALUE _)
2929 {
2930  rb_yield(key);
2931  return ST_CONTINUE;
2932 }
2933 
2934 /*
2935  * call-seq:
2936  * hsh.each_key {| key | block } -> hsh
2937  * hsh.each_key -> an_enumerator
2938  *
2939  * Calls <i>block</i> once for each key in <i>hsh</i>, passing the key
2940  * as a parameter.
2941  *
2942  * If no block is given, an enumerator is returned instead.
2943  *
2944  * h = { "a" => 100, "b" => 200 }
2945  * h.each_key {|key| puts key }
2946  *
2947  * <em>produces:</em>
2948  *
2949  * a
2950  * b
2951  */
2952 static VALUE
2953 rb_hash_each_key(VALUE hash)
2954 {
2955  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2956  rb_hash_foreach(hash, each_key_i, 0);
2957  return hash;
2958 }
2959 
2960 static int
2961 each_pair_i(VALUE key, VALUE value, VALUE _)
2962 {
2963  rb_yield(rb_assoc_new(key, value));
2964  return ST_CONTINUE;
2965 }
2966 
2967 static int
2968 each_pair_i_fast(VALUE key, VALUE value, VALUE _)
2969 {
2970  VALUE argv[2];
2971  argv[0] = key;
2972  argv[1] = value;
2973  rb_yield_values2(2, argv);
2974  return ST_CONTINUE;
2975 }
2976 
2977 /*
2978  * call-seq:
2979  * hsh.each {| key, value | block } -> hsh
2980  * hsh.each_pair {| key, value | block } -> hsh
2981  * hsh.each -> an_enumerator
2982  * hsh.each_pair -> an_enumerator
2983  *
2984  * Calls <i>block</i> once for each key in <i>hsh</i>, passing the key-value
2985  * pair as parameters.
2986  *
2987  * If no block is given, an enumerator is returned instead.
2988  *
2989  * h = { "a" => 100, "b" => 200 }
2990  * h.each {|key, value| puts "#{key} is #{value}" }
2991  *
2992  * <em>produces:</em>
2993  *
2994  * a is 100
2995  * b is 200
2996  *
2997  */
2998 
2999 static VALUE
3000 rb_hash_each_pair(VALUE hash)
3001 {
3002  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3003  if (rb_block_arity() > 1)
3004  rb_hash_foreach(hash, each_pair_i_fast, 0);
3005  else
3006  rb_hash_foreach(hash, each_pair_i, 0);
3007  return hash;
3008 }
3009 
3010 static int
3011 transform_keys_i(VALUE key, VALUE value, VALUE result)
3012 {
3013  VALUE new_key = rb_yield(key);
3014  rb_hash_aset(result, new_key, value);
3015  return ST_CONTINUE;
3016 }
3017 
3018 /*
3019  * call-seq:
3020  * hsh.transform_keys {|key| block } -> new_hash
3021  * hsh.transform_keys -> an_enumerator
3022  *
3023  * Returns a new hash with the results of running the block once for
3024  * every key.
3025  * This method does not change the values.
3026  *
3027  * h = { a: 1, b: 2, c: 3 }
3028  * h.transform_keys {|k| k.to_s } #=> { "a" => 1, "b" => 2, "c" => 3 }
3029  * h.transform_keys(&:to_s) #=> { "a" => 1, "b" => 2, "c" => 3 }
3030  * h.transform_keys.with_index {|k, i| "#{k}.#{i}" }
3031  * #=> { "a.0" => 1, "b.1" => 2, "c.2" => 3 }
3032  *
3033  * If no block is given, an enumerator is returned instead.
3034  */
3035 static VALUE
3036 rb_hash_transform_keys(VALUE hash)
3037 {
3038  VALUE result;
3039 
3040  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3041  result = rb_hash_new();
3042  if (!RHASH_EMPTY_P(hash)) {
3043  rb_hash_foreach(hash, transform_keys_i, result);
3044  }
3045 
3046  return result;
3047 }
3048 
3049 static VALUE rb_hash_flatten(int argc, VALUE *argv, VALUE hash);
3050 
3051 /*
3052  * call-seq:
3053  * hsh.transform_keys! {|key| block } -> hsh
3054  * hsh.transform_keys! -> an_enumerator
3055  *
3056  * Invokes the given block once for each key in <i>hsh</i>, replacing it
3057  * with the new key returned by the block, and then returns <i>hsh</i>.
3058  * This method does not change the values.
3059  *
3060  * h = { a: 1, b: 2, c: 3 }
3061  * h.transform_keys! {|k| k.to_s } #=> { "a" => 1, "b" => 2, "c" => 3 }
3062  * h.transform_keys!(&:to_sym) #=> { a: 1, b: 2, c: 3 }
3063  * h.transform_keys!.with_index {|k, i| "#{k}.#{i}" }
3064  * #=> { "a.0" => 1, "b.1" => 2, "c.2" => 3 }
3065  *
3066  * If no block is given, an enumerator is returned instead.
3067  */
3068 static VALUE
3069 rb_hash_transform_keys_bang(VALUE hash)
3070 {
3071  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3072  rb_hash_modify_check(hash);
3073  if (!RHASH_TABLE_EMPTY_P(hash)) {
3074  long i;
3075  VALUE pairs = rb_hash_flatten(0, NULL, hash);
3076  rb_hash_clear(hash);
3077  for (i = 0; i < RARRAY_LEN(pairs); i += 2) {
3078  VALUE key = RARRAY_AREF(pairs, i), new_key = rb_yield(key),
3079  val = RARRAY_AREF(pairs, i+1);
3080  rb_hash_aset(hash, new_key, val);
3081  }
3082  }
3083  return hash;
3084 }
3085 
3086 static int
3087 transform_values_foreach_func(st_data_t key, st_data_t value, st_data_t argp, int error)
3088 {
3089  return ST_REPLACE;
3090 }
3091 
3092 static int
3093 transform_values_foreach_replace(st_data_t *key, st_data_t *value, st_data_t argp, int existing)
3094 {
3095  VALUE new_value = rb_yield((VALUE)*value);
3096  *value = new_value;
3097  return ST_CONTINUE;
3098 }
3099 
3100 /*
3101  * call-seq:
3102  * hsh.transform_values {|value| block } -> new_hash
3103  * hsh.transform_values -> an_enumerator
3104  *
3105  * Returns a new hash with the results of running the block once for
3106  * every value.
3107  * This method does not change the keys.
3108  *
3109  * h = { a: 1, b: 2, c: 3 }
3110  * h.transform_values {|v| v * v + 1 } #=> { a: 2, b: 5, c: 10 }
3111  * h.transform_values(&:to_s) #=> { a: "1", b: "2", c: "3" }
3112  * h.transform_values.with_index {|v, i| "#{v}.#{i}" }
3113  * #=> { a: "1.0", b: "2.1", c: "3.2" }
3114  *
3115  * If no block is given, an enumerator is returned instead.
3116  */
3117 static VALUE
3118 rb_hash_transform_values(VALUE hash)
3119 {
3120  VALUE result;
3121 
3122  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3123  result = hash_dup(hash, rb_cHash, 0);
3124 
3125  if (!RHASH_EMPTY_P(hash)) {
3126  rb_hash_stlike_foreach_with_replace(result, transform_values_foreach_func, transform_values_foreach_replace, 0);
3127  }
3128 
3129  return result;
3130 }
3131 
3132 /*
3133  * call-seq:
3134  * hsh.transform_values! {|value| block } -> hsh
3135  * hsh.transform_values! -> an_enumerator
3136  *
3137  * Invokes the given block once for each value in <i>hsh</i>, replacing it
3138  * with the new value returned by the block, and then returns <i>hsh</i>.
3139  * This method does not change the keys.
3140  *
3141  * h = { a: 1, b: 2, c: 3 }
3142  * h.transform_values! {|v| v * v + 1 } #=> { a: 2, b: 5, c: 10 }
3143  * h.transform_values!(&:to_s) #=> { a: "2", b: "5", c: "10" }
3144  * h.transform_values!.with_index {|v, i| "#{v}.#{i}" }
3145  * #=> { a: "2.0", b: "5.1", c: "10.2" }
3146  *
3147  * If no block is given, an enumerator is returned instead.
3148  */
3149 static VALUE
3150 rb_hash_transform_values_bang(VALUE hash)
3151 {
3152  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3153  rb_hash_modify_check(hash);
3154 
3155  if (!RHASH_TABLE_EMPTY_P(hash)) {
3156  rb_hash_stlike_foreach_with_replace(hash, transform_values_foreach_func, transform_values_foreach_replace, 0);
3157  }
3158 
3159  return hash;
3160 }
3161 
3162 static int
3163 to_a_i(VALUE key, VALUE value, VALUE ary)
3164 {
3165  rb_ary_push(ary, rb_assoc_new(key, value));
3166  return ST_CONTINUE;
3167 }
3168 
3169 /*
3170  * call-seq:
3171  * hsh.to_a -> array
3172  *
3173  * Converts <i>hsh</i> to a nested array of <code>[</code> <i>key,
3174  * value</i> <code>]</code> arrays.
3175  *
3176  * h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 }
3177  * h.to_a #=> [["c", 300], ["a", 100], ["d", 400]]
3178  */
3179 
3180 static VALUE
3181 rb_hash_to_a(VALUE hash)
3182 {
3183  VALUE ary;
3184 
3185  ary = rb_ary_new_capa(RHASH_SIZE(hash));
3186  rb_hash_foreach(hash, to_a_i, ary);
3187 
3188  return ary;
3189 }
3190 
3191 static int
3192 inspect_i(VALUE key, VALUE value, VALUE str)
3193 {
3194  VALUE str2;
3195 
3196  str2 = rb_inspect(key);
3197  if (RSTRING_LEN(str) > 1) {
3198  rb_str_buf_cat_ascii(str, ", ");
3199  }
3200  else {
3201  rb_enc_copy(str, str2);
3202  }
3203  rb_str_buf_append(str, str2);
3204  rb_str_buf_cat_ascii(str, "=>");
3205  str2 = rb_inspect(value);
3206  rb_str_buf_append(str, str2);
3207 
3208  return ST_CONTINUE;
3209 }
3210 
3211 static VALUE
3212 inspect_hash(VALUE hash, VALUE dummy, int recur)
3213 {
3214  VALUE str;
3215 
3216  if (recur) return rb_usascii_str_new2("{...}");
3217  str = rb_str_buf_new2("{");
3218  rb_hash_foreach(hash, inspect_i, str);
3219  rb_str_buf_cat2(str, "}");
3220 
3221  return str;
3222 }
3223 
3224 /*
3225  * call-seq:
3226  * hsh.to_s -> string
3227  * hsh.inspect -> string
3228  *
3229  * Return the contents of this hash as a string.
3230  *
3231  * h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 }
3232  * h.to_s #=> "{\"c\"=>300, \"a\"=>100, \"d\"=>400}"
3233  */
3234 
3235 static VALUE
3236 rb_hash_inspect(VALUE hash)
3237 {
3238  if (RHASH_EMPTY_P(hash))
3239  return rb_usascii_str_new2("{}");
3240  return rb_exec_recursive(inspect_hash, hash, 0);
3241 }
3242 
3243 /*
3244  * call-seq:
3245  * hsh.to_hash => hsh
3246  *
3247  * Returns +self+.
3248  */
3249 
3250 static VALUE
3251 rb_hash_to_hash(VALUE hash)
3252 {
3253  return hash;
3254 }
3255 
3256 VALUE
3258 {
3259  VALUE pair;
3260 
3261  pair = rb_check_array_type(arg);
3262  if (NIL_P(pair)) {
3263  rb_raise(rb_eTypeError, "wrong element type %s (expected array)",
3265  }
3266  if (RARRAY_LEN(pair) != 2) {
3267  rb_raise(rb_eArgError, "element has wrong array length (expected 2, was %ld)",
3268  RARRAY_LEN(pair));
3269  }
3270  rb_hash_aset(hash, RARRAY_AREF(pair, 0), RARRAY_AREF(pair, 1));
3271  return hash;
3272 }
3273 
3274 static int
3275 to_h_i(VALUE key, VALUE value, VALUE hash)
3276 {
3277  rb_hash_set_pair(hash, rb_yield_values(2, key, value));
3278  return ST_CONTINUE;
3279 }
3280 
3281 static VALUE
3282 rb_hash_to_h_block(VALUE hash)
3283 {
3285  rb_hash_foreach(hash, to_h_i, h);
3286  return h;
3287 }
3288 
3289 /*
3290  * call-seq:
3291  * hsh.to_h -> hsh or new_hash
3292  * hsh.to_h {|key, value| block } -> new_hash
3293  *
3294  * Returns +self+. If called on a subclass of Hash, converts
3295  * the receiver to a Hash object.
3296  *
3297  * If a block is given, the results of the block on each pair of
3298  * the receiver will be used as pairs.
3299  */
3300 
3301 static VALUE
3302 rb_hash_to_h(VALUE hash)
3303 {
3304  if (rb_block_given_p()) {
3305  return rb_hash_to_h_block(hash);
3306  }
3307  if (rb_obj_class(hash) != rb_cHash) {
3308  const VALUE flags = RBASIC(hash)->flags;
3309  hash = hash_dup(hash, rb_cHash, flags & RHASH_PROC_DEFAULT);
3310  }
3311  return hash;
3312 }
3313 
3314 static int
3315 keys_i(VALUE key, VALUE value, VALUE ary)
3316 {
3317  rb_ary_push(ary, key);
3318  return ST_CONTINUE;
3319 }
3320 
3321 /*
3322  * call-seq:
3323  * hsh.keys -> array
3324  *
3325  * Returns a new array populated with the keys from this hash. See also
3326  * Hash#values.
3327  *
3328  * h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 }
3329  * h.keys #=> ["a", "b", "c", "d"]
3330  *
3331  */
3332 
3335 {
3336  st_index_t size = RHASH_SIZE(hash);
3338 
3339  if (size == 0) return keys;
3340 
3341  if (ST_DATA_COMPATIBLE_P(VALUE)) {
3343  if (RHASH_AR_TABLE_P(hash)) {
3344  size = ar_keys(hash, ptr, size);
3345  }
3346  else {
3347  st_table *table = RHASH_ST_TABLE(hash);
3348  size = st_keys(table, ptr, size);
3349  }
3350  });
3353  }
3354  else {
3355  rb_hash_foreach(hash, keys_i, keys);
3356  }
3357 
3358  return keys;
3359 }
3360 
3361 static int
3362 values_i(VALUE key, VALUE value, VALUE ary)
3363 {
3364  rb_ary_push(ary, value);
3365  return ST_CONTINUE;
3366 }
3367 
3368 /*
3369  * call-seq:
3370  * hsh.values -> array
3371  *
3372  * Returns a new array populated with the values from <i>hsh</i>. See
3373  * also Hash#keys.
3374  *
3375  * h = { "a" => 100, "b" => 200, "c" => 300 }
3376  * h.values #=> [100, 200, 300]
3377  *
3378  */
3379 
3380 VALUE
3382 {
3383  VALUE values;
3384  st_index_t size = RHASH_SIZE(hash);
3385 
3386  values = rb_ary_new_capa(size);
3387  if (size == 0) return values;
3388 
3389  if (ST_DATA_COMPATIBLE_P(VALUE)) {
3390  if (RHASH_AR_TABLE_P(hash)) {
3392  RARRAY_PTR_USE_TRANSIENT(values, ptr, {
3393  size = ar_values(hash, ptr, size);
3394  });
3395  }
3396  else if (RHASH_ST_TABLE_P(hash)) {
3397  st_table *table = RHASH_ST_TABLE(hash);
3399  RARRAY_PTR_USE_TRANSIENT(values, ptr, {
3400  size = st_values(table, ptr, size);
3401  });
3402  }
3403  rb_ary_set_len(values, size);
3404  }
3405  else {
3406  rb_hash_foreach(hash, values_i, values);
3407  }
3408 
3409  return values;
3410 }
3411 
3412 /*
3413  * call-seq:
3414  * hsh.has_key?(key) -> true or false
3415  * hsh.include?(key) -> true or false
3416  * hsh.key?(key) -> true or false
3417  * hsh.member?(key) -> true or false
3418  *
3419  * Returns <code>true</code> if the given key is present in <i>hsh</i>.
3420  *
3421  * h = { "a" => 100, "b" => 200 }
3422  * h.has_key?("a") #=> true
3423  * h.has_key?("z") #=> false
3424  *
3425  * Note that #include? and #member? do not test member
3426  * equality using <code>==</code> as do other Enumerables.
3427  *
3428  * See also Enumerable#include?
3429  */
3430 
3433 {
3434  if (hash_stlike_lookup(hash, key, NULL)) {
3435  return Qtrue;
3436  }
3437  else {
3438  return Qfalse;
3439  }
3440 }
3441 
3442 static int
3443 rb_hash_search_value(VALUE key, VALUE value, VALUE arg)
3444 {
3445  VALUE *data = (VALUE *)arg;
3446 
3447  if (rb_equal(value, data[1])) {
3448  data[0] = Qtrue;
3449  return ST_STOP;
3450  }
3451  return ST_CONTINUE;
3452 }
3453 
3454 /*
3455  * call-seq:
3456  * hsh.has_value?(value) -> true or false
3457  * hsh.value?(value) -> true or false
3458  *
3459  * Returns <code>true</code> if the given value is present for some key
3460  * in <i>hsh</i>.
3461  *
3462  * h = { "a" => 100, "b" => 200 }
3463  * h.value?(100) #=> true
3464  * h.value?(999) #=> false
3465  */
3466 
3467 static VALUE
3468 rb_hash_has_value(VALUE hash, VALUE val)
3469 {
3470  VALUE data[2];
3471 
3472  data[0] = Qfalse;
3473  data[1] = val;
3474  rb_hash_foreach(hash, rb_hash_search_value, (VALUE)data);
3475  return data[0];
3476 }
3477 
3478 struct equal_data {
3481  int eql;
3482 };
3483 
3484 static int
3485 eql_i(VALUE key, VALUE val1, VALUE arg)
3486 {
3487  struct equal_data *data = (struct equal_data *)arg;
3488  st_data_t val2;
3489 
3490  if (!hash_stlike_lookup(data->hash, key, &val2)) {
3491  data->result = Qfalse;
3492  return ST_STOP;
3493  }
3494  else {
3495  if (!(data->eql ? rb_eql(val1, (VALUE)val2) : (int)rb_equal(val1, (VALUE)val2))) {
3496  data->result = Qfalse;
3497  return ST_STOP;
3498  }
3499  return ST_CONTINUE;
3500  }
3501 }
3502 
3503 static VALUE
3504 recursive_eql(VALUE hash, VALUE dt, int recur)
3505 {
3506  struct equal_data *data;
3507 
3508  if (recur) return Qtrue; /* Subtle! */
3509  data = (struct equal_data*)dt;
3510  data->result = Qtrue;
3511  rb_hash_foreach(hash, eql_i, dt);
3512 
3513  return data->result;
3514 }
3515 
3516 static VALUE
3517 hash_equal(VALUE hash1, VALUE hash2, int eql)
3518 {
3519  struct equal_data data;
3520 
3521  if (hash1 == hash2) return Qtrue;
3522  if (!RB_TYPE_P(hash2, T_HASH)) {
3523  if (!rb_respond_to(hash2, idTo_hash)) {
3524  return Qfalse;
3525  }
3526  if (eql) {
3527  if (rb_eql(hash2, hash1)) {
3528  return Qtrue;
3529  }
3530  else {
3531  return Qfalse;
3532  }
3533  }
3534  else {
3535  return rb_equal(hash2, hash1);
3536  }
3537  }
3538  if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2))
3539  return Qfalse;
3540  if (!RHASH_TABLE_EMPTY_P(hash1) && !RHASH_TABLE_EMPTY_P(hash2)) {
3541  if (RHASH_TYPE(hash1) != RHASH_TYPE(hash2)) {
3542  return Qfalse;
3543  }
3544  else {
3545  data.hash = hash2;
3546  data.eql = eql;
3547  return rb_exec_recursive_paired(recursive_eql, hash1, hash2, (VALUE)&data);
3548  }
3549  }
3550 
3551 #if 0
3552  if (!(rb_equal(RHASH_IFNONE(hash1), RHASH_IFNONE(hash2)) &&
3554  return Qfalse;
3555 #endif
3556  return Qtrue;
3557 }
3558 
3559 /*
3560  * call-seq:
3561  * hsh == other_hash -> true or false
3562  *
3563  * Equality---Two hashes are equal if they each contain the same number
3564  * of keys and if each key-value pair is equal to (according to
3565  * Object#==) the corresponding elements in the other hash.
3566  *
3567  * h1 = { "a" => 1, "c" => 2 }
3568  * h2 = { 7 => 35, "c" => 2, "a" => 1 }
3569  * h3 = { "a" => 1, "c" => 2, 7 => 35 }
3570  * h4 = { "a" => 1, "d" => 2, "f" => 35 }
3571  * h1 == h2 #=> false
3572  * h2 == h3 #=> true
3573  * h3 == h4 #=> false
3574  *
3575  * The orders of each hashes are not compared.
3576  *
3577  * h1 = { "a" => 1, "c" => 2 }
3578  * h2 = { "c" => 2, "a" => 1 }
3579  * h1 == h2 #=> true
3580  *
3581  */
3582 
3583 static VALUE
3584 rb_hash_equal(VALUE hash1, VALUE hash2)
3585 {
3586  return hash_equal(hash1, hash2, FALSE);
3587 }
3588 
3589 /*
3590  * call-seq:
3591  * hash.eql?(other) -> true or false
3592  *
3593  * Returns <code>true</code> if <i>hash</i> and <i>other</i> are
3594  * both hashes with the same content.
3595  * The orders of each hashes are not compared.
3596  */
3597 
3598 static VALUE
3599 rb_hash_eql(VALUE hash1, VALUE hash2)
3600 {
3601  return hash_equal(hash1, hash2, TRUE);
3602 }
3603 
3604 static int
3605 hash_i(VALUE key, VALUE val, VALUE arg)
3606 {
3607  st_index_t *hval = (st_index_t *)arg;
3608  st_index_t hdata[2];
3609 
3610  hdata[0] = rb_hash(key);
3611  hdata[1] = rb_hash(val);
3612  *hval ^= st_hash(hdata, sizeof(hdata), 0);
3613  return ST_CONTINUE;
3614 }
3615 
3616 /*
3617  * call-seq:
3618  * hsh.hash -> integer
3619  *
3620  * Compute a hash-code for this hash. Two hashes with the same content
3621  * will have the same hash code (and will compare using <code>eql?</code>).
3622  *
3623  * See also Object#hash.
3624  */
3625 
3626 static VALUE
3627 rb_hash_hash(VALUE hash)
3628 {
3630  st_index_t hval = rb_hash_start(size);
3631  hval = rb_hash_uint(hval, (st_index_t)rb_hash_hash);
3632  if (size) {
3633  rb_hash_foreach(hash, hash_i, (VALUE)&hval);
3634  }
3635  hval = rb_hash_end(hval);
3636  return ST2FIX(hval);
3637 }
3638 
3639 static int
3640 rb_hash_invert_i(VALUE key, VALUE value, VALUE hash)
3641 {
3642  rb_hash_aset(hash, value, key);
3643  return ST_CONTINUE;
3644 }
3645 
3646 /*
3647  * call-seq:
3648  * hsh.invert -> new_hash
3649  *
3650  * Returns a new hash created by using <i>hsh</i>'s values as keys, and
3651  * the keys as values.
3652  * If a key with the same value already exists in the <i>hsh</i>, then
3653  * the last one defined will be used, the earlier value(s) will be discarded.
3654  *
3655  * h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 }
3656  * h.invert #=> {0=>"a", 100=>"m", 200=>"d", 300=>"y"}
3657  *
3658  * If there is no key with the same value, Hash#invert is involutive.
3659  *
3660  * h = { a: 1, b: 3, c: 4 }
3661  * h.invert.invert == h #=> true
3662  *
3663  * The condition, no key with the same value, can be tested by comparing
3664  * the size of inverted hash.
3665  *
3666  * # no key with the same value
3667  * h = { a: 1, b: 3, c: 4 }
3668  * h.size == h.invert.size #=> true
3669  *
3670  * # two (or more) keys has the same value
3671  * h = { a: 1, b: 3, c: 1 }
3672  * h.size == h.invert.size #=> false
3673  *
3674  */
3675 
3676 static VALUE
3677 rb_hash_invert(VALUE hash)
3678 {
3680 
3681  rb_hash_foreach(hash, rb_hash_invert_i, h);
3682  return h;
3683 }
3684 
3685 static int
3686 rb_hash_update_callback(st_data_t *key, st_data_t *value, struct update_arg *arg, int existing)
3687 {
3688  if (existing) {
3689  arg->old_value = *value;
3690  arg->new_value = arg->arg;
3691  }
3692  else {
3693  arg->new_key = *key;
3694  arg->new_value = arg->arg;
3695  }
3696  *value = arg->arg;
3697  return ST_CONTINUE;
3698 }
3699 
3700 NOINSERT_UPDATE_CALLBACK(rb_hash_update_callback)
3701 
3702 static int
3703 rb_hash_update_i(VALUE key, VALUE value, VALUE hash)
3704 {
3705  RHASH_UPDATE(hash, key, rb_hash_update_callback, value);
3706  return ST_CONTINUE;
3707 }
3708 
3709 static int
3710 rb_hash_update_block_callback(st_data_t *key, st_data_t *value, struct update_arg *arg, int existing)
3711 {
3712  VALUE newvalue = (VALUE)arg->arg;
3713 
3714  if (existing) {
3715  newvalue = rb_yield_values(3, (VALUE)*key, (VALUE)*value, newvalue);
3716  arg->old_value = *value;
3717  }
3718  else {
3719  arg->new_key = *key;
3720  }
3721  arg->new_value = newvalue;
3722  *value = newvalue;
3723  return ST_CONTINUE;
3724 }
3725 
3726 NOINSERT_UPDATE_CALLBACK(rb_hash_update_block_callback)
3727 
3728 static int
3729 rb_hash_update_block_i(VALUE key, VALUE value, VALUE hash)
3730 {
3731  RHASH_UPDATE(hash, key, rb_hash_update_block_callback, value);
3732  return ST_CONTINUE;
3733 }
3734 
3735 /*
3736  * call-seq:
3737  * hsh.merge!(other_hash1, other_hash2, ...) -> hsh
3738  * hsh.update(other_hash1, other_hash2, ...) -> hsh
3739  * hsh.merge!(other_hash1, other_hash2, ...) {|key, oldval, newval| block}
3740  * -> hsh
3741  * hsh.update(other_hash1, other_hash2, ...) {|key, oldval, newval| block}
3742  * -> hsh
3743  *
3744  * Adds the contents of the given hashes to the receiver.
3745  *
3746  * If no block is given, entries with duplicate keys are overwritten
3747  * with the values from each +other_hash+ successively,
3748  * otherwise the value for each duplicate key is determined by
3749  * calling the block with the key, its value in the receiver and
3750  * its value in each +other_hash+.
3751  *
3752  * h1 = { "a" => 100, "b" => 200 }
3753  * h1.merge! #=> {"a"=>100, "b"=>200}
3754  * h1 #=> {"a"=>100, "b"=>200}
3755  *
3756  * h1 = { "a" => 100, "b" => 200 }
3757  * h2 = { "b" => 246, "c" => 300 }
3758  * h1.merge!(h2) #=> {"a"=>100, "b"=>246, "c"=>300}
3759  * h1 #=> {"a"=>100, "b"=>246, "c"=>300}
3760  *
3761  * h1 = { "a" => 100, "b" => 200 }
3762  * h2 = { "b" => 246, "c" => 300 }
3763  * h3 = { "b" => 357, "d" => 400 }
3764  * h1.merge!(h2, h3)
3765  * #=> {"a"=>100, "b"=>357, "c"=>300, "d"=>400}
3766  * h1 #=> {"a"=>100, "b"=>357, "c"=>300, "d"=>400}
3767  *
3768  * h1 = { "a" => 100, "b" => 200 }
3769  * h2 = { "b" => 246, "c" => 300 }
3770  * h3 = { "b" => 357, "d" => 400 }
3771  * h1.merge!(h2, h3) {|key, v1, v2| v1 }
3772  * #=> {"a"=>100, "b"=>200, "c"=>300, "d"=>400}
3773  * h1 #=> {"a"=>100, "b"=>200, "c"=>300, "d"=>400}
3774  *
3775  * Hash#update is an alias for Hash#merge!.
3776  */
3777 
3778 static VALUE
3779 rb_hash_update(int argc, VALUE *argv, VALUE self)
3780 {
3781  int i;
3782  bool block_given = rb_block_given_p();
3783 
3784  rb_hash_modify(self);
3785  for (i = 0; i < argc; i++){
3786  VALUE hash = to_hash(argv[i]);
3787  if (block_given) {
3788  rb_hash_foreach(hash, rb_hash_update_block_i, self);
3789  }
3790  else {
3791  rb_hash_foreach(hash, rb_hash_update_i, self);
3792  }
3793  }
3794  return self;
3795 }
3796 
3801 };
3802 
3803 static int
3804 rb_hash_update_func_callback(st_data_t *key, st_data_t *value, struct update_arg *arg, int existing)
3805 {
3806  struct update_func_arg *uf_arg = (struct update_func_arg *)arg->arg;
3807  VALUE newvalue = uf_arg->value;
3808 
3809  if (existing) {
3810  newvalue = (*uf_arg->func)((VALUE)*key, (VALUE)*value, newvalue);
3811  arg->old_value = *value;
3812  }
3813  else {
3814  arg->new_key = *key;
3815  }
3816  arg->new_value = newvalue;
3817  *value = newvalue;
3818  return ST_CONTINUE;
3819 }
3820 
3821 NOINSERT_UPDATE_CALLBACK(rb_hash_update_func_callback)
3822 
3823 static int
3824 rb_hash_update_func_i(VALUE key, VALUE value, VALUE arg0)
3825 {
3826  struct update_func_arg *arg = (struct update_func_arg *)arg0;
3827  VALUE hash = arg->hash;
3828 
3829  arg->value = value;
3830  RHASH_UPDATE(hash, key, rb_hash_update_func_callback, (VALUE)arg);
3831  return ST_CONTINUE;
3832 }
3833 
3834 VALUE
3836 {
3837  rb_hash_modify(hash1);
3838  hash2 = to_hash(hash2);
3839  if (func) {
3840  struct update_func_arg arg;
3841  arg.hash = hash1;
3842  arg.func = func;
3843  rb_hash_foreach(hash2, rb_hash_update_func_i, (VALUE)&arg);
3844  }
3845  else {
3846  rb_hash_foreach(hash2, rb_hash_update_i, hash1);
3847  }
3848  return hash1;
3849 }
3850 
3851 /*
3852  * call-seq:
3853  * hsh.merge(other_hash1, other_hash2, ...) -> new_hash
3854  * hsh.merge(other_hash1, other_hash2, ...) {|key, oldval, newval| block}
3855  * -> new_hash
3856  *
3857  * Returns a new hash that combines the contents of the receiver and
3858  * the contents of the given hashes.
3859  *
3860  * If no block is given, entries with duplicate keys are overwritten
3861  * with the values from each +other_hash+ successively,
3862  * otherwise the value for each duplicate key is determined by
3863  * calling the block with the key, its value in the receiver and
3864  * its value in each +other_hash+.
3865  *
3866  * When called without any argument, returns a copy of the receiver.
3867  *
3868  * h1 = { "a" => 100, "b" => 200 }
3869  * h2 = { "b" => 246, "c" => 300 }
3870  * h3 = { "b" => 357, "d" => 400 }
3871  * h1.merge #=> {"a"=>100, "b"=>200}
3872  * h1.merge(h2) #=> {"a"=>100, "b"=>246, "c"=>300}
3873  * h1.merge(h2, h3) #=> {"a"=>100, "b"=>357, "c"=>300, "d"=>400}
3874  * h1.merge(h2) {|key, oldval, newval| newval - oldval}
3875  * #=> {"a"=>100, "b"=>46, "c"=>300}
3876  * h1.merge(h2, h3) {|key, oldval, newval| newval - oldval}
3877  * #=> {"a"=>100, "b"=>311, "c"=>300, "d"=>400}
3878  * h1 #=> {"a"=>100, "b"=>200}
3879  *
3880  */
3881 
3882 static VALUE
3883 rb_hash_merge(int argc, VALUE *argv, VALUE self)
3884 {
3885  return rb_hash_update(argc, argv, rb_hash_dup(self));
3886 }
3887 
3888 static int
3889 assoc_cmp(VALUE a, VALUE b)
3890 {
3891  return !RTEST(rb_equal(a, b));
3892 }
3893 
3894 static VALUE
3895 lookup2_call(VALUE arg)
3896 {
3897  VALUE *args = (VALUE *)arg;
3898  return rb_hash_lookup2(args[0], args[1], Qundef);
3899 }
3900 
3903  const struct st_hash_type *orighash;
3904 };
3905 
3906 static VALUE
3907 reset_hash_type(VALUE arg)
3908 {
3909  struct reset_hash_type_arg *p = (struct reset_hash_type_arg *)arg;
3911  RHASH_ST_TABLE(p->hash)->type = p->orighash;
3912  return Qundef;
3913 }
3914 
3915 static int
3916 assoc_i(VALUE key, VALUE val, VALUE arg)
3917 {
3918  VALUE *args = (VALUE *)arg;
3919 
3920  if (RTEST(rb_equal(args[0], key))) {
3921  args[1] = rb_assoc_new(key, val);
3922  return ST_STOP;
3923  }
3924  return ST_CONTINUE;
3925 }
3926 
3927 /*
3928  * call-seq:
3929  * hash.assoc(obj) -> an_array or nil
3930  *
3931  * Searches through the hash comparing _obj_ with the key using <code>==</code>.
3932  * Returns the key-value pair (two elements array) or +nil+
3933  * if no match is found. See Array#assoc.
3934  *
3935  * h = {"colors" => ["red", "blue", "green"],
3936  * "letters" => ["a", "b", "c" ]}
3937  * h.assoc("letters") #=> ["letters", ["a", "b", "c"]]
3938  * h.assoc("foo") #=> nil
3939  */
3940 
3941 VALUE
3943 {
3944  st_table *table;
3945  const struct st_hash_type *orighash;
3946  VALUE args[2];
3947 
3948  if (RHASH_EMPTY_P(hash)) return Qnil;
3949 
3950  ar_force_convert_table(hash, __FILE__, __LINE__);
3952  table = RHASH_ST_TABLE(hash);
3953  orighash = table->type;
3954 
3955  if (orighash != &identhash) {
3956  VALUE value;
3957  struct reset_hash_type_arg ensure_arg;
3958  struct st_hash_type assochash;
3959 
3960  assochash.compare = assoc_cmp;
3961  assochash.hash = orighash->hash;
3962  table->type = &assochash;
3963  args[0] = hash;
3964  args[1] = key;
3965  ensure_arg.hash = hash;
3966  ensure_arg.orighash = orighash;
3967  value = rb_ensure(lookup2_call, (VALUE)&args, reset_hash_type, (VALUE)&ensure_arg);
3968  if (value != Qundef) return rb_assoc_new(key, value);
3969  }
3970 
3971  args[0] = key;
3972  args[1] = Qnil;
3973  rb_hash_foreach(hash, assoc_i, (VALUE)args);
3974  return args[1];
3975 }
3976 
3977 static int
3978 rassoc_i(VALUE key, VALUE val, VALUE arg)
3979 {
3980  VALUE *args = (VALUE *)arg;
3981 
3982  if (RTEST(rb_equal(args[0], val))) {
3983  args[1] = rb_assoc_new(key, val);
3984  return ST_STOP;
3985  }
3986  return ST_CONTINUE;
3987 }
3988 
3989 /*
3990  * call-seq:
3991  * hash.rassoc(obj) -> an_array or nil
3992  *
3993  * Searches through the hash comparing _obj_ with the value using <code>==</code>.
3994  * Returns the first key-value pair (two-element array) that matches. See
3995  * also Array#rassoc.
3996  *
3997  * a = {1=> "one", 2 => "two", 3 => "three", "ii" => "two"}
3998  * a.rassoc("two") #=> [2, "two"]
3999  * a.rassoc("four") #=> nil
4000  */
4001 
4002 VALUE
4004 {
4005  VALUE args[2];
4006 
4007  args[0] = obj;
4008  args[1] = Qnil;
4009  rb_hash_foreach(hash, rassoc_i, (VALUE)args);
4010  return args[1];
4011 }
4012 
4013 static int
4014 flatten_i(VALUE key, VALUE val, VALUE ary)
4015 {
4016  VALUE pair[2];
4017 
4018  pair[0] = key;
4019  pair[1] = val;
4020  rb_ary_cat(ary, pair, 2);
4021 
4022  return ST_CONTINUE;
4023 }
4024 
4025 /*
4026  * call-seq:
4027  * hash.flatten -> an_array
4028  * hash.flatten(level) -> an_array
4029  *
4030  * Returns a new array that is a one-dimensional flattening of this
4031  * hash. That is, for every key or value that is an array, extract
4032  * its elements into the new array. Unlike Array#flatten, this
4033  * method does not flatten recursively by default. The optional
4034  * <i>level</i> argument determines the level of recursion to flatten.
4035  *
4036  * a = {1=> "one", 2 => [2,"two"], 3 => "three"}
4037  * a.flatten # => [1, "one", 2, [2, "two"], 3, "three"]
4038  * a.flatten(2) # => [1, "one", 2, 2, "two", 3, "three"]
4039  */
4040 
4041 static VALUE
4042 rb_hash_flatten(int argc, VALUE *argv, VALUE hash)
4043 {
4044  VALUE ary;
4045 
4046  rb_check_arity(argc, 0, 1);
4047 
4048  if (argc) {
4049  int level = NUM2INT(argv[0]);
4050 
4051  if (level == 0) return rb_hash_to_a(hash);
4052 
4053  ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2);
4054  rb_hash_foreach(hash, flatten_i, ary);
4055  level--;
4056 
4057  if (level > 0) {
4058  VALUE ary_flatten_level = INT2FIX(level);
4059  rb_funcallv(ary, id_flatten_bang, 1, &ary_flatten_level);
4060  }
4061  else if (level < 0) {
4062  /* flatten recursively */
4063  rb_funcallv(ary, id_flatten_bang, 0, 0);
4064  }
4065  }
4066  else {
4067  ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2);
4068  rb_hash_foreach(hash, flatten_i, ary);
4069  }
4070 
4071  return ary;
4072 }
4073 
4074 static int
4075 delete_if_nil(VALUE key, VALUE value, VALUE hash)
4076 {
4077  if (NIL_P(value)) {
4078  return ST_DELETE;
4079  }
4080  return ST_CONTINUE;
4081 }
4082 
4083 static int
4084 set_if_not_nil(VALUE key, VALUE value, VALUE hash)
4085 {
4086  if (!NIL_P(value)) {
4087  rb_hash_aset(hash, key, value);
4088  }
4089  return ST_CONTINUE;
4090 }
4091 
4092 /*
4093  * call-seq:
4094  * hsh.compact -> new_hash
4095  *
4096  * Returns a new hash with the nil values/key pairs removed
4097  *
4098  * h = { a: 1, b: false, c: nil }
4099  * h.compact #=> { a: 1, b: false }
4100  * h #=> { a: 1, b: false, c: nil }
4101  *
4102  */
4103 
4104 static VALUE
4105 rb_hash_compact(VALUE hash)
4106 {
4107  VALUE result = rb_hash_new();
4108  if (!RHASH_EMPTY_P(hash)) {
4109  rb_hash_foreach(hash, set_if_not_nil, result);
4110  }
4111  return result;
4112 }
4113 
4114 /*
4115  * call-seq:
4116  * hsh.compact! -> hsh or nil
4117  *
4118  * Removes all nil values from the hash.
4119  * Returns nil if no changes were made, otherwise returns the hash.
4120  *
4121  * h = { a: 1, b: false, c: nil }
4122  * h.compact! #=> { a: 1, b: false }
4123  *
4124  */
4125 
4126 static VALUE
4127 rb_hash_compact_bang(VALUE hash)
4128 {
4129  st_index_t n;
4130  rb_hash_modify_check(hash);
4131  n = RHASH_SIZE(hash);
4132  if (n) {
4133  rb_hash_foreach(hash, delete_if_nil, hash);
4134  if (n != RHASH_SIZE(hash))
4135  return hash;
4136  }
4137  return Qnil;
4138 }
4139 
4140 static st_table *rb_init_identtable_with_size(st_index_t size);
4141 
4142 /*
4143  * call-seq:
4144  * hsh.compare_by_identity -> hsh
4145  *
4146  * Makes <i>hsh</i> compare its keys by their identity, i.e. it
4147  * will consider exact same objects as same keys.
4148  *
4149  * h1 = { "a" => 100, "b" => 200, :c => "c" }
4150  * h1["a"] #=> 100
4151  * h1.compare_by_identity
4152  * h1.compare_by_identity? #=> true
4153  * h1["a".dup] #=> nil # different objects.
4154  * h1[:c] #=> "c" # same symbols are all same.
4155  *
4156  */
4157 
4158 static VALUE
4159 rb_hash_compare_by_id(VALUE hash)
4160 {
4161  VALUE tmp;
4162  st_table *identtable;
4163 
4164  if (rb_hash_compare_by_id_p(hash)) return hash;
4165 
4166  rb_hash_modify_check(hash);
4167  ar_force_convert_table(hash, __FILE__, __LINE__);
4169 
4170  tmp = hash_alloc(0);
4171  identtable = rb_init_identtable_with_size(RHASH_SIZE(hash));
4172  RHASH_ST_TABLE_SET(tmp, identtable);
4173  rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
4175  RHASH_ST_TABLE_SET(hash, identtable);
4176  RHASH_ST_CLEAR(tmp);
4177  rb_gc_force_recycle(tmp);
4178 
4179  return hash;
4180 }
4181 
4182 /*
4183  * call-seq:
4184  * hsh.compare_by_identity? -> true or false
4185  *
4186  * Returns <code>true</code> if <i>hsh</i> will compare its keys by
4187  * their identity. Also see Hash#compare_by_identity.
4188  *
4189  */
4190 
4193 {
4195  return Qtrue;
4196  }
4197  else {
4198  return Qfalse;
4199  }
4200 }
4201 
4202 VALUE
4204 {
4205  VALUE hash = rb_hash_new();
4207  return hash;
4208 }
4209 
4210 st_table *
4212 {
4213  return st_init_table(&identhash);
4214 }
4215 
4216 static st_table *
4217 rb_init_identtable_with_size(st_index_t size)
4218 {
4220 }
4221 
4222 static int
4223 any_p_i(VALUE key, VALUE value, VALUE arg)
4224 {
4225  VALUE ret = rb_yield(rb_assoc_new(key, value));
4226  if (RTEST(ret)) {
4227  *(VALUE *)arg = Qtrue;
4228  return ST_STOP;
4229  }
4230  return ST_CONTINUE;
4231 }
4232 
4233 static int
4234 any_p_i_fast(VALUE key, VALUE value, VALUE arg)
4235 {
4236  VALUE ret = rb_yield_values(2, key, value);
4237  if (RTEST(ret)) {
4238  *(VALUE *)arg = Qtrue;
4239  return ST_STOP;
4240  }
4241  return ST_CONTINUE;
4242 }
4243 
4244 static int
4245 any_p_i_pattern(VALUE key, VALUE value, VALUE arg)
4246 {
4247  VALUE ret = rb_funcall(((VALUE *)arg)[1], idEqq, 1, rb_assoc_new(key, value));
4248  if (RTEST(ret)) {
4249  *(VALUE *)arg = Qtrue;
4250  return ST_STOP;
4251  }
4252  return ST_CONTINUE;
4253 }
4254 
4255 /*
4256  * call-seq:
4257  * hsh.any? [{ |(key, value)| block }] -> true or false
4258  * hsh.any?(pattern) -> true or false
4259  *
4260  * See also Enumerable#any?
4261  */
4262 
4263 static VALUE
4264 rb_hash_any_p(int argc, VALUE *argv, VALUE hash)
4265 {
4266  VALUE args[2];
4267  args[0] = Qfalse;
4268 
4269  rb_check_arity(argc, 0, 1);
4270  if (RHASH_EMPTY_P(hash)) return Qfalse;
4271  if (argc) {
4272  if (rb_block_given_p()) {
4273  rb_warn("given block not used");
4274  }
4275  args[1] = argv[0];
4276 
4277  rb_hash_foreach(hash, any_p_i_pattern, (VALUE)args);
4278  }
4279  else {
4280  if (!rb_block_given_p()) {
4281  /* yields pairs, never false */
4282  return Qtrue;
4283  }
4284  if (rb_block_arity() > 1)
4285  rb_hash_foreach(hash, any_p_i_fast, (VALUE)args);
4286  else
4287  rb_hash_foreach(hash, any_p_i, (VALUE)args);
4288  }
4289  return args[0];
4290 }
4291 
4292 /*
4293  * call-seq:
4294  * hsh.dig(key, ...) -> object
4295  *
4296  * Extracts the nested value specified by the sequence of <i>key</i>
4297  * objects by calling +dig+ at each step, returning +nil+ if any
4298  * intermediate step is +nil+.
4299  *
4300  * h = { foo: {bar: {baz: 1}}}
4301  *
4302  * h.dig(:foo, :bar, :baz) #=> 1
4303  * h.dig(:foo, :zot, :xyz) #=> nil
4304  *
4305  * g = { foo: [10, 11, 12] }
4306  * g.dig(:foo, 1) #=> 11
4307  * g.dig(:foo, 1, 0) #=> TypeError: Integer does not have #dig method
4308  * g.dig(:foo, :bar) #=> TypeError: no implicit conversion of Symbol into Integer
4309  */
4310 
4311 static VALUE
4312 rb_hash_dig(int argc, VALUE *argv, VALUE self)
4313 {
4315  self = rb_hash_aref(self, *argv);
4316  if (!--argc) return self;
4317  ++argv;
4318  return rb_obj_dig(argc, argv, self, Qnil);
4319 }
4320 
4321 static int
4322 hash_le_i(VALUE key, VALUE value, VALUE arg)
4323 {
4324  VALUE *args = (VALUE *)arg;
4325  VALUE v = rb_hash_lookup2(args[0], key, Qundef);
4326  if (v != Qundef && rb_equal(value, v)) return ST_CONTINUE;
4327  args[1] = Qfalse;
4328  return ST_STOP;
4329 }
4330 
4331 static VALUE
4332 hash_le(VALUE hash1, VALUE hash2)
4333 {
4334  VALUE args[2];
4335  args[0] = hash2;
4336  args[1] = Qtrue;
4337  rb_hash_foreach(hash1, hash_le_i, (VALUE)args);
4338  return args[1];
4339 }
4340 
4341 /*
4342  * call-seq:
4343  * hash <= other -> true or false
4344  *
4345  * Returns <code>true</code> if <i>hash</i> is subset of
4346  * <i>other</i> or equals to <i>other</i>.
4347  *
4348  * h1 = {a:1, b:2}
4349  * h2 = {a:1, b:2, c:3}
4350  * h1 <= h2 #=> true
4351  * h2 <= h1 #=> false
4352  * h1 <= h1 #=> true
4353  */
4354 static VALUE
4355 rb_hash_le(VALUE hash, VALUE other)
4356 {
4357  other = to_hash(other);
4358  if (RHASH_SIZE(hash) > RHASH_SIZE(other)) return Qfalse;
4359  return hash_le(hash, other);
4360 }
4361 
4362 /*
4363  * call-seq:
4364  * hash < other -> true or false
4365  *
4366  * Returns <code>true</code> if <i>hash</i> is subset of
4367  * <i>other</i>.
4368  *
4369  * h1 = {a:1, b:2}
4370  * h2 = {a:1, b:2, c:3}
4371  * h1 < h2 #=> true
4372  * h2 < h1 #=> false
4373  * h1 < h1 #=> false
4374  */
4375 static VALUE
4376 rb_hash_lt(VALUE hash, VALUE other)
4377 {
4378  other = to_hash(other);
4379  if (RHASH_SIZE(hash) >= RHASH_SIZE(other)) return Qfalse;
4380  return hash_le(hash, other);
4381 }
4382 
4383 /*
4384  * call-seq:
4385  * hash >= other -> true or false
4386  *
4387  * Returns <code>true</code> if <i>other</i> is subset of
4388  * <i>hash</i> or equals to <i>hash</i>.
4389  *
4390  * h1 = {a:1, b:2}
4391  * h2 = {a:1, b:2, c:3}
4392  * h1 >= h2 #=> false
4393  * h2 >= h1 #=> true
4394  * h1 >= h1 #=> true
4395  */
4396 static VALUE
4397 rb_hash_ge(VALUE hash, VALUE other)
4398 {
4399  other = to_hash(other);
4400  if (RHASH_SIZE(hash) < RHASH_SIZE(other)) return Qfalse;
4401  return hash_le(other, hash);
4402 }
4403 
4404 /*
4405  * call-seq:
4406  * hash > other -> true or false
4407  *
4408  * Returns <code>true</code> if <i>other</i> is subset of
4409  * <i>hash</i>.
4410  *
4411  * h1 = {a:1, b:2}
4412  * h2 = {a:1, b:2, c:3}
4413  * h1 > h2 #=> false
4414  * h2 > h1 #=> true
4415  * h1 > h1 #=> false
4416  */
4417 static VALUE
4418 rb_hash_gt(VALUE hash, VALUE other)
4419 {
4420  other = to_hash(other);
4421  if (RHASH_SIZE(hash) <= RHASH_SIZE(other)) return Qfalse;
4422  return hash_le(other, hash);
4423 }
4424 
4425 static VALUE
4426 hash_proc_call(RB_BLOCK_CALL_FUNC_ARGLIST(key, hash))
4427 {
4428  rb_check_arity(argc, 1, 1);
4429  return rb_hash_aref(hash, *argv);
4430 }
4431 
4432 /*
4433  * call-seq:
4434  * hash.to_proc -> proc
4435  *
4436  * Returns a Proc which maps keys to values.
4437  *
4438  * h = {a:1, b:2}
4439  * hp = h.to_proc
4440  * hp.call(:a) #=> 1
4441  * hp.call(:b) #=> 2
4442  * hp.call(:c) #=> nil
4443  * [:a, :b, :c].map(&h) #=> [1, 2, nil]
4444  */
4445 static VALUE
4446 rb_hash_to_proc(VALUE hash)
4447 {
4448  return rb_func_proc_new(hash_proc_call, hash);
4449 }
4450 
4451 static VALUE
4452 rb_hash_deconstruct_keys(VALUE hash, VALUE keys)
4453 {
4454  return hash;
4455 }
4456 
4457 static int
4458 add_new_i(st_data_t *key, st_data_t *val, st_data_t arg, int existing)
4459 {
4460  VALUE *args = (VALUE *)arg;
4461  if (existing) return ST_STOP;
4462  RB_OBJ_WRITTEN(args[0], Qundef, (VALUE)*key);
4463  RB_OBJ_WRITE(args[0], (VALUE *)val, args[1]);
4464  return ST_CONTINUE;
4465 }
4466 
4467 /*
4468  * add +key+ to +val+ pair if +hash+ does not contain +key+.
4469  * returns non-zero if +key+ was contained.
4470  */
4471 int
4473 {
4474  st_table *tbl;
4475  int ret = 0;
4476  VALUE args[2];
4477  args[0] = hash;
4478  args[1] = val;
4479 
4480  if (RHASH_AR_TABLE_P(hash)) {
4481  hash_ar_table(hash);
4482 
4483  ret = ar_update(hash, (st_data_t)key, add_new_i, (st_data_t)args);
4484  if (ret != -1) {
4485  return ret;
4486  }
4487  ar_try_convert_table(hash);
4488  }
4489  tbl = RHASH_TBL_RAW(hash);
4490  return st_update(tbl, (st_data_t)key, add_new_i, (st_data_t)args);
4491 
4492 }
4493 
4494 static st_data_t
4495 key_stringify(VALUE key)
4496 {
4497  return (rb_obj_class(key) == rb_cString && !RB_OBJ_FROZEN(key)) ?
4498  rb_hash_key_str(key) : key;
4499 }
4500 
4501 static void
4502 ar_bulk_insert(VALUE hash, long argc, const VALUE *argv)
4503 {
4504  long i;
4505  for (i = 0; i < argc; ) {
4506  st_data_t k = key_stringify(argv[i++]);
4507  st_data_t v = argv[i++];
4508  ar_insert(hash, k, v);
4509  RB_OBJ_WRITTEN(hash, Qundef, k);
4511  }
4512 }
4513 
4514 void
4516 {
4517  HASH_ASSERT(argc % 2 == 0);
4518  if (argc > 0) {
4519  st_index_t size = argc / 2;
4520 
4521  if (RHASH_TABLE_NULL_P(hash)) {
4522  if (size <= RHASH_AR_TABLE_MAX_SIZE) {
4523  hash_ar_table(hash);
4524  }
4525  else {
4527  }
4528  }
4529 
4530  if (RHASH_AR_TABLE_P(hash) &&
4532  ar_bulk_insert(hash, argc, argv);
4533  }
4534  else {
4536  }
4537  }
4538 }
4539 
4540 static char **origenviron;
4541 #ifdef _WIN32
4542 #define GET_ENVIRON(e) ((e) = rb_w32_get_environ())
4543 #define FREE_ENVIRON(e) rb_w32_free_environ(e)
4544 static char **my_environ;
4545 #undef environ
4546 #define environ my_environ
4547 #undef getenv
4548 static char *(*w32_getenv)(const char*);
4549 static char *
4550 w32_getenv_unknown(const char *name)
4551 {
4552  char *(*func)(const char*);
4554  func = rb_w32_getenv;
4555  }
4556  else {
4557  func = rb_w32_ugetenv;
4558  }
4559  /* atomic assignment in flat memory model */
4560  return (w32_getenv = func)(name);
4561 }
4562 static char *(*w32_getenv)(const char*) = w32_getenv_unknown;
4563 #define getenv(n) w32_getenv(n)
4564 #elif defined(__APPLE__)
4565 #undef environ
4566 #define environ (*_NSGetEnviron())
4567 #define GET_ENVIRON(e) (e)
4568 #define FREE_ENVIRON(e)
4569 #else
4570 extern char **environ;
4571 #define GET_ENVIRON(e) (e)
4572 #define FREE_ENVIRON(e)
4573 #endif
4574 #ifdef ENV_IGNORECASE
4575 #define ENVMATCH(s1, s2) (STRCASECMP((s1), (s2)) == 0)
4576 #define ENVNMATCH(s1, s2, n) (STRNCASECMP((s1), (s2), (n)) == 0)
4577 #else
4578 #define ENVMATCH(n1, n2) (strcmp((n1), (n2)) == 0)
4579 #define ENVNMATCH(s1, s2, n) (memcmp((s1), (s2), (n)) == 0)
4580 #endif
4581 
4582 static VALUE
4583 env_enc_str_new(const char *ptr, long len, rb_encoding *enc)
4584 {
4585 #ifdef _WIN32
4587  const int ecflags = ECONV_INVALID_REPLACE | ECONV_UNDEF_REPLACE;
4588  rb_encoding *utf8 = rb_utf8_encoding();
4589  VALUE str = rb_enc_str_new(NULL, 0, (internal ? internal : enc));
4590  if (NIL_P(rb_str_cat_conv_enc_opts(str, 0, ptr, len, utf8, ecflags, Qnil))) {
4592  }
4593 #else
4595 #endif
4596 
4597  rb_obj_freeze(str);
4598  return str;
4599 }
4600 
4601 static VALUE
4602 env_enc_str_new_cstr(const char *ptr, rb_encoding *enc)
4603 {
4604  return env_enc_str_new(ptr, strlen(ptr), enc);
4605 }
4606 
4607 static VALUE
4608 env_str_new(const char *ptr, long len)
4609 {
4610  return env_enc_str_new(ptr, len, rb_locale_encoding());
4611 }
4612 
4613 static VALUE
4614 env_str_new2(const char *ptr)
4615 {
4616  if (!ptr) return Qnil;
4617  return env_str_new(ptr, strlen(ptr));
4618 }
4619 
4620 static const char TZ_ENV[] = "TZ";
4621 extern bool ruby_tz_uptodate_p;
4622 
4623 static rb_encoding *
4624 env_encoding_for(const char *name, const char *ptr)
4625 {
4626  if (ENVMATCH(name, PATH_ENV)) {
4627  return rb_filesystem_encoding();
4628  }
4629  else {
4630  return rb_locale_encoding();
4631  }
4632 }
4633 
4634 static VALUE
4635 env_name_new(const char *name, const char *ptr)
4636 {
4637  return env_enc_str_new_cstr(ptr, env_encoding_for(name, ptr));
4638 }
4639 
4640 static void *
4641 get_env_cstr(
4642 #ifdef _WIN32
4643  volatile VALUE *pstr,
4644 #else
4645  VALUE str,
4646 #endif
4647  const char *name)
4648 {
4649 #ifdef _WIN32
4650  VALUE str = *pstr;
4651 #endif
4652  char *var;
4653  rb_encoding *enc = rb_enc_get(str);
4654  if (!rb_enc_asciicompat(enc)) {
4655  rb_raise(rb_eArgError, "bad environment variable %s: ASCII incompatible encoding: %s",
4656  name, rb_enc_name(enc));
4657  }
4658 #ifdef _WIN32
4659  if (!rb_enc_str_asciionly_p(str)) {
4660  *pstr = str = rb_str_conv_enc(str, NULL, rb_utf8_encoding());
4661  }
4662 #endif
4663  var = RSTRING_PTR(str);
4664  if (memchr(var, '\0', RSTRING_LEN(str))) {
4665  rb_raise(rb_eArgError, "bad environment variable %s: contains null byte", name);
4666  }
4667  return rb_str_fill_terminator(str, 1); /* ASCII compatible */
4668 }
4669 
4670 #ifdef _WIN32
4671 #define get_env_ptr(var, val) \
4672  (var = get_env_cstr(&(val), #var))
4673 #else
4674 #define get_env_ptr(var, val) \
4675  (var = get_env_cstr(val, #var))
4676 #endif
4677 
4678 static inline const char *
4679 env_name(volatile VALUE *s)
4680 {
4681  const char *name;
4682  SafeStringValue(*s);
4683  get_env_ptr(name, *s);
4684  return name;
4685 }
4686 
4687 #define env_name(s) env_name(&(s))
4688 
4689 static VALUE env_aset(VALUE nm, VALUE val);
4690 
4691 static VALUE
4692 env_delete(VALUE name)
4693 {
4694  const char *nam, *val;
4695 
4696  nam = env_name(name);
4697  val = getenv(nam);
4698 
4699  /*
4700  * ENV['TZ'] = nil has a special meaning.
4701  * TZ is no longer considered up-to-date and ruby call tzset() as needed.
4702  * It could be useful if sysadmin change /etc/localtime.
4703  * This hack might works only on Linux glibc.
4704  */
4705  if (ENVMATCH(nam, TZ_ENV)) {
4707  }
4708 
4709  if (val) {
4710  VALUE value = env_str_new2(val);
4711 
4712  ruby_setenv(nam, 0);
4713  if (ENVMATCH(nam, PATH_ENV)) {
4714  RB_GC_GUARD(name);
4715  }
4716  return value;
4717  }
4718  return Qnil;
4719 }
4720 
4721 /*
4722  * call-seq:
4723  * ENV.delete(name) -> value
4724  * ENV.delete(name) { |name| block } -> value
4725  *
4726  * Deletes the environment variable with +name+ if it exists and returns its value:
4727  * ENV['foo'] = '0'
4728  * ENV.delete('foo') # => '0'
4729  * Returns +nil+ if the named environment variable does not exist:
4730  * ENV.delete('foo') # => nil
4731  * If a block given and the environment variable does not exist,
4732  * yields +name+ to the block and returns +nil+:
4733  * ENV.delete('foo') { |name| puts name } # => nil
4734  * foo
4735  * If a block given and the environment variable exists,
4736  * deletes the environment variable and returns its value (ignoring the block):
4737  * ENV['foo'] = '0'
4738  * ENV.delete('foo') { |name| fail 'ignored' } # => "0"
4739  * Raises an exception if +name+ is invalid.
4740  * See {Invalid Names and Values}[#class-ENV-label-Invalid-Names+and+Values].
4741  */
4742 static VALUE
4743 env_delete_m(VALUE obj, VALUE name)
4744 {
4745  VALUE val;
4746 
4747  val = env_delete(name);
4748  if (NIL_P(val) && rb_block_given_p()) rb_yield(name);
4749  return val;
4750 }
4751 
4752 /*
4753  * call-seq:
4754  * ENV[name] -> value
4755  *
4756  * Returns the value for the environment variable +name+ if it exists:
4757  * ENV['foo'] = '0'
4758  * ENV['foo'] # => "0"
4759  * Returns nil if the named variable does not exist:
4760  * ENV.clear
4761  * ENV['foo'] # => nil
4762  * Raises an exception if +name+ is invalid.
4763  * See {Invalid Names and Values}[#class-ENV-label-Invalid-Names+and+Values].
4764  */
4765 static VALUE
4766 rb_f_getenv(VALUE obj, VALUE name)
4767 {
4768  const char *nam, *env;
4769 
4770  nam = env_name(name);
4771  env = getenv(nam);
4772  if (env) {
4773  return env_name_new(nam, env);
4774  }
4775  return Qnil;
4776 }
4777 
4778 /*
4779  * call-seq:
4780  * ENV.fetch(name) -> value
4781  * ENV.fetch(name, default) -> value
4782  * ENV.fetch(name) { |name| block } -> value
4783  *
4784  * If +name+ is the name of an environment variable, returns its value:
4785  * ENV['foo'] = '0'
4786  * ENV.fetch('foo') # => '0'
4787  * Otherwise if a block is given (but not a default value),
4788  * yields +name+ to the block and returns the block's return value:
4789  * ENV.fetch('foo') { |name| :need_not_return_a_string } # => :need_not_return_a_string
4790  * Otherwise if a default value is given (but not a block), returns the default value:
4791  * ENV.delete('foo')
4792  * ENV.fetch('foo', :default_need_not_be_a_string) # => :default_need_not_be_a_string
4793  * If the environment variable does not exist and both default and block are given,
4794  * issues a warning ("warning: block supersedes default value argument"),
4795  * yields +name+ to the block, and returns the block's return value:
4796  * ENV.fetch('foo', :default) { |name| :block_return } # => :block_return
4797  * Raises KeyError if +name+ is valid, but not found,
4798  * and neither default value nor block is given:
4799  * ENV.fetch('foo') # Raises KeyError (key not found: "foo")
4800  * Raises an exception if +name+ is invalid.
4801  * See {Invalid Names and Values}[#class-ENV-label-Invalid-Names+and+Values].
4802  */
4803 static VALUE
4804 env_fetch(int argc, VALUE *argv, VALUE _)
4805 {
4806  VALUE key;
4807  long block_given;
4808  const char *nam, *env;
4809 
4810  rb_check_arity(argc, 1, 2);
4811  key = argv[0];
4812  block_given = rb_block_given_p();
4813  if (block_given && argc == 2) {
4814  rb_warn("block supersedes default value argument");
4815  }
4816  nam = env_name(key);
4817  env = getenv(nam);
4818  if (!env) {
4819  if (block_given) return rb_yield(key);
4820  if (argc == 1) {
4821  rb_key_err_raise(rb_sprintf("key not found: \"%"PRIsVALUE"\"", key), envtbl, key);
4822  }
4823  return argv[1];
4824  }
4825  return env_name_new(nam, env);
4826 }
4827 
4828 int
4830 {
4831  rb_warning("rb_env_path_tainted is deprecated and will be removed in Ruby 3.2.");
4832  return 0;
4833 }
4834 
4835 #if defined(_WIN32) || (defined(HAVE_SETENV) && defined(HAVE_UNSETENV))
4836 #elif defined __sun
4837 static int
4838 in_origenv(const char *str)
4839 {
4840  char **env;
4841  for (env = origenviron; *env; ++env) {
4842  if (*env == str) return 1;
4843  }
4844  return 0;
4845 }
4846 #else
4847 static int
4848 envix(const char *nam)
4849 {
4850  register int i, len = strlen(nam);
4851  char **env;
4852 
4853  env = GET_ENVIRON(environ);
4854  for (i = 0; env[i]; i++) {
4855  if (ENVNMATCH(env[i],nam,len) && env[i][len] == '=')
4856  break; /* memcmp must come first to avoid */
4857  } /* potential SEGV's */
4859  return i;
4860 }
4861 #endif
4862 
4863 #if defined(_WIN32)
4864 static size_t
4865 getenvsize(const WCHAR* p)
4866 {
4867  const WCHAR* porg = p;
4868  while (*p++) p += lstrlenW(p) + 1;
4869  return p - porg + 1;
4870 }
4871 
4872 static size_t
4873 getenvblocksize(void)
4874 {
4875 #ifdef _MAX_ENV
4876  return _MAX_ENV;
4877 #else
4878  return 32767;
4879 #endif
4880 }
4881 
4882 static int
4883 check_envsize(size_t n)
4884 {
4885  if (_WIN32_WINNT < 0x0600 && rb_w32_osver() < 6) {
4886  /* https://msdn.microsoft.com/en-us/library/windows/desktop/ms682653(v=vs.85).aspx */
4887  /* Windows Server 2003 and Windows XP: The maximum size of the
4888  * environment block for the process is 32,767 characters. */
4889  WCHAR* p = GetEnvironmentStringsW();
4890  if (!p) return -1; /* never happen */
4891  n += getenvsize(p);
4892  FreeEnvironmentStringsW(p);
4893  if (n >= getenvblocksize()) {
4894  return -1;
4895  }
4896  }
4897  return 0;
4898 }
4899 #endif
4900 
4901 #if defined(_WIN32) || \
4902  (defined(__sun) && !(defined(HAVE_SETENV) && defined(HAVE_UNSETENV)))
4903 
4904 NORETURN(static void invalid_envname(const char *name));
4905 
4906 static void
4907 invalid_envname(const char *name)
4908 {
4909  rb_syserr_fail_str(EINVAL, rb_sprintf("ruby_setenv(%s)", name));
4910 }
4911 
4912 static const char *
4913 check_envname(const char *name)
4914 {
4915  if (strchr(name, '=')) {
4916  invalid_envname(name);
4917  }
4918  return name;
4919 }
4920 #endif
4921 
4922 void
4923 ruby_setenv(const char *name, const char *value)
4924 {
4925 #if defined(_WIN32)
4926 # if defined(MINGW_HAS_SECURE_API) || RUBY_MSVCRT_VERSION >= 80
4927 # define HAVE__WPUTENV_S 1
4928 # endif
4929  VALUE buf;
4930  WCHAR *wname;
4931  WCHAR *wvalue = 0;
4932  int failed = 0;
4933  int len;
4934  check_envname(name);
4935  len = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0);
4936  if (value) {
4937  int len2;
4938  len2 = MultiByteToWideChar(CP_UTF8, 0, value, -1, NULL, 0);
4939  if (check_envsize((size_t)len + len2)) { /* len and len2 include '\0' */
4940  goto fail; /* 2 for '=' & '\0' */
4941  }
4942  wname = ALLOCV_N(WCHAR, buf, len + len2);
4943  wvalue = wname + len;
4944  MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, len);
4945  MultiByteToWideChar(CP_UTF8, 0, value, -1, wvalue, len2);
4946 #ifndef HAVE__WPUTENV_S
4947  wname[len-1] = L'=';
4948 #endif
4949  }
4950  else {
4951  wname = ALLOCV_N(WCHAR, buf, len + 1);
4952  MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, len);
4953  wvalue = wname + len;
4954  *wvalue = L'\0';
4955 #ifndef HAVE__WPUTENV_S
4956  wname[len-1] = L'=';
4957 #endif
4958  }
4959 #ifndef HAVE__WPUTENV_S
4960  failed = _wputenv(wname);
4961 #else
4962  failed = _wputenv_s(wname, wvalue);
4963 #endif
4964  ALLOCV_END(buf);
4965  /* even if putenv() failed, clean up and try to delete the
4966  * variable from the system area. */
4967  if (!value || !*value) {
4968  /* putenv() doesn't handle empty value */
4969  if (!SetEnvironmentVariable(name, value) &&
4970  GetLastError() != ERROR_ENVVAR_NOT_FOUND) goto fail;
4971  }
4972  if (failed) {
4973  fail:
4974  invalid_envname(name);
4975  }
4976 #elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)
4977  if (value) {
4978  if (setenv(name, value, 1))
4979  rb_sys_fail_str(rb_sprintf("setenv(%s)", name));
4980  }
4981  else {
4982 #ifdef VOID_UNSETENV
4983  unsetenv(name);
4984 #else
4985  if (unsetenv(name))
4986  rb_sys_fail_str(rb_sprintf("unsetenv(%s)", name));
4987 #endif
4988  }
4989 #elif defined __sun
4990  /* Solaris 9 (or earlier) does not have setenv(3C) and unsetenv(3C). */
4991  /* The below code was tested on Solaris 10 by:
4992  % ./configure ac_cv_func_setenv=no ac_cv_func_unsetenv=no
4993  */
4994  size_t len, mem_size;
4995  char **env_ptr, *str, *mem_ptr;
4996 
4997  check_envname(name);
4998  len = strlen(name);
4999  if (value) {
5000  mem_size = len + strlen(value) + 2;
5001  mem_ptr = malloc(mem_size);
5002  if (mem_ptr == NULL)
5003  rb_sys_fail_str(rb_sprintf("malloc("PRIuSIZE")", mem_size));
5004  snprintf(mem_ptr, mem_size, "%s=%s", name, value);
5005  }
5006  for (env_ptr = GET_ENVIRON(environ); (str = *env_ptr) != 0; ++env_ptr) {
5007  if (!strncmp(str, name, len) && str[len] == '=') {
5008  if (!in_origenv(str)) free(str);
5009  while ((env_ptr[0] = env_ptr[1]) != 0) env_ptr++;
5010  break;
5011  }
5012  }
5013  if (value) {
5014  if (putenv(mem_ptr)) {
5015  free(mem_ptr);
5016  rb_sys_fail_str(rb_sprintf("putenv(%s)", name));
5017  }
5018  }
5019 #else /* WIN32 */
5020  size_t len;
5021  int i;
5022 
5023  i=envix(name); /* where does it go? */
5024 
5025  if (environ == origenviron) { /* need we copy environment? */
5026  int j;
5027  int max;
5028  char **tmpenv;
5029 
5030  for (max = i; environ[max]; max++) ;
5031  tmpenv = ALLOC_N(char*, max+2);
5032  for (j=0; j<max; j++) /* copy environment */
5033  tmpenv[j] = ruby_strdup(environ[j]);
5034  tmpenv[max] = 0;
5035  environ = tmpenv; /* tell exec where it is now */
5036  }
5037  if (environ[i]) {
5038  char **envp = origenviron;
5039  while (*envp && *envp != environ[i]) envp++;
5040  if (!*envp)
5041  xfree(environ[i]);
5042  if (!value) {
5043  while (environ[i]) {
5044  environ[i] = environ[i+1];
5045  i++;
5046  }
5047  return;
5048  }
5049  }
5050  else { /* does not exist yet */
5051  if (!value) return;
5052  REALLOC_N(environ, char*, i+2); /* just expand it a bit */
5053  environ[i+1] = 0; /* make sure it's null terminated */
5054  }
5055  len = strlen(name) + strlen(value) + 2;
5056  environ[i] = ALLOC_N(char, len);
5057  snprintf(environ[i],len,"%s=%s",name,value); /* all that work just for this */
5058 #endif /* WIN32 */
5059 }
5060 
5061 void
5062 ruby_unsetenv(const char *name)
5063 {
5064  ruby_setenv(name, 0);
5065 }
5066 
5067 /*
5068  * call-seq:
5069  * ENV[name] = value -> value
5070  * ENV.store(name, value) -> value
5071  *
5072  * ENV.store is an alias for ENV.[]=.
5073  *
5074  * Creates, updates, or deletes the named environment variable, returning the value.
5075  * Both +name+ and +value+ may be instances of String.
5076  * See {Valid Names and Values}[#class-ENV-label-Valid+Names+and+Values].
5077  *
5078  * - If the named environment variable does not exist:
5079  * - If +value+ is +nil+, does nothing.
5080  * ENV.clear
5081  * ENV['foo'] = nil # => nil
5082  * ENV.include?('foo') # => false
5083  * ENV.store('bar', nil) # => nil
5084  * ENV.include?('bar') # => false
5085  * - If +value+ is not +nil+, creates the environment variable with +name+ and +value+:
5086  * # Create 'foo' using ENV.[]=.
5087  * ENV['foo'] = '0' # => '0'
5088  * ENV['foo'] # => '0'
5089  * # Create 'bar' using ENV.store.
5090  * ENV.store('bar', '1') # => '1'
5091  * ENV['bar'] # => '1'
5092  * - If the named environment variable exists:
5093  * - If +value+ is not +nil+, updates the environment variable with value +value+:
5094  * # Update 'foo' using ENV.[]=.
5095  * ENV['foo'] = '2' # => '2'
5096  * ENV['foo'] # => '2'
5097  * # Update 'bar' using ENV.store.
5098  * ENV.store('bar', '3') # => '3'
5099  * ENV['bar'] # => '3'
5100  * - If +value+ is +nil+, deletes the environment variable:
5101  * # Delete 'foo' using ENV.[]=.
5102  * ENV['foo'] = nil # => nil
5103  * ENV.include?('foo') # => false
5104  * # Delete 'bar' using ENV.store.
5105  * ENV.store('bar', nil) # => nil
5106  * ENV.include?('bar') # => false
5107  *
5108  * Raises an exception if +name+ or +value+ is invalid.
5109  * See {Invalid Names and Values}[#class-ENV-label-Invalid+Names+and+Values].
5110  */
5111 static VALUE
5112 env_aset_m(VALUE obj, VALUE nm, VALUE val)
5113 {
5114  return env_aset(nm, val);
5115 }
5116 
5117 static VALUE
5118 env_aset(VALUE nm, VALUE val)
5119 {
5120  char *name, *value;
5121 
5122  if (NIL_P(val)) {
5123  env_delete(nm);
5124  return Qnil;
5125  }
5126  SafeStringValue(nm);
5127  SafeStringValue(val);
5128  /* nm can be modified in `val.to_str`, don't get `name` before
5129  * check for `val` */
5130  get_env_ptr(name, nm);
5131  get_env_ptr(value, val);
5132 
5133  ruby_setenv(name, value);
5134  if (ENVMATCH(name, PATH_ENV)) {
5135  RB_GC_GUARD(nm);
5136  }
5137  else if (ENVMATCH(name, TZ_ENV)) {
5139  }
5140  return val;
5141 }
5142 
5143 static VALUE
5144 env_keys(void)
5145 {
5146  char **env;
5147  VALUE ary;
5148 
5149  ary = rb_ary_new();
5150  env = GET_ENVIRON(environ);
5151  while (*env) {
5152  char *s = strchr(*env, '=');
5153  if (s) {
5154  rb_ary_push(ary, env_str_new(*env, s-*env));
5155  }
5156  env++;
5157  }
5159  return ary;
5160 }
5161 
5162 /*
5163  * call-seq:
5164  * ENV.keys -> Array
5165  *
5166  * Returns all variable names in an Array:
5167  * ENV.replace('foo' => '0', 'bar' => '1')
5168  * ENV.keys # => ['bar', 'foo']
5169  * The order of the names is OS-dependent.
5170  * See {About Ordering}[#class-ENV-label-About+Ordering].
5171  *
5172  * Returns the empty Array if ENV is empty:
5173  * ENV.clear
5174  * ENV.keys # => []
5175  */
5176 
5177 static VALUE
5178 env_f_keys(VALUE _)
5179 {
5180  return env_keys();
5181 }
5182 
5183 static VALUE
5184 rb_env_size(VALUE ehash, VALUE args, VALUE eobj)
5185 {
5186  char **env;
5187  long cnt = 0;
5188 
5189  env = GET_ENVIRON(environ);
5190  for (; *env ; ++env) {
5191  if (strchr(*env, '=')) {
5192  cnt++;
5193  }
5194  }
5196  return LONG2FIX(cnt);
5197 }
5198 
5199 /*
5200  * call-seq:
5201  * ENV.each_key { |name| block } -> ENV
5202  * ENV.each_key -> Enumerator
5203  *
5204  * Yields each environment variable name:
5205  * ENV.replace('foo' => '0', 'bar' => '1') # => ENV
5206  * names = []
5207  * ENV.each_key { |name| names.push(name) } # => ENV
5208  * names # => ["bar", "foo"]
5209  *
5210  * Returns an Enumerator if no block given:
5211  * e = ENV.each_key # => #<Enumerator: {"bar"=>"1", "foo"=>"0"}:each_key>
5212  * names = []
5213  * e.each { |name| names.push(name) } # => ENV
5214  * names # => ["bar", "foo"]
5215  */
5216 static VALUE
5217 env_each_key(VALUE ehash)
5218 {
5219  VALUE keys;
5220  long i;
5221 
5222  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5223  keys = env_keys();
5224  for (i=0; i<RARRAY_LEN(keys); i++) {
5226  }
5227  return ehash;
5228 }
5229 
5230 static VALUE
5231 env_values(void)
5232 {
5233  VALUE ary;
5234  char **env;
5235 
5236  ary = rb_ary_new();
5237  env = GET_ENVIRON(environ);
5238  while (*env) {
5239  char *s = strchr(*env, '=');
5240  if (s) {
5241  rb_ary_push(ary, env_str_new2(s+1));
5242  }
5243  env++;
5244  }
5246  return ary;
5247 }
5248 
5249 /*
5250  * call-seq:
5251  * ENV.values -> Array
5252  *
5253  * Returns all environment variable values in an Array:
5254  * ENV.replace('foo' => '0', 'bar' => '1')
5255  * ENV.values # => ['1', '0']
5256  * The order of the values is OS-dependent.
5257  * See {About Ordering}[#class-ENV-label-About+Ordering].
5258  *
5259  * Returns the empty Array if ENV is empty:
5260  * ENV.clear
5261  * ENV.values # => []
5262  */
5263 static VALUE
5264 env_f_values(VALUE _)
5265 {
5266  return env_values();
5267 }
5268 
5269 /*
5270  * call-seq:
5271  * ENV.each_value { |value| block } -> ENV
5272  * ENV.each_value -> Enumerator
5273  *
5274  * Yields each environment variable value:
5275  * ENV.replace('foo' => '0', 'bar' => '1') # => ENV
5276  * values = []
5277  * ENV.each_value { |value| values.push(value) } # => ENV
5278  * values # => ["1", "0"]
5279  *
5280  * Returns an Enumerator if no block given:
5281  * e = ENV.each_value # => #<Enumerator: {"bar"=>"1", "foo"=>"0"}:each_value>
5282  * values = []
5283  * e.each { |value| values.push(value) } # => ENV
5284  * values # => ["1", "0"]
5285  */
5286 static VALUE
5287 env_each_value(VALUE ehash)
5288 {
5289  VALUE values;
5290  long i;
5291 
5292  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5293  values = env_values();
5294  for (i=0; i<RARRAY_LEN(values); i++) {
5295  rb_yield(RARRAY_AREF(values, i));
5296  }
5297  return ehash;
5298 }
5299 
5300 /*
5301  * call-seq:
5302  * ENV.each { |name, value| block } -> ENV
5303  * ENV.each -> Enumerator
5304  * ENV.each_pair { |name, value| block } -> ENV
5305  * ENV.each_pair -> Enumerator
5306  *
5307  * Yields each environment variable name and its value as a 2-element Array:
5308  * h = {}
5309  * ENV.each_pair { |name, value| h[name] = value } # => ENV
5310  * h # => {"bar"=>"1", "foo"=>"0"}
5311  *
5312  * Returns an Enumerator if no block given:
5313  * h = {}
5314  * e = ENV.each_pair # => #<Enumerator: {"bar"=>"1", "foo"=>"0"}:each_pair>
5315  * e.each { |name, value| h[name] = value } # => ENV
5316  * h # => {"bar"=>"1", "foo"=>"0"}
5317  */
5318 static VALUE
5319 env_each_pair(VALUE ehash)
5320 {
5321  char **env;
5322  VALUE ary;
5323  long i;
5324 
5325  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5326 
5327  ary = rb_ary_new();
5328  env = GET_ENVIRON(environ);
5329  while (*env) {
5330  char *s = strchr(*env, '=');
5331  if (s) {
5332  rb_ary_push(ary, env_str_new(*env, s-*env));
5333  rb_ary_push(ary, env_str_new2(s+1));
5334  }
5335  env++;
5336  }
5338 
5339  if (rb_block_arity() > 1) {
5340  for (i=0; i<RARRAY_LEN(ary); i+=2) {
5341  rb_yield_values(2, RARRAY_AREF(ary, i), RARRAY_AREF(ary, i+1));
5342  }
5343  }
5344  else {
5345  for (i=0; i<RARRAY_LEN(ary); i+=2) {
5346  rb_yield(rb_assoc_new(RARRAY_AREF(ary, i), RARRAY_AREF(ary, i+1)));
5347  }
5348  }
5349  return ehash;
5350 }
5351 
5352 /*
5353  * call-seq:
5354  * ENV.reject! { |name, value| block } -> ENV or nil
5355  * ENV.reject! -> Enumerator
5356  *
5357  * Similar to ENV.delete_if, but returns +nil+ if no changes were made.
5358  *
5359  * Deletes each environment variable for which the block returns a truthy value,
5360  * returning ENV (if any deletions) or +nil+ (if not):
5361  * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
5362  * ENV.reject! { |name, value| name.start_with?('b') } # => ENV
5363  * ENV # => {"foo"=>"0"}
5364  * ENV.reject! { |name, value| name.start_with?('b') } # => nil
5365  *
5366  * Returns an Enumerator if no block given:
5367  * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
5368  * e = ENV.reject! # => #<Enumerator: {"bar"=>"1", "baz"=>"2", "foo"=>"0"}:reject!>
5369  * e.each { |name, value| name.start_with?('b') } # => ENV
5370  * ENV # => {"foo"=>"0"}
5371  * e.each { |name, value| name.start_with?('b') } # => nil
5372  */
5373 static VALUE
5374 env_reject_bang(VALUE ehash)
5375 {
5376  VALUE keys;
5377  long i;
5378  int del = 0;
5379 
5380  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5381  keys = env_keys();
5383  for (i=0; i<RARRAY_LEN(keys); i++) {
5384  VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
5385  if (!NIL_P(val)) {
5386  if (RTEST(rb_yield_values(2, RARRAY_AREF(keys, i), val))) {
5387  env_delete(RARRAY_AREF(keys, i));
5388  del++;
5389  }
5390  }
5391  }
5392  RB_GC_GUARD(keys);
5393  if (del == 0) return Qnil;
5394  return envtbl;
5395 }
5396 
5397 /*
5398  * call-seq:
5399  * ENV.delete_if { |name, value| block } -> ENV
5400  * ENV.delete_if -> Enumerator
5401  *
5402  * Deletes every environment variable for which the block evaluates to +true+.
5403  *
5404  * If no block is given an enumerator is returned instead.
5405  */
5406 static VALUE
5407 env_delete_if(VALUE ehash)
5408 {
5409  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5410  env_reject_bang(ehash);
5411  return envtbl;
5412 }
5413 
5414 /*
5415  * call-seq:
5416  * ENV.values_at(name, ...) -> Array
5417  *
5418  * Returns an array containing the environment variable values associated with
5419  * the given names. See also ENV.select.
5420  */
5421 static VALUE
5422 env_values_at(int argc, VALUE *argv, VALUE _)
5423 {
5424  VALUE result;
5425  long i;
5426 
5427  result = rb_ary_new();
5428  for (i=0; i<argc; i++) {
5429  rb_ary_push(result, rb_f_getenv(Qnil, argv[i]));
5430  }
5431  return result;
5432 }
5433 
5434 /*
5435  * call-seq:
5436  * ENV.select { |name, value| block } -> Hash
5437  * ENV.select -> Enumerator
5438  * ENV.filter { |name, value| block } -> Hash
5439  * ENV.filter -> Enumerator
5440  *
5441  * Returns a copy of the environment for entries where the block returns true.
5442  *
5443  * Returns an Enumerator if no block was given.
5444  *
5445  * ENV.filter is an alias for ENV.select.
5446  */
5447 static VALUE
5448 env_select(VALUE ehash)
5449 {
5450  VALUE result;
5451  VALUE keys;
5452  long i;
5453 
5454  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5455  result = rb_hash_new();
5456  keys = env_keys();
5457  for (i = 0; i < RARRAY_LEN(keys); ++i) {
5458  VALUE key = RARRAY_AREF(keys, i);
5459  VALUE val = rb_f_getenv(Qnil, key);
5460  if (!NIL_P(val)) {
5461  if (RTEST(rb_yield_values(2, key, val))) {
5462  rb_hash_aset(result, key, val);
5463  }
5464  }
5465  }
5466  RB_GC_GUARD(keys);
5467 
5468  return result;
5469 }
5470 
5471 /*
5472  * call-seq:
5473  * ENV.select! { |name, value| block } -> ENV or nil
5474  * ENV.select! -> Enumerator
5475  * ENV.filter! { |name, value| block } -> ENV or nil
5476  * ENV.filter! -> Enumerator
5477  *
5478  * Equivalent to ENV.keep_if but returns +nil+ if no changes were made.
5479  *
5480  * ENV.filter! is an alias for ENV.select!.
5481  */
5482 static VALUE
5483 env_select_bang(VALUE ehash)
5484 {
5485  VALUE keys;
5486  long i;
5487  int del = 0;
5488 
5489  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5490  keys = env_keys();
5492  for (i=0; i<RARRAY_LEN(keys); i++) {
5493  VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
5494  if (!NIL_P(val)) {
5495  if (!RTEST(rb_yield_values(2, RARRAY_AREF(keys, i), val))) {
5496  env_delete(RARRAY_AREF(keys, i));
5497  del++;
5498  }
5499  }
5500  }
5501  RB_GC_GUARD(keys);
5502  if (del == 0) return Qnil;
5503  return envtbl;
5504 }
5505 
5506 /*
5507  * call-seq:
5508  * ENV.keep_if { |name, value| block } -> ENV
5509  * ENV.keep_if -> Enumerator
5510  *
5511  * Deletes every environment variable where the block evaluates to +false+.
5512  *
5513  * Returns an enumerator if no block was given.
5514  */
5515 static VALUE
5516 env_keep_if(VALUE ehash)
5517 {
5518  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5519  env_select_bang(ehash);
5520  return envtbl;
5521 }
5522 
5523 /*
5524  * call-seq:
5525  * ENV.slice(*keys) -> a_hash
5526  *
5527  * Returns a hash containing only the given keys from ENV and their values.
5528  *
5529  * ENV.slice("TERM","HOME") #=> {"TERM"=>"xterm-256color", "HOME"=>"/Users/rhc"}
5530  */
5531 static VALUE
5532 env_slice(int argc, VALUE *argv, VALUE _)
5533 {
5534  int i;
5535  VALUE key, value, result;
5536 
5537  if (argc == 0) {
5538  return rb_hash_new();
5539  }
5540  result = rb_hash_new_with_size(argc);
5541 
5542  for (i = 0; i < argc; i++) {
5543  key = argv[i];
5544  value = rb_f_getenv(Qnil, key);
5545  if (value != Qnil)
5546  rb_hash_aset(result, key, value);
5547  }
5548 
5549  return result;
5550 }
5551 
5552 VALUE
5554 {
5555  VALUE keys;
5556  long i;
5557 
5558  keys = env_keys();
5559  for (i=0; i<RARRAY_LEN(keys); i++) {
5560  VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
5561  if (!NIL_P(val)) {
5562  env_delete(RARRAY_AREF(keys, i));
5563  }
5564  }
5565  RB_GC_GUARD(keys);
5566  return envtbl;
5567 }
5568 
5569 /*
5570  * call-seq:
5571  * ENV.clear -> ENV
5572  *
5573  * Removes every environment variable; returns ENV:
5574  * ENV.replace('foo' => '0', 'bar' => '1')
5575  * ENV.size # => 2
5576  * ENV.clear # => ENV
5577  * ENV.size # => 0
5578  */
5579 static VALUE
5580 env_clear(VALUE _)
5581 {
5582  return rb_env_clear();
5583 }
5584 
5585 /*
5586  * call-seq:
5587  * ENV.to_s -> "ENV"
5588  *
5589  * Returns "ENV"
5590  */
5591 static VALUE
5592 env_to_s(VALUE _)
5593 {
5594  return rb_usascii_str_new2("ENV");
5595 }
5596 
5597 /*
5598  * call-seq:
5599  * ENV.inspect -> string
5600  *
5601  * Returns the contents of the environment as a String.
5602  */
5603 static VALUE
5604 env_inspect(VALUE _)
5605 {
5606  char **env;
5607  VALUE str, i;
5608 
5609  str = rb_str_buf_new2("{");
5610  env = GET_ENVIRON(environ);
5611  while (*env) {
5612  char *s = strchr(*env, '=');
5613 
5614  if (env != environ) {
5615  rb_str_buf_cat2(str, ", ");
5616  }
5617  if (s) {
5618  rb_str_buf_cat2(str, "\"");
5619  rb_str_buf_cat(str, *env, s-*env);
5620  rb_str_buf_cat2(str, "\"=>");
5621  i = rb_inspect(rb_str_new2(s+1));
5623  }
5624  env++;
5625  }
5627  rb_str_buf_cat2(str, "}");
5628 
5629  return str;
5630 }
5631 
5632 /*
5633  * call-seq:
5634  * ENV.to_a -> Array
5635  *
5636  * Converts the environment variables into an array of names and value arrays.
5637  *
5638  * ENV.to_a # => [["TERM", "xterm-color"], ["SHELL", "/bin/bash"], ...]
5639  *
5640  */
5641 static VALUE
5642 env_to_a(VALUE _)
5643 {
5644  char **env;
5645  VALUE ary;
5646 
5647  ary = rb_ary_new();
5648  env = GET_ENVIRON(environ);
5649  while (*env) {
5650  char *s = strchr(*env, '=');
5651  if (s) {
5652  rb_ary_push(ary, rb_assoc_new(env_str_new(*env, s-*env),
5653  env_str_new2(s+1)));
5654  }
5655  env++;
5656  }
5658  return ary;
5659 }
5660 
5661 /*
5662  * call-seq:
5663  * ENV.rehash
5664  *
5665  * Re-hashing the environment variables does nothing. It is provided for
5666  * compatibility with Hash.
5667  */
5668 static VALUE
5669 env_none(VALUE _)
5670 {
5671  return Qnil;
5672 }
5673 
5674 /*
5675  * call-seq:
5676  * ENV.length
5677  * ENV.size
5678  *
5679  * Returns the number of environment variables.
5680  */
5681 static VALUE
5682 env_size(VALUE _)
5683 {
5684  int i;
5685  char **env;
5686 
5687  env = GET_ENVIRON(environ);
5688  for (i=0; env[i]; i++)
5689  ;
5691  return INT2FIX(i);
5692 }
5693 
5694 /*
5695  * call-seq:
5696  * ENV.empty? -> true or false
5697  *
5698  * Returns true when there are no environment variables
5699  */
5700 static VALUE
5701 env_empty_p(VALUE _)
5702 {
5703  char **env;
5704 
5705  env = GET_ENVIRON(environ);
5706  if (env[0] == 0) {
5708  return Qtrue;
5709  }
5711  return Qfalse;
5712 }
5713 
5714 /*
5715  * call-seq:
5716  * ENV.include?(name) -> true or false
5717  * ENV.has_key?(name) -> true or false
5718  * ENV.member?(name) -> true or false
5719  * ENV.key?(name) -> true or false
5720  *
5721  * ENV.has_key?, ENV.member?, and ENV.key? are aliases for ENV.include?.
5722  *
5723  * Returns +true+ if there is an environment variable with the given +name+:
5724  * ENV.replace('foo' => '0', 'bar' => '1')
5725  * ENV.include?('foo') # => true
5726  * Returns +false+ if +name+ is a valid String and there is no such environment variable:
5727  * ENV.include?('baz') # => false
5728  * Returns +false+ if +name+ is the empty String or is a String containing character <code>'='</code>:
5729  * ENV.include?('') # => false
5730  * ENV.include?('=') # => false
5731  * Raises an exception if +name+ is a String containing the NUL character <code>"\0"</code>:
5732  * ENV.include?("\0") # Raises ArgumentError (bad environment variable name: contains null byte)
5733  * Raises an exception if +name+ has an encoding that is not ASCII-compatible:
5734  * ENV.include?("\xa1\xa1".force_encoding(Encoding::UTF_16LE))
5735  * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: UTF-16LE)
5736  * Raises an exception if +name+ is not a String:
5737  * ENV.include?(Object.new) # TypeError (no implicit conversion of Object into String)
5738  */
5739 static VALUE
5740 env_has_key(VALUE env, VALUE key)
5741 {
5742  const char *s;
5743 
5744  s = env_name(key);
5745  if (getenv(s)) return Qtrue;
5746  return Qfalse;
5747 }
5748 
5749 /*
5750  * call-seq:
5751  * ENV.assoc(name) -> Array or nil
5752  *
5753  * Returns a 2-element Array containing the name and value of the environment variable
5754  * for +name+ if it exists:
5755  * ENV.replace('foo' => '0', 'bar' => '1')
5756  * ENV.assoc('foo') # => ['foo' '0']
5757  * Returns +nil+ if +name+ is a valid String and there is no such environment variable:
5758  * ENV.assoc('baz') # => false
5759  * Returns +nil+ if +name+ is the empty String or is a String containing character <code>'='</code>:
5760  * ENV.assoc('') # => false
5761  * ENV.assoc('=') # => false
5762  * Raises an exception if +name+ is a String containing the NUL character <code>"\0"</code>:
5763  * ENV.assoc("\0") # Raises ArgumentError (bad environment variable name: contains null byte)
5764  * Raises an exception if +name+ has an encoding that is not ASCII-compatible:
5765  * ENV.assoc("\xa1\xa1".force_encoding(Encoding::UTF_16LE))
5766  * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: UTF-16LE)
5767  * Raises an exception if +name+ is not a String:
5768  * ENV.assoc(Object.new) # TypeError (no implicit conversion of Object into String)
5769  */
5770 static VALUE
5771 env_assoc(VALUE env, VALUE key)
5772 {
5773  const char *s, *e;
5774 
5775  s = env_name(key);
5776  e = getenv(s);
5777  if (e) return rb_assoc_new(key, env_str_new2(e));
5778  return Qnil;
5779 }
5780 
5781 /*
5782  * call-seq:
5783  * ENV.value?(value) -> true or false
5784  * ENV.has_value?(value) -> true or false
5785  *
5786  * Returns +true+ if there is an environment variable with the given +value+.
5787  */
5788 static VALUE
5789 env_has_value(VALUE dmy, VALUE obj)
5790 {
5791  char **env;
5792 
5794  if (NIL_P(obj)) return Qnil;
5795  env = GET_ENVIRON(environ);
5796  while (*env) {
5797  char *s = strchr(*env, '=');
5798  if (s++) {
5799  long len = strlen(s);
5800  if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
5802  return Qtrue;
5803  }
5804  }
5805  env++;
5806  }
5808  return Qfalse;
5809 }
5810 
5811 /*
5812  * call-seq:
5813  * ENV.rassoc(value)
5814  *
5815  * Returns an Array of the name and value of the environment variable with
5816  * +value+ or +nil+ if the value cannot be found.
5817  */
5818 static VALUE
5819 env_rassoc(VALUE dmy, VALUE obj)
5820 {
5821  char **env;
5822 
5824  if (NIL_P(obj)) return Qnil;
5825  env = GET_ENVIRON(environ);
5826  while (*env) {
5827  char *s = strchr(*env, '=');
5828  if (s++) {
5829  long len = strlen(s);
5830  if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
5831  VALUE result = rb_assoc_new(rb_str_new(*env, s-*env-1), obj);
5833  return result;
5834  }
5835  }
5836  env++;
5837  }
5839  return Qnil;
5840 }
5841 
5842 /*
5843  * call-seq:
5844  * ENV.key(value) -> name or nil
5845  *
5846  * Returns the name of the first environment variable with +value+ if it exists:
5847  * ENV.replace('foo' => '0', 'bar' => '1')
5848  * ENV.key('0') # =>'foo'
5849  * The order in which environment variables are examined is OS-dependent.
5850  * See {About Ordering}[#class-ENV-label-About+Ordering].
5851  *
5852  * Returns +nil+ if there is no such value:
5853  * ENV.key('2') # => nil
5854  * Raises an exception if +value+ is not a String:
5855  * ENV.key(Object.new) # raises TypeError (no implicit conversion of Object into String)
5856  */
5857 static VALUE
5858 env_key(VALUE dmy, VALUE value)
5859 {
5860  char **env;
5861  VALUE str;
5862 
5863  SafeStringValue(value);
5864  env = GET_ENVIRON(environ);
5865  while (*env) {
5866  char *s = strchr(*env, '=');
5867  if (s++) {
5868  long len = strlen(s);
5869  if (RSTRING_LEN(value) == len && strncmp(s, RSTRING_PTR(value), len) == 0) {
5870  str = env_str_new(*env, s-*env-1);
5872  return str;
5873  }
5874  }
5875  env++;
5876  }
5878  return Qnil;
5879 }
5880 
5881 /*
5882  * call-seq:
5883  * ENV.index(value) -> key
5884  *
5885  * Deprecated method that is equivalent to ENV.key
5886  */
5887 static VALUE
5888 env_index(VALUE dmy, VALUE value)
5889 {
5890  rb_warn_deprecated("ENV.index", "ENV.key");
5891  return env_key(dmy, value);
5892 }
5893 
5894 static VALUE
5895 env_to_hash(void)
5896 {
5897  char **env;
5898  VALUE hash;
5899 
5900  hash = rb_hash_new();
5901  env = GET_ENVIRON(environ);
5902  while (*env) {
5903  char *s = strchr(*env, '=');
5904  if (s) {
5905  rb_hash_aset(hash, env_str_new(*env, s-*env),
5906  env_str_new2(s+1));
5907  }
5908  env++;
5909  }
5911  return hash;
5912 }
5913 
5914 /*
5915  * call-seq:
5916  * ENV.to_hash -> hash
5917  *
5918  * Creates a hash with a copy of the environment variables.
5919  *
5920  */
5921 
5922 static VALUE
5923 env_f_to_hash(VALUE _)
5924 {
5925  return env_to_hash();
5926 }
5927 
5928 /*
5929  * call-seq:
5930  * ENV.to_h -> hash
5931  * ENV.to_h {|name, value| block } -> hash
5932  *
5933  * Creates a hash with a copy of the environment variables.
5934  *
5935  */
5936 static VALUE
5937 env_to_h(VALUE _)
5938 {
5939  VALUE hash = env_to_hash();
5940  if (rb_block_given_p()) {
5941  hash = rb_hash_to_h_block(hash);
5942  }
5943  return hash;
5944 }
5945 
5946 /*
5947  * call-seq:
5948  * ENV.reject { |name, value| block } -> Hash
5949  * ENV.reject -> Enumerator
5950  *
5951  * Same as ENV.delete_if, but works on (and returns) a copy of the
5952  * environment.
5953  */
5954 static VALUE
5955 env_reject(VALUE _)
5956 {
5957  return rb_hash_delete_if(env_to_hash());
5958 }
5959 
5960 /*
5961  * call-seq:
5962  * ENV.freeze -> raises TypeError
5963  *
5964  * Ruby does not allow ENV to be frozen, so calling ENV.freeze
5965  * raises TypeError.
5966  */
5967 static VALUE
5968 env_freeze(VALUE self)
5969 {
5970  rb_raise(rb_eTypeError, "cannot freeze ENV");
5971  return self; /* Not reached */
5972 }
5973 
5974 /*
5975  * call-seq:
5976  * ENV.shift -> [name, value] or nil
5977  *
5978  * Removes the first environment variable from ENV and returns
5979  * a 2-element Array containing its name and value:
5980  * ENV.replace('foo' => '0', 'bar' => '1')
5981  * ENV.to_hash # => {'bar' => '1', 'foo' => '0'}
5982  * ENV.shift # => ['bar', '1']
5983  * ENV.to_hash # => {'foo' => '0'}
5984  * Exactly which environment variable is "first" is OS-dependent.
5985  * See {About Ordering}[#class-ENV-label-About+Ordering].
5986  *
5987  * Returns +nil+ if the environment is empty:
5988  * ENV.clear
5989  * ENV.shift # => nil
5990  */
5991 static VALUE
5992 env_shift(VALUE _)
5993 {
5994  char **env;
5995  VALUE result = Qnil;
5996 
5997  env = GET_ENVIRON(environ);
5998  if (*env) {
5999  char *s = strchr(*env, '=');
6000  if (s) {
6001  VALUE key = env_str_new(*env, s-*env);
6002  VALUE val = env_str_new2(getenv(RSTRING_PTR(key)));
6003  env_delete(key);
6004  result = rb_assoc_new(key, val);
6005  }
6006  }
6008  return result;
6009 }
6010 
6011 /*
6012  * call-seq:
6013  * ENV.invert -> Hash
6014  *
6015  * Returns a new hash created by using environment variable names as values
6016  * and values as names.
6017  */
6018 static VALUE
6019 env_invert(VALUE _)
6020 {
6021  return rb_hash_invert(env_to_hash());
6022 }
6023 
6024 static int
6025 env_replace_i(VALUE key, VALUE val, VALUE keys)
6026 {
6027  env_aset(key, val);
6028  if (rb_ary_includes(keys, key)) {
6030  }
6031  return ST_CONTINUE;
6032 }
6033 
6034 /*
6035  * call-seq:
6036  * ENV.replace(hash) -> ENV
6037  *
6038  * Replaces the entire content of the environment variables
6039  * with the name/value pairs in the given +hash+;
6040  * returns ENV.
6041  *
6042  * Replaces the content of ENV with the given pairs:
6043  * ENV.replace('foo' => '0', 'bar' => '1') # => ENV
6044  * ENV.to_hash # => {"bar"=>"1", "foo"=>"0"}
6045  *
6046  * Raises an exception if a name or value is invalid.
6047  * See {Invalid Names and Values}[#class-ENV-label-Invalid-Names+and+Values].
6048  */
6049 static VALUE
6050 env_replace(VALUE env, VALUE hash)
6051 {
6052  VALUE keys;
6053  long i;
6054 
6055  keys = env_keys();
6056  if (env == hash) return env;
6057  hash = to_hash(hash);
6058  rb_hash_foreach(hash, env_replace_i, keys);
6059 
6060  for (i=0; i<RARRAY_LEN(keys); i++) {
6061  env_delete(RARRAY_AREF(keys, i));
6062  }
6063  RB_GC_GUARD(keys);
6064  return env;
6065 }
6066 
6067 static int
6068 env_update_i(VALUE key, VALUE val, VALUE _)
6069 {
6070  env_aset(key, val);
6071  return ST_CONTINUE;
6072 }
6073 
6074 static int
6075 env_update_block_i(VALUE key, VALUE val, VALUE _)
6076 {
6077  VALUE oldval = rb_f_getenv(Qnil, key);
6078  if (!NIL_P(oldval)) {
6079  val = rb_yield_values(3, key, oldval, val);
6080  }
6081  env_aset(key, val);
6082  return ST_CONTINUE;
6083 }
6084 
6085 /*
6086  * call-seq:
6087  * ENV.update(hash) -> ENV
6088  * ENV.update(hash) { |name, old_value, new_value| block } -> ENV
6089  * ENV.merge!(hash) -> ENV
6090  * ENV.merge!(hash) { |name, old_value, new_value| block } -> ENV
6091  *
6092  * Adds the contents of +hash+ to the environment variables. If no block is
6093  * specified entries with duplicate keys are overwritten, otherwise the value
6094  * of each duplicate name is determined by calling the block with the key, its
6095  * value from the environment and its value from the hash.
6096  */
6097 static VALUE
6098 env_update(VALUE env, VALUE hash)
6099 {
6100  if (env == hash) return env;
6101  hash = to_hash(hash);
6102  rb_foreach_func *func = rb_block_given_p() ?
6103  env_update_block_i : env_update_i;
6104  rb_hash_foreach(hash, func, 0);
6105  return env;
6106 }
6107 
6108 /*
6109  * A Hash is a dictionary-like collection of unique keys and their values.
6110  * Also called associative arrays, they are similar to Arrays, but where an
6111  * Array uses integers as its index, a Hash allows you to use any object
6112  * type.
6113  *
6114  * Hashes enumerate their values in the order that the corresponding keys
6115  * were inserted.
6116  *
6117  * A Hash can be easily created by using its implicit form:
6118  *
6119  * grades = { "Jane Doe" => 10, "Jim Doe" => 6 }
6120  *
6121  * Hashes allow an alternate syntax for keys that are symbols.
6122  * Instead of
6123  *
6124  * options = { :font_size => 10, :font_family => "Arial" }
6125  *
6126  * You could write it as:
6127  *
6128  * options = { font_size: 10, font_family: "Arial" }
6129  *
6130  * Each named key is a symbol you can access in hash:
6131  *
6132  * options[:font_size] # => 10
6133  *
6134  * A Hash can also be created through its ::new method:
6135  *
6136  * grades = Hash.new
6137  * grades["Dorothy Doe"] = 9
6138  *
6139  * Hashes have a <em>default value</em> that is returned when accessing
6140  * keys that do not exist in the hash. If no default is set +nil+ is used.
6141  * You can set the default value by sending it as an argument to Hash.new:
6142  *
6143  * grades = Hash.new(0)
6144  *
6145  * Or by using the #default= method:
6146  *
6147  * grades = {"Timmy Doe" => 8}
6148  * grades.default = 0
6149  *
6150  * Accessing a value in a Hash requires using its key:
6151  *
6152  * puts grades["Jane Doe"] # => 0
6153  *
6154  * === Common Uses
6155  *
6156  * Hashes are an easy way to represent data structures, such as
6157  *
6158  * books = {}
6159  * books[:matz] = "The Ruby Programming Language"
6160  * books[:black] = "The Well-Grounded Rubyist"
6161  *
6162  * Hashes are also commonly used as a way to have named parameters in
6163  * functions. Note that no brackets are used below. If a hash is the last
6164  * argument on a method call, no braces are needed, thus creating a really
6165  * clean interface:
6166  *
6167  * Person.create(name: "John Doe", age: 27)
6168  *
6169  * def self.create(params)
6170  * @name = params[:name]
6171  * @age = params[:age]
6172  * end
6173  *
6174  * === Hash Keys
6175  *
6176  * Two objects refer to the same hash key when their <code>hash</code> value
6177  * is identical and the two objects are <code>eql?</code> to each other.
6178  *
6179  * A user-defined class may be used as a hash key if the <code>hash</code>
6180  * and <code>eql?</code> methods are overridden to provide meaningful
6181  * behavior. By default, separate instances refer to separate hash keys.
6182  *
6183  * A typical implementation of <code>hash</code> is based on the
6184  * object's data while <code>eql?</code> is usually aliased to the overridden
6185  * <code>==</code> method:
6186  *
6187  * class Book
6188  * attr_reader :author, :title
6189  *
6190  * def initialize(author, title)
6191  * @author = author
6192  * @title = title
6193  * end
6194  *
6195  * def ==(other)
6196  * self.class === other and
6197  * other.author == @author and
6198  * other.title == @title
6199  * end
6200  *
6201  * alias eql? ==
6202  *
6203  * def hash
6204  * @author.hash ^ @title.hash # XOR
6205  * end
6206  * end
6207  *
6208  * book1 = Book.new 'matz', 'Ruby in a Nutshell'
6209  * book2 = Book.new 'matz', 'Ruby in a Nutshell'
6210  *
6211  * reviews = {}
6212  *
6213  * reviews[book1] = 'Great reference!'
6214  * reviews[book2] = 'Nice and compact!'
6215  *
6216  * reviews.length #=> 1
6217  *
6218  * See also Object#hash and Object#eql?
6219  */
6220 
6221 void
6223 {
6224 #undef rb_intern
6225 #define rb_intern(str) rb_intern_const(str)
6226  id_hash = rb_intern("hash");
6227  id_yield = rb_intern("yield");
6228  id_default = rb_intern("default");
6229  id_flatten_bang = rb_intern("flatten!");
6230  id_hash_iter_lev = rb_make_internal_id();
6231 
6232  rb_cHash = rb_define_class("Hash", rb_cObject);
6233 
6235 
6236  rb_define_alloc_func(rb_cHash, empty_hash_alloc);
6237  rb_define_singleton_method(rb_cHash, "[]", rb_hash_s_create, -1);
6238  rb_define_singleton_method(rb_cHash, "try_convert", rb_hash_s_try_convert, 1);
6239  rb_define_method(rb_cHash, "initialize", rb_hash_initialize, -1);
6240  rb_define_method(rb_cHash, "initialize_copy", rb_hash_replace, 1);
6241  rb_define_method(rb_cHash, "rehash", rb_hash_rehash, 0);
6242 
6243  rb_define_method(rb_cHash, "to_hash", rb_hash_to_hash, 0);
6244  rb_define_method(rb_cHash, "to_h", rb_hash_to_h, 0);
6245  rb_define_method(rb_cHash, "to_a", rb_hash_to_a, 0);
6246  rb_define_method(rb_cHash, "inspect", rb_hash_inspect, 0);
6247  rb_define_alias(rb_cHash, "to_s", "inspect");
6248  rb_define_method(rb_cHash, "to_proc", rb_hash_to_proc, 0);
6249 
6250  rb_define_method(rb_cHash, "==", rb_hash_equal, 1);
6252  rb_define_method(rb_cHash, "hash", rb_hash_hash, 0);
6253  rb_define_method(rb_cHash, "eql?", rb_hash_eql, 1);
6254  rb_define_method(rb_cHash, "fetch", rb_hash_fetch_m, -1);
6256  rb_define_method(rb_cHash, "store", rb_hash_aset, 2);
6257  rb_define_method(rb_cHash, "default", rb_hash_default, -1);
6258  rb_define_method(rb_cHash, "default=", rb_hash_set_default, 1);
6259  rb_define_method(rb_cHash, "default_proc", rb_hash_default_proc, 0);
6260  rb_define_method(rb_cHash, "default_proc=", rb_hash_set_default_proc, 1);
6261  rb_define_method(rb_cHash, "key", rb_hash_key, 1);
6262  rb_define_method(rb_cHash, "index", rb_hash_index, 1);
6263  rb_define_method(rb_cHash, "size", rb_hash_size, 0);
6264  rb_define_method(rb_cHash, "length", rb_hash_size, 0);
6265  rb_define_method(rb_cHash, "empty?", rb_hash_empty_p, 0);
6266 
6267  rb_define_method(rb_cHash, "each_value", rb_hash_each_value, 0);
6268  rb_define_method(rb_cHash, "each_key", rb_hash_each_key, 0);
6269  rb_define_method(rb_cHash, "each_pair", rb_hash_each_pair, 0);
6270  rb_define_method(rb_cHash, "each", rb_hash_each_pair, 0);
6271 
6272  rb_define_method(rb_cHash, "transform_keys", rb_hash_transform_keys, 0);
6273  rb_define_method(rb_cHash, "transform_keys!", rb_hash_transform_keys_bang, 0);
6274  rb_define_method(rb_cHash, "transform_values", rb_hash_transform_values, 0);
6275  rb_define_method(rb_cHash, "transform_values!", rb_hash_transform_values_bang, 0);
6276 
6277  rb_define_method(rb_cHash, "keys", rb_hash_keys, 0);
6278  rb_define_method(rb_cHash, "values", rb_hash_values, 0);
6279  rb_define_method(rb_cHash, "values_at", rb_hash_values_at, -1);
6280  rb_define_method(rb_cHash, "fetch_values", rb_hash_fetch_values, -1);
6281 
6282  rb_define_method(rb_cHash, "shift", rb_hash_shift, 0);
6283  rb_define_method(rb_cHash, "delete", rb_hash_delete_m, 1);
6284  rb_define_method(rb_cHash, "delete_if", rb_hash_delete_if, 0);
6285  rb_define_method(rb_cHash, "keep_if", rb_hash_keep_if, 0);
6286  rb_define_method(rb_cHash, "select", rb_hash_select, 0);
6288  rb_define_method(rb_cHash, "filter", rb_hash_select, 0);
6290  rb_define_method(rb_cHash, "reject", rb_hash_reject, 0);
6292  rb_define_method(rb_cHash, "slice", rb_hash_slice, -1);
6293  rb_define_method(rb_cHash, "clear", rb_hash_clear, 0);
6294  rb_define_method(rb_cHash, "invert", rb_hash_invert, 0);
6295  rb_define_method(rb_cHash, "update", rb_hash_update, -1);
6296  rb_define_method(rb_cHash, "replace", rb_hash_replace, 1);
6297  rb_define_method(rb_cHash, "merge!", rb_hash_update, -1);
6298  rb_define_method(rb_cHash, "merge", rb_hash_merge, -1);
6299  rb_define_method(rb_cHash, "assoc", rb_hash_assoc, 1);
6300  rb_define_method(rb_cHash, "rassoc", rb_hash_rassoc, 1);
6301  rb_define_method(rb_cHash, "flatten", rb_hash_flatten, -1);
6302  rb_define_method(rb_cHash, "compact", rb_hash_compact, 0);
6303  rb_define_method(rb_cHash, "compact!", rb_hash_compact_bang, 0);
6304 
6305  rb_define_method(rb_cHash, "include?", rb_hash_has_key, 1);
6306  rb_define_method(rb_cHash, "member?", rb_hash_has_key, 1);
6307  rb_define_method(rb_cHash, "has_key?", rb_hash_has_key, 1);
6308  rb_define_method(rb_cHash, "has_value?", rb_hash_has_value, 1);
6310  rb_define_method(rb_cHash, "value?", rb_hash_has_value, 1);
6311 
6312  rb_define_method(rb_cHash, "compare_by_identity", rb_hash_compare_by_id, 0);
6313  rb_define_method(rb_cHash, "compare_by_identity?", rb_hash_compare_by_id_p, 0);
6314 
6315  rb_define_method(rb_cHash, "any?", rb_hash_any_p, -1);
6316  rb_define_method(rb_cHash, "dig", rb_hash_dig, -1);
6317 
6318  rb_define_method(rb_cHash, "<=", rb_hash_le, 1);
6319  rb_define_method(rb_cHash, "<", rb_hash_lt, 1);
6320  rb_define_method(rb_cHash, ">=", rb_hash_ge, 1);
6321  rb_define_method(rb_cHash, ">", rb_hash_gt, 1);
6322 
6323  rb_define_method(rb_cHash, "deconstruct_keys", rb_hash_deconstruct_keys, 1);
6324 
6325  /* Document-class: ENV
6326  *
6327  * ENV is a hash-like accessor for environment variables.
6328  *
6329  * === Interaction with the Operating System
6330  *
6331  * The ENV object interacts with the operating system's environment variables:
6332  *
6333  * - When you get the value for a name in ENV, the value is retrieved from among the current environment variables.
6334  * - When you create or set a name-value pair in ENV, the name and value are immediately set in the environment variables.
6335  * - When you delete a name-value pair in ENV, it is immediately deleted from the environment variables.
6336  *
6337  * === Names and Values
6338  *
6339  * Generally, a name or value is a String.
6340  *
6341  * ==== Valid Names and Values
6342  *
6343  * Each name or value must be one of the following:
6344  *
6345  * - A String.
6346  * - An object that responds to \#to_str by returning a String, in which case that String will be used as the name or value.
6347  *
6348  * ==== Invalid Names and Values
6349  *
6350  * A new name:
6351  *
6352  * - May not be the empty string:
6353  * ENV[''] = '0'
6354  * # Raises Errno::EINVAL (Invalid argument - ruby_setenv())
6355  *
6356  * - May not contain character <code>"="</code>:
6357  * ENV['='] = '0'
6358  * # Raises Errno::EINVAL (Invalid argument - ruby_setenv(=))
6359  *
6360  * A new name or value:
6361  *
6362  * - May not be a non-String that does not respond to \#to_str:
6363  *
6364  * ENV['foo'] = Object.new
6365  * # Raises TypeError (no implicit conversion of Object into String)
6366  * ENV[Object.new] = '0'
6367  * # Raises TypeError (no implicit conversion of Object into String)
6368  *
6369  * - May not contain the NUL character <code>"\0"</code>:
6370  *
6371  * ENV['foo'] = "\0"
6372  * # Raises ArgumentError (bad environment variable value: contains null byte)
6373  * ENV["\0"] == '0'
6374  * # Raises ArgumentError (bad environment variable name: contains null byte)
6375  *
6376  * - May not have an ASCII-incompatible encoding such as UTF-16LE or ISO-2022-JP:
6377  *
6378  * ENV['foo'] = '0'.force_encoding(Encoding::ISO_2022_JP)
6379  * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: ISO-2022-JP)
6380  * ENV["foo".force_encoding(Encoding::ISO_2022_JP)] = '0'
6381  * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: ISO-2022-JP)
6382  *
6383  * === About Ordering
6384  *
6385  * ENV enumerates its name/value pairs in the order found
6386  * in the operating system's environment variables.
6387  * Therefore the ordering of ENV content is OS-dependent, and may be indeterminate.
6388  *
6389  * This will be seen in:
6390  * - A Hash returned by an ENV method.
6391  * - An Enumerator returned by an ENV method.
6392  * - An Array returned by ENV.keys, ENV.values, or ENV.to_a.
6393  * - The String returned by ENV.inspect.
6394  * - The Array returned by ENV.shift.
6395  * - The name returned by ENV.key.
6396  *
6397  * === About the Examples
6398  * Some methods in ENV return ENV itself. Typically, there are many environment variables.
6399  * It's not useful to display a large ENV in the examples here,
6400  * so most example snippets begin by resetting the contents of ENV:
6401  * - ENV.replace replaces ENV with a new collection of entries.
6402  * - ENV.clear empties ENV.
6403  */
6404 
6405  /*
6406  * Hack to get RDoc to regard ENV as a class:
6407  * envtbl = rb_define_class("ENV", rb_cObject);
6408  */
6409  origenviron = environ;
6410  envtbl = rb_obj_alloc(rb_cObject);
6412 
6413  rb_define_singleton_method(envtbl, "[]", rb_f_getenv, 1);
6414  rb_define_singleton_method(envtbl, "fetch", env_fetch, -1);
6415  rb_define_singleton_method(envtbl, "[]=", env_aset_m, 2);
6416  rb_define_singleton_method(envtbl, "store", env_aset_m, 2);
6417  rb_define_singleton_method(envtbl, "each", env_each_pair, 0);
6418  rb_define_singleton_method(envtbl, "each_pair", env_each_pair, 0);
6419  rb_define_singleton_method(envtbl, "each_key", env_each_key, 0);
6420  rb_define_singleton_method(envtbl, "each_value", env_each_value, 0);
6421  rb_define_singleton_method(envtbl, "delete", env_delete_m, 1);
6422  rb_define_singleton_method(envtbl, "delete_if", env_delete_if, 0);
6423  rb_define_singleton_method(envtbl, "keep_if", env_keep_if, 0);
6424  rb_define_singleton_method(envtbl, "slice", env_slice, -1);
6425  rb_define_singleton_method(envtbl, "clear", env_clear, 0);
6426  rb_define_singleton_method(envtbl, "reject", env_reject, 0);
6427  rb_define_singleton_method(envtbl, "reject!", env_reject_bang, 0);
6428  rb_define_singleton_method(envtbl, "select", env_select, 0);
6429  rb_define_singleton_method(envtbl, "select!", env_select_bang, 0);
6430  rb_define_singleton_method(envtbl, "filter", env_select, 0);
6431  rb_define_singleton_method(envtbl, "filter!", env_select_bang, 0);
6432  rb_define_singleton_method(envtbl, "shift", env_shift, 0);
6433  rb_define_singleton_method(envtbl, "freeze", env_freeze, 0);
6434  rb_define_singleton_method(envtbl, "invert", env_invert, 0);
6435  rb_define_singleton_method(envtbl, "replace", env_replace, 1);
6436  rb_define_singleton_method(envtbl, "update", env_update, 1);
6437  rb_define_singleton_method(envtbl, "merge!", env_update, 1);
6438  rb_define_singleton_method(envtbl, "inspect", env_inspect, 0);
6439  rb_define_singleton_method(envtbl, "rehash", env_none, 0);
6440  rb_define_singleton_method(envtbl, "to_a", env_to_a, 0);
6441  rb_define_singleton_method(envtbl, "to_s", env_to_s, 0);
6442  rb_define_singleton_method(envtbl, "key", env_key, 1);
6443  rb_define_singleton_method(envtbl, "index", env_index, 1);
6444  rb_define_singleton_method(envtbl, "size", env_size, 0);
6445  rb_define_singleton_method(envtbl, "length", env_size, 0);
6446  rb_define_singleton_method(envtbl, "empty?", env_empty_p, 0);
6447  rb_define_singleton_method(envtbl, "keys", env_f_keys, 0);
6448  rb_define_singleton_method(envtbl, "values", env_f_values, 0);
6449  rb_define_singleton_method(envtbl, "values_at", env_values_at, -1);
6450  rb_define_singleton_method(envtbl, "include?", env_has_key, 1);
6451  rb_define_singleton_method(envtbl, "member?", env_has_key, 1);
6452  rb_define_singleton_method(envtbl, "has_key?", env_has_key, 1);
6453  rb_define_singleton_method(envtbl, "has_value?", env_has_value, 1);
6454  rb_define_singleton_method(envtbl, "key?", env_has_key, 1);
6455  rb_define_singleton_method(envtbl, "value?", env_has_value, 1);
6456  rb_define_singleton_method(envtbl, "to_hash", env_f_to_hash, 0);
6457  rb_define_singleton_method(envtbl, "to_h", env_to_h, 0);
6458  rb_define_singleton_method(envtbl, "assoc", env_assoc, 1);
6459  rb_define_singleton_method(envtbl, "rassoc", env_rassoc, 1);
6460 
6461  /*
6462  * ENV is a Hash-like accessor for environment variables.
6463  *
6464  * See ENV (the class) for more details.
6465  */
6466  rb_define_global_const("ENV", envtbl);
6467 
6468  /* for callcc */
6469  ruby_register_rollback_func_for_ensure(hash_foreach_ensure, hash_foreach_ensure_rollback);
6470 
6471  HASH_ASSERT(sizeof(ar_hint_t) * RHASH_AR_TABLE_MAX_SIZE == sizeof(VALUE));
6472 }
rb_yield_values
#define rb_yield_values(argc,...)
Definition: rb_mjit_min_header-2.7.0.h:6584
rb_hash_st_table_set
void rb_hash_st_table_set(VALUE hash, st_table *st)
Definition: hash.c:558
equal_data::eql
int eql
Definition: hash.c:3481
st_foreach_safe
void st_foreach_safe(st_table *table, st_foreach_func *func, st_data_t a)
Definition: hash.c:1272
FLONUM_P
#define FLONUM_P(x)
Definition: ruby.h:430
rehash_arg::hash
VALUE hash
Definition: hash.c:1848
rb_ary_new_capa
VALUE rb_ary_new_capa(long capa)
Definition: array.c:717
rb_hash_update_func
VALUE rb_hash_update_func(VALUE newkey, VALUE oldkey, VALUE value)
Definition: intern.h:573
rb_transient_heap_managed_ptr_p
int rb_transient_heap_managed_ptr_p(const void *ptr)
Definition: transient_heap.c:506
rb_str_ellipsize
VALUE rb_str_ellipsize(VALUE, long)
Shortens str and adds three dots, an ellipsis, if it is longer than len characters.
Definition: string.c:10185
rb_proc_lambda_p
VALUE rb_proc_lambda_p(VALUE)
Definition: proc.c:275
UNLIKELY
#define UNLIKELY(x)
Definition: ffi_common.h:126
ID
unsigned long ID
Definition: ruby.h:103
rb_to_hash_type
VALUE rb_to_hash_type(VALUE hash)
Definition: hash.c:1818
ruby_xfree
void ruby_xfree(void *x)
Definition: gc.c:10150
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:649
equal_data
Definition: hash.c:3478
RHASH_PROC_DEFAULT
@ RHASH_PROC_DEFAULT
Definition: internal.h:819
rb_hash_keep_if
VALUE rb_hash_keep_if(VALUE hash)
Definition: hash.c:2668
rb_raw_obj_info
const char * rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
Definition: gc.c:11419
rb_fstring
VALUE rb_fstring(VALUE)
Definition: string.c:312
rb_method_basic_definition_p
#define rb_method_basic_definition_p(klass, mid)
Definition: rb_mjit_min_header-2.7.0.h:7900
STATIC_SYM_P
#define STATIC_SYM_P(x)
Definition: ruby.h:411
TRUE
#define TRUE
Definition: nkf.h:175
rb_hash_tbl_raw
MJIT_FUNC_EXPORTED struct st_table * rb_hash_tbl_raw(VALUE hash)
Definition: hash.c:1567
rb_check_convert_type_with_id
VALUE rb_check_convert_type_with_id(VALUE, int, const char *, ID)
Definition: object.c:2957
rb_block_arity
int rb_block_arity(void)
Definition: proc.c:1144
st_foreach_with_replace
int st_foreach_with_replace(st_table *tab, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
Definition: st.c:1700
T_FLOAT
#define T_FLOAT
Definition: ruby.h:527
rb_include_module
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:869
RHASH_AR_TABLE_MAX_SIZE
#define RHASH_AR_TABLE_MAX_SIZE
Definition: internal.h:821
st_update_callback_func
int st_update_callback_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
Definition: st.h:131
rb_assoc_new
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:896
st_copy
st_table * st_copy(st_table *old_tab)
Definition: st.c:1320
rb_str_new2
#define rb_str_new2
Definition: intern.h:903
rb_enc_name
#define rb_enc_name(enc)
Definition: encoding.h:177
rb_filesystem_encoding
rb_encoding * rb_filesystem_encoding(void)
Definition: encoding.c:1387
rb_str_hash
st_index_t rb_str_hash(VALUE)
Definition: string.c:3163
hash_foreach_arg::hash
VALUE hash
Definition: hash.c:1287
rehash_arg
Definition: hash.c:1847
update_callback_arg
Definition: hash.c:1593
foreach_safe_arg::tbl
st_table * tbl
Definition: hash.c:1252
st_table::num_entries
st_index_t num_entries
Definition: st.h:86
env
#define env
FIX2INT
#define FIX2INT(x)
Definition: ruby.h:717
update_arg::old_value
VALUE old_value
Definition: hash.c:1618
rb_class_has_methods
int rb_class_has_methods(VALUE c)
Definition: class.c:2201
rb_ident_hash_new
VALUE rb_ident_hash_new(void)
Definition: hash.c:4203
rb_hash_new
VALUE rb_hash_new(void)
Definition: hash.c:1501
rb_hash_st_table
st_table * rb_hash_st_table(VALUE hash)
Definition: hash.c:551
ST_CHECK
@ ST_CHECK
Definition: st.h:99
rb_hash_resurrect
MJIT_FUNC_EXPORTED VALUE rb_hash_resurrect(VALUE hash)
Definition: hash.c:1548
rb_str_buf_cat2
#define rb_str_buf_cat2
Definition: intern.h:911
rb_warn
void rb_warn(const char *fmt,...)
Definition: error.c:313
HASH_ASSERT
#define HASH_ASSERT(expr)
Definition: hash.c:435
rb_block_given_p
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:897
update_arg::arg
st_data_t arg
Definition: hash.c:1613
RHASH_ST_CLEAR
#define RHASH_ST_CLEAR(h)
Definition: internal.h:862
ar_hint_t
unsigned char ar_hint_t
Definition: rb_mjit_min_header-2.7.0.h:6887
uint64_t
#define uint64_t
Definition: siphash.h:15
rb_hash_values
VALUE rb_hash_values(VALUE hash)
Definition: hash.c:3381
rb_warning
void rb_warning(const char *fmt,...)
Definition: error.c:334
rb_hash_size_num
size_t rb_hash_size_num(VALUE hash)
Definition: hash.c:2872
gc.h
RBASIC_CLEAR_CLASS
#define RBASIC_CLEAR_CLASS(obj)
Definition: internal.h:1981
ST_STOP
@ ST_STOP
Definition: st.h:99
rb_str_buf_cat_ascii
VALUE rb_str_buf_cat_ascii(VALUE, const char *)
Definition: string.c:2926
update_arg::hash
VALUE hash
Definition: hash.c:1614
idEqq
@ idEqq
Definition: id.h:97
rb_gc_force_recycle
void rb_gc_force_recycle(VALUE obj)
Definition: gc.c:7011
INT2FIX
#define INT2FIX(i)
Definition: ruby.h:263
rb_make_internal_id
ID rb_make_internal_id(void)
Definition: symbol.c:810
rb_hash_clear
VALUE rb_hash_clear(VALUE hash)
Definition: hash.c:2696
RHASH_UPDATE_ITER
#define RHASH_UPDATE_ITER(h, iter_lev, key, func, a)
Definition: hash.c:1663
snprintf
int snprintf(char *__restrict, size_t, const char *__restrict,...) __attribute__((__format__(__printf__
strchr
char * strchr(char *, char)
RHASH_SET_TRANSIENT_FLAG
#define RHASH_SET_TRANSIENT_FLAG(h)
Definition: internal.h:871
st_hash
st_index_t st_hash(const void *ptr, size_t len, st_index_t h)
Definition: st.c:1897
ruby_xmalloc
void * ruby_xmalloc(size_t size)
Definition: gc.c:11950
rb_hash_default_value
VALUE rb_hash_default_value(VALUE hash, VALUE key)
Definition: hash.c:1917
RSTRING_PTR
#define RSTRING_PTR(str)
Definition: ruby.h:1009
NUM2LONG
#define NUM2LONG(x)
Definition: ruby.h:679
st_shift
int st_shift(st_table *tab, st_data_t *key, st_data_t *value)
Definition: st.c:1440
rb_hash_reject
VALUE rb_hash_reject(VALUE hash)
Definition: hash.c:2477
rb_hash_aref
VALUE rb_hash_aref(VALUE hash, VALUE key)
Definition: hash.c:1964
rb_equal
VALUE rb_equal(VALUE, VALUE)
Same as Object#===, case equality.
Definition: object.c:124
rb_locale_encoding
rb_encoding * rb_locale_encoding(void)
Definition: encoding.c:1372
RUBY_SPECIAL_SHIFT
@ RUBY_SPECIAL_SHIFT
Definition: ruby.h:460
VALUE
unsigned long VALUE
Definition: ruby.h:102
rb_hash_size
VALUE rb_hash_size(VALUE hash)
Definition: hash.c:2866
index
int index
Definition: rb_mjit_min_header-2.7.0.h:11246
rb_eArgError
VALUE rb_eArgError
Definition: error.c:923
encoding.h
ruby_verbose
#define ruby_verbose
Definition: ruby.h:1925
malloc
void * malloc(size_t) __attribute__((__malloc__)) __attribute__((__warn_unused_result__)) __attribute__((__alloc_size__(1)))
st_delete
int st_delete(st_table *tab, st_data_t *key, st_data_t *value)
Definition: st.c:1418
st_foreach_check
int st_foreach_check(st_table *tab, st_foreach_check_callback_func *func, st_data_t arg, st_data_t never ATTRIBUTE_UNUSED)
Definition: st.c:1726
RB_TYPE_P
#define RB_TYPE_P(obj, type)
Definition: ruby.h:560
hash_foreach_arg
Definition: generator.c:722
shift_var
Definition: hash.c:2322
ENVNMATCH
#define ENVNMATCH(s1, s2, n)
Definition: hash.c:4579
update_arg::new_key
VALUE new_key
Definition: hash.c:1615
rb_enc_get
rb_encoding * rb_enc_get(VALUE obj)
Definition: encoding.c:872
st_add_direct
void st_add_direct(st_table *tab, st_data_t key, st_data_t value)
Definition: st.c:1251
id_yield
ID id_yield
Definition: eventids1.c:136
rb_enc_asciicompat
#define rb_enc_asciicompat(enc)
Definition: encoding.h:245
update_func_arg::func
rb_hash_update_func * func
Definition: hash.c:3800
rb_obj_hash
VALUE rb_obj_hash(VALUE obj)
Definition: hash.c:291
rb_float_value
double rb_float_value(VALUE v)
Definition: numeric.c:5834
ECONV_UNDEF_REPLACE
#define ECONV_UNDEF_REPLACE
Definition: encoding.h:396
RUBY_DTRACE_CREATE_HOOK
#define RUBY_DTRACE_CREATE_HOOK(name, arg)
Definition: internal.h:2584
st_retval
st_retval
Definition: st.h:99
int
__inline__ int
Definition: rb_mjit_min_header-2.7.0.h:2839
NORETURN
NORETURN(static void no_new_key(void))
id.h
getenv
#define getenv(name)
Definition: win32.c:73
RSYMBOL
#define RSYMBOL(obj)
Definition: symbol.h:33
uint64_t
unsigned long long uint64_t
Definition: sha2.h:102
rb_inspect
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
Definition: object.c:551
shift_var::val
VALUE val
Definition: hash.c:2324
rb_hash_lookup2
VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
Definition: hash.c:1977
rb_check_string_type
VALUE rb_check_string_type(VALUE)
Definition: string.c:2314
putenv
int putenv(char *__string)
Qundef
#define Qundef
Definition: ruby.h:470
rb_define_singleton_method
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1755
CHAR_BIT
#define CHAR_BIT
Definition: ruby.h:227
RHASH_ST_TABLE_FLAG
@ RHASH_ST_TABLE_FLAG
Definition: internal.h:820
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1551
rb_hash_update_by
VALUE rb_hash_update_by(VALUE hash1, VALUE hash2, rb_hash_update_func *func)
Definition: hash.c:3835
rb_proc_arity
int rb_proc_arity(VALUE)
Definition: proc.c:1112
rb_hash_keys
MJIT_FUNC_EXPORTED VALUE rb_hash_keys(VALUE hash)
Definition: hash.c:3334
RHASH_AR_TABLE_SIZE_INC
#define RHASH_AR_TABLE_SIZE_INC(h)
Definition: hash.c:607
ptr
struct RIMemo * ptr
Definition: debug.c:74
hash_verify
#define hash_verify(h)
Definition: hash.c:510
T_DATA
#define T_DATA
Definition: ruby.h:538
rb_obj_id
VALUE rb_obj_id(VALUE obj)
Definition: gc.c:3770
Qfalse
#define Qfalse
Definition: ruby.h:467
rb_hash_rassoc
VALUE rb_hash_rassoc(VALUE hash, VALUE obj)
Definition: hash.c:4003
update_func_arg::value
VALUE value
Definition: hash.c:3799
RETURN_SIZED_ENUMERATOR
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
Definition: intern.h:271
rb_hash_dup
VALUE rb_hash_dup(VALUE hash)
Definition: hash.c:1537
ar_table_pair
struct ar_table_pair_struct ar_table_pair
RB_OBJ_FROZEN
#define RB_OBJ_FROZEN(x)
Definition: ruby.h:1342
rb_hash_assoc
VALUE rb_hash_assoc(VALUE hash, VALUE key)
Definition: hash.c:3942
rb_hash_stlike_lookup
MJIT_FUNC_EXPORTED int rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval)
Definition: hash.c:1944
rb_ary_delete
VALUE rb_ary_delete(VALUE ary, VALUE item)
Definition: array.c:3365
SPECIAL_CONST_P
#define SPECIAL_CONST_P(x)
Definition: ruby.h:1313
rb_hash_select_bang
VALUE rb_hash_select_bang(VALUE hash)
Definition: hash.c:2641
st.h
NUM2LL
#define NUM2LL(x)
NULL
#define NULL
Definition: _sdbm.c:101
ST_DELETE
@ ST_DELETE
Definition: st.h:99
uint32_t
unsigned int uint32_t
Definition: sha2.h:101
SafeStringValue
#define SafeStringValue(v)
Definition: ruby.h:607
FL_TEST
#define FL_TEST(x, f)
Definition: ruby.h:1353
functor
Definition: hash.c:906
FL_WB_PROTECTED
#define FL_WB_PROTECTED
Definition: ruby.h:1279
PRIsVALUE
#define PRIsVALUE
Definition: ruby.h:166
rb_init_identtable
st_table * rb_init_identtable(void)
Definition: hash.c:4211
rb_hash_ar_table_p
int rb_hash_ar_table_p(VALUE hash)
Definition: hash.c:532
RHASH_AR_TABLE_SIZE_RAW
#define RHASH_AR_TABLE_SIZE_RAW(h)
Definition: internal.h:841
rb_str_cat_conv_enc_opts
VALUE rb_str_cat_conv_enc_opts(VALUE newstr, long ofs, const char *ptr, long len, rb_encoding *from, int ecflags, VALUE ecopts)
Definition: string.c:943
hash_foreach_arg::arg
VALUE arg
Definition: hash.c:1289
RHASH_AR_TABLE_SIZE
#define RHASH_AR_TABLE_SIZE(h)
Definition: hash.c:422
st_insert
int st_insert(st_table *tab, st_data_t key, st_data_t value)
Definition: st.c:1171
FIX2LONG
#define FIX2LONG(x)
Definition: ruby.h:394
error
const rb_iseq_t const char * error
Definition: rb_mjit_min_header-2.7.0.h:13506
strlen
size_t strlen(const char *)
rb_hash_bulk_insert_into_st_table
void rb_hash_bulk_insert_into_st_table(long, const VALUE *, VALUE)
Definition: st.c:2380
T_SYMBOL
#define T_SYMBOL
Definition: ruby.h:540
rb_hash_set_default_proc
VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc)
Definition: hash.c:2169
rb_ascii8bit_encindex
int rb_ascii8bit_encindex(void)
Definition: encoding.c:1322
strncmp
int strncmp(const char *, const char *, size_t)
foreach_safe_arg::arg
st_data_t arg
Definition: hash.c:1254
rb_big_hash
VALUE rb_big_hash(VALUE x)
Definition: bignum.c:6726
rb_define_alias
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1800
L
#define L(x)
Definition: asm.h:125
rb_respond_to
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:2190
RB_BLOCK_CALL_FUNC_ARGLIST
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
Definition: ruby.h:1964
rb_protect
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
Protects a function call from potential global escapes from the function.
Definition: eval.c:1071
rb_check_arity
#define rb_check_arity
Definition: intern.h:347
rb_eql
int rb_eql(VALUE, VALUE)
Determines if obj1 and obj2 are equal in terms of Object::eql?.
Definition: object.c:147
rb_memhash
st_index_t rb_memhash(const void *ptr, long len)
Definition: random.c:1440
rb_hash_new_with_size
MJIT_FUNC_EXPORTED VALUE rb_hash_new_with_size(st_index_t size)
Definition: hash.c:1507
v
int VALUE v
Definition: rb_mjit_min_header-2.7.0.h:12332
ALLOC_N
#define ALLOC_N(type, n)
Definition: ruby.h:1663
rb_hash_has_key
MJIT_FUNC_EXPORTED VALUE rb_hash_has_key(VALUE hash, VALUE key)
Definition: hash.c:3432
rb_funcallv
#define rb_funcallv(recv, mid, argc, argv)
Definition: rb_mjit_min_header-2.7.0.h:7899
RHASH_AR_TABLE_BOUND
#define RHASH_AR_TABLE_BOUND(h)
Definition: hash.c:429
UNLIMITED_ARGUMENTS
#define UNLIMITED_ARGUMENTS
Definition: intern.h:57
rb_str_fill_terminator
char * rb_str_fill_terminator(VALUE str, const int termlen)
Definition: string.c:2306
st_init_table_with_size
st_table * st_init_table_with_size(const struct st_hash_type *type, st_index_t size)
Definition: st.c:577
rb_hash_delete_entry
VALUE rb_hash_delete_entry(VALUE hash, VALUE key)
Definition: hash.c:2253
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2669
rb_str_hash_cmp
int rb_str_hash_cmp(VALUE, VALUE)
Definition: string.c:3173
rb_ivar_get
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1070
if
if((ID)(DISPID) nameid !=nameid)
Definition: win32ole.c:357
reset_hash_type_arg::hash
VALUE hash
Definition: hash.c:3902
obj
const VALUE VALUE obj
Definition: rb_mjit_min_header-2.7.0.h:5742
rb_ivar_set_internal
void rb_ivar_set_internal(VALUE obj, ID id, VALUE val)
Definition: variable.c:1308
rb_hash_stlike_update
int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func func, st_data_t arg)
Definition: hash.c:1624
rb_ident_cmp
#define rb_ident_cmp
Definition: hash.c:302
rb_obj_class
VALUE rb_obj_class(VALUE)
Equivalent to Object#class in Ruby.
Definition: object.c:217
rb_integer_pack
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
Definition: bignum.c:3547
probes.h
update_callback_arg::arg
st_data_t arg
Definition: hash.c:1595
rb_hash_add_new_element
int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:4472
NOINLINE
NOINLINE(static int ar_equal(VALUE x, VALUE y))
rb_obj_is_proc
VALUE rb_obj_is_proc(VALUE)
Definition: proc.c:152
rb_obj_info
const MJIT_FUNC_EXPORTED char * rb_obj_info(VALUE obj)
Definition: gc.c:11655
PRIuSIZE
#define PRIuSIZE
Definition: ruby.h:208
st_foreach_check_callback_func
int st_foreach_check_callback_func(st_data_t, st_data_t, st_data_t, int)
Definition: st.h:138
ST_REPLACE
@ ST_REPLACE
Definition: st.h:99
OBJ_WB_UNPROTECT
#define OBJ_WB_UNPROTECT(x)
Definition: ruby.h:1495
fprintf
int fprintf(FILE *__restrict, const char *__restrict,...) __attribute__((__format__(__printf__
RHASH_UNSET_TRANSIENT_FLAG
#define RHASH_UNSET_TRANSIENT_FLAG(h)
Definition: internal.h:872
rb_hash_rehash
VALUE rb_hash_rehash(VALUE hash)
Definition: hash.c:1885
st_clear
void st_clear(st_table *tab)
Definition: st.c:698
rb_encoding
const typedef OnigEncodingType rb_encoding
Definition: encoding.h:115
ALLOCV_END
#define ALLOCV_END(v)
Definition: ruby.h:1750
rb_check_frozen
#define rb_check_frozen(obj)
Definition: intern.h:319
rb_hash_transient_heap_evacuate
void rb_hash_transient_heap_evacuate(VALUE hash, int promote)
Definition: hash.c:1222
RHASH_SIZE
#define RHASH_SIZE(hsh)
Definition: fbuffer.h:8
rb_ary_includes
VALUE rb_ary_includes(VALUE ary, VALUE item)
Definition: array.c:4340
rb_hash_compare_by_id_p
MJIT_FUNC_EXPORTED VALUE rb_hash_compare_by_id_p(VALUE hash)
Definition: hash.c:4192
rb_obj_dig
VALUE rb_obj_dig(int argc, VALUE *argv, VALUE self, VALUE notfound)
Definition: object.c:3791
foreach_safe_arg::func
st_foreach_func * func
Definition: hash.c:1253
rb_convert_type_with_id
VALUE rb_convert_type_with_id(VALUE, int, const char *, ID)
Definition: object.c:2914
ALLOCV_N
#define ALLOCV_N(type, v, n)
Definition: ruby.h:1749
reset_hash_type_arg
Definition: hash.c:3901
rb_ary_cat
VALUE rb_ary_cat(VALUE ary, const VALUE *argv, long len)
Definition: array.c:1208
rb_hash_stlike_delete
int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval)
Definition: hash.c:2237
NOINSERT_UPDATE_CALLBACK
#define NOINSERT_UPDATE_CALLBACK(func)
Definition: hash.c:1598
st_foreach_callback_func
int st_foreach_callback_func(st_data_t, st_data_t, st_data_t)
Definition: st.h:137
functor::func
st_foreach_callback_func * func
Definition: hash.c:907
rb_hash_ar_table_size
size_t rb_hash_ar_table_size(void)
Definition: hash.c:355
i
uint32_t i
Definition: rb_mjit_min_header-2.7.0.h:5464
rb_hash_values_at
VALUE rb_hash_values_at(int argc, VALUE *argv, VALUE hash)
Definition: hash.c:2539
FL_EXIVAR
#define FL_EXIVAR
Definition: ruby.h:1286
RB_OBJ_WRITTEN
#define RB_OBJ_WRITTEN(a, oldv, b)
Definition: ruby.h:1509
RHASH_EMPTY_P
#define RHASH_EMPTY_P(h)
Definition: ruby.h:1131
st_data_t
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
Definition: st.h:22
rb_hash_tbl
struct st_table * rb_hash_tbl(VALUE hash, const char *file, int line)
Definition: hash.c:1574
RHASH_LEV_MASK
#define RHASH_LEV_MASK
Definition: internal.h:828
rb_hash_fetch_values
VALUE rb_hash_fetch_values(int argc, VALUE *argv, VALUE hash)
Definition: hash.c:2567
rb_hash_delete_if
VALUE rb_hash_delete_if(VALUE hash)
Definition: hash.c:2420
long
#define long
Definition: rb_mjit_min_header-2.7.0.h:2880
rb_hash_lookup
VALUE rb_hash_lookup(VALUE hash, VALUE key)
Definition: hash.c:1990
bin
char bin[32]
Definition: siphash.c:135
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:1195
st_index_t
st_data_t st_index_t
Definition: st.h:50
st_hash_type
Definition: st.h:61
cnt
rb_atomic_t cnt[RUBY_NSIG]
Definition: signal.c:503
rb_hash_start
st_index_t rb_hash_start(st_index_t)
Definition: random.c:1434
transient_heap.h
rb_obj_freeze
VALUE rb_obj_freeze(VALUE)
Make the object unmodifiable.
Definition: object.c:1080
RHASH_IFNONE
#define RHASH_IFNONE(h)
Definition: ruby.h:1129
stderr
#define stderr
Definition: rb_mjit_min_header-2.7.0.h:1485
st_hash_type::compare
int(* compare)(st_data_t, st_data_t)
Definition: st.h:62
rb_hash_bulk_insert
void rb_hash_bulk_insert(long argc, const VALUE *argv, VALUE hash)
Definition: hash.c:4515
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:922
RBASIC_CLASS
#define RBASIC_CLASS(obj)
Definition: ruby.h:906
rb_copy_generic_ivar
void rb_copy_generic_ivar(VALUE, VALUE)
Definition: variable.c:1447
rb_ary_set_len
void rb_ary_set_len(VALUE ary, long len)
Definition: array.c:1932
INTEGER_PACK_NATIVE_BYTE_ORDER
#define INTEGER_PACK_NATIVE_BYTE_ORDER
Definition: intern.h:155
rb_eRuntimeError
VALUE rb_eRuntimeError
Definition: error.c:920
RSHIFT
#define RSHIFT(x, y)
Definition: rb_mjit_min_header-2.7.0.h:414
RARRAY_AREF
#define RARRAY_AREF(a, i)
Definition: ruby.h:1101
RHASH_TRANSIENT_P
#define RHASH_TRANSIENT_P(hash)
Definition: internal.h:870
rb_transient_heap_alloc
void * rb_transient_heap_alloc(VALUE obj, size_t req_size)
Definition: transient_heap.c:359
rb_enc_copy
void rb_enc_copy(VALUE obj1, VALUE obj2)
Definition: encoding.c:990
symbol.h
size
int size
Definition: encoding.c:58
FALSE
#define FALSE
Definition: nkf.h:174
uint128_t
#define uint128_t
Definition: rb_mjit_min_header-2.7.0.h:235
FIXNUM_P
#define FIXNUM_P(f)
Definition: ruby.h:396
RCLASS_SUPER
#define RCLASS_SUPER(c)
Definition: classext.h:16
RHASH_AR_TABLE_BOUND_MASK
#define RHASH_AR_TABLE_BOUND_MASK
Definition: internal.h:866
rb_to_int
VALUE rb_to_int(VALUE)
Converts val into Integer.
Definition: object.c:3021
rb_env_clear
VALUE rb_env_clear(void)
Definition: hash.c:5553
rb_gc_writebarrier_remember
MJIT_FUNC_EXPORTED void rb_gc_writebarrier_remember(VALUE obj)
Definition: gc.c:6875
rb_hash_foreach
void rb_hash_foreach(VALUE hash, rb_foreach_func *func, VALUE farg)
Definition: hash.c:1461
FL_SET_RAW
#define FL_SET_RAW(x, f)
Definition: ruby.h:1358
rb_str_new_frozen
VALUE rb_str_new_frozen(VALUE)
Definition: string.c:1203
RHash::basic
struct RBasic basic
Definition: internal.h:888
getpid
pid_t getpid(void)
RHASH
#define RHASH(obj)
Definition: internal.h:859
rb_default_internal_encoding
rb_encoding * rb_default_internal_encoding(void)
Definition: encoding.c:1512
rb_w32_ugetenv
char * rb_w32_ugetenv(const char *)
Definition: win32.c:5230
RB_OBJ_WRITE
#define RB_OBJ_WRITE(a, slot, b)
Definition: ruby.h:1508
ar_table
struct ar_table_struct ar_table
st_update
int st_update(st_table *tab, st_data_t key, st_update_callback_func *func, st_data_t arg)
Definition: st.c:1510
EINVAL
#define EINVAL
Definition: rb_mjit_min_header-2.7.0.h:10959
rb_extend_object
void rb_extend_object(VALUE obj, VALUE module)
Extend the object with the module.
Definition: eval.c:1700
rb_cHash
VALUE rb_cHash
Definition: hash.c:92
rb_check_array_type
VALUE rb_check_array_type(VALUE ary)
Definition: array.c:909
ID_SCOPE_SHIFT
#define ID_SCOPE_SHIFT
Definition: id.h:31
key
key
Definition: openssl_missing.h:181
T_HASH
#define T_HASH
Definition: ruby.h:531
rb_yield_values2
VALUE rb_yield_values2(int n, const VALUE *argv)
Definition: vm_eval.c:1271
idTo_hash
@ idTo_hash
Definition: rb_mjit_min_header-2.7.0.h:8717
RHASH_ST_TABLE_P
#define RHASH_ST_TABLE_P(h)
Definition: internal.h:861
rb_hashtype_ident
const struct st_hash_type rb_hashtype_ident
Definition: hash.c:322
rb_hash_set_pair
VALUE rb_hash_set_pair(VALUE hash, VALUE arg)
Definition: hash.c:3257
RHash
Definition: internal.h:887
CLASS_OF
#define CLASS_OF(v)
Definition: ruby.h:484
rb_str_buf_append
VALUE rb_str_buf_append(VALUE, VALUE)
Definition: string.c:2950
rb_exec_recursive_outer
VALUE rb_exec_recursive_outer(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
Definition: thread.c:5098
st_values
st_index_t st_values(st_table *tab, st_data_t *values, st_index_t size)
Definition: st.c:1795
crt_externs.h
RARRAY_LEN
#define RARRAY_LEN(a)
Definition: ruby.h:1070
st_foreach
int st_foreach(st_table *tab, st_foreach_callback_func *func, st_data_t arg)
Definition: st.c:1718
RHASH_AR_TABLE
#define RHASH_AR_TABLE(hash)
Definition: internal.h:855
RHASH_ST_TABLE_SET
#define RHASH_ST_TABLE_SET(h, s)
Definition: hash.c:432
rb_check_hash_type
VALUE rb_check_hash_type(VALUE hash)
Definition: hash.c:1825
PATH_ENV
#define PATH_ENV
Definition: defines.h:441
RHASH_AR_TABLE_BOUND_SHIFT
#define RHASH_AR_TABLE_BOUND_SHIFT
Definition: internal.h:867
FL_TEST_RAW
#define FL_TEST_RAW(x, f)
Definition: ruby.h:1352
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:2010
rb_ary_new2
#define rb_ary_new2
Definition: intern.h:103
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4322
n
const char size_t n
Definition: rb_mjit_min_header-2.7.0.h:5456
rb_func_proc_new
VALUE rb_func_proc_new(rb_block_call_func_t func, VALUE val)
Definition: proc.c:728
fopen
FILE * fopen(const char *__restrict _name, const char *__restrict _type)
T_BIGNUM
#define T_BIGNUM
Definition: ruby.h:533
rb_funcall
#define rb_funcall(recv, mid, argc,...)
Definition: rb_mjit_min_header-2.7.0.h:6585
rb_foreach_func
int rb_foreach_func(VALUE, VALUE, VALUE)
Definition: hash.c:1284
rb_bug
void rb_bug(const char *fmt,...)
Definition: error.c:634
foreach_safe_arg
Definition: hash.c:1251
internal.h
update_func_arg
Definition: hash.c:3797
arg
VALUE arg
Definition: rb_mjit_min_header-2.7.0.h:5601
argv
char ** argv
Definition: ruby.c:223
f
#define f
RHASH_ST_TABLE
#define RHASH_ST_TABLE(hash)
Definition: internal.h:856
update_arg::new_value
VALUE new_value
Definition: hash.c:1617
ar_table_pair_struct::val
VALUE val
Definition: hash.c:346
rb_define_global_const
void rb_define_global_const(const char *, VALUE)
Definition: variable.c:2892
ST_CONTINUE
@ ST_CONTINUE
Definition: st.h:99
ruby_setenv
void ruby_setenv(const char *name, const char *value)
Definition: hash.c:4923
st_init_table
st_table * st_init_table(const struct st_hash_type *type)
Definition: st.c:645
rb_hash_uint
#define rb_hash_uint(h, i)
Definition: intern.h:815
id_hash
ID id_hash
Definition: eventids1.c:53
st_keys
st_index_t st_keys(st_table *tab, st_data_t *keys, st_index_t size)
Definition: st.c:1757
rb_w32_osver
DWORD rb_w32_osver(void)
Definition: win32.c:319
rb_warn_deprecated
void rb_warn_deprecated(const char *fmt, const char *suggest,...)
Definition: error.c:364
rb_sprintf
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1197
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.0.h:13254
st_data_t
unsigned long st_data_t
Definition: rb_mjit_min_header-2.7.0.h:5363
rb_utf8_encoding
rb_encoding * rb_utf8_encoding(void)
Definition: encoding.c:1328
rb_hash
VALUE rb_hash(VALUE obj)
Definition: hash.c:129
rb_obj_alloc
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
Definition: object.c:1895
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
shift_var::key
VALUE key
Definition: hash.c:2323
st_index_hash
#define st_index_hash(index)
Definition: hash.c:265
RGENGC_WB_PROTECTED_HASH
#define RGENGC_WB_PROTECTED_HASH
Definition: ruby.h:805
rb_hash_end
#define rb_hash_end(h)
Definition: intern.h:816
ruby_register_rollback_func_for_ensure
void ruby_register_rollback_func_for_ensure(e_proc *ensure_func, e_proc *rollback_func)
Definition: cont.c:1520
debug_counter.h
env_name
#define env_name(s)
Definition: hash.c:4687
keys
const rb_iseq_t const char const VALUE keys
Definition: rb_mjit_min_header-2.7.0.h:13506
functor::arg
st_data_t arg
Definition: hash.c:908
st_table::type
const struct st_hash_type * type
Definition: st.h:84
rb_locale_encindex
int rb_locale_encindex(void)
Definition: encoding.c:1354
rb_hash_aset
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:2779
rb_cString
RUBY_EXTERN VALUE rb_cString
Definition: ruby.h:2044
RHASH_SET_IFNONE
#define RHASH_SET_IFNONE(h, ifnone)
Definition: ruby.h:1132
update_arg::old_key
VALUE old_key
Definition: hash.c:1616
rb_obj_info_dump
void rb_obj_info_dump(VALUE obj)
Definition: gc.c:11661
NIL_P
#define NIL_P(v)
Definition: ruby.h:482
rb_hash_delete
VALUE rb_hash_delete(VALUE hash, VALUE key)
Definition: hash.c:2271
fail
#define fail()
Definition: date_strptime.c:123
to_hash
#define to_hash
Definition: hash.c:1822
idTo_proc
@ idTo_proc
Definition: rb_mjit_min_header-2.7.0.h:8718
identhash
#define identhash
Definition: hash.c:321
rb_external_str_new_with_enc
VALUE rb_external_str_new_with_enc(const char *ptr, long len, rb_encoding *)
Definition: string.c:1036
argc
int argc
Definition: ruby.c:222
rb_str_initialize
VALUE rb_str_initialize(VALUE str, const char *ptr, long len, rb_encoding *enc)
Definition: string.c:964
st
enum ruby_tag_type st
Definition: rb_mjit_min_header-2.7.0.h:11111
rb_exec_recursive
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
Definition: thread.c:5075
rb_obj_classname
const char * rb_obj_classname(VALUE)
Definition: variable.c:289
rb_sys_fail_str
void rb_sys_fail_str(VALUE mesg)
Definition: error.c:2799
rb_hash_fetch
VALUE rb_hash_fetch(VALUE hash, VALUE key)
Definition: hash.c:2061
REALLOC_N
#define REALLOC_N(var, type, n)
Definition: ruby.h:1667
GET_ENVIRON
#define GET_ENVIRON(e)
Definition: hash.c:4571
free
#define free(x)
Definition: dln.c:52
RHASH_ITER_LEV
#define RHASH_ITER_LEV(h)
Definition: ruby.h:1128
recur
#define recur(fmt)
Definition: date_strptime.c:152
RHASH_LEV_SHIFT
@ RHASH_LEV_SHIFT
Definition: internal.h:835
update_callback_arg::hash
VALUE hash
Definition: hash.c:1594
BUILTIN_TYPE
#define BUILTIN_TYPE(x)
Definition: ruby.h:551
xfree
#define xfree
Definition: defines.h:216
RBASIC
#define RBASIC(obj)
Definition: ruby.h:1267
RHASH_TYPE
#define RHASH_TYPE(hash)
Definition: hash.c:433
ruby_strdup
char * ruby_strdup(const char *)
Definition: util.c:527
ar_table_struct::pairs
ar_table_pair pairs[RHASH_AR_TABLE_MAX_SIZE]
Definition: hash.c:351
SET_PROC_DEFAULT
#define SET_PROC_DEFAULT(hash, proc)
Definition: hash.c:50
rb_str_new
#define rb_str_new(str, len)
Definition: rb_mjit_min_header-2.7.0.h:6116
st_hash_t
st_index_t st_hash_t
Definition: hash.c:327
RHASH_AR_TABLE_BOUND_RAW
#define RHASH_AR_TABLE_BOUND_RAW(h)
Definition: hash.c:425
FREE_ENVIRON
#define FREE_ENVIRON(e)
Definition: hash.c:4572
st_foreach_func
int st_foreach_func(st_data_t, st_data_t, st_data_t)
Definition: hash.c:1249
MJIT_FUNC_EXPORTED
#define MJIT_FUNC_EXPORTED
Definition: defines.h:396
_
#define _(args)
Definition: dln.h:28
setenv
int setenv(const char *__string, const char *__value, int __overwrite)
ar_table_struct
Definition: hash.c:349
Qtrue
#define Qtrue
Definition: ruby.h:468
rb_hash_set_ifnone
VALUE rb_hash_set_ifnone(VALUE hash, VALUE ifnone)
Definition: hash.c:99
ruby_tz_uptodate_p
bool ruby_tz_uptodate_p
Definition: time.c:674
update_func_arg::hash
VALUE hash
Definition: hash.c:3798
HAS_EXTRA_STATES
#define HAS_EXTRA_STATES(hash, klass)
Definition: hash.c:41
equal_data::result
VALUE result
Definition: hash.c:3479
len
uint8_t len
Definition: escape.c:17
SYMBOL_P
#define SYMBOL_P(x)
Definition: ruby.h:413
rb_hash_ar_table
ar_table * rb_hash_ar_table(VALUE hash)
Definition: hash.c:544
RB_DEBUG_COUNTER_INC
#define RB_DEBUG_COUNTER_INC(type)
Definition: debug_counter.h:375
rb_usascii_str_new2
#define rb_usascii_str_new2
Definition: intern.h:909
tbl_update_func
int(* tbl_update_func)(st_data_t *, st_data_t *, st_data_t, int)
Definition: hash.c:1621
rb_exec_recursive_paired
VALUE rb_exec_recursive_paired(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE, VALUE)
Definition: thread.c:5086
LONG2FIX
#define LONG2FIX(i)
Definition: ruby.h:265
T_STRING
#define T_STRING
Definition: ruby.h:528
rb_hash_key_str
VALUE rb_hash_key_str(VALUE key)
Definition: hash.c:2729
MAYBE_UNUSED
#define MAYBE_UNUSED
Definition: ffi_common.h:32
rb_hash_stlike_foreach_with_replace
int rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
Definition: hash.c:1431
rb_hash_select
VALUE rb_hash_select(VALUE hash)
Definition: hash.c:2606
hash_foreach_arg::func
rb_foreach_func * func
Definition: hash.c:1288
RHASH_TBL_RAW
#define RHASH_TBL_RAW(h)
Definition: internal.h:1689
rb_yield
VALUE rb_yield(VALUE)
Definition: vm_eval.c:1237
reset_hash_type_arg::orighash
const struct st_hash_type * orighash
Definition: hash.c:3903
rb_hash_stlike_foreach
int rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg)
Definition: hash.c:1420
SET_DEFAULT
#define SET_DEFAULT(hash, ifnone)
Definition: hash.c:46
update_arg
Definition: hash.c:1612
rb_ensure
VALUE rb_ensure(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*e_proc)(VALUE), VALUE data2)
An equivalent to ensure clause.
Definition: eval.c:1114
COPY_DEFAULT
#define COPY_DEFAULT(hash, hash2)
Definition: hash.c:52
ECONV_INVALID_REPLACE
#define ECONV_INVALID_REPLACE
Definition: encoding.h:394
rb_builtin_class_name
const char * rb_builtin_class_name(VALUE x)
Definition: error.c:797
ST2FIX
#define ST2FIX(h)
Definition: ruby_missing.h:21
rb_enc_str_asciionly_p
int rb_enc_str_asciionly_p(VALUE)
Definition: string.c:678
RHASH_AR_TABLE_SIZE_SHIFT
#define RHASH_AR_TABLE_SIZE_SHIFT
Definition: internal.h:865
RHASH_AR_TABLE_SIZE_MASK
#define RHASH_AR_TABLE_SIZE_MASK
Definition: internal.h:864
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:723
NEWOBJ_OF
#define NEWOBJ_OF(obj, type, klass, flags)
Definition: ruby.h:785
NUM2INT
#define NUM2INT(x)
Definition: ruby.h:715
Qnil
#define Qnil
Definition: ruby.h:469
ar_table_pair_struct
Definition: hash.c:344
rehash_arg::tbl
st_table * tbl
Definition: hash.c:1849
rb_str_buf_cat
#define rb_str_buf_cat
Definition: intern.h:910
rb_hash_reject_bang
VALUE rb_hash_reject_bang(VALUE hash)
Definition: hash.c:2440
rb_w32_getenv
char * rb_w32_getenv(const char *)
Definition: win32.c:5237
rb_key_err_raise
#define rb_key_err_raise(mesg, recv, name)
Definition: internal.h:1578
rb_mEnumerable
VALUE rb_mEnumerable
Definition: enum.c:20
h
size_t st_index_t h
Definition: rb_mjit_min_header-2.7.0.h:5462
st_lookup
int st_lookup(st_table *tab, st_data_t key, st_data_t *value)
Definition: st.c:1101
util.h
ar_table_pair_struct::key
VALUE key
Definition: hash.c:345
ST_DATA_COMPATIBLE_P
#define ST_DATA_COMPATIBLE_P(type)
Definition: st.h:72
RB_FL_ANY_RAW
#define RB_FL_ANY_RAW(x, f)
Definition: ruby.h:1318
RB_GC_GUARD
#define RB_GC_GUARD(v)
Definition: ruby.h:585
environ
char ** environ
unsetenv
int unsetenv(const char *)
RARRAY_PTR_USE_TRANSIENT
#define RARRAY_PTR_USE_TRANSIENT(ary, ptr_name, expr)
Definition: ruby.h:1084
RHASH_AR_TABLE_MAX_BOUND
#define RHASH_AR_TABLE_MAX_BOUND
Definition: hash.c:339
rb_hash_freeze
VALUE rb_hash_freeze(VALUE hash)
Definition: hash.c:87
RSTRING_LEN
#define RSTRING_LEN(str)
Definition: ruby.h:1005
st_free_table
void st_free_table(st_table *tab)
Definition: st.c:709
st_table
Definition: st.h:79
RHASH_AR_TABLE_P
#define RHASH_AR_TABLE_P(hash)
Definition: internal.h:854
rb_str_conv_enc
VALUE rb_str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to)
Definition: string.c:1030
RHASH_UPDATE
#define RHASH_UPDATE(hash, key, func, arg)
Definition: hash.c:1667
ruby_assert.h
rb_intern
#define rb_intern(str)
rb_any_to_s
VALUE rb_any_to_s(VALUE)
Default implementation of #to_s.
Definition: object.c:527
equal_data::hash
VALUE hash
Definition: hash.c:3480
rb_enc_str_new
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
Definition: string.c:796
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
rb_dbl_long_hash
long rb_dbl_long_hash(double d)
Definition: hash.c:160
ruby_unsetenv
void ruby_unsetenv(const char *name)
Definition: hash.c:5062
ENVMATCH
#define ENVMATCH(n1, n2)
Definition: hash.c:4578
RTEST
#define RTEST(v)
Definition: ruby.h:481
object_id
#define object_id
Definition: vm_method.c:31
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
rb_str_buf_new2
#define rb_str_buf_new2
Definition: intern.h:908
RHASH_AR_TABLE_REF
#define RHASH_AR_TABLE_REF(hash, n)
Definition: hash.c:341
RHASH_AR_CLEARED_HINT
#define RHASH_AR_CLEARED_HINT
Definition: hash.c:342
__sFILE
Definition: vsnprintf.c:169
get_env_ptr
#define get_env_ptr(var, val)
Definition: hash.c:4674
rb_env_path_tainted
int rb_env_path_tainted(void)
Definition: hash.c:4829
Init_Hash
void Init_Hash(void)
Definition: hash.c:6222
rb_syserr_fail_str
void rb_syserr_fail_str(int e, VALUE mesg)
Definition: error.c:2787
st_hash_type::hash
st_index_t(* hash)(st_data_t)
Definition: st.h:63
RHASH_LEV_MAX
@ RHASH_LEV_MAX
Definition: internal.h:836
memchr
void * memchr(const void *, int, size_t)
name
const char * name
Definition: nkf.c:208
rb_block_proc
VALUE rb_block_proc(void)
Definition: proc.c:837