Ruby
2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)
|
Go to the documentation of this file.
26 # ifdef HAVE_CRT_EXTERNS_H
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)))
46 #define SET_DEFAULT(hash, ifnone) ( \
47 FL_UNSET_RAW(hash, RHASH_PROC_DEFAULT), \
48 RHASH_SET_IFNONE(hash, ifnone))
50 #define SET_PROC_DEFAULT(hash, proc) set_proc_default(hash, proc)
52 #define COPY_DEFAULT(hash, hash2) copy_default(RHASH(hash), RHASH(hash2))
55 copy_default(
struct RHash *hash,
const struct RHash *hash2)
96 static ID id_hash_iter_lev;
108 if (a == b)
return 0;
124 if (recurse)
return INT2FIX(0);
152 dbl_to_index(
double d)
163 if (d == 0.0) d = 0.0;
164 #if SIZEOF_INT == SIZEOF_VOIDP
167 return rb_objid_hash(dbl_to_index(d));
204 hnum = other_func(a);
207 #if SIZEOF_LONG < SIZEOF_ST_INDEX_T
209 hnum &= (
unsigned long)-1 >> 2;
211 hnum |= ~((
unsigned long)-1 >> 2);
229 return any_hash(a, obj_any_hash);
238 static const uint32_t prime2 = 0x830fcab9;
244 #if defined HAVE_UINT128_T
248 uint64_t hm1 = m1 >> 32, hm2 = m2 >> 32;
251 uint64_t v32_96 = hm1 * lm2 + lm1 * hm2;
254 return (v64_128 + (v32_96 >> 32)) ^ ((v32_96 << 32) + v1_32);
261 return mult_and_mix(
key + seed, prime1);
265 #define st_index_hash(index) key64_hash(rb_hash_start(index), prime2)
280 #if SIZEOF_LONG == SIZEOF_VOIDP
282 #elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
293 long hnum = any_hash(
obj, objid_hash);
302 #define rb_ident_cmp st_numcmp
321 #define identhash rb_hashtype_ident
339 #define RHASH_AR_TABLE_MAX_BOUND RHASH_AR_TABLE_MAX_SIZE
341 #define RHASH_AR_TABLE_REF(hash, n) (&RHASH_AR_TABLE(hash)->pairs[n])
342 #define RHASH_AR_CLEARED_HINT 0xff
387 ar_hint_set_hint(hash,
index, ar_do_hash_hint(hash_value));
391 ar_clear_entry(
VALUE hash,
unsigned int index)
399 ar_cleared_entry(
VALUE hash,
unsigned int index)
419 ar_hint_set(hash,
index, hash_value);
422 #define RHASH_AR_TABLE_SIZE(h) (HASH_ASSERT(RHASH_AR_TABLE_P(h)), \
423 RHASH_AR_TABLE_SIZE_RAW(h))
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)))
429 #define RHASH_AR_TABLE_BOUND(h) (HASH_ASSERT(RHASH_AR_TABLE_P(h)), \
430 RHASH_AR_TABLE_BOUND_RAW(h))
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)
435 #define HASH_ASSERT(expr) RUBY_ASSERT_MESG_WHEN(HASH_DEBUG, expr, #expr)
438 #define hash_verify(hash) hash_verify_(hash, __FILE__, __LINE__)
441 rb_hash_dump(
VALUE hash)
451 for (
i=0;
i<bound;
i++) {
454 if (!ar_cleared_entry(hash,
i)) {
455 char b1[0x100], b2[0x100];
473 hash_verify_(
VALUE hash,
const char *file,
int line)
480 for (
i=0;
i<bound;
i++) {
482 if (!ar_cleared_entry(hash,
i)) {
510 #define hash_verify(h) ((void)0)
514 RHASH_TABLE_NULL_P(
VALUE hash)
526 RHASH_TABLE_EMPTY_P(
VALUE hash)
547 return RHASH(hash)->as.ar;
554 return RHASH(hash)->as.st;
570 RHASH(hash)->as.ar = ar;
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)
607 #define RHASH_AR_TABLE_SIZE_INC(h) HASH_AR_TABLE_SIZE_ADD(h, 1)
610 RHASH_AR_TABLE_SIZE_DEC(
VALUE h)
616 RHASH_AR_TABLE_SIZE_SET(
h, new_size);
619 RHASH_AR_TABLE_SIZE_SET(
h, 0);
620 RHASH_AR_TABLE_BOUND_SET(
h, 0);
626 RHASH_AR_TABLE_CLEAR(
VALUE h)
631 hash_ar_table_set(
h,
NULL);
635 ar_alloc_table(
VALUE hash)
647 RHASH_AR_TABLE_SIZE_SET(hash, 0);
648 RHASH_AR_TABLE_BOUND_SET(hash, 0);
649 hash_ar_table_set(hash, tab);
659 return rb_any_cmp(x, y) == 0;
670 for (
i = 0;
i < bound;
i++) {
671 if (hints[
i] == hint) {
673 if (ar_equal(
key, pair->
key)) {
680 static char fname[256];
684 snprintf(fname,
sizeof(fname),
"/tmp/ruby-armiss.%d", pid =
getpid());
691 fprintf(fp,
"miss: hash_eq:%d hints[%d]:%02x hint:%02x\n"
693 " pair->key:%016lx %s\n",
694 h1 == h2,
i, hints[
i], hint,
708 ar_hint_t hint = ar_do_hash_hint(hash_value);
709 return ar_find_entry_hint(hash, hint,
key);
713 ar_free_and_clear_table(
VALUE hash)
724 RHASH_AR_TABLE_CLEAR(hash);
732 ar_try_convert_table(
VALUE hash)
748 ar_free_and_clear_table(hash);
754 ar_force_convert_table(
VALUE hash,
const char *file,
int line)
765 #if RHASH_CONVERT_TABLE_DEBUG
773 for (
i = 0;
i < bound;
i++) {
774 if (ar_cleared_entry(hash,
i))
continue;
779 ar_free_and_clear_table(hash);
790 hash_ar_table(
VALUE hash)
792 if (RHASH_TABLE_NULL_P(hash)) {
793 ar_alloc_table(hash);
799 ar_compact_table(
VALUE hash)
811 for (
i=0;
i<bound;
i++) {
812 if (ar_cleared_entry(hash,
i)) {
814 for (; j<bound; j++) {
815 if (!ar_cleared_entry(hash, j)) {
817 ar_hint_set_hint(hash,
i, (
st_hash_t)ar_hint(hash, j));
818 ar_clear_entry(hash, j);
831 RHASH_AR_TABLE_BOUND_SET(hash,
size);
847 bin = ar_compact_table(hash);
852 ar_set_entry(hash,
bin,
key, val, hash_value);
853 RHASH_AR_TABLE_BOUND_SET(hash,
bin+1);
865 for (
i = 0;
i < bound;
i++) {
866 if (ar_cleared_entry(hash,
i))
continue;
891 ar_clear_entry(hash,
i);
892 RHASH_AR_TABLE_SIZE_DEC(hash);
903 return ar_general_foreach(hash, func, replace,
arg);
914 const struct functor *
f = (
void *)d;
915 return f->func(k,
v,
f->arg);
922 return ar_general_foreach(hash, apply_functor,
NULL, (
st_data_t)&
f);
936 for (
i = 0;
i < bound;
i++) {
937 if (ar_cleared_entry(hash,
i))
continue;
941 hint = ar_hint(hash,
i);
943 retval = (*func)(
key, pair->
val,
arg, 0);
948 if (pair->
key == never)
break;
949 ret = ar_find_entry_hint(hash, hint,
key);
951 retval = (*func)(0, 0,
arg, 1);
961 if (!ar_cleared_entry(hash,
i)) {
962 ar_clear_entry(hash,
i);
963 RHASH_AR_TABLE_SIZE_DEC(hash);
977 int retval, existing;
983 bin = ar_find_entry(hash, hash_value,
key);
997 retval = (*func)(&
key, &value,
arg, existing);
1003 if (ar_add_direct_with_hash(hash,
key, value, hash_value)) {
1009 if (old_key !=
key) {
1017 ar_clear_entry(hash,
bin);
1018 RHASH_AR_TABLE_SIZE_DEC(hash);
1031 hash_ar_table(hash);
1033 bin = ar_find_entry(hash, hash_value,
key);
1039 bin = ar_compact_table(hash);
1040 hash_ar_table(hash);
1044 ar_set_entry(hash,
bin,
key, value, hash_value);
1045 RHASH_AR_TABLE_BOUND_SET(hash,
bin+1);
1063 unsigned bin = ar_find_entry(hash, hash_value,
key);
1070 if (value !=
NULL) {
1085 bin = ar_find_entry(hash, hash_value, *
key);
1088 if (value != 0) *value = 0;
1096 ar_clear_entry(hash,
bin);
1097 RHASH_AR_TABLE_SIZE_DEC(hash);
1108 for (
i = 0;
i < bound;
i++) {
1109 if (!ar_cleared_entry(hash,
i)) {
1111 if (value != 0) *value = pair->
val;
1113 ar_clear_entry(hash,
i);
1114 RHASH_AR_TABLE_SIZE_DEC(hash);
1119 if (value !=
NULL) *value = 0;
1129 for (
i = 0;
i < bound;
i++) {
1130 if (
keys == keys_end) {
1134 if (!ar_cleared_entry(hash,
i)) {
1140 return keys - keys_start;
1147 st_data_t *values_start = values, *values_end = values +
size;
1149 for (
i = 0;
i < bound;
i++) {
1150 if (values == values_end) {
1154 if (!ar_cleared_entry(hash,
i)) {
1160 return values - values_start;
1168 if (old_tab !=
NULL) {
1170 if (new_tab ==
NULL) {
1172 if (new_tab !=
NULL) {
1180 *new_tab = *old_tab;
1181 RHASH(hash1)->ar_hint.word =
RHASH(hash2)->ar_hint.word;
1184 hash_ar_table_set(hash1, new_tab);
1200 hash_ar_table_set(hash1,
NULL);
1208 ar_clear(
VALUE hash)
1211 RHASH_AR_TABLE_SIZE_SET(hash, 0);
1212 RHASH_AR_TABLE_BOUND_SET(hash, 0);
1220 #if USE_TRANSIENT_HEAP
1240 if (new_tab ==
NULL)
goto promote;
1242 *new_tab = *old_tab;
1243 hash_ar_table_set(hash, new_tab);
1264 status = (*
arg->func)(
key, value,
arg->arg);
1348 iter_lev_in_ivar_set(
VALUE hash,
int lev)
1363 int lev = iter_lev_in_flags(
hash);
1366 return iter_lev_in_ivar(
hash);
1376 int lev = iter_lev_in_flags(
hash);
1378 lev = iter_lev_in_ivar(
hash);
1379 iter_lev_in_ivar_set(
hash, lev+1);
1385 iter_lev_in_ivar_set(
hash, lev);
1393 int lev = iter_lev_in_flags(
hash);
1395 lev = iter_lev_in_ivar(
hash);
1397 iter_lev_in_ivar_set(
hash, lev-1);
1406 hash_foreach_ensure_rollback(
VALUE hash)
1408 hash_iter_lev_inc(
hash);
1415 hash_iter_lev_dec(
hash);
1434 return ar_foreach_with_replace(
hash,
func, replace,
arg);
1447 ret = ar_foreach_check(
hash, hash_ar_foreach_iter,
1465 if (RHASH_TABLE_EMPTY_P(
hash))
1467 hash_iter_lev_inc(
hash);
1489 return hash_alloc_flags(
klass, 0,
Qnil);
1497 return hash_alloc(
klass);
1514 ar_alloc_table(ret);
1561 #if RHASH_CONVERT_TABLE_DEBUG
1564 return ar_force_convert_table(hash, file, line);
1569 return ar_force_convert_table(hash,
NULL, 0);
1581 rb_hash_modify(
VALUE hash)
1583 rb_hash_modify_check(hash);
1586 NORETURN(
static void no_new_key(
void));
1598 #define NOINSERT_UPDATE_CALLBACK(func) \
1600 func##_noinsert(st_data_t *key, st_data_t *val, st_data_t arg, int existing) \
1602 if (!existing) no_new_key(); \
1603 return func(key, val, (struct update_arg *)arg, existing); \
1607 func##_insert(st_data_t *key, st_data_t *val, st_data_t arg, int existing) \
1609 return func(key, val, (struct update_arg *)arg, existing); \
1629 ar_try_convert_table(hash);
1645 arg.arg = optional_arg;
1661 #define UPDATE_CALLBACK(iter_lev, func) ((iter_lev) > 0 ? func##_noinsert : func##_insert)
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)); \
1667 #define RHASH_UPDATE(hash, key, func, arg) \
1668 RHASH_UPDATE_ITER(hash, RHASH_ITER_LEV(hash), key, func, arg)
1676 if (
n != 2 && (
n >= 0 ||
n < -3)) {
1677 if (
n < 0)
n = -
n-1;
1726 rb_hash_modify(
hash);
1767 tmp = rb_hash_s_try_convert(
Qnil,
argv[0]);
1807 if (
argc % 2 != 0) {
1822 #define to_hash rb_to_hash_type
1893 rb_hash_modify_check(hash);
1895 tmp = hash_alloc(0);
1896 ar_alloc_table(tmp);
1898 ar_free_and_clear_table(hash);
1900 ar_free_and_clear_table(tmp);
1904 tmp = hash_alloc(0);
1936 return ar_lookup(hash,
key, pval);
1946 return hash_stlike_lookup(hash,
key, pval);
1968 if (hash_stlike_lookup(hash,
key, &val)) {
1981 if (hash_stlike_lookup(hash,
key, &val)) {
2035 if (block_given &&
argc == 2) {
2036 rb_warn(
"block supersedes default value argument");
2039 if (hash_stlike_lookup(hash,
key, &val)) {
2046 else if (
argc == 1) {
2063 return rb_hash_fetch_m(1, &
key, hash);
2090 VALUE args[2], ifnone;
2124 rb_hash_set_default(
VALUE hash,
VALUE ifnone)
2126 rb_hash_modify_check(hash);
2147 rb_hash_default_proc(
VALUE hash)
2173 rb_hash_modify_check(hash);
2181 "wrong default_proc type %s (expected Proc)",
2233 return rb_hash_key(hash, value);
2240 return ar_delete(hash, pkey, pval);
2275 if (deleted_value !=
Qundef) {
2276 return deleted_value;
2306 rb_hash_modify_check(hash);
2351 rb_hash_shift(
VALUE hash)
2355 rb_hash_modify_check(hash);
2359 if (ar_shift(hash, &var.key, &var.val)) {
2423 rb_hash_modify_check(hash);
2424 if (!RHASH_TABLE_EMPTY_P(hash)) {
2445 rb_hash_modify(hash);
2447 if (!
n)
return Qnil;
2646 rb_hash_modify_check(hash);
2648 if (!
n)
return Qnil;
2671 rb_hash_modify_check(hash);
2672 if (!RHASH_TABLE_EMPTY_P(hash)) {
2698 rb_hash_modify_check(hash);
2717 arg->new_value =
arg->arg;
2722 arg->new_value =
arg->arg;
2745 return hash_aset(
key,
val,
arg, existing);
2783 rb_hash_modify(hash);
2785 if (RHASH_TABLE_NULL_P(hash)) {
2786 if (iter_lev > 0) no_new_key();
2787 ar_alloc_table(hash);
2814 rb_hash_modify_check(hash);
2815 if (hash == hash2)
return hash;
2828 ar_free_and_clear_table(hash);
2888 rb_hash_empty_p(
VALUE hash)
2920 rb_hash_each_value(
VALUE hash)
2953 rb_hash_each_key(
VALUE hash)
3000 rb_hash_each_pair(
VALUE hash)
3036 rb_hash_transform_keys(
VALUE hash)
3069 rb_hash_transform_keys_bang(
VALUE hash)
3072 rb_hash_modify_check(hash);
3073 if (!RHASH_TABLE_EMPTY_P(hash)) {
3075 VALUE pairs = rb_hash_flatten(0,
NULL, hash);
3118 rb_hash_transform_values(
VALUE hash)
3123 result = hash_dup(hash,
rb_cHash, 0);
3150 rb_hash_transform_values_bang(
VALUE hash)
3153 rb_hash_modify_check(hash);
3155 if (!RHASH_TABLE_EMPTY_P(hash)) {
3181 rb_hash_to_a(
VALUE hash)
3236 rb_hash_inspect(
VALUE hash)
3251 rb_hash_to_hash(
VALUE hash)
3282 rb_hash_to_h_block(
VALUE hash)
3302 rb_hash_to_h(
VALUE hash)
3305 return rb_hash_to_h_block(hash);
3387 if (
size == 0)
return values;
3434 if (hash_stlike_lookup(hash,
key,
NULL)) {
3490 if (!hash_stlike_lookup(data->
hash,
key, &val2)) {
3521 if (hash1 == hash2)
return Qtrue;
3527 if (
rb_eql(hash2, hash1)) {
3540 if (!RHASH_TABLE_EMPTY_P(hash1) && !RHASH_TABLE_EMPTY_P(hash2)) {
3586 return hash_equal(hash1, hash2,
FALSE);
3601 return hash_equal(hash1, hash2,
TRUE);
3612 *hval ^=
st_hash(hdata,
sizeof(hdata), 0);
3689 arg->old_value = *value;
3690 arg->new_value =
arg->arg;
3694 arg->new_value =
arg->arg;
3716 arg->old_value = *value;
3721 arg->new_value = newvalue;
3784 rb_hash_modify(
self);
3816 arg->new_value = newvalue;
3837 rb_hash_modify(hash1);
3950 ar_force_convert_table(
hash, __FILE__, __LINE__);
3953 orighash = table->
type;
3960 assochash.
compare = assoc_cmp;
3962 table->
type = &assochash;
4051 if (level == 0)
return rb_hash_to_a(
hash);
4059 rb_funcallv(ary, id_flatten_bang, 1, &ary_flatten_level);
4061 else if (level < 0) {
4086 if (!
NIL_P(value)) {
4130 rb_hash_modify_check(
hash);
4166 rb_hash_modify_check(
hash);
4167 ar_force_convert_table(
hash, __FILE__, __LINE__);
4170 tmp = hash_alloc(0);
4273 rb_warn(
"given block not used");
4316 if (!--
argc)
return self;
4359 return hash_le(
hash, other);
4380 return hash_le(
hash, other);
4401 return hash_le(other,
hash);
4422 return hash_le(other,
hash);
4481 hash_ar_table(
hash);
4487 ar_try_convert_table(
hash);
4505 for (
i = 0;
i <
argc; ) {
4508 ar_insert(
hash, k,
v);
4521 if (RHASH_TABLE_NULL_P(
hash)) {
4523 hash_ar_table(
hash);
4540 static char **origenviron;
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;
4546 #define environ my_environ
4548 static char *(*w32_getenv)(
const char*);
4550 w32_getenv_unknown(
const char *
name)
4552 char *(*func)(
const char*);
4560 return (w32_getenv = func)(
name);
4562 static char *(*w32_getenv)(
const char*) = w32_getenv_unknown;
4563 #define getenv(n) w32_getenv(n)
4564 #elif defined(__APPLE__)
4566 #define environ (*_NSGetEnviron())
4567 #define GET_ENVIRON(e) (e)
4568 #define FREE_ENVIRON(e)
4571 #define GET_ENVIRON(e) (e)
4572 #define FREE_ENVIRON(e)
4574 #ifdef ENV_IGNORECASE
4575 #define ENVMATCH(s1, s2) (STRCASECMP((s1), (s2)) == 0)
4576 #define ENVNMATCH(s1, s2, n) (STRNCASECMP((s1), (s2), (n)) == 0)
4578 #define ENVMATCH(n1, n2) (strcmp((n1), (n2)) == 0)
4579 #define ENVNMATCH(s1, s2, n) (memcmp((s1), (s2), (n)) == 0)
4608 env_str_new(
const char *
ptr,
long len)
4614 env_str_new2(
const char *
ptr)
4620 static const char TZ_ENV[] =
"TZ";
4624 env_encoding_for(
const char *
name,
const char *
ptr)
4635 env_name_new(
const char *
name,
const char *
ptr)
4637 return env_enc_str_new_cstr(
ptr, env_encoding_for(
name,
ptr));
4643 volatile VALUE *pstr,
4671 #define get_env_ptr(var, val) \
4672 (var = get_env_cstr(&(val), #var))
4674 #define get_env_ptr(var, val) \
4675 (var = get_env_cstr(val, #var))
4678 static inline const char *
4687 #define env_name(s) env_name(&(s))
4694 const char *nam, *val;
4710 VALUE value = env_str_new2(val);
4747 val = env_delete(
name);
4768 const char *nam, *
env;
4773 return env_name_new(nam,
env);
4808 const char *nam, *
env;
4813 if (block_given &&
argc == 2) {
4814 rb_warn(
"block supersedes default value argument");
4825 return env_name_new(nam,
env);
4831 rb_warning(
"rb_env_path_tainted is deprecated and will be removed in Ruby 3.2.");
4835 #if defined(_WIN32) || (defined(HAVE_SETENV) && defined(HAVE_UNSETENV))
4838 in_origenv(
const char *
str)
4842 if (*
env ==
str)
return 1;
4848 envix(
const char *nam)
4854 for (
i = 0;
env[
i];
i++) {
4865 getenvsize(
const WCHAR* p)
4867 const WCHAR* porg = p;
4868 while (*p++) p += lstrlenW(p) + 1;
4869 return p - porg + 1;
4873 getenvblocksize(
void)
4883 check_envsize(
size_t n)
4889 WCHAR* p = GetEnvironmentStringsW();
4892 FreeEnvironmentStringsW(p);
4893 if (
n >= getenvblocksize()) {
4901 #if defined(_WIN32) || \
4902 (defined(__sun) && !(defined(HAVE_SETENV) && defined(HAVE_UNSETENV)))
4904 NORETURN(
static void invalid_envname(
const char *
name));
4907 invalid_envname(
const char *
name)
4913 check_envname(
const char *
name)
4916 invalid_envname(
name);
4926 # if defined(MINGW_HAS_SECURE_API) || RUBY_MSVCRT_VERSION >= 80
4927 # define HAVE__WPUTENV_S 1
4934 check_envname(
name);
4935 len = MultiByteToWideChar(CP_UTF8, 0,
name, -1,
NULL, 0);
4938 len2 = MultiByteToWideChar(CP_UTF8, 0, value, -1,
NULL, 0);
4939 if (check_envsize((
size_t)
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'=';
4952 MultiByteToWideChar(CP_UTF8, 0,
name, -1, wname,
len);
4953 wvalue = wname +
len;
4955 #ifndef HAVE__WPUTENV_S
4956 wname[
len-1] =
L'=';
4959 #ifndef HAVE__WPUTENV_S
4960 failed = _wputenv(wname);
4962 failed = _wputenv_s(wname, wvalue);
4967 if (!value || !*value) {
4969 if (!SetEnvironmentVariable(
name, value) &&
4970 GetLastError() != ERROR_ENVVAR_NOT_FOUND)
goto fail;
4974 invalid_envname(
name);
4976 #elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)
4982 #ifdef VOID_UNSETENV
4994 size_t len, mem_size;
4995 char **env_ptr, *
str, *mem_ptr;
4997 check_envname(
name);
5001 mem_ptr =
malloc(mem_size);
5002 if (mem_ptr ==
NULL)
5009 while ((env_ptr[0] = env_ptr[1]) != 0) env_ptr++;
5030 for (max =
i;
environ[max]; max++) ;
5031 tmpenv =
ALLOC_N(
char*, max+2);
5032 for (j=0; j<max; j++)
5038 char **envp = origenviron;
5039 while (*envp && *envp !=
environ[
i]) envp++;
5114 return env_aset(nm, val);
5217 env_each_key(
VALUE ehash)
5266 return env_values();
5287 env_each_value(
VALUE ehash)
5293 values = env_values();
5319 env_each_pair(
VALUE ehash)
5374 env_reject_bang(
VALUE ehash)
5393 if (del == 0)
return Qnil;
5407 env_delete_if(
VALUE ehash)
5410 env_reject_bang(ehash);
5448 env_select(
VALUE ehash)
5483 env_select_bang(
VALUE ehash)
5502 if (del == 0)
return Qnil;
5516 env_keep_if(
VALUE ehash)
5519 env_select_bang(ehash);
5544 value = rb_f_getenv(
Qnil,
key);
5653 env_str_new2(s+1)));
5891 return env_key(dmy, value);
5925 return env_to_hash();
5968 env_freeze(
VALUE self)
6021 return rb_hash_invert(env_to_hash());
6078 if (!
NIL_P(oldval)) {
6103 env_update_block_i : env_update_i;
6225 #define rb_intern(str) rb_intern_const(str)
6229 id_flatten_bang =
rb_intern(
"flatten!");
void rb_hash_st_table_set(VALUE hash, st_table *st)
void st_foreach_safe(st_table *table, st_foreach_func *func, st_data_t a)
VALUE rb_ary_new_capa(long capa)
VALUE rb_hash_update_func(VALUE newkey, VALUE oldkey, VALUE value)
int rb_transient_heap_managed_ptr_p(const void *ptr)
VALUE rb_str_ellipsize(VALUE, long)
Shortens str and adds three dots, an ellipsis, if it is longer than len characters.
VALUE rb_proc_lambda_p(VALUE)
VALUE rb_to_hash_type(VALUE hash)
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
VALUE rb_hash_keep_if(VALUE hash)
const char * rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
MJIT_FUNC_EXPORTED struct st_table * rb_hash_tbl_raw(VALUE hash)
VALUE rb_check_convert_type_with_id(VALUE, int, const char *, ID)
int st_foreach_with_replace(st_table *tab, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
void rb_include_module(VALUE klass, VALUE module)
#define RHASH_AR_TABLE_MAX_SIZE
int st_update_callback_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
VALUE rb_assoc_new(VALUE car, VALUE cdr)
st_table * st_copy(st_table *old_tab)
rb_encoding * rb_filesystem_encoding(void)
st_index_t rb_str_hash(VALUE)
int rb_class_has_methods(VALUE c)
VALUE rb_ident_hash_new(void)
st_table * rb_hash_st_table(VALUE hash)
MJIT_FUNC_EXPORTED VALUE rb_hash_resurrect(VALUE hash)
void rb_warn(const char *fmt,...)
#define HASH_ASSERT(expr)
int rb_block_given_p(void)
Determines if the current method is given a block.
#define RHASH_ST_CLEAR(h)
VALUE rb_hash_values(VALUE hash)
void rb_warning(const char *fmt,...)
size_t rb_hash_size_num(VALUE hash)
#define RBASIC_CLEAR_CLASS(obj)
VALUE rb_str_buf_cat_ascii(VALUE, const char *)
void rb_gc_force_recycle(VALUE obj)
ID rb_make_internal_id(void)
VALUE rb_hash_clear(VALUE hash)
#define RHASH_UPDATE_ITER(h, iter_lev, key, func, a)
char * strchr(char *, char)
#define RHASH_SET_TRANSIENT_FLAG(h)
st_index_t st_hash(const void *ptr, size_t len, st_index_t h)
void * ruby_xmalloc(size_t size)
VALUE rb_hash_default_value(VALUE hash, VALUE key)
int st_shift(st_table *tab, st_data_t *key, st_data_t *value)
VALUE rb_hash_reject(VALUE hash)
VALUE rb_hash_aref(VALUE hash, VALUE key)
VALUE rb_equal(VALUE, VALUE)
Same as Object#===, case equality.
rb_encoding * rb_locale_encoding(void)
VALUE rb_hash_size(VALUE hash)
int st_delete(st_table *tab, st_data_t *key, st_data_t *value)
int st_foreach_check(st_table *tab, st_foreach_check_callback_func *func, st_data_t arg, st_data_t never ATTRIBUTE_UNUSED)
#define RB_TYPE_P(obj, type)
#define ENVNMATCH(s1, s2, n)
rb_encoding * rb_enc_get(VALUE obj)
void st_add_direct(st_table *tab, st_data_t key, st_data_t value)
#define rb_enc_asciicompat(enc)
rb_hash_update_func * func
VALUE rb_obj_hash(VALUE obj)
double rb_float_value(VALUE v)
#define ECONV_UNDEF_REPLACE
#define RUBY_DTRACE_CREATE_HOOK(name, arg)
NORETURN(static void no_new_key(void))
unsigned long long uint64_t
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
VALUE rb_check_string_type(VALUE)
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
VALUE rb_hash_update_by(VALUE hash1, VALUE hash2, rb_hash_update_func *func)
MJIT_FUNC_EXPORTED VALUE rb_hash_keys(VALUE hash)
#define RHASH_AR_TABLE_SIZE_INC(h)
VALUE rb_obj_id(VALUE obj)
VALUE rb_hash_rassoc(VALUE hash, VALUE obj)
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
VALUE rb_hash_dup(VALUE hash)
struct ar_table_pair_struct ar_table_pair
VALUE rb_hash_assoc(VALUE hash, VALUE key)
MJIT_FUNC_EXPORTED int rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval)
VALUE rb_ary_delete(VALUE ary, VALUE item)
#define SPECIAL_CONST_P(x)
VALUE rb_hash_select_bang(VALUE hash)
#define SafeStringValue(v)
st_table * rb_init_identtable(void)
int rb_hash_ar_table_p(VALUE hash)
#define RHASH_AR_TABLE_SIZE_RAW(h)
VALUE rb_str_cat_conv_enc_opts(VALUE newstr, long ofs, const char *ptr, long len, rb_encoding *from, int ecflags, VALUE ecopts)
#define RHASH_AR_TABLE_SIZE(h)
int st_insert(st_table *tab, st_data_t key, st_data_t value)
size_t strlen(const char *)
void rb_hash_bulk_insert_into_st_table(long, const VALUE *, VALUE)
VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc)
int rb_ascii8bit_encindex(void)
VALUE rb_big_hash(VALUE x)
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
int rb_respond_to(VALUE, ID)
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
Protects a function call from potential global escapes from the function.
int rb_eql(VALUE, VALUE)
Determines if obj1 and obj2 are equal in terms of Object::eql?.
st_index_t rb_memhash(const void *ptr, long len)
MJIT_FUNC_EXPORTED VALUE rb_hash_new_with_size(st_index_t size)
MJIT_FUNC_EXPORTED VALUE rb_hash_has_key(VALUE hash, VALUE key)
#define RHASH_AR_TABLE_BOUND(h)
#define UNLIMITED_ARGUMENTS
char * rb_str_fill_terminator(VALUE str, const int termlen)
st_table * st_init_table_with_size(const struct st_hash_type *type, st_index_t size)
VALUE rb_hash_delete_entry(VALUE hash, VALUE key)
void rb_raise(VALUE exc, const char *fmt,...)
int rb_str_hash_cmp(VALUE, VALUE)
VALUE rb_ivar_get(VALUE, ID)
if((ID)(DISPID) nameid !=nameid)
void rb_ivar_set_internal(VALUE obj, ID id, VALUE val)
int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func func, st_data_t arg)
VALUE rb_obj_class(VALUE)
Equivalent to Object#class in Ruby.
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val)
NOINLINE(static int ar_equal(VALUE x, VALUE y))
VALUE rb_obj_is_proc(VALUE)
const MJIT_FUNC_EXPORTED char * rb_obj_info(VALUE obj)
int st_foreach_check_callback_func(st_data_t, st_data_t, st_data_t, int)
#define OBJ_WB_UNPROTECT(x)
#define RHASH_UNSET_TRANSIENT_FLAG(h)
VALUE rb_hash_rehash(VALUE hash)
void st_clear(st_table *tab)
const typedef OnigEncodingType rb_encoding
#define rb_check_frozen(obj)
void rb_hash_transient_heap_evacuate(VALUE hash, int promote)
VALUE rb_ary_includes(VALUE ary, VALUE item)
MJIT_FUNC_EXPORTED VALUE rb_hash_compare_by_id_p(VALUE hash)
VALUE rb_obj_dig(int argc, VALUE *argv, VALUE self, VALUE notfound)
VALUE rb_convert_type_with_id(VALUE, int, const char *, ID)
#define ALLOCV_N(type, v, n)
VALUE rb_ary_cat(VALUE ary, const VALUE *argv, long len)
int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval)
#define NOINSERT_UPDATE_CALLBACK(func)
int st_foreach_callback_func(st_data_t, st_data_t, st_data_t)
st_foreach_callback_func * func
size_t rb_hash_ar_table_size(void)
VALUE rb_hash_values_at(int argc, VALUE *argv, VALUE hash)
#define RB_OBJ_WRITTEN(a, oldv, b)
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
struct st_table * rb_hash_tbl(VALUE hash, const char *file, int line)
VALUE rb_hash_fetch_values(int argc, VALUE *argv, VALUE hash)
VALUE rb_hash_delete_if(VALUE hash)
VALUE rb_hash_lookup(VALUE hash, VALUE key)
VALUE rb_ary_push(VALUE ary, VALUE item)
rb_atomic_t cnt[RUBY_NSIG]
st_index_t rb_hash_start(st_index_t)
VALUE rb_obj_freeze(VALUE)
Make the object unmodifiable.
int(* compare)(st_data_t, st_data_t)
void rb_hash_bulk_insert(long argc, const VALUE *argv, VALUE hash)
#define RBASIC_CLASS(obj)
void rb_copy_generic_ivar(VALUE, VALUE)
void rb_ary_set_len(VALUE ary, long len)
#define INTEGER_PACK_NATIVE_BYTE_ORDER
#define RARRAY_AREF(a, i)
#define RHASH_TRANSIENT_P(hash)
void * rb_transient_heap_alloc(VALUE obj, size_t req_size)
void rb_enc_copy(VALUE obj1, VALUE obj2)
#define RHASH_AR_TABLE_BOUND_MASK
VALUE rb_to_int(VALUE)
Converts val into Integer.
MJIT_FUNC_EXPORTED void rb_gc_writebarrier_remember(VALUE obj)
void rb_hash_foreach(VALUE hash, rb_foreach_func *func, VALUE farg)
VALUE rb_str_new_frozen(VALUE)
rb_encoding * rb_default_internal_encoding(void)
char * rb_w32_ugetenv(const char *)
#define RB_OBJ_WRITE(a, slot, b)
struct ar_table_struct ar_table
int st_update(st_table *tab, st_data_t key, st_update_callback_func *func, st_data_t arg)
void rb_extend_object(VALUE obj, VALUE module)
Extend the object with the module.
VALUE rb_check_array_type(VALUE ary)
VALUE rb_yield_values2(int n, const VALUE *argv)
#define RHASH_ST_TABLE_P(h)
const struct st_hash_type rb_hashtype_ident
VALUE rb_hash_set_pair(VALUE hash, VALUE arg)
VALUE rb_str_buf_append(VALUE, VALUE)
VALUE rb_exec_recursive_outer(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
st_index_t st_values(st_table *tab, st_data_t *values, st_index_t size)
int st_foreach(st_table *tab, st_foreach_callback_func *func, st_data_t arg)
#define RHASH_AR_TABLE(hash)
#define RHASH_ST_TABLE_SET(h, s)
VALUE rb_check_hash_type(VALUE hash)
#define RHASH_AR_TABLE_BOUND_SHIFT
#define FL_TEST_RAW(x, f)
RUBY_EXTERN VALUE rb_cObject
unsigned char buf[MIME_BUF_SIZE]
VALUE rb_func_proc_new(rb_block_call_func_t func, VALUE val)
int rb_foreach_func(VALUE, VALUE, VALUE)
void rb_bug(const char *fmt,...)
#define RHASH_ST_TABLE(hash)
void rb_define_global_const(const char *, VALUE)
void ruby_setenv(const char *name, const char *value)
st_table * st_init_table(const struct st_hash_type *type)
#define rb_hash_uint(h, i)
st_index_t st_keys(st_table *tab, st_data_t *keys, st_index_t size)
void rb_warn_deprecated(const char *fmt, const char *suggest,...)
VALUE rb_sprintf(const char *format,...)
rb_encoding * rb_utf8_encoding(void)
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
char str[HTML_ESCAPE_MAX_LEN+1]
#define st_index_hash(index)
#define RGENGC_WB_PROTECTED_HASH
void ruby_register_rollback_func_for_ensure(e_proc *ensure_func, e_proc *rollback_func)
const struct st_hash_type * type
int rb_locale_encindex(void)
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
RUBY_EXTERN VALUE rb_cString
#define RHASH_SET_IFNONE(h, ifnone)
void rb_obj_info_dump(VALUE obj)
VALUE rb_hash_delete(VALUE hash, VALUE key)
VALUE rb_external_str_new_with_enc(const char *ptr, long len, rb_encoding *)
VALUE rb_str_initialize(VALUE str, const char *ptr, long len, rb_encoding *enc)
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
const char * rb_obj_classname(VALUE)
void rb_sys_fail_str(VALUE mesg)
VALUE rb_hash_fetch(VALUE hash, VALUE key)
#define REALLOC_N(var, type, n)
#define RHASH_ITER_LEV(h)
char * ruby_strdup(const char *)
ar_table_pair pairs[RHASH_AR_TABLE_MAX_SIZE]
#define SET_PROC_DEFAULT(hash, proc)
#define RHASH_AR_TABLE_BOUND_RAW(h)
int st_foreach_func(st_data_t, st_data_t, st_data_t)
#define MJIT_FUNC_EXPORTED
VALUE rb_hash_set_ifnone(VALUE hash, VALUE ifnone)
#define HAS_EXTRA_STATES(hash, klass)
ar_table * rb_hash_ar_table(VALUE hash)
#define RB_DEBUG_COUNTER_INC(type)
#define rb_usascii_str_new2
int(* tbl_update_func)(st_data_t *, st_data_t *, st_data_t, int)
VALUE rb_exec_recursive_paired(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE, VALUE)
VALUE rb_hash_key_str(VALUE key)
int rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
VALUE rb_hash_select(VALUE hash)
const struct st_hash_type * orighash
int rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg)
#define SET_DEFAULT(hash, ifnone)
VALUE rb_ensure(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*e_proc)(VALUE), VALUE data2)
An equivalent to ensure clause.
#define COPY_DEFAULT(hash, hash2)
#define ECONV_INVALID_REPLACE
const char * rb_builtin_class_name(VALUE x)
int rb_enc_str_asciionly_p(VALUE)
#define RHASH_AR_TABLE_SIZE_SHIFT
#define RHASH_AR_TABLE_SIZE_MASK
#define NEWOBJ_OF(obj, type, klass, flags)
VALUE rb_hash_reject_bang(VALUE hash)
char * rb_w32_getenv(const char *)
#define rb_key_err_raise(mesg, recv, name)
int st_lookup(st_table *tab, st_data_t key, st_data_t *value)
#define ST_DATA_COMPATIBLE_P(type)
#define RB_FL_ANY_RAW(x, f)
#define RARRAY_PTR_USE_TRANSIENT(ary, ptr_name, expr)
#define RHASH_AR_TABLE_MAX_BOUND
VALUE rb_hash_freeze(VALUE hash)
void st_free_table(st_table *tab)
#define RHASH_AR_TABLE_P(hash)
VALUE rb_str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to)
#define RHASH_UPDATE(hash, key, func, arg)
VALUE rb_any_to_s(VALUE)
Default implementation of #to_s.
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
long rb_dbl_long_hash(double d)
void ruby_unsetenv(const char *name)
VALUE type(ANYARGS)
ANYARGS-ed function type.
#define RHASH_AR_TABLE_REF(hash, n)
#define RHASH_AR_CLEARED_HINT
#define get_env_ptr(var, val)
int rb_env_path_tainted(void)
void rb_syserr_fail_str(int e, VALUE mesg)
st_index_t(* hash)(st_data_t)
VALUE rb_block_proc(void)