15 #define IS_RBEXT(e) (strcmp((e), ".rb") == 0)
16 #define IS_SOEXT(e) (strcmp((e), ".so") == 0 || strcmp((e), ".o") == 0)
18 #define IS_DLEXT(e) (strcmp((e), DLEXT) == 0 || strcmp((e), DLEXT2) == 0)
20 #define IS_DLEXT(e) (strcmp((e), DLEXT) == 0)
63 int is_string, non_cache;
67 non_cache = !is_string ? 1 : 0;
75 (!as_cstr[0] || as_cstr[0] !=
'~')) ||
84 if (!*has_non_cache && non_cache)
116 int has_relative = 0, has_non_cache = 0;
121 else if (has_non_cache) {
130 int has_relative = 1, has_non_cache = 1;
133 &has_relative, &has_non_cache);
136 int has_relative = 1, has_non_cache = 1;
143 &has_relative, &has_non_cache);
148 &has_relative, &has_non_cache);
163 return GET_VM()->loaded_features;
176 return GET_VM()->loaded_features_index;
182 return GET_VM()->loading_table;
190 char *short_feature_cstr;
199 if (
NIL_P(this_feature_index)) {
203 VALUE feature_indexes[2];
204 feature_indexes[0] = this_feature_index;
205 feature_indexes[1] = offset;
229 const char *feature_str, *feature_end, *ext, *
p;
234 for (ext = feature_end; ext > feature_str; ext--)
235 if (*ext ==
'.' || *ext ==
'/')
242 p = ext ? ext : feature_end;
245 while (p >= feature_str && *p !=
'/')
250 short_feature =
rb_str_subseq(feature, p + 1 - feature_str, feature_end - p - 1);
253 short_feature =
rb_str_subseq(feature, p + 1 - feature_str, ext - p - 1);
259 short_feature =
rb_str_subseq(feature, 0, ext - feature_str);
321 if (vlen < len+1)
return 0;
322 if (
strchr(feature,
'.') && !strncmp(name+(vlen-len), feature, len)) {
326 for (e = name + vlen; name != e && *e !=
'.' && *e !=
'/'; --
e);
329 strncmp(e-len, feature, len))
331 plen = e - name -
len;
333 if (plen > 0 && name[plen-1] !=
'/') {
336 if (type ==
's' ? !
IS_DLEXT(&name[plen+len]) :
337 type ==
'r' ? !
IS_RBEXT(&name[plen+len]) :
344 if (plen > 0) --plen;
350 if (n != plen)
continue;
351 if (n && strncmp(name, s, n))
continue;
368 const char *
s = (
const char *)v;
378 rb_feature_p(
const char *feature,
const char *ext,
int rb,
int expanded,
const char **fn)
382 long i,
len, elen,
n;
383 st_table *loading_tbl, *features_index;
390 len =
strlen(feature) - elen;
391 type = rb ?
'r' :
's';
428 if (!
NIL_P(this_feature_index)) {
433 if (i >=
RARRAY_LEN(this_feature_index))
break;
438 entry = this_feature_index;
445 if (strncmp(f, feature, len) != 0) {
446 if (expanded)
continue;
453 if (!*(e = f + len)) {
457 if (*e !=
'.')
continue;
461 if ((rb || !ext) && (
IS_RBEXT(e))) {
478 if ((f = fs.result) != 0) {
484 if (fn) *fn = (
const char*)data;
486 if (!ext)
return 'u';
492 static const char so_ext[][4] = {
496 if (ext && *ext)
return 0;
499 MEMCPY(buf, feature,
char, len);
504 if (fn) *fn = (
const char*)data;
505 return i ?
's' :
'r';
508 for (i = 0; i <
numberof(so_ext); i++) {
512 if (fn) *fn = (
const char*)data;
531 const char *ext =
strrchr(feature,
'.');
532 volatile VALUE fullpath = 0;
534 if (*feature ==
'.' &&
535 (feature[1] ==
'/' || strncmp(feature+1,
"./", 2) == 0)) {
539 if (ext && !
strchr(ext,
'/')) {
562 "$LOADED_FEATURES is frozen; cannot append feature");
585 volatile int loaded =
FALSE;
586 volatile int mild_compile_error;
587 #if !defined __GNUC__
619 #if !defined __GNUC__
730 return (
char *)ftptr;
741 rb_warning(
"loading in progress, circular require considered harmful - %s", ftptr);
752 return (
char *)ftptr;
851 if (ext && !
strchr(ext,
'/')) {
912 goto statically_linked;
928 return type ?
's' :
'r';
954 char *
volatile ftptr = 0;
1020 if (
NIL_P(result)) {
1046 const char *
name = (
char *)*key;
1049 rb_warn(
"%s is already registered", name);
1163 #define rb_intern(str) rb_intern2((str), strlen(str))
1165 static const char var_load_path[] =
"$:";
1166 ID id_load_path =
rb_intern2(var_load_path,
sizeof(var_load_path)-1);
#define RB_TYPE_P(obj, type)
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
static void features_index_add(VALUE feature, VALUE offset)
static VALUE get_loaded_features(void)
VALUE rb_ary_entry(VALUE ary, long offset)
int rb_is_absolute_path(const char *)
VALUE rb_require_safe(VALUE, int)
RUBY_EXTERN VALUE rb_cModule
size_t strlen(const char *)
#define RUBY_DTRACE_REQUIRE_ENTRY_ENABLED()
static int register_init_ext(st_data_t *key, st_data_t *value, st_data_t init, int existing)
VALUE rb_get_expanded_load_path(void)
int st_lookup(st_table *, st_data_t, st_data_t *)
VALUE rb_str_tmp_new(long)
#define RUBY_DTRACE_FIND_REQUIRE_ENTRY(arg0, arg1, arg2)
int rb_file_load_ok(const char *)
void rb_backtrace_print_to(VALUE output)
static void rb_load_internal(VALUE fname, int wrap)
#define rb_usascii_str_new2
#define RUBY_DTRACE_LOAD_RETURN_ENABLED()
struct st_table * loaded_features_index
static void rb_provide_feature(VALUE feature)
#define RUBY_DTRACE_FIND_REQUIRE_RETURN_ENABLED()
#define RUBY_DTRACE_FIND_REQUIRE_ENTRY_ENABLED()
VALUE rb_str_subseq(VALUE, long, long)
VALUE rb_obj_freeze(VALUE)
void rb_define_hooked_variable(const char *, VALUE *, VALUE(*)(ANYARGS), void(*)(ANYARGS))
int rb_find_file_ext_safe(VALUE *, const char *const *, int)
static VALUE load_ext(VALUE path)
VALUE rb_file_expand_path_fast(VALUE, VALUE)
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rb_require(const char *)
VALUE rb_ary_tmp_new(long capa)
VALUE rb_ary_shared_with_p(VALUE ary1, VALUE ary2)
VALUE rb_get_load_path(void)
VALUE rb_find_file_safe(VALUE, int)
VALUE rb_autoload_p(VALUE, ID)
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_str_encode_ospath(VALUE)
VALUE rb_f_require_relative(VALUE obj, VALUE fname)
st_table * st_init_strtable(void)
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
void * rb_load_file_str(VALUE)
ID rb_check_id(volatile VALUE *namep)
Returns ID for the given name if it is interned already, or 0.
void rb_load_fail(VALUE path, const char *err)
void rb_loaderror(const char *fmt,...)
static int loaded_features_index_clear_i(st_data_t key, st_data_t val, st_data_t arg)
#define RUBY_DTRACE_REQUIRE_ENTRY(arg0, arg1, arg2)
static void reset_loaded_features_snapshot(void)
static int rb_feature_p(const char *feature, const char *ext, int rb, int expanded, const char **fn)
#define RUBY_DTRACE_LOAD_ENTRY_ENABLED()
#define RUBY_DTRACE_LOAD_ENTRY(arg0, arg1, arg2)
VALUE rb_str_equal(VALUE str1, VALUE str2)
RUBY_EXTERN size_t strlcpy(char *, const char *, size_t)
static const char *const loadable_ext[]
static char * load_lock(const char *ftptr)
RUBY_EXTERN void ruby_init_ext(const char *name, void(*init)(void))
int rb_feature_provided(const char *, const char **)
void rb_exc_raise(VALUE mesg)
static struct st_table * get_loaded_features_index_raw(void)
int st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data_t arg)
VALUE rb_find_file(VALUE)
VALUE rb_file_dirname(VALUE fname)
void rb_provide(const char *)
void rb_ary_free(VALUE ary)
VALUE rb_iseq_new_top(NODE *node, VALUE name, VALUE path, VALUE absolute_path, VALUE parent)
#define RUBY_DTRACE_REQUIRE_RETURN_ENABLED()
VALUE rb_ary_cat(VALUE ary, const VALUE *ptr, long len)
#define StringValuePtr(v)
#define RUBY_DTRACE_LOAD_RETURN(arg0, arg1, arg2)
char * ruby_strdup(const char *)
VALUE rb_get_path_check_convert(VALUE, VALUE, int)
VALUE rb_ary_replace(VALUE copy, VALUE orig)
static VALUE load_path_getter(ID id, rb_vm_t *vm)
#define RARRAY_AREF(a, i)
#define StringValueCStr(v)
static VALUE loaded_feature_path(const char *name, long vlen, const char *feature, long len, int type, VALUE load_path)
VALUE load_path_check_cache
VALUE rb_str_cat2(VALUE, const char *)
static int release_thread_shield(st_data_t *key, st_data_t *value, st_data_t done, int existing)
void rb_ary_store(VALUE ary, long idx, VALUE val)
void rb_gvar_readonly_setter(VALUE val, ID id, void *data, struct rb_global_variable *gvar)
VALUE rb_thread_shield_wait(VALUE self)
VALUE rb_str_freeze(VALUE)
static VALUE rb_f_autoload(VALUE obj, VALUE sym, VALUE file)
VALUE rb_thread_shield_release(VALUE self)
#define RUBY_FUNC_EXPORTED
unsigned char buf[MIME_BUF_SIZE]
int rb_provided(const char *)
static st_table * get_loading_table(void)
VALUE rb_file_absolute_path(VALUE, VALUE)
VALUE rb_vm_call_cfunc(VALUE recv, VALUE(*func)(VALUE), VALUE arg, const rb_block_t *blockptr, VALUE filename)
VALUE rb_str_resize(VALUE, long)
VALUE rb_thread_shield_destroy(VALUE self)
int st_foreach(st_table *, int(*)(ANYARGS), st_data_t)
VALUE rb_obj_clone(VALUE)
static VALUE load_path_getcwd(void)
VALUE rb_f_require(VALUE, VALUE)
void rb_gc_register_mark_object(VALUE)
static void rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
int st_get_key(st_table *, st_data_t, st_data_t *)
static int loaded_feature_path_i(st_data_t v, st_data_t b, st_data_t f)
static VALUE rb_mod_autoload_p(VALUE mod, VALUE sym)
VALUE rb_iseq_eval(VALUE iseqval)
void rb_set_safe_level_force(int)
char * strchr(char *, char)
void rb_extend_object(VALUE obj, VALUE module)
static VALUE rb_f_load(int argc, VALUE *argv)
static st_table * get_loaded_features_index(void)
void * dln_load(const char *file)
#define RUBY_DTRACE_FIND_REQUIRE_RETURN(arg0, arg1, arg2)
#define MEMCPY(p1, p2, type, n)
#define NEW_MEMO(a, b, c)
static void features_index_add_single(VALUE short_feature, VALUE offset)
RUBY_EXTERN VALUE rb_stderr
VALUE rb_realpath_internal(VALUE basedir, VALUE path, int strict)
static VALUE rb_mod_autoload(VALUE mod, VALUE sym, VALUE file)
VALUE rb_module_new(void)
int mild_compile_error
Thread-local state of compiling context.
VALUE rb_thread_shield_new(void)
static void rb_construct_expanded_load_path(int type, int *has_relative, int *has_non_cache)
int st_insert(st_table *, st_data_t, st_data_t)
void rb_define_virtual_variable(const char *, VALUE(*)(ANYARGS), void(*)(ANYARGS))
VALUE loaded_features_snapshot
#define RUBY_DTRACE_REQUIRE_RETURN(arg0, arg1, arg2)
static int search_required(VALUE fname, volatile VALUE *path, int safe_level)
VALUE rb_class_real(VALUE)
static void load_failed(VALUE fname)
void rb_warning(const char *fmt,...)
VALUE rb_current_realfilepath(void)
static VALUE rb_f_autoload_p(VALUE obj, VALUE sym)
VALUE rb_get_path_check_to_string(VALUE, int)
#define SPECIAL_CONST_P(x)
ID rb_intern2(const char *name, long len)
VALUE rb_filesystem_str_new_cstr(const char *)
static void load_unlock(const char *ftptr, int done)
void rb_load_protect(VALUE, int, int *)
void rb_vm_jump_tag_but_local_jump(int state)
static rb_thread_t * GET_THREAD(void)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
void rb_warn(const char *fmt,...)
char * strrchr(const char *, const char)
void rb_alias_variable(ID, ID)
void rb_autoload(VALUE, ID, const char *)