file.c: join with /

* file.c (rb_file_join): join using "/" always, not a constant.
  and fix the document.  [ruby-core:79579] [Bug #13223]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57960 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2017-03-13 09:29:19 +00:00
parent 16e804117c
commit b75f68ab8d
2 changed files with 26 additions and 23 deletions

36
file.c
View File

@ -4359,20 +4359,17 @@ rb_file_s_split(VALUE klass, VALUE path)
return rb_assoc_new(rb_file_dirname(path), rb_file_s_basename(1,&path)); return rb_assoc_new(rb_file_dirname(path), rb_file_s_basename(1,&path));
} }
static VALUE separator; static VALUE rb_file_join(VALUE ary);
static VALUE rb_file_join(VALUE ary, VALUE sep);
static VALUE static VALUE
file_inspect_join(VALUE ary, VALUE argp, int recur) file_inspect_join(VALUE ary, VALUE arg, int recur)
{ {
VALUE *arg = (VALUE *)argp; if (recur || ary == arg) rb_raise(rb_eArgError, "recursive array");
if (recur || ary == arg[0]) rb_raise(rb_eArgError, "recursive array"); return rb_file_join(arg);
return rb_file_join(arg[0], arg[1]);
} }
static VALUE static VALUE
rb_file_join(VALUE ary, VALUE sep) rb_file_join(VALUE ary)
{ {
long len, i; long len, i;
VALUE result, tmp; VALUE result, tmp;
@ -4393,10 +4390,7 @@ rb_file_join(VALUE ary, VALUE sep)
len += 10; len += 10;
} }
} }
if (!NIL_P(sep)) { len += RARRAY_LEN(ary) - 1;
StringValue(sep);
len += RSTRING_LEN(sep) * (RARRAY_LEN(ary) - 1);
}
result = rb_str_buf_new(len); result = rb_str_buf_new(len);
RBASIC_CLEAR_CLASS(result); RBASIC_CLEAR_CLASS(result);
OBJ_INFECT(result, ary); OBJ_INFECT(result, ary);
@ -4412,11 +4406,7 @@ rb_file_join(VALUE ary, VALUE sep)
rb_raise(rb_eArgError, "recursive array"); rb_raise(rb_eArgError, "recursive array");
} }
else { else {
VALUE args[2]; tmp = rb_exec_recursive(file_inspect_join, ary, tmp);
args[0] = tmp;
args[1] = sep;
tmp = rb_exec_recursive(file_inspect_join, ary, (VALUE)args);
} }
break; break;
default: default:
@ -4427,15 +4417,13 @@ rb_file_join(VALUE ary, VALUE sep)
if (i == 0) { if (i == 0) {
rb_enc_copy(result, tmp); rb_enc_copy(result, tmp);
} }
else if (!NIL_P(sep)) { else {
tail = chompdirsep(name, name + len, rb_enc_get(result)); tail = chompdirsep(name, name + len, rb_enc_get(result));
if (RSTRING_PTR(tmp) && isdirsep(RSTRING_PTR(tmp)[0])) { if (RSTRING_PTR(tmp) && isdirsep(RSTRING_PTR(tmp)[0])) {
rb_str_set_len(result, tail - name); rb_str_set_len(result, tail - name);
} }
else if (!*tail) { else if (!*tail) {
enc = rb_enc_check(result, sep); rb_str_cat(result, "/", 1);
rb_str_buf_append(result, sep);
rb_enc_associate(result, enc);
} }
} }
enc = rb_enc_check(result, tmp); enc = rb_enc_check(result, tmp);
@ -4452,7 +4440,7 @@ rb_file_join(VALUE ary, VALUE sep)
* File.join(string, ...) -> string * File.join(string, ...) -> string
* *
* Returns a new string formed by joining the strings using * Returns a new string formed by joining the strings using
* <code>File::SEPARATOR</code>. * <code>"/"</code>.
* *
* File.join("usr", "mail", "gumby") #=> "usr/mail/gumby" * File.join("usr", "mail", "gumby") #=> "usr/mail/gumby"
* *
@ -4461,7 +4449,7 @@ rb_file_join(VALUE ary, VALUE sep)
static VALUE static VALUE
rb_file_s_join(VALUE klass, VALUE args) rb_file_s_join(VALUE klass, VALUE args)
{ {
return rb_file_join(args, separator); return rb_file_join(args);
} }
#if defined(HAVE_TRUNCATE) || defined(HAVE_CHSIZE) #if defined(HAVE_TRUNCATE) || defined(HAVE_CHSIZE)
@ -5954,6 +5942,8 @@ static const char null_device[] =
void void
Init_File(void) Init_File(void)
{ {
VALUE separator;
rb_mFileTest = rb_define_module("FileTest"); rb_mFileTest = rb_define_module("FileTest");
rb_cFile = rb_define_class("File", rb_cIO); rb_cFile = rb_define_class("File", rb_cIO);

View File

@ -1260,6 +1260,19 @@ class TestFileExhaustive < Test::Unit::TestCase
assert_raise(Encoding::CompatibilityError, bug7168) {File.join(names)} assert_raise(Encoding::CompatibilityError, bug7168) {File.join(names)}
end end
def test_join_with_changed_separator
assert_separately([], "#{<<~"begin;"}\n#{<<~"end;"}")
bug = '[ruby-core:79579] [Bug #13223]'
begin;
class File
remove_const :Separator
remove_const :SEPARATOR
end
GC.start
assert_equal("hello/world", File.join("hello", "world"), bug)
end;
end
def test_truncate def test_truncate
[regular_file, utf8_file].each do |file| [regular_file, utf8_file].each do |file|
assert_equal(0, File.truncate(file, 1)) assert_equal(0, File.truncate(file, 1))