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

ruby-changes:21613

From: usa <ko1@a...>
Date: Tue, 8 Nov 2011 02:48:23 +0900 (JST)
Subject: [ruby-changes:21613] usa:r33662 (trunk): * include/ruby/encoding.h (ECONV_NEWLINE_DECORATOR_READ_MASK,

usa	2011-11-08 02:48:11 +0900 (Tue, 08 Nov 2011)

  New Revision: 33662

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=33662

  Log:
    * include/ruby/encoding.h (ECONV_NEWLINE_DECORATOR_READ_MASK,
      ECONV_NEWLINE_DECORATOR_WRITE_MASK): new macro.
    
    * io.c (rb_io_extract_modeenc, pipe_open, prep_stdio, argf_next_argv):
      set TEXTMODE_NEWLINE_DECORATOR_ON_WRITE for textmode on creating IO
      if the flag is available.
    
    * io.c (make_writeconv): drop decorators for reading.
    
    * io.c (make_readconv): drop decorators for writing.
    
    * io.c (do_writeconv): existing writeconv is not the condition to raise
      ArgumentError.  should check textmode or not.
    
    * test/ruby/test_io_m17n.rb
      (TestIO_M17N#test_{cr,lf,crlf}_decorator_on_stdout): test above
      changes.

  Modified files:
    trunk/include/ruby/encoding.h
    trunk/io.c
    trunk/test/ruby/test_io_m17n.rb

Index: include/ruby/encoding.h
===================================================================
--- include/ruby/encoding.h	(revision 33661)
+++ include/ruby/encoding.h	(revision 33662)
@@ -305,6 +305,8 @@
 
 #define ECONV_DECORATOR_MASK                    0x0000ff00
 #define ECONV_NEWLINE_DECORATOR_MASK            0x00003f00
+#define ECONV_NEWLINE_DECORATOR_READ_MASK       0x00000f00
+#define ECONV_NEWLINE_DECORATOR_WRITE_MASK      0x00003000
 
 #define ECONV_UNIVERSAL_NEWLINE_DECORATOR       0x00000100
 #define ECONV_CRLF_NEWLINE_DECORATOR            0x00001000
Index: io.c
===================================================================
--- io.c	(revision 33661)
+++ io.c	(revision 33662)
@@ -903,16 +903,8 @@
 
         fptr->writeconv_initialized = 1;
 
-        ecflags = fptr->encs.ecflags;
+        ecflags = fptr->encs.ecflags & ~ECONV_NEWLINE_DECORATOR_READ_MASK;
         ecopts = fptr->encs.ecopts;
-#ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
-	if (NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) &&
-	    (!(ecflags & ECONV_NEWLINE_DECORATOR_MASK) ||
-	     (ecflags & ECONV_UNIVERSAL_NEWLINE_DECORATOR))) {
-            ecflags &= ~ECONV_UNIVERSAL_NEWLINE_DECORATOR;
-            ecflags |= TEXTMODE_NEWLINE_DECORATOR_ON_WRITE;
-	}
-#endif
 
         if (!fptr->encs.enc || (fptr->encs.enc == rb_ascii8bit_encoding() && !fptr->encs.enc2)) {
             /* no encoding conversion */
@@ -1050,6 +1042,8 @@
     return len;
 }
 
+# define MODE_BTMODE(a,b,c) ((fmode & FMODE_BINMODE) ? (b) : \
+                             (fmode & FMODE_TEXTMODE) ? (c) : (a))
 static VALUE
 do_writeconv(VALUE str, rb_io_t *fptr)
 {
@@ -1059,12 +1053,14 @@
         make_writeconv(fptr);
 
         if (fptr->writeconv) {
+#define fmode (fptr->mode)
             if (!NIL_P(fptr->writeconv_asciicompat))
                 common_encoding = fptr->writeconv_asciicompat;
-            else if (!rb_enc_asciicompat(rb_enc_get(str))) {
+            else if (MODE_BTMODE(DEFAULT_TEXTMODE,0,1) && !rb_enc_asciicompat(rb_enc_get(str))) {
                 rb_raise(rb_eArgError, "ASCII incompatible string written for text mode IO without encoding conversion: %s",
                          rb_enc_name(rb_enc_get(str)));
             }
+#undef fmode
         }
         else {
             if (fptr->encs.enc2)
@@ -1806,7 +1802,7 @@
         int ecflags;
         VALUE ecopts;
         const char *sname, *dname;
-        ecflags = fptr->encs.ecflags;
+        ecflags = fptr->encs.ecflags & ~ECONV_NEWLINE_DECORATOR_WRITE_MASK;
         ecopts = fptr->encs.ecopts;
         if (fptr->encs.enc2) {
             sname = rb_enc_name(fptr->encs.enc2);
@@ -4214,8 +4210,6 @@
 static const char*
 rb_io_fmode_modestr(int fmode)
 {
-# define MODE_BTMODE(a,b,c) ((fmode & FMODE_BINMODE) ? (b) : \
-                             (fmode & FMODE_TEXTMODE) ? (c) : (a))
     if (fmode & FMODE_APPEND) {
 	if ((fmode & FMODE_READWRITE) == FMODE_READWRITE) {
 	    return MODE_BTMODE("a+", "ab+", "at+");
@@ -4680,6 +4674,11 @@
 	ecflags = (fmode & FMODE_READABLE) ?
 	    MODE_BTMODE(ECONV_DEFAULT_NEWLINE_DECORATOR,
 			0, ECONV_UNIVERSAL_NEWLINE_DECORATOR) : 0;
+#ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
+	ecflags |= (fmode & FMODE_WRITABLE) ?
+	    MODE_BTMODE(TEXTMODE_NEWLINE_DECORATOR_ON_WRITE,
+			0, TEXTMODE_NEWLINE_DECORATOR_ON_WRITE) : 0;
+#endif
         ecopts = Qnil;
     }
     else {
@@ -4715,6 +4714,11 @@
 	ecflags = (fmode & FMODE_READABLE) ?
 	    MODE_BTMODE(ECONV_DEFAULT_NEWLINE_DECORATOR,
 			0, ECONV_UNIVERSAL_NEWLINE_DECORATOR) : 0;
+#ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
+	ecflags |= (fmode & FMODE_WRITABLE) ?
+	    MODE_BTMODE(TEXTMODE_NEWLINE_DECORATOR_ON_WRITE,
+			0, TEXTMODE_NEWLINE_DECORATOR_ON_WRITE) : 0;
+#endif
         ecflags = rb_econv_prepare_options(opthash, &ecopts, ecflags);
 
         if (rb_io_extract_encoding_option(opthash, &enc, &enc2, &fmode)) {
@@ -5411,8 +5415,15 @@
     if (convconfig) {
         fptr->encs = *convconfig;
     }
-    else if (NEED_NEWLINE_DECORATOR_ON_READ(fptr)) {
-        fptr->encs.ecflags |= ECONV_UNIVERSAL_NEWLINE_DECORATOR;
+    else {
+	if (NEED_NEWLINE_DECORATOR_ON_READ(fptr)) {
+	    fptr->encs.ecflags |= ECONV_UNIVERSAL_NEWLINE_DECORATOR;
+	}
+#ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
+	if (NEED_NEWLINE_DECORATOR_ON_WRITE(fptr)) {
+	    fptr->encs.ecflags |= TEXTMODE_NEWLINE_DECORATOR_ON_WRITE;
+	}
+#endif
     }
     fptr->pid = pid;
 
@@ -6581,6 +6592,9 @@
 
     GetOpenFile(io, fptr);
     fptr->encs.ecflags |= ECONV_DEFAULT_NEWLINE_DECORATOR;
+#ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
+    fptr->encs.ecflags |= TEXTMODE_NEWLINE_DECORATOR_ON_WRITE;
+#endif
     fptr->stdio_file = f;
 
     return io;
@@ -7118,7 +7132,12 @@
 		    if (stdout_binmode) rb_io_binmode(rb_stdout);
 		}
 		fmode = FMODE_READABLE;
-		if (!ARGF.binmode) fmode |= DEFAULT_TEXTMODE;
+		if (!ARGF.binmode) {
+		    fmode |= DEFAULT_TEXTMODE;
+#ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
+		    fptr->encs.ecflags |= TEXTMODE_NEWLINE_DECORATOR_ON_WRITE;
+#endif
+		}
 		ARGF.current_file = prep_io(fr, fmode, rb_cFile, fn);
 		if (!NIL_P(write_io)) {
 		    rb_io_set_write_io(ARGF.current_file, write_io);
Index: test/ruby/test_io_m17n.rb
===================================================================
--- test/ruby/test_io_m17n.rb	(revision 33661)
+++ test/ruby/test_io_m17n.rb	(revision 33662)
@@ -2117,4 +2117,61 @@
       end
     end
   end if /mswin|mingw/ =~ RUBY_PLATFORM
+
+  def test_cr_decorator_on_stdout
+    with_pipe do |in_r, in_w|
+      with_pipe do |out_r, out_w|
+        pid = Process.spawn({}, EnvUtil.rubybin, in: in_r, out: out_w)
+        in_r.close
+        out_w.close
+        in_w.write <<-EOS
+          STDOUT.set_encoding('locale', nil, newline: :cr)
+          STDOUT.puts "abc"
+          STDOUT.flush
+        EOS
+        in_w.close
+        Process.wait pid
+        assert_equal "abc\r", out_r.binmode.read
+        out_r.close
+      end
+    end
+  end
+
+  def test_lf_decorator_on_stdout
+    with_pipe do |in_r, in_w|
+      with_pipe do |out_r, out_w|
+        pid = Process.spawn({}, EnvUtil.rubybin, in: in_r, out: out_w)
+        in_r.close
+        out_w.close
+        in_w.write <<-EOS
+          STDOUT.set_encoding('locale', nil, newline: :lf)
+          STDOUT.puts "abc"
+          STDOUT.flush
+        EOS
+        in_w.close
+        Process.wait pid
+        assert_equal "abc\n", out_r.binmode.read
+        out_r.close
+      end
+    end
+  end
+
+  def test_crlf_decorator_on_stdout
+    with_pipe do |in_r, in_w|
+      with_pipe do |out_r, out_w|
+        pid = Process.spawn({}, EnvUtil.rubybin, in: in_r, out: out_w)
+        in_r.close
+        out_w.close
+        in_w.write <<-EOS
+          STDOUT.set_encoding('locale', nil, newline: :crlf)
+          STDOUT.puts "abc"
+          STDOUT.flush
+        EOS
+        in_w.close
+        Process.wait pid
+        assert_equal "abc\r\n", out_r.binmode.read
+        out_r.close
+      end
+    end
+  end
 end

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

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