Revision: 3430 http://trac.macosforge.org/projects/ruby/changeset/3430 Author: lsansonetti@apple.com Date: 2010-02-03 21:29:57 -0800 (Wed, 03 Feb 2010) Log Message: ----------- moved the ENV stuff into a separate file Modified Paths: -------------- MacRuby/trunk/hash.c MacRuby/trunk/rakelib/builder/builder.rb Added Paths: ----------- MacRuby/trunk/env.c Added: MacRuby/trunk/env.c =================================================================== --- MacRuby/trunk/env.c (rev 0) +++ MacRuby/trunk/env.c 2010-02-04 05:29:57 UTC (rev 3430) @@ -0,0 +1,741 @@ +/* + * MacRuby implementation of ENV. + * + * This file is covered by the Ruby license. See COPYING for more details. + * + * Copyright (C) 2007-2010, Apple Inc. All rights reserved. + * Copyright (C) 1993-2007 Yukihiro Matsumoto + * Copyright (C) 2000 Network Applied Communication Laboratory, Inc. + * Copyright (C) 2000 Information-technology Promotion Agency, Japan + */ + +#include "ruby/ruby.h" +#include "ruby/st.h" +#include "ruby/util.h" +#include "ruby/node.h" +#include "vm.h" + +#include <crt_externs.h> + +static VALUE envtbl; + +static int path_tainted = -1; + +static char **origenviron; +#define GET_ENVIRON() (*_NSGetEnviron()) + +static VALUE +to_hash(VALUE hash) +{ + return rb_convert_type(hash, T_HASH, "Hash", "to_hash"); +} + +static VALUE +env_str_new(const char *ptr, long len) +{ + VALUE str = rb_tainted_str_new(ptr, len); + rb_obj_freeze(str); + return str; +} + +static VALUE +env_str_new2(const char *ptr) +{ + if (ptr == NULL) { + return Qnil; + } + return env_str_new(ptr, strlen(ptr)); +} + +static VALUE +env_delete(VALUE obj, VALUE name) +{ + rb_secure(4); + SafeStringValue(name); + const char *nam = RSTRING_PTR(name); + if (strlen(nam) != RSTRING_LEN(name)) { + rb_raise(rb_eArgError, "bad environment variable name"); + } + const char *val = getenv(nam); + if (val != NULL) { + VALUE value = env_str_new2(val); + ruby_setenv(nam, 0); + if (strcmp(nam, PATH_ENV) == 0) { + path_tainted = 0; + } + return value; + } + return Qnil; +} + +static VALUE +env_delete_m(VALUE obj, SEL sel, VALUE name) +{ + VALUE val = env_delete(obj, name); + if (NIL_P(val) && rb_block_given_p()) { + rb_yield(name); + } + return val; +} + +static VALUE +rb_f_getenv(VALUE obj, SEL sel, VALUE name) +{ + rb_secure(4); + SafeStringValue(name); + const char *nam = RSTRING_PTR(name); + if (strlen(nam) != RSTRING_LEN(name)) { + rb_raise(rb_eArgError, "bad environment variable name"); + } + const char *env = getenv(nam); + if (env != NULL) { + if (strcmp(nam, PATH_ENV) == 0 && !rb_env_path_tainted()) { + VALUE str = rb_str_new2(env); + rb_obj_freeze(str); + return str; + } + return env_str_new2(env); + } + return Qnil; +} + +static VALUE +env_fetch(VALUE rcv, SEL sel, int argc, VALUE *argv) +{ + rb_secure(4); + + VALUE key, if_none; + rb_scan_args(argc, argv, "11", &key, &if_none); + + const bool block_given = rb_block_given_p(); + if (block_given && argc == 2) { + rb_warn("block supersedes default value argument"); + } + SafeStringValue(key); + const char *nam = RSTRING_PTR(key); + if (strlen(nam) != RSTRING_LEN(key)) { + rb_raise(rb_eArgError, "bad environment variable name"); + } + const char *env = getenv(nam); + if (env == NULL) { + if (block_given) { + return rb_yield(key); + } + if (argc == 1) { + rb_raise(rb_eKeyError, "key not found"); + } + return if_none; + } + if (strcmp(nam, PATH_ENV) == 0 && !rb_env_path_tainted()) { + return rb_str_new2(env); + } + return env_str_new2(env); +} + +static void +path_tainted_p(const char *path) +{ + path_tainted = rb_path_check(path) ? 0 : 1; +} + +int +rb_env_path_tainted(void) +{ + if (path_tainted < 0) { + path_tainted_p(getenv(PATH_ENV)); + } + return path_tainted; +} + +void +ruby_setenv(const char *name, const char *value) +{ +#undef setenv +#undef unsetenv + if (value != NULL) { + setenv(name, value, 1); + } + else { + unsetenv(name); + } +} + +void +ruby_unsetenv(const char *name) +{ + ruby_setenv(name, 0); +} + +static VALUE +env_aset(VALUE obj, SEL sel, VALUE nm, VALUE val) +{ + if (rb_safe_level() >= 4) { + rb_raise(rb_eSecurityError, "can't change environment variable"); + } + + if (NIL_P(val)) { + env_delete(obj, nm); + return Qnil; + } + StringValue(nm); + StringValue(val); + const char *name = RSTRING_PTR(nm); + const char *value = RSTRING_PTR(val); + if (strlen(name) != RSTRING_LEN(nm)) { + rb_raise(rb_eArgError, "bad environment variable name"); + } + if (strlen(value) != RSTRING_LEN(val)) { + rb_raise(rb_eArgError, "bad environment variable value"); + } + + ruby_setenv(name, value); + if (strcmp(name, PATH_ENV) == 0) { + if (OBJ_TAINTED(val)) { + /* already tainted, no check */ + path_tainted = 1; + return val; + } + else { + path_tainted_p(value); + } + } + return val; +} + +static VALUE +env_keys(VALUE rcv, SEL sel) +{ + rb_secure(4); + + VALUE ary = rb_ary_new(); + char **env = GET_ENVIRON(); + while (*env != NULL) { + const char *s = strchr(*env, '='); + if (s != NULL) { + rb_ary_push(ary, env_str_new(*env, s - *env)); + } + env++; + } + return ary; +} + +static VALUE +env_each_key(VALUE ehash, SEL sel) +{ + RETURN_ENUMERATOR(ehash, 0, 0); + VALUE keys = env_keys(Qnil, 0); /* rb_secure(4); */ + for (long i = 0, count = RARRAY_LEN(keys); i < count; i++) { + rb_yield(RARRAY_AT(keys, i)); + RETURN_IF_BROKEN(); + } + return ehash; +} + +static VALUE +env_values(VALUE rcv, SEL sel) +{ + rb_secure(4); + + VALUE ary = rb_ary_new(); + char **env = GET_ENVIRON(); + while (*env != NULL) { + const char *s = strchr(*env, '='); + if (s != NULL) { + rb_ary_push(ary, env_str_new2(s + 1)); + } + env++; + } + return ary; +} + +static VALUE +env_each_value(VALUE ehash, SEL sel) +{ + RETURN_ENUMERATOR(ehash, 0, 0); + VALUE values = env_values(Qnil, 0); /* rb_secure(4); */ + for (long i = 0, count = RARRAY_LEN(values); i < count; i++) { + rb_yield(RARRAY_AT(values, i)); + RETURN_IF_BROKEN(); + } + return ehash; +} + +static VALUE +env_each_pair(VALUE ehash, SEL sel) +{ + RETURN_ENUMERATOR(ehash, 0, 0); + + rb_secure(4); + VALUE ary = rb_ary_new(); + char **env = GET_ENVIRON(); + while (*env != NULL) { + const char *s = strchr(*env, '='); + if (s != NULL) { + rb_ary_push(ary, env_str_new(*env, s - *env)); + rb_ary_push(ary, env_str_new2(s + 1)); + } + env++; + } + + for (long i = 0, count = RARRAY_LEN(ary); i < count; i += 2) { + rb_yield(rb_assoc_new(RARRAY_AT(ary, i), RARRAY_AT(ary, i + 1))); + RETURN_IF_BROKEN(); + } + return ehash; +} + +static VALUE +env_reject_bang(VALUE ehash, SEL sel) +{ + RETURN_ENUMERATOR(ehash, 0, 0); + VALUE keys = env_keys(Qnil, 0); /* rb_secure(4); */ + bool deleted = false; + for (long i = 0, count = RARRAY_LEN(keys); i < count; i++) { + VALUE key = RARRAY_AT(keys, i); + VALUE val = rb_f_getenv(Qnil, 0, key); + if (!NIL_P(val)) { + VALUE v = rb_yield_values(2, key, val); + RETURN_IF_BROKEN(); + if (RTEST(v)) { + rb_obj_untaint(key); + env_delete(Qnil, key); + deleted = true; + } + } + } + return deleted ? envtbl : Qnil; +} + +static VALUE +env_delete_if(VALUE ehash, SEL sel) +{ + RETURN_ENUMERATOR(ehash, 0, 0); + env_reject_bang(ehash, 0); + return envtbl; +} + +static VALUE +env_values_at(VALUE rcv, SEL sel, int argc, VALUE *argv) +{ + rb_secure(4); + VALUE result = rb_ary_new(); + for (long i = 0; i < argc; i++) { + rb_ary_push(result, rb_f_getenv(Qnil, 0, argv[i])); + } + return result; +} + +static VALUE +env_select(VALUE ehash, SEL sel) +{ + RETURN_ENUMERATOR(ehash, 0, 0); + rb_secure(4); + VALUE result = rb_hash_new(); + char **env = GET_ENVIRON(); + while (*env != NULL) { + const char *s = strchr(*env, '='); + if (s != NULL) { + VALUE k = env_str_new(*env, s - *env); + VALUE v = env_str_new2(s + 1); + VALUE v2 = rb_yield_values(2, k, v); + RETURN_IF_BROKEN(); + if (RTEST(v2)) { + rb_hash_aset(result, k, v); + } + } + env++; + } + return result; +} + +static VALUE +rb_env_clear_imp(VALUE rcv, SEL sel) +{ + VALUE keys = env_keys(Qnil, 0); /* rb_secure(4); */ + for (long i = 0, count = RARRAY_LEN(keys); i < count; i++) { + VALUE val = rb_f_getenv(Qnil, 0, RARRAY_AT(keys, i)); + if (!NIL_P(val)) { + env_delete(Qnil, RARRAY_AT(keys, i)); + } + } + return envtbl; +} + +VALUE +rb_env_clear(void) +{ + return rb_env_clear_imp(Qnil, 0); +} + +static VALUE +env_to_s(VALUE rcv, SEL sel) +{ + return rb_usascii_str_new2("ENV"); +} + +static VALUE +env_inspect(VALUE rcv, SEL sel) +{ + rb_secure(4); + + VALUE str = rb_str_buf_new2("{"); + char **env = GET_ENVIRON(); + while (*env != NULL) { + const char *s = strchr(*env, '='); + + if (env != GET_ENVIRON()) { + rb_str_buf_cat2(str, ", "); + } + if (s != NULL) { + rb_str_buf_cat2(str, "\""); + rb_str_buf_cat(str, *env, s - *env); + rb_str_buf_cat2(str, "\"=>"); + VALUE i = rb_inspect(rb_str_new2(s + 1)); + rb_str_buf_append(str, i); + } + env++; + } + rb_str_buf_cat2(str, "}"); + OBJ_TAINT(str); + + return str; +} + +static VALUE +env_to_a(VALUE rcv, SEL sel) +{ + rb_secure(4); + + VALUE ary = rb_ary_new(); + char **env = GET_ENVIRON(); + while (*env != NULL) { + const char *s = strchr(*env, '='); + if (s != NULL) { + rb_ary_push(ary, rb_assoc_new(env_str_new(*env, s - *env), + env_str_new2(s + 1))); + } + env++; + } + return ary; +} + +static VALUE +env_none(VALUE rcv, SEL sel) +{ + return Qnil; +} + +static VALUE +env_size(VALUE rcv, SEL sel) +{ + rb_secure(4); + + char **env = GET_ENVIRON(); + int i = 0; + while (env[i] != NULL) { + i++; + } + return INT2FIX(i); +} + +static VALUE +env_empty_p(VALUE rcv, SEL sel) +{ + rb_secure(4); + + char **env = GET_ENVIRON(); + if (env[0] == NULL) { + return Qtrue; + } + return Qfalse; +} + +static VALUE +env_has_key(VALUE env, SEL sel, VALUE key) +{ + rb_secure(4); + + const char *s = StringValuePtr(key); + if (strlen(s) != RSTRING_LEN(key)) { + rb_raise(rb_eArgError, "bad environment variable name"); + } + if (getenv(s) != NULL) { + return Qtrue; + } + return Qfalse; +} + +static VALUE +env_assoc(VALUE env, SEL sel, VALUE key) +{ + rb_secure(4); + + const char *s = StringValuePtr(key); + if (strlen(s) != RSTRING_LEN(key)) { + rb_raise(rb_eArgError, "bad environment variable name"); + } + const char *e = getenv(s); + if (e != NULL) { + return rb_assoc_new(key, rb_tainted_str_new2(e)); + } + return Qnil; +} + +static VALUE +env_has_value(VALUE dmy, SEL sel, VALUE obj) +{ + rb_secure(4); + + obj = rb_check_string_type(obj); + if (NIL_P(obj)) { + return Qnil; + } + char **env = GET_ENVIRON(); + while (*env != NULL) { + const char *s = strchr(*env, '='); + if (s++ != NULL) { + const long len = strlen(s); + if (RSTRING_LEN(obj) == len + && strncmp(s, RSTRING_PTR(obj), len) == 0) { + return Qtrue; + } + } + env++; + } + return Qfalse; +} + +static VALUE +env_rassoc(VALUE dmy, VALUE obj) +{ + rb_secure(4); + + obj = rb_check_string_type(obj); + if (NIL_P(obj)) { + return Qnil; + } + char **env = GET_ENVIRON(); + while (*env != NULL) { + const char *s = strchr(*env, '='); + if (s++ != NULL) { + const long len = strlen(s); + if (RSTRING_LEN(obj) == len + && strncmp(s, RSTRING_PTR(obj), len) == 0) { + return rb_assoc_new(rb_tainted_str_new(*env, s - *env - 1), + obj); + } + } + env++; + } + return Qnil; +} + +static VALUE +env_key(VALUE dmy, SEL sel, VALUE value) +{ + rb_secure(4); + + StringValue(value); + char **env = GET_ENVIRON(); + while (*env != NULL) { + const char *s = strchr(*env, '='); + if (s++ != NULL) { + const long len = strlen(s); + if (RSTRING_LEN(value) == len + && strncmp(s, RSTRING_PTR(value), len) == 0) { + return env_str_new(*env, s - *env - 1); + } + } + env++; + } + return Qnil; +} + +static VALUE +env_index(VALUE dmy, SEL sel, VALUE value) +{ + rb_warn("ENV.index is deprecated; use ENV.key"); + return env_key(dmy, 0, value); +} + +static VALUE +env_to_hash(VALUE rcv, SEL sel) +{ + rb_secure(4); + + VALUE hash = rb_hash_new(); + char **env = GET_ENVIRON(); + while (*env != NULL) { + const char *s = strchr(*env, '='); + if (s != NULL) { + rb_hash_aset(hash, env_str_new(*env, s - *env), + env_str_new2(s + 1)); + } + env++; + } + return hash; +} + +static VALUE +env_reject(VALUE rcv, SEL sel) +{ + rb_secure(4); + + RETURN_ENUMERATOR(rcv, 0, 0); + + VALUE hash = rb_hash_new(); + char **env = GET_ENVIRON(); + while (*env != NULL) { + const char *s = strchr(*env, '='); + if (s != NULL) { + VALUE key = env_str_new(*env, s - *env); + VALUE val = env_str_new2(s + 1); + if (!RTEST(rb_yield_values(2, key, val))) { + rb_hash_aset(hash, key, val); + } + } + env++; + } + return hash; +} + +static VALUE +env_shift(VALUE rcv, SEL sel) +{ + rb_secure(4); + + char **env = GET_ENVIRON(); + if (*env != NULL) { + const char *s = strchr(*env, '='); + if (s != NULL) { + VALUE key = env_str_new(*env, s - *env); + VALUE val = env_str_new2(getenv(RSTRING_PTR(key))); + env_delete(Qnil, key); + return rb_assoc_new(key, val); + } + } + return Qnil; +} + +static VALUE +env_invert(VALUE rcv, SEL sel) +{ + rb_secure(4); + + VALUE hash = rb_hash_new(); + char **env = GET_ENVIRON(); + while (*env != NULL) { + const char *s = strchr(*env, '='); + if (s != NULL) { + rb_hash_aset(hash, env_str_new2(s + 1), + env_str_new(*env, s - *env)); + } + env++; + } + return hash; +} + +static int +env_replace_i(VALUE key, VALUE val, VALUE keys) +{ + if (key != Qundef) { + env_aset(Qnil, 0, key, val); + if (rb_ary_includes(keys, key)) { + rb_ary_delete(keys, key); + } + } + return ST_CONTINUE; +} + +static VALUE +env_replace(VALUE env, SEL sel, VALUE hash) +{ + VALUE keys = env_keys(Qnil, 0); /* rb_secure(4); */ + if (env == hash) { + return env; + } + hash = to_hash(hash); + rb_hash_foreach(hash, env_replace_i, keys); + + for (long i = 0, count = RARRAY_LEN(keys); i < count; i++) { + env_delete(env, RARRAY_AT(keys, i)); + } + return env; +} + +static int +env_update_i(VALUE key, VALUE val) +{ + if (key != Qundef) { + if (rb_block_given_p()) { + val = rb_yield_values(3, key, rb_f_getenv(Qnil, 0, key), val); + RETURN_IF_BROKEN(); + } + env_aset(Qnil, 0, key, val); + } + return ST_CONTINUE; +} + +static VALUE +env_update(VALUE env, SEL sel, VALUE hash) +{ + rb_secure(4); + if (env == hash) { + return env; + } + hash = to_hash(hash); + rb_hash_foreach(hash, env_update_i, 0); + return env; +} + +void +Init_ENV(void) +{ + origenviron = GET_ENVIRON(); + envtbl = rb_obj_alloc(rb_cObject); + rb_extend_object(envtbl, rb_mEnumerable); + + VALUE klass = rb_singleton_class(envtbl); + + rb_objc_define_method(klass, "[]", rb_f_getenv, 1); + rb_objc_define_method(klass, "fetch", env_fetch, -1); + rb_objc_define_method(klass, "[]=", env_aset, 2); + rb_objc_define_method(klass, "store", env_aset, 2); + rb_objc_define_method(klass, "each", env_each_pair, 0); + rb_objc_define_method(klass, "each_pair", env_each_pair, 0); + rb_objc_define_method(klass, "each_key", env_each_key, 0); + rb_objc_define_method(klass, "each_value", env_each_value, 0); + rb_objc_define_method(klass, "delete", env_delete_m, 1); + rb_objc_define_method(klass, "delete_if", env_delete_if, 0); + rb_objc_define_method(klass, "clear", rb_env_clear_imp, 0); + rb_objc_define_method(klass, "reject", env_reject, 0); + rb_objc_define_method(klass, "reject!", env_reject_bang, 0); + rb_objc_define_method(klass, "select", env_select, 0); + rb_objc_define_method(klass, "shift", env_shift, 0); + rb_objc_define_method(klass, "invert", env_invert, 0); + rb_objc_define_method(klass, "replace", env_replace, 1); + rb_objc_define_method(klass, "update", env_update, 1); + rb_objc_define_method(klass, "inspect", env_inspect, 0); + rb_objc_define_method(klass, "rehash", env_none, 0); + rb_objc_define_method(klass, "to_a", env_to_a, 0); + rb_objc_define_method(klass, "to_s", env_to_s, 0); + rb_objc_define_method(klass, "key", env_key, 1); + rb_objc_define_method(klass, "index", env_index, 1); + rb_objc_define_method(klass, "size", env_size, 0); + rb_objc_define_method(klass, "length", env_size, 0); + rb_objc_define_method(klass, "empty?", env_empty_p, 0); + rb_objc_define_method(klass, "keys", env_keys, 0); + rb_objc_define_method(klass, "values", env_values, 0); + rb_objc_define_method(klass, "values_at", env_values_at, -1); + rb_objc_define_method(klass, "include?", env_has_key, 1); + rb_objc_define_method(klass, "member?", env_has_key, 1); + rb_objc_define_method(klass, "has_key?", env_has_key, 1); + rb_objc_define_method(klass, "has_value?", env_has_value, 1); + rb_objc_define_method(klass, "key?", env_has_key, 1); + rb_objc_define_method(klass, "value?", env_has_value, 1); + rb_objc_define_method(klass, "to_hash", env_to_hash, 0); + rb_objc_define_method(klass, "assoc", env_assoc, 1); + rb_objc_define_method(klass, "rassoc", env_rassoc, 1); + + rb_define_global_const("ENV", envtbl); +} Modified: MacRuby/trunk/hash.c =================================================================== --- MacRuby/trunk/hash.c 2010-02-04 02:10:07 UTC (rev 3429) +++ MacRuby/trunk/hash.c 2010-02-04 05:29:57 UTC (rev 3430) @@ -18,8 +18,6 @@ #include "objc.h" #include "vm.h" -#include <crt_externs.h> - static VALUE rhash_try_convert(VALUE, SEL, VALUE); VALUE @@ -61,7 +59,6 @@ return __klass_is_rhash(klass); } -static VALUE envtbl; static ID id_yield; static void *defaultCache = NULL; @@ -1853,709 +1850,6 @@ return Qfalse; } -static int path_tainted = -1; - -static char **origenviron; -#undef environ -#define environ (*_NSGetEnviron()) -#define GET_ENVIRON(e) (e) -#define FREE_ENVIRON(e) - -static VALUE -env_str_new(const char *ptr, long len) -{ - VALUE str = rb_tainted_str_new(ptr, len); - - rb_obj_freeze(str); - return str; -} - -static VALUE -env_str_new2(const char *ptr) -{ - if (!ptr) return Qnil; - return env_str_new(ptr, strlen(ptr)); -} - -static VALUE -env_delete(VALUE obj, VALUE name) -{ - const char *nam, *val; - - rb_secure(4); - SafeStringValue(name); - nam = RSTRING_PTR(name); - if (strlen(nam) != RSTRING_LEN(name)) { - rb_raise(rb_eArgError, "bad environment variable name"); - } - val = getenv(nam); - if (val) { - VALUE value = env_str_new2(val); - - ruby_setenv(nam, 0); -#ifdef ENV_IGNORECASE - if (STRCASECMP(nam, PATH_ENV) == 0) -#else - if (strcmp(nam, PATH_ENV) == 0) -#endif - { - path_tainted = 0; - } - return value; - } - return Qnil; -} - -static VALUE -env_delete_m(VALUE obj, SEL sel, VALUE name) -{ - VALUE val; - - val = env_delete(obj, name); - if (NIL_P(val) && rb_block_given_p()) rb_yield(name); - return val; -} - -static VALUE -rb_f_getenv(VALUE obj, SEL sel, VALUE name) -{ - const char *nam, *env; - - rb_secure(4); - SafeStringValue(name); - nam = RSTRING_PTR(name); - if (strlen(nam) != RSTRING_LEN(name)) { - rb_raise(rb_eArgError, "bad environment variable name"); - } - env = getenv(nam); - if (env) { -#ifdef ENV_IGNORECASE - if (STRCASECMP(nam, PATH_ENV) == 0 && !rb_env_path_tainted()) -#else - if (strcmp(nam, PATH_ENV) == 0 && !rb_env_path_tainted()) -#endif - { - VALUE str = rb_str_new2(env); - - rb_obj_freeze(str); - return str; - } - return env_str_new2(env); - } - return Qnil; -} - -static VALUE -env_fetch(VALUE rcv, SEL sel, int argc, VALUE *argv) -{ - VALUE key, if_none; - long block_given; - const char *nam, *env; - - rb_secure(4); - rb_scan_args(argc, argv, "11", &key, &if_none); - block_given = rb_block_given_p(); - if (block_given && argc == 2) { - rb_warn("block supersedes default value argument"); - } - SafeStringValue(key); - nam = RSTRING_PTR(key); - if (strlen(nam) != RSTRING_LEN(key)) { - rb_raise(rb_eArgError, "bad environment variable name"); - } - env = getenv(nam); - if (!env) { - if (block_given) return rb_yield(key); - if (argc == 1) { - rb_raise(rb_eKeyError, "key not found"); - } - return if_none; - } -#ifdef ENV_IGNORECASE - if (STRCASECMP(nam, PATH_ENV) == 0 && !rb_env_path_tainted()) -#else - if (strcmp(nam, PATH_ENV) == 0 && !rb_env_path_tainted()) -#endif - return rb_str_new2(env); - return env_str_new2(env); -} - -static void -path_tainted_p(const char *path) -{ - path_tainted = rb_path_check(path)?0:1; -} - -int -rb_env_path_tainted(void) -{ - if (path_tainted < 0) { - path_tainted_p(getenv(PATH_ENV)); - } - return path_tainted; -} - -void -ruby_setenv(const char *name, const char *value) -{ -#undef setenv -#undef unsetenv - if (value) - setenv(name,value,1); - else - unsetenv(name); -} - -void -ruby_unsetenv(const char *name) -{ - ruby_setenv(name, 0); -} - -static VALUE -env_aset(VALUE obj, SEL sel, VALUE nm, VALUE val) -{ - const char *name, *value; - - if (rb_safe_level() >= 4) { - rb_raise(rb_eSecurityError, "can't change environment variable"); - } - - if (NIL_P(val)) { - env_delete(obj, nm); - return Qnil; - } - StringValue(nm); - StringValue(val); - name = RSTRING_PTR(nm); - value = RSTRING_PTR(val); - if (strlen(name) != RSTRING_LEN(nm)) { - rb_raise(rb_eArgError, "bad environment variable name"); - } - if (strlen(value) != RSTRING_LEN(val)) { - rb_raise(rb_eArgError, "bad environment variable value"); - } - - ruby_setenv(name, value); -#ifdef ENV_IGNORECASE - if (STRCASECMP(name, PATH_ENV) == 0) { -#else - if (strcmp(name, PATH_ENV) == 0) { -#endif - if (OBJ_TAINTED(val)) { - /* already tainted, no check */ - path_tainted = 1; - return val; - } - else { - path_tainted_p(value); - } - } - return val; -} - -static VALUE -env_keys(VALUE rcv, SEL sel) -{ - char **env; - VALUE ary; - - rb_secure(4); - ary = rb_ary_new(); - env = GET_ENVIRON(environ); - while (*env) { - char *s = strchr(*env, '='); - if (s) { - rb_ary_push(ary, env_str_new(*env, s-*env)); - } - env++; - } - FREE_ENVIRON(environ); - return ary; -} - -static VALUE -env_each_key(VALUE ehash, SEL sel) -{ - VALUE keys; - long i; - - RETURN_ENUMERATOR(ehash, 0, 0); - keys = env_keys(Qnil, 0); /* rb_secure(4); */ - for (i=0; i<RARRAY_LEN(keys); i++) { - rb_yield(RARRAY_AT(keys, i)); - RETURN_IF_BROKEN(); - } - return ehash; -} - -static VALUE -env_values(VALUE rcv, SEL sel) -{ - VALUE ary; - char **env; - - rb_secure(4); - ary = rb_ary_new(); - env = GET_ENVIRON(environ); - while (*env) { - char *s = strchr(*env, '='); - if (s) { - rb_ary_push(ary, env_str_new2(s+1)); - } - env++; - } - FREE_ENVIRON(environ); - return ary; -} - -static VALUE -env_each_value(VALUE ehash, SEL sel) -{ - VALUE values; - long i; - - RETURN_ENUMERATOR(ehash, 0, 0); - values = env_values(Qnil, 0); /* rb_secure(4); */ - for (i=0; i<RARRAY_LEN(values); i++) { - rb_yield(RARRAY_AT(values, i)); - RETURN_IF_BROKEN(); - } - return ehash; -} - -static VALUE -env_each_pair(VALUE ehash, SEL sel) -{ - char **env; - VALUE ary; - long i; - - RETURN_ENUMERATOR(ehash, 0, 0); - - rb_secure(4); - ary = rb_ary_new(); - env = GET_ENVIRON(environ); - while (*env) { - char *s = strchr(*env, '='); - if (s) { - rb_ary_push(ary, env_str_new(*env, s-*env)); - rb_ary_push(ary, env_str_new2(s+1)); - } - env++; - } - FREE_ENVIRON(environ); - - for (i=0; i<RARRAY_LEN(ary); i+=2) { - rb_yield(rb_assoc_new(RARRAY_AT(ary, i), RARRAY_AT(ary, i+1))); - RETURN_IF_BROKEN(); - } - return ehash; -} - -static VALUE -env_reject_bang(VALUE ehash, SEL sel) -{ - volatile VALUE keys; - long i; - int del = 0; - - RETURN_ENUMERATOR(ehash, 0, 0); - keys = env_keys(Qnil, 0); /* rb_secure(4); */ - for (i=0; i<RARRAY_LEN(keys); i++) { - VALUE val = rb_f_getenv(Qnil, 0, RARRAY_AT(keys, i)); - if (!NIL_P(val)) { - VALUE v = rb_yield_values(2, RARRAY_AT(keys, i), val); - RETURN_IF_BROKEN(); - if (RTEST(v)) { - rb_obj_untaint(RARRAY_AT(keys, i)); - env_delete(Qnil, RARRAY_AT(keys, i)); - del++; - } - } - } - if (del == 0) return Qnil; - return envtbl; -} - -static VALUE -env_delete_if(VALUE ehash, SEL sel) -{ - RETURN_ENUMERATOR(ehash, 0, 0); - env_reject_bang(ehash, 0); - return envtbl; -} - -static VALUE -env_values_at(VALUE rcv, SEL sel, int argc, VALUE *argv) -{ - VALUE result; - long i; - - rb_secure(4); - result = rb_ary_new(); - for (i=0; i<argc; i++) { - rb_ary_push(result, rb_f_getenv(Qnil, 0, argv[i])); - } - return result; -} - -static VALUE -env_select(VALUE ehash, SEL sel) -{ - VALUE result; - char **env; - - RETURN_ENUMERATOR(ehash, 0, 0); - rb_secure(4); - result = rb_hash_new(); - env = GET_ENVIRON(environ); - while (*env) { - char *s = strchr(*env, '='); - if (s) { - VALUE k = env_str_new(*env, s-*env); - VALUE v = env_str_new2(s+1); - VALUE v2 = rb_yield_values(2, k, v); - RETURN_IF_BROKEN(); - if (RTEST(v2)) { - rb_hash_aset(result, k, v); - } - } - env++; - } - FREE_ENVIRON(environ); - - return result; -} - -static VALUE -rb_env_clear_imp(VALUE rcv, SEL sel) -{ - VALUE keys; - long i; - - keys = env_keys(Qnil, 0); /* rb_secure(4); */ - for (i=0; i<RARRAY_LEN(keys); i++) { - VALUE val = rb_f_getenv(Qnil, 0, RARRAY_AT(keys, i)); - if (!NIL_P(val)) { - env_delete(Qnil, RARRAY_AT(keys, i)); - } - } - return envtbl; -} - -VALUE -rb_env_clear(void) -{ - return rb_env_clear_imp(Qnil, 0); -} - -static VALUE -env_to_s(VALUE rcv, SEL sel) -{ - return rb_usascii_str_new2("ENV"); -} - -static VALUE -env_inspect(VALUE rcv, SEL sel) -{ - char **env; - VALUE str, i; - - rb_secure(4); - str = rb_str_buf_new2("{"); - env = GET_ENVIRON(environ); - while (*env) { - char *s = strchr(*env, '='); - - if (env != environ) { - rb_str_buf_cat2(str, ", "); - } - if (s) { - rb_str_buf_cat2(str, "\""); - rb_str_buf_cat(str, *env, s-*env); - rb_str_buf_cat2(str, "\"=>"); - i = rb_inspect(rb_str_new2(s+1)); - rb_str_buf_append(str, i); - } - env++; - } - FREE_ENVIRON(environ); - rb_str_buf_cat2(str, "}"); - OBJ_TAINT(str); - - return str; -} - -static VALUE -env_to_a(VALUE rcv, SEL sel) -{ - char **env; - VALUE ary; - - rb_secure(4); - ary = rb_ary_new(); - env = GET_ENVIRON(environ); - while (*env) { - char *s = strchr(*env, '='); - if (s) { - rb_ary_push(ary, rb_assoc_new(env_str_new(*env, s-*env), - env_str_new2(s+1))); - } - env++; - } - FREE_ENVIRON(environ); - return ary; -} - -static VALUE -env_none(VALUE rcv, SEL sel) -{ - return Qnil; -} - -static VALUE -env_size(VALUE rcv, SEL sel) -{ - int i; - char **env; - - rb_secure(4); - env = GET_ENVIRON(environ); - for(i=0; env[i]; i++) - ; - FREE_ENVIRON(environ); - return INT2FIX(i); -} - -static VALUE -env_empty_p(VALUE rcv, SEL sel) -{ - char **env; - - rb_secure(4); - env = GET_ENVIRON(environ); - if (env[0] == 0) { - FREE_ENVIRON(environ); - return Qtrue; - } - FREE_ENVIRON(environ); - return Qfalse; -} - -static VALUE -env_has_key(VALUE env, SEL sel, VALUE key) -{ - char *s; - - rb_secure(4); - s = StringValuePtr(key); - if (strlen(s) != RSTRING_LEN(key)) - rb_raise(rb_eArgError, "bad environment variable name"); - if (getenv(s)) return Qtrue; - return Qfalse; -} - -static VALUE -env_assoc(VALUE env, SEL sel, VALUE key) -{ - char *s, *e; - - rb_secure(4); - s = StringValuePtr(key); - if (strlen(s) != RSTRING_LEN(key)) - rb_raise(rb_eArgError, "bad environment variable name"); - e = getenv(s); - if (e) return rb_assoc_new(key, rb_tainted_str_new2(e)); - return Qnil; -} - -static VALUE -env_has_value(VALUE dmy, SEL sel, VALUE obj) -{ - char **env; - - rb_secure(4); - obj = rb_check_string_type(obj); - if (NIL_P(obj)) return Qnil; - env = GET_ENVIRON(environ); - while (*env) { - char *s = strchr(*env, '='); - if (s++) { - long len = strlen(s); - if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) { - FREE_ENVIRON(environ); - return Qtrue; - } - } - env++; - } - FREE_ENVIRON(environ); - return Qfalse; -} - -static VALUE -env_rassoc(VALUE dmy, VALUE obj) -{ - char **env; - - rb_secure(4); - obj = rb_check_string_type(obj); - if (NIL_P(obj)) return Qnil; - env = GET_ENVIRON(environ); - while (*env) { - char *s = strchr(*env, '='); - if (s++) { - long len = strlen(s); - if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) { - VALUE result = rb_assoc_new(rb_tainted_str_new(*env, s-*env-1), obj); - FREE_ENVIRON(environ); - return result; - } - } - env++; - } - FREE_ENVIRON(environ); - return Qnil; -} - -static VALUE -env_key(VALUE dmy, SEL sel, VALUE value) -{ - char **env; - VALUE str; - - rb_secure(4); - StringValue(value); - env = GET_ENVIRON(environ); - while (*env) { - char *s = strchr(*env, '='); - if (s++) { - long len = strlen(s); - if (RSTRING_LEN(value) == len && strncmp(s, RSTRING_PTR(value), len) == 0) { - str = env_str_new(*env, s-*env-1); - FREE_ENVIRON(environ); - return str; - } - } - env++; - } - FREE_ENVIRON(environ); - return Qnil; -} - -static VALUE -env_index(VALUE dmy, SEL sel, VALUE value) -{ - rb_warn("ENV.index is deprecated; use ENV.key"); - return env_key(dmy, 0, value); -} - -static VALUE -env_to_hash(VALUE rcv, SEL sel) -{ - char **env; - VALUE hash; - - rb_secure(4); - hash = rb_hash_new(); - env = GET_ENVIRON(environ); - while (*env) { - char *s = strchr(*env, '='); - if (s) { - rb_hash_aset(hash, env_str_new(*env, s-*env), - env_str_new2(s+1)); - } - env++; - } - FREE_ENVIRON(environ); - return hash; -} - -static VALUE -env_reject(VALUE rcv, SEL sel) -{ - return rhash_delete_if(env_to_hash(Qnil, 0), 0); -} - -static VALUE -env_shift(VALUE rcv, SEL sel) -{ - char **env; - - rb_secure(4); - env = GET_ENVIRON(environ); - if (*env) { - char *s = strchr(*env, '='); - if (s) { - VALUE key = env_str_new(*env, s-*env); - VALUE val = env_str_new2(getenv(RSTRING_PTR(key))); - env_delete(Qnil, key); - return rb_assoc_new(key, val); - } - } - FREE_ENVIRON(environ); - return Qnil; -} - -static VALUE -env_invert(VALUE rcv, SEL sel) -{ - return rhash_invert(env_to_hash(Qnil, 0), 0); -} - -static int -env_replace_i(VALUE key, VALUE val, VALUE keys) -{ - if (key != Qundef) { - env_aset(Qnil, 0, key, val); - if (rb_ary_includes(keys, key)) { - rb_ary_delete(keys, key); - } - } - return ST_CONTINUE; -} - -static VALUE -env_replace(VALUE env, SEL sel, VALUE hash) -{ - volatile VALUE keys; - long i; - - keys = env_keys(Qnil, 0); /* rb_secure(4); */ - if (env == hash) return env; - hash = to_hash(hash); - rb_hash_foreach(hash, env_replace_i, keys); - - for (i=0; i<RARRAY_LEN(keys); i++) { - env_delete(env, RARRAY_AT(keys, i)); - } - return env; -} - -static int -env_update_i(VALUE key, VALUE val) -{ - if (key != Qundef) { - if (rb_block_given_p()) { - val = rb_yield_values(3, key, rb_f_getenv(Qnil, 0, key), val); - RETURN_IF_BROKEN(); - } - env_aset(Qnil, 0, key, val); - } - return ST_CONTINUE; -} - -static VALUE -env_update(VALUE env, SEL sel, VALUE hash) -{ - rb_secure(4); - if (env == hash) return env; - hash = to_hash(hash); - rb_hash_foreach(hash, env_update_i, 0); - return env; -} - bool rb_objc_hash_is_pure(VALUE hash) { @@ -2756,50 +2050,4 @@ (IMP)imp_rhash_keyenum_allObjects); rb_objc_install_method2((Class)rb_cRubyHashKeyEnumerator, "nextObject", (IMP)imp_rhash_keyenum_nextObject); - - origenviron = environ; - envtbl = rb_obj_alloc(rb_cObject); - rb_extend_object(envtbl, rb_mEnumerable); - - rb_objc_define_method(*(VALUE *)envtbl, "[]", rb_f_getenv, 1); - rb_objc_define_method(*(VALUE *)envtbl, "fetch", env_fetch, -1); - rb_objc_define_method(*(VALUE *)envtbl, "[]=", env_aset, 2); - rb_objc_define_method(*(VALUE *)envtbl, "store", env_aset, 2); - rb_objc_define_method(*(VALUE *)envtbl, "each", env_each_pair, 0); - rb_objc_define_method(*(VALUE *)envtbl, "each_pair", env_each_pair, 0); - rb_objc_define_method(*(VALUE *)envtbl, "each_key", env_each_key, 0); - rb_objc_define_method(*(VALUE *)envtbl, "each_value", env_each_value, 0); - rb_objc_define_method(*(VALUE *)envtbl, "delete", env_delete_m, 1); - rb_objc_define_method(*(VALUE *)envtbl, "delete_if", env_delete_if, 0); - rb_objc_define_method(*(VALUE *)envtbl, "clear", rb_env_clear_imp, 0); - rb_objc_define_method(*(VALUE *)envtbl, "reject", env_reject, 0); - rb_objc_define_method(*(VALUE *)envtbl, "reject!", env_reject_bang, 0); - rb_objc_define_method(*(VALUE *)envtbl, "select", env_select, 0); - rb_objc_define_method(*(VALUE *)envtbl, "shift", env_shift, 0); - rb_objc_define_method(*(VALUE *)envtbl, "invert", env_invert, 0); - rb_objc_define_method(*(VALUE *)envtbl, "replace", env_replace, 1); - rb_objc_define_method(*(VALUE *)envtbl, "update", env_update, 1); - rb_objc_define_method(*(VALUE *)envtbl, "inspect", env_inspect, 0); - rb_objc_define_method(*(VALUE *)envtbl, "rehash", env_none, 0); - rb_objc_define_method(*(VALUE *)envtbl, "to_a", env_to_a, 0); - rb_objc_define_method(*(VALUE *)envtbl, "to_s", env_to_s, 0); - rb_objc_define_method(*(VALUE *)envtbl, "key", env_key, 1); - rb_objc_define_method(*(VALUE *)envtbl, "index", env_index, 1); - rb_objc_define_method(*(VALUE *)envtbl, "size", env_size, 0); - rb_objc_define_method(*(VALUE *)envtbl, "length", env_size, 0); - rb_objc_define_method(*(VALUE *)envtbl, "empty?", env_empty_p, 0); - rb_objc_define_method(*(VALUE *)envtbl, "keys", env_keys, 0); - rb_objc_define_method(*(VALUE *)envtbl, "values", env_values, 0); - rb_objc_define_method(*(VALUE *)envtbl, "values_at", env_values_at, -1); - rb_objc_define_method(*(VALUE *)envtbl, "include?", env_has_key, 1); - rb_objc_define_method(*(VALUE *)envtbl, "member?", env_has_key, 1); - rb_objc_define_method(*(VALUE *)envtbl, "has_key?", env_has_key, 1); - rb_objc_define_method(*(VALUE *)envtbl, "has_value?", env_has_value, 1); - rb_objc_define_method(*(VALUE *)envtbl, "key?", env_has_key, 1); - rb_objc_define_method(*(VALUE *)envtbl, "value?", env_has_value, 1); - rb_objc_define_method(*(VALUE *)envtbl, "to_hash", env_to_hash, 0); - rb_objc_define_method(*(VALUE *)envtbl, "assoc", env_assoc, 1); - rb_objc_define_method(*(VALUE *)envtbl, "rassoc", env_rassoc, 1); - - rb_define_global_const("ENV", envtbl); } Modified: MacRuby/trunk/rakelib/builder/builder.rb =================================================================== --- MacRuby/trunk/rakelib/builder/builder.rb 2010-02-04 02:10:07 UTC (rev 3429) +++ MacRuby/trunk/rakelib/builder/builder.rb 2010-02-04 05:29:57 UTC (rev 3430) @@ -2,7 +2,7 @@ OBJS = %w{ array bignum class compar complex enum enumerator error eval file load proc - gc hash inits io math numeric object pack parse prec dir process + gc hash env inits io math numeric object pack parse prec dir process random range rational re onig/regcomp onig/regext onig/regposix onig/regenc onig/reggnu onig/regsyntax onig/regerror onig/regparse onig/regtrav onig/regexec onig/regposerr onig/regversion onig/enc/ascii onig/enc/unicode
participants (1)
-
source_changes@macosforge.org