merge revision(s) 49528:

dir.c: preserve encoding

	* dir.c (sys_enc_warning_in): preserve encoding of path name in
  warning messages.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_2@49665 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
naruse 2015-02-20 08:39:10 +00:00
parent a712ced7cb
commit e896f10487
3 changed files with 85 additions and 13 deletions

52
dir.c
View file

@ -1081,16 +1081,45 @@ dir_s_rmdir(VALUE obj, VALUE dir)
return INT2FIX(0); return INT2FIX(0);
} }
struct warning_args {
#ifdef RUBY_FUNCTION_NAME_STRING
const char *func;
#endif
const char *mesg;
rb_encoding *enc;
};
#ifndef RUBY_FUNCTION_NAME_STRING
#define sys_enc_warning_in(func, mesg, enc) sys_enc_warning(mesg, enc)
#endif
static VALUE static VALUE
sys_warning_1(VALUE mesg) sys_warning_1(VALUE mesg)
{ {
rb_sys_warning("%s", (const char *)mesg); const struct warning_args *arg = (struct warning_args *)mesg;
#ifdef RUBY_FUNCTION_NAME_STRING
rb_sys_enc_warning(arg->enc, "%s: %s", arg->func, arg->mesg);
#else
rb_sys_enc_warning(arg->enc, "%s", arg->mesg);
#endif
return Qnil; return Qnil;
} }
static void
sys_enc_warning_in(const char *func, const char *mesg, rb_encoding *enc)
{
struct warning_args arg;
#ifdef RUBY_FUNCTION_NAME_STRING
arg.func = func;
#endif
arg.mesg = mesg;
arg.enc = enc;
rb_protect(sys_warning_1, (VALUE)&arg, 0);
}
#define GLOB_VERBOSE (1U << (sizeof(int) * CHAR_BIT - 1)) #define GLOB_VERBOSE (1U << (sizeof(int) * CHAR_BIT - 1))
#define sys_warning(val) \ #define sys_warning(val, enc) \
(void)((flags & GLOB_VERBOSE) && rb_protect(sys_warning_1, (VALUE)(val), 0)) ((flags & GLOB_VERBOSE) ? sys_enc_warning_in(RUBY_FUNCTION_NAME_STRING, (val), (enc)) :(void)0)
#define GLOB_ALLOC(type) ((type *)malloc(sizeof(type))) #define GLOB_ALLOC(type) ((type *)malloc(sizeof(type)))
#define GLOB_ALLOC_N(type, n) ((type *)malloc(sizeof(type) * (n))) #define GLOB_ALLOC_N(type, n) ((type *)malloc(sizeof(type) * (n)))
@ -1112,23 +1141,22 @@ sys_warning_1(VALUE mesg)
/* System call with warning */ /* System call with warning */
static int static int
do_stat(const char *path, struct stat *pst, int flags) do_stat(const char *path, struct stat *pst, int flags, rb_encoding *enc)
{ {
int ret = STAT(path, pst); int ret = STAT(path, pst);
if (ret < 0 && !to_be_ignored(errno)) if (ret < 0 && !to_be_ignored(errno))
sys_warning(path); sys_warning(path, enc);
return ret; return ret;
} }
#if defined HAVE_LSTAT || defined lstat #if defined HAVE_LSTAT || defined lstat
static int static int
do_lstat(const char *path, struct stat *pst, int flags) do_lstat(const char *path, struct stat *pst, int flags, rb_encoding *enc)
{ {
int ret = lstat(path, pst); int ret = lstat(path, pst);
if (ret < 0 && !to_be_ignored(errno)) if (ret < 0 && !to_be_ignored(errno))
sys_warning(path); sys_warning(path, enc);
return ret; return ret;
} }
@ -1152,7 +1180,7 @@ do_opendir(const char *path, int flags, rb_encoding *enc)
#endif #endif
dirp = opendir(path); dirp = opendir(path);
if (dirp == NULL && !to_be_ignored(errno)) if (dirp == NULL && !to_be_ignored(errno))
sys_warning(path); sys_warning(path, enc);
#ifdef _WIN32 #ifdef _WIN32
if (tmp) rb_str_resize(tmp, 0); /* GC guard */ if (tmp) rb_str_resize(tmp, 0); /* GC guard */
#endif #endif
@ -1551,7 +1579,7 @@ glob_helper(
pathlen = strlen(path); pathlen = strlen(path);
if (*path) { if (*path) {
if (match_all && exist == UNKNOWN) { if (match_all && exist == UNKNOWN) {
if (do_lstat(path, &st, flags) == 0) { if (do_lstat(path, &st, flags, enc) == 0) {
exist = YES; exist = YES;
isdir = S_ISDIR(st.st_mode) ? YES : S_ISLNK(st.st_mode) ? UNKNOWN : NO; isdir = S_ISDIR(st.st_mode) ? YES : S_ISLNK(st.st_mode) ? UNKNOWN : NO;
} }
@ -1561,7 +1589,7 @@ glob_helper(
} }
} }
if (match_dir && isdir == UNKNOWN) { if (match_dir && isdir == UNKNOWN) {
if (do_stat(path, &st, flags) == 0) { if (do_stat(path, &st, flags, enc) == 0) {
exist = YES; exist = YES;
isdir = S_ISDIR(st.st_mode) ? YES : NO; isdir = S_ISDIR(st.st_mode) ? YES : NO;
} }
@ -1663,7 +1691,7 @@ glob_helper(
if (recursive && dotfile < ((flags & FNM_DOTMATCH) ? 2 : 1)) { if (recursive && dotfile < ((flags & FNM_DOTMATCH) ? 2 : 1)) {
/* RECURSIVE never match dot files unless FNM_DOTMATCH is set */ /* RECURSIVE never match dot files unless FNM_DOTMATCH is set */
#ifndef _WIN32 #ifndef _WIN32
if (do_lstat(buf, &st, flags) == 0) if (do_lstat(buf, &st, flags, enc) == 0)
new_isdir = S_ISDIR(st.st_mode) ? YES : S_ISLNK(st.st_mode) ? UNKNOWN : NO; new_isdir = S_ISDIR(st.st_mode) ? YES : S_ISLNK(st.st_mode) ? UNKNOWN : NO;
else else
new_isdir = NO; new_isdir = NO;

View file

@ -303,6 +303,50 @@ class TestDir_M17N < Test::Unit::TestCase
} }
end end
def with_enc_path
with_tmpdir do |d|
names = %W"\u{391 392 393 394 395} \u{3042 3044 3046 3048 304a}"
names.each do |dir|
Dir.mkdir(dir) rescue next
begin
yield(dir)
ensure
File.chmod(0700, dir)
end
end
end
end
def test_glob_warning_opendir
with_enc_path do |dir|
open("#{dir}/x", "w") {}
File.chmod(0300, dir)
assert_warning(/#{dir}/) do
Dir.glob("#{dir}/*")
end
end
end
def test_glob_warning_match_all
with_enc_path do |dir|
open("#{dir}/x", "w") {}
File.chmod(0000, dir)
assert_warning(/#{dir}/) do
Dir.glob("#{dir}/x")
end
end
end
def test_glob_warning_match_dir
with_enc_path do |dir|
Dir.mkdir("#{dir}/x")
File.chmod(0000, dir)
assert_warning(/#{dir}/) do
Dir.glob("#{dir}/x/")
end
end
end
def test_entries_compose def test_entries_compose
bug7267 = '[ruby-core:48745] [Bug #7267]' bug7267 = '[ruby-core:48745] [Bug #7267]'

View file

@ -1,6 +1,6 @@
#define RUBY_VERSION "2.2.0" #define RUBY_VERSION "2.2.0"
#define RUBY_RELEASE_DATE "2015-02-20" #define RUBY_RELEASE_DATE "2015-02-20"
#define RUBY_PATCHLEVEL 66 #define RUBY_PATCHLEVEL 67
#define RUBY_RELEASE_YEAR 2015 #define RUBY_RELEASE_YEAR 2015
#define RUBY_RELEASE_MONTH 2 #define RUBY_RELEASE_MONTH 2