1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

dir.c: NORMALIZE_UTF8PATH

* dir.c (NORMALIZE_UTF8PATH): Unicode decomposition seems to
  perform in an upper layer than file systems on OSX, as all path
  names are always decomposed regardless of file system types.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49166 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2015-01-07 07:51:18 +00:00
parent bc5fd04fd9
commit a921841b48
2 changed files with 29 additions and 38 deletions

View file

@ -1,3 +1,9 @@
Wed Jan 7 16:51:16 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
* dir.c (NORMALIZE_UTF8PATH): Unicode decomposition seems to
perform in an upper layer than file systems on OSX, as all path
names are always decomposed regardless of file system types.
Tue Jan 6 21:41:04 2015 Tanaka Akira <akr@fsij.org> Tue Jan 6 21:41:04 2015 Tanaka Akira <akr@fsij.org>
* time.c (timelocalw): Set tm_isdst field -1 if vtm->isdst is * time.c (timelocalw): Set tm_isdst field -1 if vtm->isdst is

61
dir.c
View file

@ -84,24 +84,17 @@ char *strchr(char*,char);
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
# define HAVE_HFS 1 # define NORMALIZE_UTF8PATH 1
#else #else
# define HAVE_HFS 0 # define NORMALIZE_UTF8PATH 0
#endif #endif
#if HAVE_HFS
#if NORMALIZE_UTF8PATH || USE_NAME_ON_FS
#include <sys/param.h> #include <sys/param.h>
#include <sys/mount.h> #include <sys/mount.h>
#endif
static inline int #if NORMALIZE_UTF8PATH
is_hfs(DIR *dirp)
{
struct statfs buf;
if (fstatfs(dirfd(dirp), &buf) == 0) {
return buf.f_type == 17; /* HFS on darwin */
}
return FALSE;
}
static inline int static inline int
has_nonascii(const char *ptr, size_t len) has_nonascii(const char *ptr, size_t len)
{ {
@ -113,9 +106,9 @@ has_nonascii(const char *ptr, size_t len)
return 0; return 0;
} }
# define IF_HAVE_HFS(something) something # define IF_NORMALIZE_UTF8PATH(something) something
#else #else
# define IF_HAVE_HFS(something) /* nothing */ # define IF_NORMALIZE_UTF8PATH(something) /* nothing */
#endif #endif
#define FNM_NOESCAPE 0x01 #define FNM_NOESCAPE 0x01
@ -658,18 +651,16 @@ dir_each(VALUE dir)
{ {
struct dir_data *dirp; struct dir_data *dirp;
struct dirent *dp; struct dirent *dp;
IF_HAVE_HFS(int hfs_p);
RETURN_ENUMERATOR(dir, 0, 0); RETURN_ENUMERATOR(dir, 0, 0);
GetDIR(dir, dirp); GetDIR(dir, dirp);
rewinddir(dirp->dir); rewinddir(dirp->dir);
IF_HAVE_HFS(hfs_p = is_hfs(dirp->dir));
while ((dp = READDIR(dirp->dir, dirp->enc)) != NULL) { while ((dp = READDIR(dirp->dir, dirp->enc)) != NULL) {
const char *name = dp->d_name; const char *name = dp->d_name;
size_t namlen = NAMLEN(dp); size_t namlen = NAMLEN(dp);
VALUE path; VALUE path;
#if HAVE_HFS #if NORMALIZE_UTF8PATH
if (hfs_p && has_nonascii(name, namlen) && if (has_nonascii(name, namlen) &&
!NIL_P(path = rb_str_normalize_ospath(name, namlen))) { !NIL_P(path = rb_str_normalize_ospath(name, namlen))) {
path = rb_external_str_with_enc(path, dirp->enc); path = rb_external_str_with_enc(path, dirp->enc);
} }
@ -1328,7 +1319,7 @@ join_path(const char *path, long len, int dirsep, const char *name, size_t namle
#ifdef HAVE_GETATTRLIST #ifdef HAVE_GETATTRLIST
static char * static char *
replace_real_basename(char *path, long base, int hfs_p) replace_real_basename(char *path, long base)
{ {
u_int32_t attrbuf[(sizeof(attrreference_t) + MAXPATHLEN * 3 + sizeof(u_int32_t) - 1) / sizeof(u_int32_t) + 1]; u_int32_t attrbuf[(sizeof(attrreference_t) + MAXPATHLEN * 3 + sizeof(u_int32_t) - 1) / sizeof(u_int32_t) + 1];
struct attrlist al = {ATTR_BIT_MAP_COUNT, 0, ATTR_CMN_NAME}; struct attrlist al = {ATTR_BIT_MAP_COUNT, 0, ATTR_CMN_NAME};
@ -1336,7 +1327,7 @@ replace_real_basename(char *path, long base, int hfs_p)
const char *name; const char *name;
long len; long len;
char *tmp; char *tmp;
IF_HAVE_HFS(VALUE utf8str = Qnil); IF_NORMALIZE_UTF8PATH(VALUE utf8str = Qnil);
if (getattrlist(path, &al, attrbuf, sizeof(attrbuf), FSOPT_NOFOLLOW)) if (getattrlist(path, &al, attrbuf, sizeof(attrbuf), FSOPT_NOFOLLOW))
return path; return path;
@ -1346,8 +1337,8 @@ replace_real_basename(char *path, long base, int hfs_p)
if (name + len > (char *)attrbuf + sizeof(attrbuf)) if (name + len > (char *)attrbuf + sizeof(attrbuf))
return path; return path;
# if HAVE_HFS # if NORMALIZE_UTF8PATH
if (hfs_p && has_nonascii(name, len)) { if (has_nonascii(name, len)) {
if (!NIL_P(utf8str = rb_str_normalize_ospath(name, len))) { if (!NIL_P(utf8str = rb_str_normalize_ospath(name, len))) {
RSTRING_GETMEM(utf8str, name, len); RSTRING_GETMEM(utf8str, name, len);
} }
@ -1360,7 +1351,7 @@ replace_real_basename(char *path, long base, int hfs_p)
memcpy(path + base, name, len); memcpy(path + base, name, len);
path[base + len] = '\0'; path[base + len] = '\0';
} }
IF_HAVE_HFS(if (!NIL_P(utf8str)) rb_str_resize(utf8str, 0)); IF_NORMALIZE_UTF8PATH(if (!NIL_P(utf8str)) rb_str_resize(utf8str, 0));
return path; return path;
} }
#endif #endif
@ -1491,7 +1482,6 @@ glob_helper(
# ifdef DOSISH # ifdef DOSISH
char *plainname = 0; char *plainname = 0;
# endif # endif
IF_HAVE_HFS(int hfs_p);
# ifdef DOSISH # ifdef DOSISH
if (cur + 1 == end && (*cur)->type <= ALPHA) { if (cur + 1 == end && (*cur)->type <= ALPHA) {
plainname = join_path(path, pathlen, dirsep, (*cur)->str, strlen((*cur)->str)); plainname = join_path(path, pathlen, dirsep, (*cur)->str, strlen((*cur)->str));
@ -1503,7 +1493,7 @@ glob_helper(
# endif # endif
dirp = do_opendir(*path ? path : ".", flags, enc); dirp = do_opendir(*path ? path : ".", flags, enc);
if (dirp == NULL) { if (dirp == NULL) {
# if FNM_SYSCASE || HAVE_HFS # if FNM_SYSCASE
if ((magical < 2) && !recursive && (errno == EACCES)) { if ((magical < 2) && !recursive && (errno == EACCES)) {
/* no read permission, fallback */ /* no read permission, fallback */
goto literally; goto literally;
@ -1511,13 +1501,8 @@ glob_helper(
# endif # endif
return 0; return 0;
} }
IF_HAVE_HFS(hfs_p = is_hfs(dirp));
# if HAVE_HFS # ifdef __APPLE__
if (!(hfs_p || magical || recursive)) {
closedir(dirp);
goto literally;
}
flags |= FNM_CASEFOLD; flags |= FNM_CASEFOLD;
# endif # endif
while ((dp = READDIR(dirp, enc)) != NULL) { while ((dp = READDIR(dirp, enc)) != NULL) {
@ -1526,7 +1511,7 @@ glob_helper(
const char *name; const char *name;
size_t namlen; size_t namlen;
int dotfile = 0; int dotfile = 0;
IF_HAVE_HFS(VALUE utf8str = Qnil); IF_NORMALIZE_UTF8PATH(VALUE utf8str = Qnil);
if (recursive && dp->d_name[0] == '.') { if (recursive && dp->d_name[0] == '.') {
++dotfile; ++dotfile;
@ -1543,15 +1528,15 @@ glob_helper(
name = dp->d_name; name = dp->d_name;
namlen = NAMLEN(dp); namlen = NAMLEN(dp);
# if HAVE_HFS # if NORMALIZE_UTF8PATH
if (hfs_p && has_nonascii(name, namlen)) { if (has_nonascii(name, namlen)) {
if (!NIL_P(utf8str = rb_str_normalize_ospath(name, namlen))) { if (!NIL_P(utf8str = rb_str_normalize_ospath(name, namlen))) {
RSTRING_GETMEM(utf8str, name, namlen); RSTRING_GETMEM(utf8str, name, namlen);
} }
} }
# endif # endif
buf = join_path(path, pathlen, dirsep, name, namlen); buf = join_path(path, pathlen, dirsep, name, namlen);
IF_HAVE_HFS(if (!NIL_P(utf8str)) rb_str_resize(utf8str, 0)); IF_NORMALIZE_UTF8PATH(if (!NIL_P(utf8str)) rb_str_resize(utf8str, 0));
if (!buf) { if (!buf) {
status = -1; status = -1;
break; break;
@ -1612,7 +1597,7 @@ glob_helper(
else if (plain) { else if (plain) {
struct glob_pattern **copy_beg, **copy_end, **cur2; struct glob_pattern **copy_beg, **copy_end, **cur2;
# if FNM_SYSCASE || HAVE_HFS # if FNM_SYSCASE
literally: literally:
# endif # endif
copy_beg = copy_end = GLOB_ALLOC_N(struct glob_pattern *, end - beg); copy_beg = copy_end = GLOB_ALLOC_N(struct glob_pattern *, end - beg);
@ -1658,7 +1643,7 @@ glob_helper(
#ifdef HAVE_GETATTRLIST #ifdef HAVE_GETATTRLIST
if ((*cur)->type == ALPHA) { if ((*cur)->type == ALPHA) {
long base = pathlen + (dirsep != 0); long base = pathlen + (dirsep != 0);
buf = replace_real_basename(buf, base, IF_HAVE_HFS(1)+0); buf = replace_real_basename(buf, base);
} }
#endif #endif
status = glob_helper(buf, 1, UNKNOWN, UNKNOWN, new_beg, status = glob_helper(buf, 1, UNKNOWN, UNKNOWN, new_beg,