~ubuntu-branches/ubuntu/quantal/ruby1.9.1/quantal

« back to all changes in this revision

Viewing changes to hash.c

  • Committer: Bazaar Package Importer
  • Author(s): Lucas Nussbaum
  • Date: 2011-09-24 19:16:17 UTC
  • mfrom: (1.1.8 upstream) (13.1.7 experimental)
  • Revision ID: james.westby@ubuntu.com-20110924191617-o1qz4rcmqjot8zuy
Tags: 1.9.3~rc1-1
* New upstream release: 1.9.3 RC1.
  + Includes load.c fixes. Closes: #639959.
* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
  hash.c -
4
4
 
5
 
  $Author: yugui $
 
5
  $Author: nobu $
6
6
  created at: Mon Nov 22 18:51:18 JST 1993
7
7
 
8
8
  Copyright (C) 1993-2007 Yukihiro Matsumoto
14
14
#include "ruby/ruby.h"
15
15
#include "ruby/st.h"
16
16
#include "ruby/util.h"
 
17
#include "ruby/encoding.h"
17
18
#include <errno.h>
18
19
 
19
20
#ifdef __APPLE__
248
249
static void
249
250
rb_hash_modify_check(VALUE hash)
250
251
{
251
 
    if (OBJ_FROZEN(hash)) rb_error_frozen("hash");
 
252
    rb_check_frozen(hash);
252
253
    if (!OBJ_UNTRUSTED(hash) && rb_safe_level() >= 4)
253
254
        rb_raise(rb_eSecurityError, "Insecure: can't modify hash");
254
255
}
418
419
    return rb_convert_type(hash, T_HASH, "Hash", "to_hash");
419
420
}
420
421
 
 
422
VALUE
 
423
rb_check_hash_type(VALUE hash)
 
424
{
 
425
    return rb_check_convert_type(hash, T_HASH, "Hash", "to_hash");
 
426
}
 
427
 
421
428
/*
422
429
 *  call-seq:
423
430
 *     Hash.try_convert(obj) -> hash or nil
432
439
static VALUE
433
440
rb_hash_s_try_convert(VALUE dummy, VALUE hash)
434
441
{
435
 
    return rb_check_convert_type(hash, T_HASH, "Hash", "to_hash");
 
442
    return rb_check_hash_type(hash);
436
443
}
437
444
 
438
445
static int
500
507
VALUE
501
508
rb_hash_aref(VALUE hash, VALUE key)
502
509
{
503
 
    VALUE val;
 
510
    st_data_t val;
504
511
 
505
512
    if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
506
 
        return rb_funcall(hash, id_default, 1, key);
 
513
        if (!FL_TEST(hash, HASH_PROC_DEFAULT) &&
 
514
            rb_method_basic_definition_p(CLASS_OF(hash), id_default)) {
 
515
            return RHASH_IFNONE(hash);
 
516
        }
 
517
        else {
 
518
            return rb_funcall(hash, id_default, 1, key);
 
519
        }
507
520
    }
508
 
    return val;
 
521
    return (VALUE)val;
509
522
}
510
523
 
511
524
VALUE
512
525
rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
513
526
{
514
 
    VALUE val;
 
527
    st_data_t val;
515
528
 
516
529
    if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
517
530
        return def; /* without Hash#default */
518
531
    }
519
 
    return val;
 
532
    return (VALUE)val;
520
533
}
521
534
 
522
535
VALUE
558
571
rb_hash_fetch_m(int argc, VALUE *argv, VALUE hash)
559
572
{
560
573
    VALUE key, if_none;
561
 
    VALUE val;
 
574
    st_data_t val;
562
575
    long block_given;
563
576
 
564
577
    rb_scan_args(argc, argv, "11", &key, &if_none);
571
584
        if (block_given) return rb_yield(key);
572
585
        if (argc == 1) {
573
586
            volatile VALUE desc = rb_protect(rb_inspect, key, 0);
574
 
            if (NIL_P(desc) || RSTRING_LEN(desc) > 65) {
 
587
            if (NIL_P(desc)) {
575
588
                desc = rb_any_to_s(key);
576
589
            }
 
590
            desc = rb_str_ellipsize(desc, 65);
577
591
            rb_raise(rb_eKeyError, "key not found: %s", RSTRING_PTR(desc));
578
592
        }
579
593
        return if_none;
580
594
    }
581
 
    return val;
 
595
    return (VALUE)val;
582
596
}
583
597
 
