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/