summaryrefslogtreecommitdiff
path: root/file.c
diff options
context:
space:
mode:
authorluislavena <luislavena@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-08-24 03:44:56 +0000
committerluislavena <luislavena@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-08-24 03:44:56 +0000
commit86df08dac6fc4642a6bac7bab6ccd5f44b7a293c (patch)
tree8629b0ba3bf876488b74145b455e85cbd030e469 /file.c
parentd212a89c380683490dc735c770855f08391540a1 (diff)
Improve require/File.expand_path performance on Windows
* configure.in (mingw): add shlwapi to the list of dependency libs for Windows. * win32/Makefile.sub (EXTSOLIBS): ditto. * internal.h: declare internal functions rb_w32_init_file, rb_file_expand_path_internal and rb_file_expand_path_fast. * file.c (Init_File): invoke Windows initialization rb_w32_init_file * win32/file.c (rb_file_load_path_internal): new function. Windows-specific implementation that replaces file_expand_path. [Bug #6836][ruby-core:46996] * win32/file.c (rb_w32_init_file): new function. Initialize codepage cache for faster conversion encodings lookup. * file.c (file_expand_path): rename to rb_file_expand_path_internal. Conditionally exclude from Windows. * file.c (rb_file_expand_path_fast): new function. delegates to rb_file_expand_path_internal without performing a hit to the filesystem. * file.c (file_expand_path_1): use rb_file_expand_path_internal without path expansion (used by require). * file.c (rb_find_file_ext_safe): ditto. * file.c (rb_find_file_safe): ditto. * load.c (rb_get_expanded_load_path): use rb_file_expand_path_fast. * load.c (rb_feature_provided): ditto. * file.c (rb_file_expand_path): use rb_file_expand_path_internal with path expansion. * file.c (rb_file_absolute_path): ditto. * test/ruby/test_file_exhaustive.rb: new tests to exercise rb_file_expand_path_internal implementation and compliance with existing behaviors. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36811 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'file.c')
-rw-r--r--file.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/file.c b/file.c
index 24aa1115fe..8c63f56d01 100644
--- a/file.c
+++ b/file.c
@@ -2882,8 +2882,9 @@ append_fspath(VALUE result, VALUE fname, char *dir, rb_encoding **enc, rb_encodi
return buf + dirlen;
}
-static VALUE
-file_expand_path(VALUE fname, VALUE dname, int abs_mode, VALUE result)
+#ifndef _WIN32
+VALUE
+rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_name, VALUE result)
{
const char *s, *b, *fend;
char *buf, *p, *pend, *root;
@@ -2945,7 +2946,7 @@ file_expand_path(VALUE fname, VALUE dname, int abs_mode, VALUE result)
/* specified drive, but not full path */
int same = 0;
if (!NIL_P(dname) && !not_same_drive(dname, s[0])) {
- file_expand_path(dname, Qnil, abs_mode, result);
+ rb_file_expand_path_internal(dname, Qnil, abs_mode, long_name, result);
BUFINIT();
if (has_drive_letter(p) && TOLOWER(p[0]) == TOLOWER(s[0])) {
/* ok, same drive */
@@ -2969,7 +2970,7 @@ file_expand_path(VALUE fname, VALUE dname, int abs_mode, VALUE result)
#endif
else if (!rb_is_absolute_path(s)) {
if (!NIL_P(dname)) {
- file_expand_path(dname, Qnil, abs_mode, result);
+ rb_file_expand_path_internal(dname, Qnil, abs_mode, long_name, result);
rb_enc_associate(result, rb_enc_check(result, fname));
BUFINIT();
p = pend;
@@ -3222,6 +3223,7 @@ file_expand_path(VALUE fname, VALUE dname, int abs_mode, VALUE result)
ENC_CODERANGE_CLEAR(result);
return result;
}
+#endif /* _WIN32 */
#define EXPAND_PATH_BUFFER() rb_usascii_str_new(0, MAXPATHLEN + 2)
@@ -3232,14 +3234,21 @@ file_expand_path(VALUE fname, VALUE dname, int abs_mode, VALUE result)
static VALUE
file_expand_path_1(VALUE fname)
{
- return file_expand_path(fname, Qnil, 0, EXPAND_PATH_BUFFER());
+ return rb_file_expand_path_internal(fname, Qnil, 0, 0, EXPAND_PATH_BUFFER());
}
VALUE
rb_file_expand_path(VALUE fname, VALUE dname)
{
check_expand_path_args(fname, dname);
- return file_expand_path(fname, dname, 0, EXPAND_PATH_BUFFER());
+ return rb_file_expand_path_internal(fname, dname, 0, 1, EXPAND_PATH_BUFFER());
+}
+
+VALUE
+rb_file_expand_path_fast(VALUE fname, VALUE dname)
+{
+ check_expand_path_args(fname, dname);
+ return rb_file_expand_path_internal(fname, dname, 0, 0, EXPAND_PATH_BUFFER());
}
/*
@@ -3276,7 +3285,7 @@ VALUE
rb_file_absolute_path(VALUE fname, VALUE dname)
{
check_expand_path_args(fname, dname);
- return file_expand_path(fname, dname, 1, EXPAND_PATH_BUFFER());
+ return rb_file_expand_path_internal(fname, dname, 1, 1, EXPAND_PATH_BUFFER());
}
/*
@@ -5251,7 +5260,7 @@ rb_find_file_ext_safe(VALUE *filep, const char *const *ext, int safe_level)
RB_GC_GUARD(str) = rb_get_path_check(str, safe_level);
if (RSTRING_LEN(str) == 0) continue;
- file_expand_path(fname, str, 0, tmp);
+ rb_file_expand_path_internal(fname, str, 0, 0, tmp);
if (rb_file_load_ok(RSTRING_PTR(tmp))) {
*filep = copy_path_class(tmp, *filep);
return (int)(j+1);
@@ -5311,7 +5320,7 @@ rb_find_file_safe(VALUE path, int safe_level)
VALUE str = RARRAY_PTR(load_path)[i];
RB_GC_GUARD(str) = rb_get_path_check(str, safe_level);
if (RSTRING_LEN(str) > 0) {
- file_expand_path(path, str, 0, tmp);
+ rb_file_expand_path_internal(path, str, 0, 0, tmp);
f = RSTRING_PTR(tmp);
if (rb_file_load_ok(f)) goto found;
}
@@ -5546,4 +5555,8 @@ Init_File(void)
rb_define_method(rb_cStat, "setuid?", rb_stat_suid, 0);
rb_define_method(rb_cStat, "setgid?", rb_stat_sgid, 0);
rb_define_method(rb_cStat, "sticky?", rb_stat_sticky, 0);
+
+#ifdef _WIN32
+ rb_w32_init_file();
+#endif
}