[前][次][番号順一覧][スレッド一覧]

ruby-changes:48041

From: nobu <ko1@a...>
Date: Tue, 10 Oct 2017 21:30:48 +0900 (JST)
Subject: [ruby-changes:48041] nobu:r60155 (trunk): io.c: encoding of ARGF.inplace_mode

nobu	2017-10-10 21:30:42 +0900 (Tue, 10 Oct 2017)

  New Revision: 60155

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=60155

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

  Modified files:
    trunk/io.c
    trunk/test/objspace/test_objspace.rb
    trunk/test/ruby/test_argf.rb
Index: test/ruby/test_argf.rb
===================================================================
--- test/ruby/test_argf.rb	(revision 60154)
+++ test/ruby/test_argf.rb	(revision 60155)
@@ -344,6 +344,29 @@ class TestArgf < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_argf.rb#L344
     $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|
       {#
Index: test/objspace/test_objspace.rb
===================================================================
--- test/objspace/test_objspace.rb	(revision 60154)
+++ test/objspace/test_objspace.rb	(revision 60155)
@@ -45,7 +45,7 @@ class TestObjSpace < Test::Unit::TestCas https://github.com/ruby/ruby/blob/trunk/test/objspace/test_objspace.rb#L45
     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
Index: io.c
===================================================================
--- io.c	(revision 60154)
+++ io.c	(revision 60155)
@@ -181,7 +181,7 @@ struct argf { https://github.com/ruby/ruby/blob/trunk/io.c#L181
     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) https://github.com/ruby/ruby/blob/trunk/io.c#L8067
     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 o https://github.com/ruby/ruby/blob/trunk/io.c#L8123
     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) https://github.com/ruby/ruby/blob/trunk/io.c#L8265
 		    }
 		    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 https://github.com/ruby/ruby/blob/trunk/io.c#L12182
 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 https://github.com/ruby/ruby/blob/trunk/io.c#L12219
 	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) https://github.com/ruby/ruby/blob/trunk/io.c#L12239
 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);
 }
 
 /*

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]