584
598
VALUE
675
689
    return Qnil;
676
690
}
677
691
 
678
 
VALUE rb_obj_is_proc(VALUE proc);
679
 
 
680
692
/*
681
693
 *  call-seq:
682
694
 *     hsh.default_proc = proc_obj     -> proc_obj
725
737
 *  call-seq:
726
738
 *     hsh.key(value)    -> key
727
739
 *
728
 
 *  Returns the key for a given value. If not found, returns <code>nil</code>.
 
740
 *  Returns the key of an occurrence of a given value. If the value is
 
741
 *  not found, returns <code>nil</code>.
729
742
 *
730
 
 *     h = { "a" => 100, "b" => 200 }
 
743
 *     h = { "a" => 100, "b" => 200, "c" => 300, "d" => 300 }
731
744
 *     h.key(200)   #=> "b"
 
745
 *     h.key(300)   #=> "c"
732
746
 *     h.key(999)   #=> nil
733
747
 *
734
748
 */
930
944
/*
931
945
 *  call-seq:
932
946
 *     hsh.reject {| key, value | block }  -> a_hash
 
947
 *     hsh.reject                          -> an_enumerator
933
948
 *
934
949
 *  Same as <code>Hash#delete_if</code>, but works on (and returns) a
935
950
 *  copy of the <i>hsh</i>. Equivalent to
1088
1103
    return hash;
1089
1104
}
1090
1105
 
 
1106
static st_data_t
 
1107
copy_str_key(st_data_t str)
 
1108
{
 
1109
    return (st_data_t)rb_str_new4((VALUE)str);
 
1110
}
 
1111
 
1091
1112
/*
1092
1113
 *  call-seq:
1093
1114
 *     hsh[key] = value        -> value
1115
1136
        st_insert(RHASH(hash)->ntbl, key, val);
1116
1137
    }
1117
1138
    else {
1118
 
        st_insert2(RHASH(hash)->ntbl, key, val, rb_str_new4);
 
1139
        st_insert2(RHASH(hash)->ntbl, key, val, copy_str_key);
1119
1140
    }
1120
1141
    return val;
1121
1142
}
1347
1368
    VALUE str2;
1348
1369
 
1349
1370
    if (key == Qundef) return ST_CONTINUE;
 
1371
    str2 = rb_inspect(key);
1350
1372
    if (RSTRING_LEN(str) > 1) {
1351
1373
        rb_str_cat2(str, ", ");
1352
1374
    }
1353
 
    str2 = rb_inspect(key);
 
1375
    else {
 
1376
        rb_enc_copy(str, str2);
 
1377
    }
1354
1378
    rb_str_buf_append(str, str2);
1355
1379
    OBJ_INFECT(str, str2);
1356
1380
    rb_str_buf_cat2(str, "=>");
1542
1566
eql_i(VALUE key, VALUE val1, VALUE arg)
1543
1567
{
1544
1568
    struct equal_data *data = (struct equal_data *)arg;
1545
 
    VALUE val2;
 
1569
    st_data_t val2;
1546
1570
 
1547
1571
    if (key == Qundef) return ST_CONTINUE;
1548
1572
    if (!st_lookup(data->tbl, key, &val2)) {
1549
1573
        data->result = Qfalse;
1550
1574
        return ST_STOP;
1551
1575
    }
1552
 
    if (!(data->eql ? rb_eql(val1, val2) : (int)rb_equal(val1, val2))) {
 
1576
    if (!(data->eql ? rb_eql(val1, (VALUE)val2) : (int)rb_equal(val1, (VALUE)val2))) {
1553
1577
        data->result = Qfalse;
1554
1578
        return ST_STOP;
1555
1579
    }
1644
1668
hash_i(VALUE key, VALUE val, VALUE arg)
1645
1669
{
1646
1670
    st_index_t *hval = (st_index_t *)arg;
 
1671
    st_index_t hdata[2];
1647
1672
 
1648
1673
    if (key == Qundef) return ST_CONTINUE;
1649
 
    *hval ^= rb_hash_end(rb_hash_uint(rb_hash_start(rb_hash(key)), rb_hash(val)));
 
1674
    hdata[0] = rb_hash(key);
 
1675
    hdata[1] = rb_hash(val);
 
1676
    *hval ^= st_hash(hdata, sizeof(hdata), 0);
1650
1677
    return ST_CONTINUE;
1651
1678
}
1652
1679
 
1658
1685
    if (!RHASH(hash)->ntbl)
1659
1686
        return LONG2FIX(0);
1660
1687
    hval = RHASH(hash)->ntbl->num_entries;
 
1688
    if (!hval) return LONG2FIX(0);
1661
1689
    if (recur)
1662
 
        hval = rb_hash_end(rb_hash_uint(rb_hash_start(rb_hash(rb_cHash)), hval));
 
1690
        hval = rb_hash_uint(rb_hash_start(rb_hash(rb_cHash)), hval);
1663
1691
    else
1664
1692
        rb_hash_foreach(hash, hash_i, (VALUE)&hval);
 
1693
    hval = rb_hash_end(hval);
1665
1694
    return INT2FIX(hval);
1666
1695
}
1667
1696
 
1766
1795
    return hash1;
1767
1796
}
1768
1797
 
 
1798
struct update_arg {
 
1799
    VALUE hash;
 
1800
    rb_hash_update_func *func;
 
1801
};
 
1802
 
 
1803
static int
 
1804
rb_hash_update_func_i(VALUE key, VALUE value, VALUE arg0)
 
1805
{
 
1806
    struct update_arg *arg = (struct update_arg *)arg0;
 
1807
    VALUE hash = arg->hash;
 
1808
 
 
1809
    if (key == Qundef) return ST_CONTINUE;
 
1810
    if (rb_hash_has_key(hash, key)) {
 
1811
        value = (*arg->func)(key, rb_hash_aref(hash, key), value);
 
1812
    }
 
1813
    hash_update(hash, key);
 
1814
    st_insert(RHASH(hash)->ntbl, key, value);
 
1815
    return ST_CONTINUE;
 
1816
}
 
1817
 
 
1818
VALUE
 
1819
rb_hash_update_by(VALUE hash1, VALUE hash2, rb_hash_update_func *func)
 
1820
{
 
1821
    rb_hash_modify(hash1);
 
1822
    hash2 = to_hash(hash2);
 
1823
    if (func) {
 
1824
        struct update_arg arg;
 
1825
        arg.hash = hash1;
 
1826
        arg.func = func;
 
1827
        rb_hash_foreach(hash2, rb_hash_update_func_i, (VALUE)&arg);
 
1828
    }
 
1829
    else {
 
1830
        rb_hash_foreach(hash2, rb_hash_update_i, hash1);
 
1831
    }
 
1832
    return hash1;
 
1833
}
 
1834
 
1769
1835
/*
1770
1836
 *  call-seq:
1771
1837
 *     hsh.merge(other_hash)                              -> new_hash
1845
1911
 
1846
1912
/*
1847
1913
 *  call-seq:
1848
 
 *     hash.rassoc(key) -> an_array or nil
 
1914
 *     hash.rassoc(obj) -> an_array or nil
1849
1915
 *
1850
1916
 *  Searches through the hash comparing _obj_ with the value using <code>==</code>.
1851
1917
 *  Returns the first key-value pair (two-element array) that matches. See
1947
2013
 
1948
2014
static char **origenviron;
1949
2015
#ifdef _WIN32
1950
 
#define GET_ENVIRON(e) (e = rb_w32_get_environ())
 
2016
#define GET_ENVIRON(e) ((e) = rb_w32_get_environ())
1951
2017
#define FREE_ENVIRON(e) rb_w32_free_environ(e)
1952
2018
static char **my_environ;
1953
2019
#undef environ
1963
2029
#define FREE_ENVIRON(e)
1964
2030
#endif
1965
2031
#ifdef ENV_IGNORECASE
1966
 
#define ENVMATCH(s1, s2) (STRCASECMP(s1, s2) == 0)
1967
 
#define ENVNMATCH(s1, s2, n) (STRNCASECMP(s1, s2, n) == 0)
 
2032
#define ENVMATCH(s1, s2) (STRCASECMP((s1), (s2)) == 0)
 
2033
#define ENVNMATCH(s1, s2, n) (STRNCASECMP((s1), (s2), (n)) == 0)
1968
2034
#else
1969
 
#define ENVMATCH(n1, n2) (strcmp(n1, n2) == 0)
1970
 
#define ENVNMATCH(s1, s2, n) (memcmp(s1, s2, n) == 0)
 
2035
#define ENVMATCH(n1, n2) (strcmp((n1), (n2)) == 0)
 
2036
#define ENVNMATCH(s1, s2, n) (memcmp((s1), (s2), (n)) == 0)
1971
2037
#endif
1972
2038
 
1973
2039
static VALUE
2010
2076
    return Qnil;
2011
2077
}
2012
2078
 
 
2079
/*
 
2080
 * call-seq:
 
2081
 *   ENV.delete(name)            -> value
 
2082
 *   ENV.delete(name) { |name| } -> value
 
2083
 *
 
2084
 * Deletes the environment variable with +name+ and returns the value of the
 
2085
 * variable.  If a block is given it will be called when the named environment
 
2086
 * does not exist.
 
2087
 */
