mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
compose HFS file names
* dir.c (glob_helper): compose HFS file names from UTF8-MAC. [ruby-core:48745] [Bug #7267] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39821 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
353cd01e2f
commit
29dc980e65
3 changed files with 87 additions and 2 deletions
|
@ -1,3 +1,8 @@
|
|||
Tue Mar 19 17:06:50 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* dir.c (glob_helper): compose HFS file names from UTF8-MAC.
|
||||
[ruby-core:48745] [Bug #7267]
|
||||
|
||||
Sat Mar 16 01:44:29 2013 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||
|
||||
* internal.h: added a declaration of ruby_kill().
|
||||
|
|
66
dir.c
66
dir.c
|
@ -79,6 +79,49 @@ char *strchr(char*,char);
|
|||
#define opendir(p) rb_w32_uopendir(p)
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
# define HAVE_HFS 1
|
||||
#else
|
||||
# define HAVE_HFS 0
|
||||
#endif
|
||||
#if HAVE_HFS
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
rb_encoding *
|
||||
rb_utf8mac_encoding(void)
|
||||
{
|
||||
static rb_encoding *utf8mac;
|
||||
if (!utf8mac) utf8mac = rb_enc_find("UTF8-MAC");
|
||||
return utf8mac;
|
||||
}
|
||||
|
||||
static inline int
|
||||
is_hfs(const char *path)
|
||||
{
|
||||
struct statfs buf;
|
||||
if (statfs(path, &buf) == 0) {
|
||||
return buf.f_type == 17; /* HFS on darwin */
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static inline int
|
||||
has_nonascii(const char *ptr, size_t len)
|
||||
{
|
||||
while (len > 0) {
|
||||
if (!ISASCII(*ptr)) return 1;
|
||||
ptr++;
|
||||
--len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
# define IF_HAVE_HFS(something) something
|
||||
#else
|
||||
# define IF_HAVE_HFS(something) /* nothing */
|
||||
#endif
|
||||
|
||||
#define FNM_NOESCAPE 0x01
|
||||
#define FNM_PATHNAME 0x02
|
||||
#define FNM_DOTMATCH 0x04
|
||||
|
@ -1377,12 +1420,17 @@ glob_helper(
|
|||
struct dirent *dp;
|
||||
DIR *dirp;
|
||||
IF_HAVE_READDIR_R(DEFINE_STRUCT_DIRENT entry);
|
||||
IF_HAVE_HFS(int hfs_p);
|
||||
dirp = do_opendir(*path ? path : ".", flags, enc);
|
||||
if (dirp == NULL) return 0;
|
||||
IF_HAVE_HFS(hfs_p = is_hfs(*path ? path : "."));
|
||||
|
||||
while (READDIR(dirp, enc, &STRUCT_DIRENT(entry), dp)) {
|
||||
char *buf;
|
||||
enum answer new_isdir = UNKNOWN;
|
||||
const char *name;
|
||||
size_t namlen;
|
||||
IF_HAVE_HFS(VALUE utf8str = Qnil);
|
||||
|
||||
if (recursive && dp->d_name[0] == '.') {
|
||||
/* RECURSIVE never match dot files unless FNM_DOTMATCH is set */
|
||||
|
@ -1393,11 +1441,25 @@ glob_helper(
|
|||
if (dp->d_name[1] == '.' && !dp->d_name[2]) continue;
|
||||
}
|
||||
|
||||
buf = join_path(path, pathlen, dirsep, dp->d_name, NAMLEN(dp));
|
||||
name = dp->d_name;
|
||||
namlen = NAMLEN(dp);
|
||||
# if HAVE_HFS
|
||||
if (hfs_p && has_nonascii(name, namlen)) {
|
||||
rb_encoding *utf8mac = rb_utf8mac_encoding();
|
||||
if (utf8mac) {
|
||||
utf8str = rb_str_conv_enc(rb_str_new(name, namlen),
|
||||
utf8mac, rb_utf8_encoding());
|
||||
RSTRING_GETMEM(utf8str, name, namlen);
|
||||
}
|
||||
}
|
||||
# endif
|
||||
buf = join_path(path, pathlen, dirsep, name, namlen);
|
||||
IF_HAVE_HFS(if (!NIL_P(utf8str)) rb_str_resize(utf8str, 0));
|
||||
if (!buf) {
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
name = buf + pathlen + (dirsep != 0);
|
||||
if (recursive) {
|
||||
#ifndef _WIN32
|
||||
if (do_lstat(buf, &st, flags) == 0)
|
||||
|
@ -1424,7 +1486,7 @@ glob_helper(
|
|||
p = p->next; /* 0 times recursion */
|
||||
}
|
||||
if (p->type == PLAIN || p->type == MAGICAL) {
|
||||
if (fnmatch(p->str, enc, dp->d_name, flags) == 0)
|
||||
if (fnmatch(p->str, enc, name, flags) == 0)
|
||||
*new_end++ = p->next;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -269,4 +269,22 @@ class TestDir_M17N < Test::Unit::TestCase
|
|||
m = Class.new {define_method(:to_path) {d}}
|
||||
assert_raise(Encoding::CompatibilityError) {Dir.glob(m.new)}
|
||||
end
|
||||
|
||||
def test_glob_compose
|
||||
bug7267 = '[ruby-core:48745] [Bug #7267]'
|
||||
|
||||
pp = Object.new.extend(Test::Unit::Assertions)
|
||||
def pp.mu_pp(str) #:nodoc:
|
||||
str.dump
|
||||
end
|
||||
|
||||
with_tmpdir {|d|
|
||||
orig = %W"d\u{e9}tente x\u{304c 304e 3050 3052 3054}"
|
||||
orig.each {|n| open(n, "w") {}}
|
||||
orig.each do |o|
|
||||
n = Dir.glob("#{o[0..0]}*")[0]
|
||||
pp.assert_equal(o, n, bug7267)
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue