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

io.c: improved IO#reopen

* io.c (rb_io_reopen): improvement to accept optional arguments.
  a patch by Glass_saga (Masaki Matsushita) in [ruby-core:47806].
  [Feature #7103]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37071 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2012-10-03 02:43:19 +00:00
parent 48af304cf7
commit 5c677a83ba
3 changed files with 83 additions and 35 deletions

View file

@ -1,3 +1,9 @@
Wed Oct 3 11:43:15 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* io.c (rb_io_reopen): improvement to accept optional arguments.
a patch by Glass_saga (Masaki Matsushita) in [ruby-core:47806].
[Feature #7103]
Wed Oct 3 04:36:11 2012 Eric Hodel <drbrain@segment7.net> Wed Oct 3 04:36:11 2012 Eric Hodel <drbrain@segment7.net>
* ext/openssl/ossl_x509store.c (ossl_x509store_add_file): Added * ext/openssl/ossl_x509store.c (ossl_x509store_add_file): Added

44
io.c
View file

@ -4792,23 +4792,6 @@ parse_mode_enc(const char *estr, rb_encoding **enc_p, rb_encoding **enc2_p, int
rb_io_ext_int_to_encs(ext_enc, int_enc, enc_p, enc2_p); rb_io_ext_int_to_encs(ext_enc, int_enc, enc_p, enc2_p);
} }
static void
mode_enc(rb_io_t *fptr, const char *estr)
{
clear_codeconv(fptr);
parse_mode_enc(estr, &fptr->encs.enc, &fptr->encs.enc2, NULL);
}
static void
rb_io_mode_enc(rb_io_t *fptr, const char *modestr)
{
const char *p = strchr(modestr, ':');
if (p) {
mode_enc(fptr, p+1);
}
}
int int
rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p) rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p)
{ {
@ -6344,12 +6327,12 @@ io_reopen(VALUE io, VALUE nfile)
static VALUE static VALUE
rb_io_reopen(int argc, VALUE *argv, VALUE file) rb_io_reopen(int argc, VALUE *argv, VALUE file)
{ {
VALUE fname, nmode; VALUE fname, nmode, opt;
int oflags; int oflags;
rb_io_t *fptr; rb_io_t *fptr;
rb_secure(4); rb_secure(4);
if (rb_scan_args(argc, argv, "11", &fname, &nmode) == 1) { if (rb_scan_args(argc, argv, "11:", &fname, &nmode, &opt) == 1) {
VALUE tmp = rb_io_check_io(fname); VALUE tmp = rb_io_check_io(fname);
if (!NIL_P(tmp)) { if (!NIL_P(tmp)) {
return io_reopen(file, tmp); return io_reopen(file, tmp);
@ -6364,18 +6347,11 @@ rb_io_reopen(int argc, VALUE *argv, VALUE file)
MEMZERO(fptr, rb_io_t, 1); MEMZERO(fptr, rb_io_t, 1);
} }
if (!NIL_P(nmode)) { if (!NIL_P(nmode) || !NIL_P(opt)) {
VALUE intmode = rb_check_to_int(nmode);
int fmode; int fmode;
convconfig_t convconfig;
if (!NIL_P(intmode)) { rb_io_extract_modeenc(&nmode, 0, opt, &oflags, &fmode, &convconfig);
oflags = NUM2INT(intmode);
fmode = rb_io_oflags_fmode(oflags);
}
else {
fmode = rb_io_modestr_fmode(StringValueCStr(nmode));
}
if (IS_PREP_STDIO(fptr) && if (IS_PREP_STDIO(fptr) &&
((fptr->mode & FMODE_READWRITE) & (fmode & FMODE_READWRITE)) != ((fptr->mode & FMODE_READWRITE) & (fmode & FMODE_READWRITE)) !=
(fptr->mode & FMODE_READWRITE)) { (fptr->mode & FMODE_READWRITE)) {
@ -6385,15 +6361,13 @@ rb_io_reopen(int argc, VALUE *argv, VALUE file)
rb_io_fmode_modestr(fmode)); rb_io_fmode_modestr(fmode));
} }
fptr->mode = fmode; fptr->mode = fmode;
if (NIL_P(intmode)) { fptr->encs = convconfig;
rb_io_mode_enc(fptr, StringValueCStr(nmode)); }
} else {
fptr->encs.ecflags = 0; oflags = rb_io_fmode_oflags(fptr->mode);
fptr->encs.ecopts = Qnil;
} }
fptr->pathv = rb_str_new_frozen(fname); fptr->pathv = rb_str_new_frozen(fname);
oflags = rb_io_fmode_oflags(fptr->mode);
if (fptr->fd < 0) { if (fptr->fd < 0) {
fptr->fd = rb_sysopen(fptr->pathv, oflags, 0666); fptr->fd = rb_sysopen(fptr->pathv, oflags, 0666);
fptr->stdio_file = 0; fptr->stdio_file = 0;

View file

@ -1732,6 +1732,74 @@ End
} }
end end
def test_reopen_opt
feature7103 = '[ruby-core:47806]'
make_tempfile {|t|
open(__FILE__) do |f|
assert_nothing_raised(feature7103) {
f.reopen(t.path, "r", binmode: true)
}
assert_equal("foo\n", f.gets)
end
open(__FILE__) do |f|
assert_nothing_raised(feature7103) {
f.reopen(t.path, autoclose: false)
}
assert_equal("foo\n", f.gets)
end
}
end
def make_tempfile_for_encoding
t = make_tempfile
open(t.path, "rb+:utf-8") {|f| f.puts "\u7d05\u7389bar\n"}
if block_given?
yield t
else
t
end
ensure
t.close(true) if t and block_given?
end
def test_reopen_encoding
make_tempfile_for_encoding {|t|
open(__FILE__) {|f|
f.reopen(t.path, "r:utf-8")
s = f.gets
assert_equal(Encoding::UTF_8, s.encoding)
assert_equal("\u7d05\u7389bar\n", s)
}
open(__FILE__) {|f|
f.reopen(t.path, "r:UTF-8:EUC-JP")
s = f.gets
assert_equal(Encoding::EUC_JP, s.encoding)
assert_equal("\xB9\xC8\xB6\xCCbar\n".force_encoding(Encoding::EUC_JP), s)
}
}
end
def test_reopen_opt_encoding
feature7103 = '[ruby-core:47806]'
make_tempfile_for_encoding {|t|
open(__FILE__) {|f|
assert_nothing_raised(feature7103) {f.reopen(t.path, encoding: "ASCII-8BIT")}
s = f.gets
assert_equal(Encoding::ASCII_8BIT, s.encoding)
assert_equal("\xe7\xb4\x85\xe7\x8e\x89bar\n", s)
}
open(__FILE__) {|f|
assert_nothing_raised(feature7103) {f.reopen(t.path, encoding: "UTF-8:EUC-JP")}
s = f.gets
assert_equal(Encoding::EUC_JP, s.encoding)
assert_equal("\xB9\xC8\xB6\xCCbar\n".force_encoding(Encoding::EUC_JP), s)
}
}
end
def test_foreach def test_foreach
a = [] a = []
IO.foreach("|" + EnvUtil.rubybin + " -e 'puts :foo; puts :bar; puts :baz'") {|x| a << x } IO.foreach("|" + EnvUtil.rubybin + " -e 'puts :foo; puts :bar; puts :baz'") {|x| a << x }