2013
2088
static VALUE
2014
2089
env_delete_m(VALUE obj, VALUE name)
2015
2090
{
2022
2097
 
2023
2098
static int env_path_tainted(const char *);
2024
2099
 
 
2100
/*
 
2101
 * call-seq:
 
2102
 *   ENV[name] -> value
 
2103
 *
 
2104
 * Retrieves the +value+ for environment variable +name+ as a String.  Returns
 
2105
 * +nil+ if the named variable does not exist.
 
2106
 */
2025
2107
static VALUE
2026
2108
rb_f_getenv(VALUE obj, VALUE name)
2027
2109
{
2046
2128
    return Qnil;
2047
2129
}
2048
2130
 
 
2131
/*
 
2132
 * :yield: missing_name
 
2133
 * call-seq:
 
2134
 *   ENV.fetch(name)                        -> value
 
2135
 *   ENV.fetch(name, default)               -> value
 
2136
 *   ENV.fetch(name) { |missing_name| ... } -> value
 
2137
 *
 
2138
 * Retrieves the environment variable +name+.
 
2139
 *
 
2140
 * If the given name does not exist and neither +default+ nor a block a
 
2141
 * provided an IndexError is raised.  If a block is given it is called with
 
2142
 * the missing name to provide a value.  If a default value is given it will
 
2143
 * be returned when no block is given.
 
2144
 */
2049
2145
static VALUE
2050
2146
env_fetch(int argc, VALUE *argv)
2051
2147
{
2129
2225
}
2130
2226
#endif
2131
2227
 
 
2228
#if defined(_WIN32)
 
2229
static size_t
 
2230
getenvsize(const char* p)
 
2231
{
 
2232
    const char* porg = p;
 
2233
    while (*p++) p += strlen(p) + 1;
 
2234
    return p - porg + 1;
 
2235
}
 
2236
static size_t
 
2237
getenvblocksize()
 
2238
{
 
2239
    return (rb_w32_osver() >= 5) ? 32767 : 5120;
 
2240
}
 
2241
#endif
 
2242
 
2132
2243
void
2133
2244
ruby_setenv(const char *name, const char *value)
2134
2245
{
2135
2246
#if defined(_WIN32)
2136
 
    int len;
2137
 
    char *buf;
 
2247
    VALUE buf;
2138
2248
    int failed = 0;
2139
2249
    if (strchr(name, '=')) {
 
2250
      fail:
2140
2251
        errno = EINVAL;
2141
2252
        rb_sys_fail("ruby_setenv");
2142
2253
    }
2143
2254
    if (value) {
2144
 
        len = strlen(name) + 1 + strlen(value) + 1;
2145
 
        buf = ALLOCA_N(char, len);
2146
 
        snprintf(buf, len, "%s=%s", name, value);
2147
 
        failed = putenv(buf);
2148
 
 
 
2255
        const char* p = GetEnvironmentStringsA();
 
2256
        if (!p) goto fail; /* never happen */
 
2257
        if (strlen(name) + 2 + strlen(value) + getenvsize(p) >= getenvblocksize()) {
 
2258
            goto fail;  /* 2 for '=' & '\0' */
 
2259
        }
 
2260
        buf = rb_sprintf("%s=%s", name, value);
 
2261
    }
 
2262
    else {
 
2263
        buf = rb_sprintf("%s=", name);
 
2264
    }
 
2265
    failed = putenv(RSTRING_PTR(buf));
 
2266
    /* even if putenv() failed, clean up and try to delete the
 
2267
     * variable from the system area. */
 
2268
    rb_str_resize(buf, 0);
 
2269
    if (!value || !*value) {
2149
2270
        /* putenv() doesn't handle empty value */
2150
 
        if (!*value)
2151
 
            failed = !SetEnvironmentVariable(name,value);
2152
 
    }
2153
 
    else {
2154
 
        len = strlen(name) + 1 + 1;
2155
 
        buf = ALLOCA_N(char, len);
2156
 
        snprintf(buf, len, "%s=", name);
2157
 
        putenv(buf);
2158
 
        failed = !SetEnvironmentVariable(name, 0);
2159
 
    }
2160
 
    if (failed) {
2161
 
        rb_warn("failed to set environment variable. Ruby 1.9.3 will raise SystemCallError in this case.");
2162
 
    }
 
2271
        if (!SetEnvironmentVariable(name, value) &&
 
2272
            GetLastError() != ERROR_ENVVAR_NOT_FOUND) goto fail;
 
2273
    }
 
2274
    if (failed) goto fail;
2163
2275
#elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)
2164
2276
#undef setenv
2165
2277
#undef unsetenv
2246
2358
    ruby_setenv(name, 0);
2247
2359
}
2248
2360
 
 
2361
/*
 
2362
 * call-seq:
 
2363
 *   ENV[name] = value
 
2364
 *   ENV.store(name, value) -> value
 
2365
 *
 
2366
 * Sets the environment variable +name+ to +value+.  If the value given is
 
2367
 * +nil+ the environment variable is deleted.
 
2368
 *
 
2369
 */
