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)
62 VALUE path, as_str, expanded_path;
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 (!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__
686 VALUE fname, wrap, path;
728 return (
char *)ftptr;
732 void (*init)(void) = (
void (*)(void))memo->nd_cfnc;
739 rb_warning(
"loading in progress, circular require considered harmful - %s", ftptr);
750 return (
char *)ftptr;
849 if (ext && !
strchr(ext,
'/')) {
910 goto statically_linked;
926 return type ?
's' :
'r';
952 char *
volatile ftptr = 0;
1018 if (
NIL_P(result)) {
1044 const char *
name = (
char *)*key;
1047 rb_warn(
"%s is already registered", name);
1161 #define rb_intern(str) rb_intern2((str), strlen(str))
1163 static const char var_load_path[] =
"$:";
1164 ID id_load_path =
rb_intern2(var_load_path,
sizeof(var_load_path)-1);