mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Clarify and explain loaded_feature_path and rb_feature_p
* load.c (loaded_feature_path): clarify and briefly comment function. These clarifications have no effect on the behavior of the function. * load.c (rb_feature_p): explain the search loop. Especially useful because the logic is complicated as described in the second paragraph. Patch by Greg Price. [ruby-core:47970] [Bug #7158] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37477 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
9bb55f7633
commit
4d414c9f68
2 changed files with 53 additions and 12 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
Mon Nov 5 23:21:14 2012 Greg Price <price@mit.edu>
|
||||||
|
|
||||||
|
* load.c (loaded_feature_path): clarify and briefly comment
|
||||||
|
function. These clarifications have no effect on the behavior
|
||||||
|
of the function.
|
||||||
|
|
||||||
|
* load.c (rb_feature_p): explain the search loop. Especially
|
||||||
|
useful because the logic is complicated as described in the
|
||||||
|
second paragraph.
|
||||||
|
Patch by Greg Price.
|
||||||
|
[ruby-core:47970] [Bug #7158]
|
||||||
|
|
||||||
Mon Nov 5 22:45:03 2012 Hiroshi Shirosaki <h.shirosaki@gmail.com>
|
Mon Nov 5 22:45:03 2012 Hiroshi Shirosaki <h.shirosaki@gmail.com>
|
||||||
|
|
||||||
* ext/dl/win32/lib/Win32API.rb (Win32API#call): use 64bit pointer for x64
|
* ext/dl/win32/lib/Win32API.rb (Win32API#call): use 64bit pointer for x64
|
||||||
|
|
53
load.c
53
load.c
|
@ -69,6 +69,17 @@ get_loading_table(void)
|
||||||
return GET_VM()->loading_table;
|
return GET_VM()->loading_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This searches `load_path` for a value such that
|
||||||
|
name == "#{load_path[i]}/#{feature}"
|
||||||
|
if `feature` is a suffix of `name`, or otherwise
|
||||||
|
name == "#{load_path[i]}/#{feature}#{ext}"
|
||||||
|
for an acceptable string `ext`. It returns
|
||||||
|
`load_path[i].to_str` if found, else 0.
|
||||||
|
|
||||||
|
If type is 's', then `ext` is acceptable only if IS_DLEXT(ext);
|
||||||
|
if 'r', then only if IS_RBEXT(ext); otherwise `ext` may be absent
|
||||||
|
or have any value matching `%r{^\.[^./]*$}`.
|
||||||
|
*/
|
||||||
static VALUE
|
static VALUE
|
||||||
loaded_feature_path(const char *name, long vlen, const char *feature, long len,
|
loaded_feature_path(const char *name, long vlen, const char *feature, long len,
|
||||||
int type, VALUE load_path)
|
int type, VALUE load_path)
|
||||||
|
@ -77,7 +88,7 @@ loaded_feature_path(const char *name, long vlen, const char *feature, long len,
|
||||||
long plen;
|
long plen;
|
||||||
const char *e;
|
const char *e;
|
||||||
|
|
||||||
if (vlen < len) return 0;
|
if (vlen < len+1) return 0
|
||||||
if (!strncmp(name+(vlen-len), feature, len)) {
|
if (!strncmp(name+(vlen-len), feature, len)) {
|
||||||
plen = vlen - len - 1;
|
plen = vlen - len - 1;
|
||||||
}
|
}
|
||||||
|
@ -89,23 +100,22 @@ loaded_feature_path(const char *name, long vlen, const char *feature, long len,
|
||||||
return 0;
|
return 0;
|
||||||
plen = e - name - len - 1;
|
plen = e - name - len - 1;
|
||||||
}
|
}
|
||||||
|
if (type == 's' && !IS_DLEXT(&name[plen+len+1])
|
||||||
|
|| type == 'r' && !IS_RBEXT(&name[plen+len+1])
|
||||||
|
|| name[plen] != '/') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* Now name == "#{prefix}/#{feature}#{ext}" where ext is acceptable
|
||||||
|
(possibly empty) and prefix is some string of length plen. */
|
||||||
|
|
||||||
for (i = 0; i < RARRAY_LEN(load_path); ++i) {
|
for (i = 0; i < RARRAY_LEN(load_path); ++i) {
|
||||||
VALUE p = RARRAY_PTR(load_path)[i];
|
VALUE p = RARRAY_PTR(load_path)[i];
|
||||||
const char *s = StringValuePtr(p);
|
const char *s = StringValuePtr(p);
|
||||||
long n = RSTRING_LEN(p);
|
long n = RSTRING_LEN(p);
|
||||||
|
|
||||||
if (n != plen) continue;
|
if (n != plen) continue;
|
||||||
if (n && (strncmp(name, s, n) || name[n] != '/')) continue;
|
if (n && strncmp(name, s, n)) continue;
|
||||||
switch (type) {
|
return p;
|
||||||
case 's':
|
|
||||||
if (IS_DLEXT(&name[n+len+1])) return p;
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
if (IS_RBEXT(&name[n+len+1])) return p;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -153,6 +163,25 @@ rb_feature_p(const char *feature, const char *ext, int rb, int expanded, const c
|
||||||
}
|
}
|
||||||
features = get_loaded_features();
|
features = get_loaded_features();
|
||||||
for (i = 0; i < RARRAY_LEN(features); ++i) {
|
for (i = 0; i < RARRAY_LEN(features); ++i) {
|
||||||
|
/* This loop searches `features` for an entry such that either
|
||||||
|
"#{features[i]}" == "#{load_path[j]}/#{feature}#{e}"
|
||||||
|
for some j, or
|
||||||
|
"#{features[i]}" == "#{feature}#{e}"
|
||||||
|
Here `e` is an "allowed" extension -- either empty or one
|
||||||
|
of the extensions accepted by IS_RBEXT, IS_SOEXT, or
|
||||||
|
IS_DLEXT. Further, if `ext && rb` then `IS_RBEXT(e)`,
|
||||||
|
and if `ext && !rb` then `IS_SOEXT(e) || IS_DLEXT(e)`.
|
||||||
|
|
||||||
|
If `expanded`, then only the latter form (without
|
||||||
|
load_path[j]) is accepted. Otherwise either form is
|
||||||
|
accepted, *unless* `ext` is false and an otherwise-matching
|
||||||
|
entry of the first form is preceded by an entry of the form
|
||||||
|
"#{features[i2]}" == "#{load_path[j2]}/#{feature}#{e2}"
|
||||||
|
where `e2` matches /^\.[^./]*$/ but is not an allowed extension.
|
||||||
|
After a "distractor" entry of this form, only entries of the
|
||||||
|
form "#{feature}#{e}" are accepted.
|
||||||
|
*/
|
||||||
|
|
||||||
v = RARRAY_PTR(features)[i];
|
v = RARRAY_PTR(features)[i];
|
||||||
f = StringValuePtr(v);
|
f = StringValuePtr(v);
|
||||||
if ((n = RSTRING_LEN(v)) < len) continue;
|
if ((n = RSTRING_LEN(v)) < len) continue;
|
||||||
|
|
Loading…
Add table
Reference in a new issue