2249
2370
static VALUE
2250
2371
env_aset(VALUE obj, VALUE nm, VALUE val)
2251
2372
{
2282
2403
    return val;
2283
2404
}
2284
2405
 
 
2406
/*
 
2407
 * call-seq:
 
2408
 *   ENV.keys -> Array
 
2409
 *
 
2410
 * Returns every environment variable name in an Array
 
2411
 */
2285
2412
static VALUE
2286
2413
env_keys(void)
2287
2414
{
2302
2429
    return ary;
2303
2430
}
2304
2431
 
 
2432
/*
 
2433
 * call-seq:
 
2434
 *   ENV.each_key { |name| } -> Hash
 
2435
 *   ENV.each_key            -> Enumerator
 
2436
 *
 
2437
 * Yields each environment variable name.
 
2438
 *
 
2439
 * An Enumerator is returned if no block is given.
 
2440
 */
2305
2441
static VALUE
2306
2442
env_each_key(VALUE ehash)
2307
2443
{
2316
2452
    return ehash;
2317
2453
}
2318
2454
 
 
2455
/*
 
2456
 * call-seq:
 
2457
 *   ENV.values -> Array
 
2458
 *
 
2459
 * Returns every environment variable value as an Array
 
2460
 */
2319
2461
static VALUE
2320
2462
env_values(void)
2321
2463
{
2336
2478
    return ary;
2337
2479
}
2338
2480
 
 
2481
/*
 
2482
 * call-seq:
 
2483
 *   ENV.each_value { |value| } -> Hash
 
2484
 *   ENV.each_value             -> Enumerator
 
2485
 *
 
2486
 * Yields each environment variable +value+.
 
2487
 *
 
2488
 * An Enumerator is returned if no block was given.
 
2489
 */
