Ruby
2.7.1p83(2020-03-31revisiona0c7c23c9cec0d0ffcba012279cd652d28ad5bf3)
|
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
245 uint128_t r = (uint128_t) m1 * (uint128_t) m2;
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)
751 ar_free_and_clear_table(hash);
757 ar_force_convert_table(
VALUE hash,
const char *file,
int line)
768 #if RHASH_CONVERT_TABLE_DEBUG
776 for (
i = 0;
i < bound;
i++) {
777 if (ar_cleared_entry(hash,
i))
continue;
782 ar_free_and_clear_table(hash);
793 hash_ar_table(
VALUE hash)
795 if (RHASH_TABLE_NULL_P(hash)) {
796 ar_alloc_table(hash);
802 ar_compact_table(
VALUE hash)
814 for (
i=0;
i<bound;
i++) {
815 if (ar_cleared_entry(hash,
i)) {
817 for (; j<bound; j++) {
818 if (!ar_cleared_entry(hash, j)) {
820 ar_hint_set_hint(hash,
i, (
st_hash_t)ar_hint(hash, j));
821 ar_clear_entry(hash, j);
834 RHASH_AR_TABLE_BOUND_SET(hash,
size);
850 bin = ar_compact_table(hash);
855 ar_set_entry(hash,
bin,
key, val, hash_value);
856 RHASH_AR_TABLE_BOUND_SET(hash,
bin+1);
868 for (
i = 0;
i < bound;
i++) {
869 if (ar_cleared_entry(hash,
i))
continue;
894 ar_clear_entry(hash,
i);
895 RHASH_AR_TABLE_SIZE_DEC(hash);
906 return ar_general_foreach(hash, func, replace,
arg);
917 const struct functor *
f = (
void *)d;
918 return f->func(k,
v,
f->arg);
925 return ar_general_foreach(hash, apply_functor,
NULL, (
st_data_t)&
f);
939 for (
i = 0;
i < bound;
i++) {
940 if (ar_cleared_entry(hash,
i))
continue;
944 hint = ar_hint(hash,
i);
946 retval = (*func)(
key, pair->
val,
arg, 0);
952 if (pair->
key == never)
break;
953 ret = ar_find_entry_hint(hash, hint,
key);
955 retval = (*func)(0, 0,
arg, 1);
965 if (!ar_cleared_entry(hash,
i)) {
966 ar_clear_entry(hash,
i);
967 RHASH_AR_TABLE_SIZE_DEC(hash);
981 int retval, existing;
992 bin = ar_find_entry(hash, hash_value,
key);
1006 retval = (*func)(&
key, &value,
arg, existing);
1012 if (ar_add_direct_with_hash(hash,
key, value, hash_value)) {
1018 if (old_key !=
key) {
1026 ar_clear_entry(hash,
bin);
1027 RHASH_AR_TABLE_SIZE_DEC(hash);
1045 hash_ar_table(hash);
1047 bin = ar_find_entry(hash, hash_value,
key);
1053 bin = ar_compact_table(hash);
1054 hash_ar_table(hash);
1058 ar_set_entry(hash,
bin,
key, value, hash_value);
1059 RHASH_AR_TABLE_BOUND_SET(hash,
bin+1);
1081 unsigned bin = ar_find_entry(hash, hash_value,
key);
1088 if (value !=
NULL) {
1107 bin = ar_find_entry(hash, hash_value, *
key);
1110 if (value != 0) *value = 0;
1118 ar_clear_entry(hash,
bin);
1119 RHASH_AR_TABLE_SIZE_DEC(hash);
1130 for (
i = 0;
i < bound;
i++) {
1131 if (!ar_cleared_entry(hash,
i)) {
1133 if (value != 0) *value = pair->
val;
1135 ar_clear_entry(hash,
i);
1136 RHASH_AR_TABLE_SIZE_DEC(hash);
1141 if (value !=
NULL) *value = 0;
1151 for (
i = 0;
i < bound;
i++) {
1152 if (
keys == keys_end) {
1156 if (!ar_cleared_entry(hash,
i)) {
1162 return keys - keys_start;
1169 st_data_t *values_start = values, *values_end = values +
size;
1171 for (
i = 0;
i < bound;
i++) {
1172 if (values == values_end) {
1176 if (!ar_cleared_entry(hash,
i)) {
1182 return values - values_start;
1190 if (old_tab !=
NULL) {
1192 if (new_tab ==
NULL) {
1194 if (new_tab !=
NULL) {
1202 *new_tab = *old_tab;
1203 RHASH(hash1)->ar_hint.word =
RHASH(hash2)->ar_hint.word;
1206 hash_ar_table_set(hash1, new_tab);
1222 hash_ar_table_set(hash1,
NULL);
1230 ar_clear(
VALUE hash)
1233 RHASH_AR_TABLE_SIZE_SET(hash, 0);
1234 RHASH_AR_TABLE_BOUND_SET(hash, 0);
1242 #if USE_TRANSIENT_HEAP
1262 if (new_tab ==
NULL)
goto promote;
1264 *new_tab = *old_tab;
1265 hash_ar_table_set(hash, new_tab);
1286 status = (*
arg->func)(
key, value,
arg->arg);
1370 iter_lev_in_ivar_set(
VALUE hash,
int lev)
1385 int lev = iter_lev_in_flags(
hash);
1388 return iter_lev_in_ivar(
hash);
1398 int lev = iter_lev_in_flags(
hash);
1400 lev = iter_lev_in_ivar(
hash);
1401 iter_lev_in_ivar_set(
hash, lev+1);
1407 iter_lev_in_ivar_set(
hash, lev);
1415 int lev = iter_lev_in_flags(
hash);
1417 lev = iter_lev_in_ivar(
hash);
1419 iter_lev_in_ivar_set(
hash, lev-1);
1428 hash_foreach_ensure_rollback(
VALUE hash)
1430 hash_iter_lev_inc(
hash);
1437 hash_iter_lev_dec(
hash);
1456 return ar_foreach_with_replace(
hash,
func, replace,
arg);
1469 ret = ar_foreach_check(
hash, hash_ar_foreach_iter,
1487 if (RHASH_TABLE_EMPTY_P(
hash))
1489 hash_iter_lev_inc(
hash);
1511 return hash_alloc_flags(
klass, 0,
Qnil);
1519 return hash_alloc(
klass);
1536 ar_alloc_table(ret);
1583 #if RHASH_CONVERT_TABLE_DEBUG
1586 return ar_force_convert_table(hash, file, line);
1591 return ar_force_convert_table(hash,
NULL, 0);
1603 rb_hash_modify(
VALUE hash)
1605 rb_hash_modify_check(hash);
1608 NORETURN(
static void no_new_key(
void));
1620 #define NOINSERT_UPDATE_CALLBACK(func) \
1622 func##_noinsert(st_data_t *key, st_data_t *val, st_data_t arg, int existing) \
1624 if (!existing) no_new_key(); \
1625 return func(key, val, (struct update_arg *)arg, existing); \
1629 func##_insert(st_data_t *key, st_data_t *val, st_data_t arg, int existing) \
1631 return func(key, val, (struct update_arg *)arg, existing); \
1651 ar_try_convert_table(hash);
1667 arg.arg = optional_arg;
1683 #define UPDATE_CALLBACK(iter_lev, func) ((iter_lev) > 0 ? func##_noinsert : func##_insert)
1685 #define RHASH_UPDATE_ITER(h, iter_lev, key, func, a) do { \
1686 tbl_update((h), (key), UPDATE_CALLBACK((iter_lev), func), (st_data_t)(a)); \
1689 #define RHASH_UPDATE(hash, key, func, arg) \
1690 RHASH_UPDATE_ITER(hash, RHASH_ITER_LEV(hash), key, func, arg)
1698 if (
n != 2 && (
n >= 0 ||
n < -3)) {
1699 if (
n < 0)
n = -
n-1;
1748 rb_hash_modify(
hash);
1789 tmp = rb_hash_s_try_convert(
Qnil,
argv[0]);
1829 if (
argc % 2 != 0) {
1844 #define to_hash rb_to_hash_type
1961 rb_hash_modify_check(hash);
1963 tmp = hash_alloc(0);
1964 ar_alloc_table(tmp);
1966 ar_free_and_clear_table(hash);
1968 ar_free_and_clear_table(tmp);
1972 tmp = hash_alloc(0);
2004 return ar_lookup(hash,
key, pval);
2014 return hash_stlike_lookup(hash,
key, pval);
2036 if (hash_stlike_lookup(hash,
key, &val)) {
2049 if (hash_stlike_lookup(hash,
key, &val)) {
2103 if (block_given &&
argc == 2) {
2104 rb_warn(
"block supersedes default value argument");
2107 if (hash_stlike_lookup(hash,
key, &val)) {
2114 else if (
argc == 1) {
2131 return rb_hash_fetch_m(1, &
key, hash);
2158 VALUE args[2], ifnone;
2192 rb_hash_set_default(
VALUE hash,
VALUE ifnone)
2194 rb_hash_modify_check(hash);
2215 rb_hash_default_proc(
VALUE hash)
2241 rb_hash_modify_check(hash);
2249 "wrong default_proc type %s (expected Proc)",
2301 return rb_hash_key(hash, value);
2308 return ar_delete(hash, pkey, pval);
2343 if (deleted_value !=
Qundef) {
2344 return deleted_value;
2374 rb_hash_modify_check(hash);
2419 rb_hash_shift(
VALUE hash)
2423 rb_hash_modify_check(hash);
2427 if (ar_shift(hash, &var.key, &var.val)) {
2491 rb_hash_modify_check(hash);
2492 if (!RHASH_TABLE_EMPTY_P(hash)) {
2513 rb_hash_modify(hash);
2515 if (!
n)
return Qnil;
2714 rb_hash_modify_check(hash);
2716 if (!
n)
return Qnil;
2739 rb_hash_modify_check(hash);
2740 if (!RHASH_TABLE_EMPTY_P(hash)) {
2766 rb_hash_modify_check(hash);
2785 arg->new_value =
arg->arg;
2790 arg->new_value =
arg->arg;
2813 return hash_aset(
key,
val,
arg, existing);
2851 rb_hash_modify(hash);
2853 if (RHASH_TABLE_NULL_P(hash)) {
2854 if (iter_lev > 0) no_new_key();
2855 ar_alloc_table(hash);
2882 rb_hash_modify_check(hash);
2883 if (hash == hash2)
return hash;
2896 ar_free_and_clear_table(hash);
2956 rb_hash_empty_p(
VALUE hash)
2988 rb_hash_each_value(
VALUE hash)
3021 rb_hash_each_key(
VALUE hash)
3068 rb_hash_each_pair(
VALUE hash)
3104 rb_hash_transform_keys(
VALUE hash)
3137 rb_hash_transform_keys_bang(
VALUE hash)
3140 rb_hash_modify_check(hash);
3141 if (!RHASH_TABLE_EMPTY_P(hash)) {
3143 VALUE pairs = rb_hash_flatten(0,
NULL, hash);
3187 rb_hash_transform_values(
VALUE hash)
3192 result = hash_dup(hash,
rb_cHash, 0);
3219 rb_hash_transform_values_bang(
VALUE hash)
3222 rb_hash_modify_check(hash);
3224 if (!RHASH_TABLE_EMPTY_P(hash)) {
3250 rb_hash_to_a(
VALUE hash)
3305 rb_hash_inspect(
VALUE hash)
3320 rb_hash_to_hash(
VALUE hash)
3351 rb_hash_to_h_block(
VALUE hash)
3371 rb_hash_to_h(
VALUE hash)
3374 return rb_hash_to_h_block(hash);
3456 if (
size == 0)
return values;
3503 if (hash_stlike_lookup(hash,
key,
NULL)) {
3559 if (!hash_stlike_lookup(data->
hash,
key, &val2)) {
3590 if (hash1 == hash2)
return Qtrue;
3596 if (
rb_eql(hash2, hash1)) {
3609 if (!RHASH_TABLE_EMPTY_P(hash1) && !RHASH_TABLE_EMPTY_P(hash2)) {
3655 return hash_equal(hash1, hash2,
FALSE);
3670 return hash_equal(hash1, hash2,
TRUE);
3681 *hval ^=
st_hash(hdata,
sizeof(hdata), 0);
3758 arg->old_value = *value;
3759 arg->new_value =
arg->arg;
3763 arg->new_value =
arg->arg;
3785 arg->old_value = *value;
3790 arg->new_value = newvalue;
3853 rb_hash_modify(
self);
3885 arg->new_value = newvalue;
3906 rb_hash_modify(hash1);
4019 ar_force_convert_table(
hash, __FILE__, __LINE__);
4022 orighash = table->
type;
4029 assochash.
compare = assoc_cmp;
4031 table->
type = &assochash;
4120 if (level == 0)
return rb_hash_to_a(
hash);
4128 rb_funcallv(ary, id_flatten_bang, 1, &ary_flatten_level);
4130 else if (level < 0) {
4155 if (!
NIL_P(value)) {
4199 rb_hash_modify_check(
hash);
4235 rb_hash_modify_check(
hash);
4236 ar_force_convert_table(
hash, __FILE__, __LINE__);
4239 tmp = hash_alloc(0);
4342 rb_warn(
"given block not used");
4385 if (!--
argc)
return self;
4428 return hash_le(
hash, other);
4449 return hash_le(
hash, other);
4470 return hash_le(other,
hash);
4491 return hash_le(other,
hash);
4550 hash_ar_table(
hash);
4556 ar_try_convert_table(
hash);
4574 for (
i = 0;
i <
argc; ) {
4577 ar_insert(
hash, k,
v);
4590 if (RHASH_TABLE_NULL_P(
hash)) {
4592 hash_ar_table(
hash);
4609 static char **origenviron;
4611 #define GET_ENVIRON(e) ((e) = rb_w32_get_environ())
4612 #define FREE_ENVIRON(e) rb_w32_free_environ(e)
4613 static char **my_environ;
4615 #define environ my_environ
4617 static char *(*w32_getenv)(
const char*);
4619 w32_getenv_unknown(
const char *
name)
4621 char *(*func)(
const char*);
4629 return (w32_getenv = func)(
name);
4631 static char *(*w32_getenv)(
const char*) = w32_getenv_unknown;
4632 #define getenv(n) w32_getenv(n)
4633 #elif defined(__APPLE__)
4635 #define environ (*_NSGetEnviron())
4636 #define GET_ENVIRON(e) (e)
4637 #define FREE_ENVIRON(e)
4640 #define GET_ENVIRON(e) (e)
4641 #define FREE_ENVIRON(e)
4643 #ifdef ENV_IGNORECASE
4644 #define ENVMATCH(s1, s2) (STRCASECMP((s1), (s2)) == 0)
4645 #define ENVNMATCH(s1, s2, n) (STRNCASECMP((s1), (s2), (n)) == 0)
4647 #define ENVMATCH(n1, n2) (strcmp((n1), (n2)) == 0)
4648 #define ENVNMATCH(s1, s2, n) (memcmp((s1), (s2), (n)) == 0)
4677 env_str_new(
const char *
ptr,
long len)
4683 env_str_new2(
const char *
ptr)
4689 static const char TZ_ENV[] =
"TZ";
4693 env_encoding_for(
const char *
name,
const char *
ptr)
4704 env_name_new(
const char *
name,
const char *
ptr)
4706 return env_enc_str_new_cstr(
ptr, env_encoding_for(
name,
ptr));
4712 volatile VALUE *pstr,
4740 #define get_env_ptr(var, val) \
4741 (var = get_env_cstr(&(val), #var))
4743 #define get_env_ptr(var, val) \
4744 (var = get_env_cstr(val, #var))
4747 static inline const char *
4756 #define env_name(s) env_name(&(s))
4763 const char *nam, *val;
4779 VALUE value = env_str_new2(val);
4816 val = env_delete(
name);
4837 const char *nam, *
env;
4842 return env_name_new(nam,
env);
4877 const char *nam, *
env;
4882 if (block_given &&
argc == 2) {
4883 rb_warn(
"block supersedes default value argument");
4894 return env_name_new(nam,
env);
4900 rb_warning(
"rb_env_path_tainted is deprecated and will be removed in Ruby 3.2.");
4904 #if defined(_WIN32) || (defined(HAVE_SETENV) && defined(HAVE_UNSETENV))
4907 in_origenv(
const char *
str)
4911 if (*
env ==
str)
return 1;
4917 envix(
const char *nam)
4923 for (
i = 0;
env[
i];
i++) {
4934 getenvsize(
const WCHAR* p)
4936 const WCHAR* porg = p;
4937 while (*p++) p += lstrlenW(p) + 1;
4938 return p - porg + 1;
4942 getenvblocksize(
void)
4952 check_envsize(
size_t n)
4958 WCHAR* p = GetEnvironmentStringsW();
4961 FreeEnvironmentStringsW(p);
4962 if (
n >= getenvblocksize()) {
4970 #if defined(_WIN32) || \
4971 (defined(__sun) && !(defined(HAVE_SETENV) && defined(HAVE_UNSETENV)))
4973 NORETURN(
static void invalid_envname(
const char *
name));
4976 invalid_envname(
const char *
name)
4982 check_envname(
const char *
name)
4985 invalid_envname(
name);
4995 # if defined(MINGW_HAS_SECURE_API) || RUBY_MSVCRT_VERSION >= 80
4996 # define HAVE__WPUTENV_S 1
5003 check_envname(
name);
5004 len = MultiByteToWideChar(CP_UTF8, 0,
name, -1,
NULL, 0);
5007 len2 = MultiByteToWideChar(CP_UTF8, 0, value, -1,
NULL, 0);
5008 if (check_envsize((
size_t)
len + len2)) {
5012 wvalue = wname +
len;
5013 MultiByteToWideChar(CP_UTF8, 0,
name, -1, wname,
len);
5014 MultiByteToWideChar(CP_UTF8, 0, value, -1, wvalue, len2);
5015 #ifndef HAVE__WPUTENV_S
5016 wname[
len-1] =
L'=';
5021 MultiByteToWideChar(CP_UTF8, 0,
name, -1, wname,
len);
5022 wvalue = wname +
len;
5024 #ifndef HAVE__WPUTENV_S
5025 wname[
len-1] =
L'=';
5028 #ifndef HAVE__WPUTENV_S
5029 failed = _wputenv(wname);
5031 failed = _wputenv_s(wname, wvalue);
5036 if (!value || !*value) {
5038 if (!SetEnvironmentVariable(
name, value) &&
5039 GetLastError() != ERROR_ENVVAR_NOT_FOUND)
goto fail;
5043 invalid_envname(
name);
5045 #elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)
5051 #ifdef VOID_UNSETENV
5063 size_t len, mem_size;
5064 char **env_ptr, *
str, *mem_ptr;
5066 check_envname(
name);
5070 mem_ptr =
malloc(mem_size);
5071 if (mem_ptr ==
NULL)
5078 while ((env_ptr[0] = env_ptr[1]) != 0) env_ptr++;
5099 for (max =
i;
environ[max]; max++) ;
5100 tmpenv =
ALLOC_N(
char*, max+2);
5101 for (j=0; j<max; j++)
5107 char **envp = origenviron;
5108 while (*envp && *envp !=
environ[
i]) envp++;
5183 return env_aset(nm, val);
5286 env_each_key(
VALUE ehash)
5335 return env_values();
5356 env_each_value(
VALUE ehash)
5362 values = env_values();
5388 env_each_pair(
VALUE ehash)
5443 env_reject_bang(
VALUE ehash)
5462 if (del == 0)
return Qnil;
5476 env_delete_if(
VALUE ehash)
5479 env_reject_bang(ehash);
5517 env_select(
VALUE ehash)
5552 env_select_bang(
VALUE ehash)
5571 if (del == 0)
return Qnil;
5585 env_keep_if(
VALUE ehash)
5588 env_select_bang(ehash);
5613 value = rb_f_getenv(
Qnil,
key);
5722 env_str_new2(s+1)));
5960 return env_key(dmy, value);
5994 return env_to_hash();
6037 env_freeze(
VALUE self)
6090 return rb_hash_invert(env_to_hash());
6147 if (!
NIL_P(oldval)) {
6172 env_update_block_i : env_update_i;
6294 #define rb_intern(str) rb_intern_const(str)
6298 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_foreach_check(st_table *tab, st_foreach_check_callback_func *func, st_data_t arg, st_data_t never ATTRIBUTE_UNUSED)
int st_delete(st_table *tab, st_data_t *key, st_data_t *value)
#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)