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

ruby-changes:7272

From: akr <ko1@a...>
Date: Sat, 23 Aug 2008 17:41:25 +0900 (JST)
Subject: [ruby-changes:7272] Ruby:r18791 (trunk): * include/ruby/io.h (FMODE_INVALID_MASK): defined.

akr	2008-08-23 17:41:02 +0900 (Sat, 23 Aug 2008)

  New Revision: 18791

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

  Log:
    * include/ruby/io.h (FMODE_INVALID_MASK): defined.
      (FMODE_INVALID_IGNORE): defined.
      (FMODE_INVALID_REPLACE): defined.
      (FMODE_UNDEF_MASK): defined.
      (FMODE_UNDEF_IGNORE): defined.
      (FMODE_UNDEF_REPLACE): defined.
    
    * io.c (sym_invalid): defined.
      (sym_undef): defined.
      (sym_ignore): defined.
      (sym_replace): defined.
      (make_readconv): specify ECONV_INVALID_* and ECONV_UNDEF_* if
      FMODE_INVALID_* and FMODE_UNDEF_* is set.
      (rb_io_extract_modeenc): check {:invalid, :undef} => {:replace,
      :ignore} for FMODE_INVALID_* and FMODE_UNDEF_*.

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

Index: include/ruby/io.h
===================================================================
--- include/ruby/io.h	(revision 18790)
+++ include/ruby/io.h	(revision 18791)
@@ -72,21 +72,27 @@
 
 #define HAVE_RB_IO_T 1
 
-#define FMODE_READABLE                  0x0001
-#define FMODE_WRITABLE                  0x0002
-#define FMODE_READWRITE                 (FMODE_READABLE|FMODE_WRITABLE)
-#define FMODE_BINMODE                   0x0004
-#define FMODE_SYNC                      0x0008
-#define FMODE_TTY                       0x0010
-#define FMODE_DUPLEX                    0x0020
-#define FMODE_APPEND                    0x0040
-#define FMODE_CREATE                    0x0080
-/* #define FMODE_NOREVLOOKUP            0x0100 */
-#define FMODE_WSPLIT                    0x0200
-#define FMODE_WSPLIT_INITIALIZED        0x0400
-#define FMODE_TRUNC                     0x0800
-#define FMODE_TEXTMODE                  0x1000
-/* #define FMODE_PREP                  0x10000 */
+#define FMODE_READABLE              0x00000001
+#define FMODE_WRITABLE              0x00000002
+#define FMODE_READWRITE             (FMODE_READABLE|FMODE_WRITABLE)
+#define FMODE_BINMODE               0x00000004
+#define FMODE_SYNC                  0x00000008
+#define FMODE_TTY                   0x00000010
+#define FMODE_DUPLEX                0x00000020
+#define FMODE_APPEND                0x00000040
+#define FMODE_CREATE                0x00000080
+/* #define FMODE_NOREVLOOKUP        0x00000100 */
+#define FMODE_WSPLIT                0x00000200
+#define FMODE_WSPLIT_INITIALIZED    0x00000400
+#define FMODE_TRUNC                 0x00000800
+#define FMODE_TEXTMODE              0x00001000
+/* #define FMODE_PREP               0x00010000 */
+#define FMODE_INVALID_MASK          0x00f00000
+#define FMODE_INVALID_IGNORE        0x00100000
+#define FMODE_INVALID_REPLACE       0x00200000
+#define FMODE_UNDEF_MASK            0x0f000000
+#define FMODE_UNDEF_IGNORE          0x01000000
+#define FMODE_UNDEF_REPLACE         0x02000000
 
 #define GetOpenFile(obj,fp) rb_io_check_closed((fp) = RFILE(rb_io_taint_check(obj))->fptr)
 
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 18790)
+++ ChangeLog	(revision 18791)
@@ -1,3 +1,21 @@
+Sat Aug 23 16:59:42 2008  Tanaka Akira  <akr@f...>
+
+	* include/ruby/io.h (FMODE_INVALID_MASK): defined.
+	  (FMODE_INVALID_IGNORE): defined.
+	  (FMODE_INVALID_REPLACE): defined.
+	  (FMODE_UNDEF_MASK): defined.
+	  (FMODE_UNDEF_IGNORE): defined.
+	  (FMODE_UNDEF_REPLACE): defined.
+
+	* io.c (sym_invalid): defined.
+	  (sym_undef): defined.
+	  (sym_ignore): defined.
+	  (sym_replace): defined.
+	  (make_readconv): specify ECONV_INVALID_* and ECONV_UNDEF_* if
+	  FMODE_INVALID_* and FMODE_UNDEF_* is set.
+	  (rb_io_extract_modeenc): check {:invalid, :undef} => {:replace,
+	  :ignore} for FMODE_INVALID_* and FMODE_UNDEF_*.
+
 Sat Aug 23 17:06:57 2008  Nobuyoshi Nakada  <nobu@r...>
 
 	* strftime.c (rb_strftime): support more flags.