2339
2490
static VALUE
2340
2491
env_each_value(VALUE ehash)
2341
2492
{
2350
2501
    return ehash;
2351
2502
}
2352
2503
 
 
2504
/*
 
2505
 * call-seq:
 
2506
 *   ENV.each      { |name, value| } -> Hash
 
2507
 *   ENV.each                        -> Enumerator
 
2508
 *   ENV.each_pair { |name, value| } -> Hash
 
2509
 *   ENV.each_pair                   -> Enumerator
 
2510
 *
 
2511
 * Yields each environment variable +name+ and +value+.
 
2512
 *
 
2513
 * If no block is given an Enumerator is returned.
 
2514
 */
2353
2515
static VALUE
2354
2516
env_each_pair(VALUE ehash)
2355
2517
{
2378
2540
    return ehash;
2379
2541
}
2380
2542
 
 
2543
/*
 
2544
 * call-seq:
 
2545
 *   ENV.reject! { |name, value| } -> Hash or nil
 
2546
 *   ENV.reject!                   -> Enumerator
 
2547
 *
 
2548
 * Equivalent to ENV#delete_if but returns +nil+ if no changes were made.
 
2549
 *
 
2550
 * Returns an Enumerator if no block was given.
 
2551
 */
2381
2552
static VALUE
2382
2553
env_reject_bang(VALUE ehash)
2383
2554
{
2401
2572
    return envtbl;
2402
2573
}
2403
2574
 
 
2575
/*
 
2576
 * call-seq:
 
2577
 *   ENV.delete_if { |name, value| } -> Hash
 
2578
 *   ENV.delete_if                   -> Enumerator
 
2579
 *
 
2580
 * Deletes every environment variable for which the block evaluates to +true+.
 
2581
 *
 
2582
 * If no block is given an enumerator is returned instead.
 
2583
 */
