* file.c (rb_file_expand_path_internal): drop characters ignored
  by filesystem on Mac OS X.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48991 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2014-12-25 07:01:22 +00:00
Родитель 0ebfc6f216
Коммит f0806c4863
3 изменённых файлов: 86 добавлений и 11 удалений

Просмотреть файл

@ -1,3 +1,8 @@
Thu Dec 25 16:01:19 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* file.c (rb_file_expand_path_internal): drop characters ignored
by filesystem on Mac OS X.
Thu Dec 25 15:36:15 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* dir.c (replace_real_basename): get the real name and replace the

78
file.c
Просмотреть файл

@ -315,6 +315,38 @@ rb_str_normalize_ospath(const char *ptr, long len)
return str;
}
static int
ignored_char_p(const char *p, const char *e, rb_encoding *enc)
{
unsigned char c;
if (p+3 > e) return 0;
switch ((unsigned char)*p) {
case 0xe2:
switch ((unsigned char)p[1]) {
case 0x80:
c = (unsigned char)p[2];
/* c >= 0x200c && c <= 0x200f */
if (c >= 0x8c && c <= 0x8f) return 3;
/* c >= 0x202a && c <= 0x202e */
if (c >= 0xaa && c <= 0xae) return 3;
return 0;
case 0x81:
c = (unsigned char)p[2];
/* c >= 0x206a && c <= 0x206f */
if (c >= 0xaa && c <= 0xaf) return 3;
return 0;
}
break;
case 0xef:
/* c == 0xfeff */
if ((unsigned char)p[1] == 0xbb &&
(unsigned char)p[2] == 0xbf)
return 3;
break;
}
return 0;
}
#endif
static long
@ -3103,6 +3135,27 @@ ntfs_tail(const char *path, const char *end, rb_encoding *enc)
buflen = RSTRING_LEN(result),\
pend = p + buflen)
#ifdef __APPLE__
# define SKIPPATHSEP(p) ((*(p)) ? 1 : 0)
#else
# define SKIPPATHSEP(p) 1
#endif
#define BUFCOPY(srcptr, srclen) do { \
const int skip = SKIPPATHSEP(p); \
rb_str_set_len(result, p-buf+skip); \
BUFCHECK(bdiff + ((srclen)+skip) >= buflen); \
p += skip; \
memcpy(p, (srcptr), (srclen)); \
p += (srclen); \
} while (0)
#define WITH_ROOTDIFF(stmt) do { \
long rootdiff = root - buf; \
stmt; \
root = buf + rootdiff; \
} while (0)
static VALUE
copy_home_path(VALUE result, const char *dir)
{
@ -3374,17 +3427,25 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
case '\\':
#endif
if (s > b) {
long rootdiff = root - buf;
rb_str_set_len(result, p-buf+1);
BUFCHECK(bdiff + (s-b+1) >= buflen);
root = buf + rootdiff;
memcpy(++p, b, s-b);
p += s-b;
WITH_ROOTDIFF(BUFCOPY(b, s-b));
*p = '/';
}
b = ++s;
break;
default:
#ifdef __APPLE__
{
int n = ignored_char_p(s, fend, enc);
if (n) {
if (s > b) {
WITH_ROOTDIFF(BUFCOPY(b, s-b));
*p = '\0';
}
b = s += n;
break;
}
}
#endif
Inc(s, fend, enc);
break;
}
@ -3406,10 +3467,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
}
}
#endif
rb_str_set_len(result, p-buf+1);
BUFCHECK(bdiff + (s-b) >= buflen);
memcpy(++p, b, s-b);
p += s-b;
BUFCOPY(b, s-b);
rb_str_set_len(result, p-buf);
}
if (p == skiproot(buf, p + !!*p, enc) - 1) p++;

Просмотреть файл

@ -440,13 +440,25 @@ class TestFileExhaustive < Test::Unit::TestCase
def test_expand_path
assert_equal(@file, File.expand_path(File.basename(@file), File.dirname(@file)))
if /cygwin|mingw|mswin|bccwin/ =~ RUBY_PLATFORM
case RUBY_PLATFORM
when /cygwin|mingw|mswin|bccwin/
assert_equal(@file, File.expand_path(@file + " "))
assert_equal(@file, File.expand_path(@file + "."))
assert_equal(@file, File.expand_path(@file + "::$DATA"))
assert_match(/\Ac:\//i, File.expand_path('c:'), '[ruby-core:31591]')
assert_match(/\Ac:\//i, File.expand_path('c:foo', 'd:/bar'))
assert_match(%r'\Ac:/bar/foo\z'i, File.expand_path('c:foo', 'c:/bar'))
when /darwin/
["\u{feff}", *"\u{2000}"..."\u{2100}"].each do |c|
file = @file + c
begin
open(file) {}
rescue
assert_equal(file, File.expand_path(file), c.dump)
else
assert_equal(@file, File.expand_path(file), c.dump)
end
end
end
if DRIVE
assert_match(%r"\Az:/foo\z"i, File.expand_path('/foo', "z:/bar"))