Index: io.c
===================================================================
--- io.c	(revision 18790)
+++ io.c	(revision 18791)
@@ -126,6 +126,7 @@
 static ID id_write, id_read, id_getc, id_flush, id_readpartial;
 static VALUE sym_mode, sym_perm, sym_extenc, sym_intenc, sym_encoding, sym_open_args;
 static VALUE sym_textmode, sym_binmode;
+static VALUE sym_invalid, sym_undef, sym_ignore, sym_replace;
 
 struct timeval rb_time_interval(VALUE);
 
@@ -1433,6 +1434,10 @@
         const char *sname, *dname;
         if (NEED_NEWLINE_DECODER(fptr))
             ecflags |= ECONV_UNIVERSAL_NEWLINE_DECODER;
+        if (fptr->mode & FMODE_INVALID_MASK)
+            ecflags |= (fptr->mode / (FMODE_INVALID_MASK/ECONV_INVALID_MASK)) & ECONV_INVALID_MASK;
+        if (fptr->mode & FMODE_UNDEF_MASK)
+            ecflags |= (fptr->mode / (FMODE_UNDEF_MASK/ECONV_UNDEF_MASK)) & ECONV_UNDEF_MASK;
         if (fptr->enc2) {
             sname = fptr->enc2->name;
             dname = fptr->enc->name;
@@ -3876,6 +3881,32 @@
             modenum |= O_BINARY;
 #endif
         }
+        v = rb_hash_aref(opthash, sym_invalid);
+        if (!NIL_P(v)) {
+            if (v == sym_replace) {
+                flags |= FMODE_INVALID_REPLACE;
+            }
+            else if (v == sym_ignore) {
+                flags |= FMODE_INVALID_IGNORE;
+            }
+            else {
+                v = rb_inspect(v);
+                rb_raise(rb_eArgError, "unexpected action for invalid byte sequence: %s", StringValueCStr(v));
+            }
+        }
+        v = rb_hash_aref(opthash, sym_undef);
+        if (!NIL_P(v)) {
+            if (v == sym_replace) {
+                flags |= FMODE_UNDEF_REPLACE;
+            }
+            else if (v == sym_ignore) {
+                flags |= FMODE_UNDEF_IGNORE;
+            }
+            else {
+                v = rb_inspect(v);
+                rb_raise(rb_eArgError, "unexpected action for undefined conversion: %s", StringValueCStr(v));
+            }
+        }
 
         if (io_extract_encoding_option(opthash, &enc, &enc2)) {
             if (has_enc) {
@@ -8353,4 +8384,8 @@
     sym_open_args = ID2SYM(rb_intern("open_args"));
     sym_textmode = ID2SYM(rb_intern("textmode"));
     sym_binmode = ID2SYM(rb_intern("binmode"));
+    sym_invalid = ID2SYM(rb_intern("invalid"));
+    sym_undef = ID2SYM(rb_intern("undef"));
+    sym_ignore = ID2SYM(rb_intern("ignore"));
+    sym_replace = ID2SYM(rb_intern("replace"));
 }
Index: test/ruby/test_io_m17n.rb
===================================================================
--- test/ruby/test_io_m17n.rb	(revision 18790)
+++ test/ruby/test_io_m17n.rb	(revision 18791)
@@ -1163,5 +1163,44 @@
     }
   end
 
+  def test_invalid_r
+    with_tmpdir {
+      generate_file("t.txt", "a\x80b")
+      open("t.txt", "r:utf-8:euc-jp", :invalid => :replace) {|f|
+        assert_equal("a?b", f.read)
+      }
+      open("t.txt", "r:utf-8:euc-jp", :invalid => :ignore) {|f|
+        assert_equal("ab", f.read)
+      }
+      open("t.txt", "r:utf-8:euc-jp", :undef => :replace) {|f|
+        assert_raise(Encoding::InvalidByteSequence) { f.read }
+        assert_equal("b", f.read)
+      }
+      open("t.txt", "r:utf-8:euc-jp", :undef => :ignore) {|f|
+        assert_raise(Encoding::InvalidByteSequence) { f.read }
+        assert_equal("b", f.read)
+      }
+    }
+  end
+
+  def test_undef_r
+    with_tmpdir {
+      generate_file("t.txt", "a\uFFFDb")
+      open("t.txt", "r:utf-8:euc-jp", :undef => :replace) {|f|
+        assert_equal("a?b", f.read)
+      }
+      open("t.txt", "r:utf-8:euc-jp", :undef => :ignore) {|f|
+        assert_equal("ab", f.read)
+      }
+      open("t.txt", "r:utf-8:euc-jp", :invalid => :replace) {|f|
+        assert_raise(Encoding::ConversionUndefined) { f.read }
+        assert_equal("b", f.read)
+      }
+      open("t.txt", "r:utf-8:euc-jp", :invalid => :ignore) {|f|
+        assert_raise(Encoding::ConversionUndefined) { f.read }
+        assert_equal("b", f.read)
+      }
+    }
+  end
 end
 

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

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