2404
2584
static VALUE
2405
2585
env_delete_if(VALUE ehash)
2406
2586
{
2409
2589
    return envtbl;
2410
2590
}
2411
2591
 
 
2592
/*
 
2593
 * call-seq:
 
2594
 *   ENV.values_at(name, ...) -> Array
 
2595
 *
 
2596
 * Returns an array containing the environment variable values associated with
 
2597
 * the given names.  See also ENV.select.
 
2598
 */
2412
2599
static VALUE
2413
2600
env_values_at(int argc, VALUE *argv)
2414
2601
{
2423
2610
    return result;
2424
2611
}
2425
2612
 
 
2613
/*
 
2614
 * call-seq:
 
2615
 *   ENV.select { |name, value| } -> Hash
 
2616
 *   ENV.select                   -> Enumerator
 
2617
 *
 
2618
 * Returns a copy of the environment for entries where the block returns true.
 
2619
 *
 
2620
 * Returns an Enumerator if no block was given.
 
2621
 */
2426
2622
static VALUE
2427
2623
env_select(VALUE ehash)
2428
2624
{
2449
2645
    return result;
2450
2646
}
2451
2647
 
 
2648
/*
 
2649
 * call-seq:
 
2650
 *   ENV.select! { |name, value| } -> ENV or nil
 
2651
 *   ENV.select!                   -> Enumerator
 
2652
 *
 
2653
 * Equivalent to ENV#keep_if but returns +nil+ if no changes were made.
 
2654
 */
2452
2655
static VALUE
2453
2656
env_select_bang(VALUE ehash)
2454
2657
{
2472
2675
    return envtbl;
2473
2676
}
2474
2677
 
 
2678
/*
 
2679
 * call-seq:
 
2680
 *   ENV.keep_if { |name, value| } -> Hash
 
2681
 *   ENV.keep_if                   -> Enumerator
 
2682
 *
 
2683
 * Deletes every environment variable where the block evaluates to +false+.
 
2684
 *
 
2685
 * Returns an enumerator if no block was given.
 
2686
 */
2475
2687
static VALUE
2476
2688
env_keep_if(VALUE ehash)
2477
2689
{
2480
2692
    return envtbl;
2481
2693
}
2482
2694
 
 
2695
/*
 
2696
 * call-seq:
 
2697
 *   ENV.clear
 
2698
 *
 
2699
 * Removes every environment variable.
 
2700
 */
2483
2701
VALUE
2484
2702
rb_env_clear(void)
2485
2703
{
2496
2714
    return envtbl;
2497
2715
}
2498
2716
 
 
2717
/*
 
2718
 * call-seq:
 
2719
 *   ENV.to_s -> "ENV"
 
2720
 *
 
2721
 * Returns "ENV"
 
2722
 */
2499
2723
static VALUE
2500
2724
env_to_s(void)
2501
2725
{
2502
2726
    return rb_usascii_str_new2("ENV");
2503
2727
}
2504
2728
 
 
2729
/*
 
2730
 * call-seq:
 
2731
 *   ENV.inspect -> string
 
2732
 *
 
2733
 * Returns the contents of the environment as a String.
 
2734
 */
2505
2735
static VALUE
2506
2736
env_inspect(void)
2507
2737
{
2533
2763
    return str;
2534
2764
}
2535
2765
 
 
2766
/*
 
2767
 * call-seq:
 
2768
 *   ENV.to_a -> Array
 
2769
 *
 
2770
 * Converts the environment variables into an array of names and value arrays.
 
2771
 *
 
2772
 *   ENV.to_a # => [["TERM" => "xterm-color"], ["SHELL" => "/bin/bash"], ...]
 
2773
 *
 
2774
 */
