コード例 #1
0
ファイル: load.c プロジェクト: scorpion007/ruby
static st_table *
get_loaded_features_index(void)
{
    VALUE features;
    int i;
    rb_vm_t *vm = GET_VM();

    if (!rb_ary_shared_with_p(vm->loaded_features_snapshot, vm->loaded_features)) {
	/* The sharing was broken; something (other than us in rb_provide_feature())
	   modified loaded_features.  Rebuild the index. */
	st_foreach(vm->loaded_features_index, loaded_features_index_clear_i, 0);
	features = vm->loaded_features;
	for (i = 0; i < RARRAY_LEN(features); i++) {
	    VALUE entry, as_str;
	    as_str = entry = rb_ary_entry(features, i);
	    StringValue(as_str);
	    as_str = rb_fstring(rb_str_freeze(as_str));
	    if (as_str != entry)
		rb_ary_store(features, i, as_str);
	    features_index_add(as_str, INT2FIX(i));
	}
	reset_loaded_features_snapshot();
    }
    return vm->loaded_features_index;
}
コード例 #2
0
ファイル: encoding.c プロジェクト: tenderlove/ruby
static int
load_encoding(const char *name)
{
    VALUE enclib = rb_sprintf("enc/%s.so", name);
    VALUE verbose = ruby_verbose;
    VALUE debug = ruby_debug;
    VALUE errinfo;
    char *s = RSTRING_PTR(enclib) + 4, *e = RSTRING_END(enclib) - 3;
    int loaded;
    int idx;

    while (s < e) {
	if (!ISALNUM(*s)) *s = '_';
	else if (ISUPPER(*s)) *s = (char)TOLOWER(*s);
	++s;
    }
    FL_UNSET(enclib, FL_TAINT);
    enclib = rb_fstring(enclib);
    ruby_verbose = Qfalse;
    ruby_debug = Qfalse;
    errinfo = rb_errinfo();
    loaded = rb_require_internal(enclib, rb_safe_level());
    ruby_verbose = verbose;
    ruby_debug = debug;
    rb_set_errinfo(errinfo);
    if (loaded < 0 || 1 < loaded) return -1;
    if ((idx = rb_enc_registered(name)) < 0) return -1;
    if (enc_autoload_p(enc_table.list[idx].enc)) return -1;
    return idx;
}
コード例 #3
0
ファイル: load.c プロジェクト: scorpion007/ruby
/* Construct expanded load path and store it to cache.
   We rebuild load path partially if the cache is invalid.
   We don't cache non string object and expand it every time. We ensure that
   string objects in $LOAD_PATH are frozen.
 */
static void
rb_construct_expanded_load_path(int type, int *has_relative, int *has_non_cache)
{
    rb_vm_t *vm = GET_VM();
    VALUE load_path = vm->load_path;
    VALUE expanded_load_path = vm->expanded_load_path;
    VALUE ary;
    long i;
    int level = rb_safe_level();

    ary = rb_ary_tmp_new(RARRAY_LEN(load_path));
    for (i = 0; i < RARRAY_LEN(load_path); ++i) {
	VALUE path, as_str, expanded_path;
	int is_string, non_cache;
	char *as_cstr;
	as_str = path = RARRAY_AREF(load_path, i);
	is_string = RB_TYPE_P(path, T_STRING) ? 1 : 0;
	non_cache = !is_string ? 1 : 0;
	as_str = rb_get_path_check_to_string(path, level);
	as_cstr = RSTRING_PTR(as_str);

	if (!non_cache) {
	    if ((type == EXPAND_RELATIVE &&
		    rb_is_absolute_path(as_cstr)) ||
		(type == EXPAND_HOME &&
		    (!as_cstr[0] || as_cstr[0] != '~')) ||
		(type == EXPAND_NON_CACHE)) {
		    /* Use cached expanded path. */
		    rb_ary_push(ary, RARRAY_AREF(expanded_load_path, i));
		    continue;
	    }
	}
	if (!*has_relative && !rb_is_absolute_path(as_cstr))
	    *has_relative = 1;
	if (!*has_non_cache && non_cache)
	    *has_non_cache = 1;
	/* Freeze only string object. We expand other objects every time. */
	if (is_string)
	    rb_str_freeze(path);
	as_str = rb_get_path_check_convert(path, as_str, level);
	expanded_path = rb_file_expand_path_fast(as_str, Qnil);
	rb_str_freeze(expanded_path);
	rb_ary_push(ary, rb_fstring(expanded_path));
    }
    rb_obj_freeze(ary);
    vm->expanded_load_path = ary;
    rb_ary_replace(vm->load_path_snapshot, vm->load_path);
}
コード例 #4
0
ファイル: load.c プロジェクト: scorpion007/ruby
static void
rb_provide_feature(VALUE feature)
{
    VALUE features;

    features = get_loaded_features();
    if (OBJ_FROZEN(features)) {
	rb_raise(rb_eRuntimeError,
		 "$LOADED_FEATURES is frozen; cannot append feature");
    }
    rb_str_freeze(feature);

    rb_ary_push(features, rb_fstring(feature));
    features_index_add(feature, INT2FIX(RARRAY_LEN(features)-1));
    reset_loaded_features_snapshot();
}