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

io.c: encoding of ARGF.inplace_mode

* io.c (argf_next_argv): encode inplace mode suffix to the path
  encoding.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60155 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2017-10-10 12:30:42 +00:00
parent 4ed65f1242
commit 5e52f06529
3 changed files with 43 additions and 31 deletions

49
io.c
View file

@ -181,7 +181,7 @@ struct argf {
long last_lineno; /* $. */
long lineno;
VALUE argv;
char *inplace;
VALUE inplace;
struct rb_io_enc_t encs;
int8_t init_p, next_p, binmode;
};
@ -8067,29 +8067,21 @@ argf_mark(void *ptr)
rb_gc_mark(p->filename);
rb_gc_mark(p->current_file);
rb_gc_mark(p->argv);
rb_gc_mark(p->inplace);
rb_gc_mark(p->encs.ecopts);
}
static void
argf_free(void *ptr)
{
struct argf *p = ptr;
xfree(p->inplace);
xfree(p);
}
static size_t
argf_memsize(const void *ptr)
{
const struct argf *p = ptr;
size_t size = sizeof(*p);
if (p->inplace) size += strlen(p->inplace) + 1;
return size;
}
static const rb_data_type_t argf_type = {
"ARGF",
{argf_mark, argf_free, argf_memsize},
{argf_mark, RUBY_TYPED_DEFAULT_FREE, argf_memsize},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
@ -8131,11 +8123,6 @@ argf_initialize_copy(VALUE argf, VALUE orig)
if (!OBJ_INIT_COPY(argf, orig)) return argf;
ARGF = argf_of(orig);
ARGF.argv = rb_obj_dup(ARGF.argv);
if (ARGF.inplace) {
const char *inplace = ARGF.inplace;
ARGF.inplace = 0;
ARGF.inplace = ruby_strdup(inplace);
}
return argf;
}
@ -8278,10 +8265,14 @@ argf_next_argv(VALUE argf)
}
fstat(fr, &st);
str = filename;
if (*ARGF.inplace) {
if (!NIL_P(ARGF.inplace)) {
VALUE suffix = ARGF.inplace;
str = rb_str_dup(str);
rb_str_cat2(str, ARGF.inplace);
/* TODO: encoding of ARGF.inplace */
if (NIL_P(rb_str_cat_conv_enc_opts(str, RSTRING_LEN(str),
RSTRING_PTR(suffix), RSTRING_LEN(suffix),
rb_enc_get(suffix), 0, Qnil))) {
rb_str_append(str, suffix);
}
#ifdef NO_SAFE_RENAME
(void)close(fr);
(void)unlink(RSTRING_PTR(str));
@ -12191,7 +12182,8 @@ static VALUE
argf_inplace_mode_get(VALUE argf)
{
if (!ARGF.inplace) return Qnil;
return rb_str_new2(ARGF.inplace);
if (NIL_P(ARGF.inplace)) return rb_str_new(0, 0);
return rb_str_dup(ARGF.inplace);
}
static VALUE
@ -12227,14 +12219,13 @@ argf_inplace_mode_set(VALUE argf, VALUE val)
rb_insecure_operation();
if (!RTEST(val)) {
if (ARGF.inplace) free(ARGF.inplace);
ARGF.inplace = 0;
ARGF.inplace = Qfalse;
}
else if (StringValueCStr(val), !RSTRING_LEN(val)) {
ARGF.inplace = Qnil;
}
else {
const char *suffix = StringValueCStr(val);
if (ARGF.inplace) free(ARGF.inplace);
ARGF.inplace = 0;
ARGF.inplace = strdup(suffix);
ARGF.inplace = rb_str_new_frozen(val);
}
return argf;
}
@ -12248,15 +12239,13 @@ opt_i_set(VALUE val, ID id, VALUE *var)
const char *
ruby_get_inplace_mode(void)
{
return ARGF.inplace;
return RSTRING_PTR(ARGF.inplace);
}
void
ruby_set_inplace_mode(const char *suffix)
{
if (ARGF.inplace) free(ARGF.inplace);
ARGF.inplace = 0;
if (suffix) ARGF.inplace = strdup(suffix);
ARGF.inplace = !suffix ? Qfalse : !*suffix ? Qnil : rb_fstring_cstr(suffix);
}
/*

View file

@ -45,7 +45,7 @@ class TestObjSpace < Test::Unit::TestCase
argf.inplace_mode = nil
size = ObjectSpace.memsize_of(argf)
argf.inplace_mode = "inplace_mode_suffix"
assert_equal(size + 20, ObjectSpace.memsize_of(argf))
assert_equal(size, ObjectSpace.memsize_of(argf))
end
def test_memsize_of_all

View file

@ -344,6 +344,29 @@ class TestArgf < Test::Unit::TestCase
$stdout = stdout
end
def test_inplace_suffix_encoding
base = "argf-\u{30c6 30b9 30c8}"
name = "#{@tmpdir}/#{base}"
suffix = "-bak"
File.write(name, "foo")
stdout = $stdout
argf = ARGF.class.new(name)
argf.inplace_mode = suffix.encode(Encoding::UTF_16LE)
begin
argf.each do |s|
puts "+"+s
end
ensure
$stdout.close unless $stdout == stdout
$stdout = stdout
end
assert_file.exist?(name)
assert_equal("+foo\n", File.read(name))
assert_file.not_exist?(name+"-")
assert_file.exist?(name+suffix)
assert_equal("foo", File.read(name+suffix))
end
def test_encoding
ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
{#