2536
2775
static VALUE
2537
2776
env_to_a(void)
2538
2777
{
2554
2793
    return ary;
2555
2794
}
2556
2795
 
 
2796
/*
 
2797
 * call-seq:
 
2798
 *   ENV.rehash
 
2799
 *
 
2800
 * Re-hashing the environment variables does nothing.  It is provided for
 
2801
 * compatibility with Hash.
 
2802
 */
2557
2803
static VALUE
2558
2804
env_none(void)
2559
2805
{
2560
2806
    return Qnil;
2561
2807
}
2562
2808
 
 
2809
/*
 
2810
 * call-seq:
 
2811
 *   ENV.length
 
2812
 *   ENV.size
 
2813
 *
 
2814
 * Returns the number of environment variables.
 
2815
 */
2563
2816
static VALUE
2564
2817
env_size(void)
2565
2818
{
2574
2827
    return INT2FIX(i);
2575
2828
}
2576
2829
 
 
2830
/*
 
2831
 * call-seq:
 
2832
 *   ENV.empty? -> true or false
 
2833
 *
 
2834
 * Returns true when there are no environment variables
 
2835
 */
2577
2836
static VALUE
2578
2837
env_empty_p(void)
2579
2838
{
2589
2848
    return Qfalse;
2590
2849
}
2591
2850
 
 
2851
/*
 
2852
 * call-seq:
 
2853
 *   ENV.key?(name)     -> true or false
 
2854
 *   ENV.include?(name) -> true or false
 
2855
 *   ENV.has_key?(name) -> true or false
 
2856
 *   ENV.member?(name)  -> true or false
 
2857
 *
 
2858
 * Returns +true+ if there is an environment variable with the given +name+.
 
2859
 */
2592
2860
static VALUE
2593
2861
env_has_key(VALUE env, VALUE key)
2594
2862
{
2602
2870
    return Qfalse;
2603
2871
}
2604
2872
 
 
2873
/*
 
2874
 * call-seq:
 
2875
 *   ENV.assoc(name) -> Array or nil
 
2876
 *
 
2877
 * Returns an Array of the name and value of the environment variable with
 
2878
 * +name+ or +nil+ if the name cannot be found.
 
2879
 */
2605
2880
static VALUE
2606
2881
env_assoc(VALUE env, VALUE key)
2607
2882
{
2616
2891
    return Qnil;
2617
2892
}
2618
2893
 
 
2894
/*
 
2895
 * call-seq:
 
2896
 *   ENV.value?(value) -> true or false
 
2897
 *   ENV.has_value?(value) -> true or false
 
2898
 *
 
2899
 * Returns +true+ if there is an environment variable with the given +value+.
 
2900
 */
2619
2901
static VALUE
2620
2902
env_has_value(VALUE dmy, VALUE obj)
2621
2903
{
2640
2922
    return Qfalse;
2641
2923
}
2642
2924
 
 
2925
/*
 
2926
 * call-seq:
 
2927
 *   ENV.rassoc(value)
 
2928
 *
 
2929
 * Returns an Array of the name and value of the environment variable with
 
2930
 * +value+ or +nil+ if the value cannot be found.
 
2931
 */
2643
2932
static VALUE
2644
2933
env_rassoc(VALUE dmy, VALUE obj)
2645
2934
{
2665
2954
    return Qnil;
2666
2955
}
2667
2956
 
 
2957
/*
 
2958
 * call-seq:
 
2959
 *   ENV.key(value) -> name
 
2960
 *
 
2961
 * Returns the name of the environment variable with +value+.  If the value is
 
2962
 * not found +nil+ is returned.
 
2963
 */
2668
2964
static VALUE
2669
2965
env_key(VALUE dmy, VALUE value)
2670
2966
{
2690
2986
    return Qnil;
2691
2987
}
2692
2988
 
 
2989
/*
 
2990
 * call-seq:
 
2991
 *   ENV.index(value) -> key
 
2992
 *
 
2993
 * Deprecated method that is equivalent to ENV.key
 
2994
 */
