summaryrefslogtreecommitdiff
path: root/io.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-08-23 08:41:02 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-08-23 08:41:02 +0000
commit2b78afebc731e3f9e447076c3cd2e53328b9e97a (patch)
tree92472d4223537daff1773cec05d01aefe7881dda /io.c
parent5378f8e5b1bc23bb8d5a9d4180582c306813f454 (diff)
* 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_*. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18791 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r--io.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/io.c b/io.c
index a87b8f3bef..c05a0b8ac2 100644
--- a/io.c
+++ b/io.c
@@ -126,6 +126,7 @@ static VALUE argf;
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 @@ make_readconv(rb_io_t *fptr)
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 @@ rb_io_extract_modeenc(VALUE *mode_p, VALUE opthash,
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 @@ Init_IO(void)
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"));
}