2693
2995
static VALUE
2694
2996
env_index(VALUE dmy, VALUE value)
2695
2997
{
2697
2999
    return env_key(dmy, value);
2698
3000
}
2699
3001
 
 
3002
/*
 
3003
 * call-seq:
 
3004
 *   ENV.to_hash -> Hash
 
3005
 *
 
3006
 * Creates a hash with a copy of the environment variables.
 
3007
 *
 
3008
 */
2700
3009
static VALUE
2701
3010
env_to_hash(void)
2702
3011
{
2718
3027
    return hash;
2719
3028
}
2720
3029
 
 
3030
/*
 
3031
 * call-seq:
 
3032
 *   ENV.reject { |name, value| } -> Hash
 
3033
 *   ENV.reject                   -> Enumerator
 
3034
 *
 
3035
 * Same as ENV#delete_if, but works on (and returns) a copy of the
 
3036
 * environment.
 
3037
 */
2721
3038
static VALUE
2722
3039
env_reject(void)
2723
3040
{
2724
3041
    return rb_hash_delete_if(env_to_hash());
2725
3042
}
2726
3043
 
 
3044
/*
 
3045
 * call-seq:
 
3046
 *   ENV.shift -> Array or nil
 
3047
 *
 
3048
 * Removes an environment variable name-value pair from ENV and returns it as
 
3049
 * an Array.  Returns +nil+ if when the environment is empty.
 
3050
 */
2727
3051
static VALUE
2728
3052
env_shift(void)
2729
3053
{
2744
3068
    return Qnil;
2745
3069
}
2746
3070
 
 
3071
/*
 
3072
 * call-seq:
 
3073
 *   ENV.invert -> Hash
 
3074
 *
 
3075
 * Returns a new hash created by using environment variable names as values
 
3076
 * and values as names.
 
3077
 */
2747
3078
static VALUE
2748
3079
env_invert(void)
2749
3080
{
2762
3093
    return ST_CONTINUE;
2763
3094
}
2764
3095
 
 
3096
/*
 
3097
 * call-seq:
 
3098
 *   ENV.replace(hash) -> env
 
3099
 *
 
3100
 * Replaces the contents of the environment variables with the contents of
 
3101
 * +hash+.
 
3102
 */
2765
3103
static VALUE
2766
3104
env_replace(VALUE env, VALUE hash)
2767
3105
{
2791
3129
    return ST_CONTINUE;
2792
3130
}
2793
3131
 
 
3132
/*
 
3133
 * call-seq:
 
3134
 *   ENV.update(hash)                                  -> Hash
 
3135
 *   ENV.update(hash) { |name, old_value, new_value| } -> Hash
 
3136
 *
 
3137
 * Adds the contents of +hash+ to the environment variables.  If no block is
 
3138
 * specified entries with duplicate keys are overwritten, otherwise the value
 
3139
 * of each duplicate name is determined by calling the block with the key, its
 
3140
 * value from the environment and its value from the hash.
 
3141
 */
2794
3142
static VALUE
2795
3143
env_update(VALUE env, VALUE hash)
2796
3144
{
2893
3241
    rb_define_method(rb_cHash,"compare_by_identity", rb_hash_compare_by_id, 0);
2894
3242
    rb_define_method(rb_cHash,"compare_by_identity?", rb_hash_compare_by_id_p, 0);
2895
3243
 
 
3244
    /* Document-class: ENV
 
3245
     *
 
3246
     * ENV is a hash-like accessor for environment variables.
 
3247
     */
 
3248
 
 
3249
    /*
 
3250
     * Hack to get RDoc to regard ENV as a class:
 
3251
     * envtbl = rb_define_class("ENV", rb_cObject);
 
3252
     */
2896
3253
    origenviron = environ;
2897
3254
    envtbl = rb_obj_alloc(rb_cObject);
2898
3255
    rb_extend_object(envtbl, rb_mEnumerable);
2939
3296
    rb_define_singleton_method(envtbl,"assoc", env_assoc, 1);
2940
3297
    rb_define_singleton_method(envtbl,"rassoc", env_rassoc, 1);
2941
3298
 
 
3299
    /*
 
3300
     * ENV is a Hash-like accessor for environment variables.
 
3301
     *
 
3302
     * See ENV (the class) for more details.
 
3303
     */
2942
3304
    rb_define_global_const("ENV", envtbl);
2943
3305
}