From 098ca001752dd6cfd6c044f06e9773fc39536c6e Mon Sep 17 00:00:00 2001 From: matz Date: Wed, 12 Dec 2007 13:23:07 +0000 Subject: [PATCH] * io.c (rb_io_mode_enc): allow specifying external encoding in open mode, e.g. open(path, "r:utf-8"). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14201 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 +++++ io.c | 42 +++++++++++++++++++++++++++++++++++------- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index f516098c1a..d0157aed8e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Wed Dec 12 22:21:34 2007 Yukihiro Matsumoto + + * io.c (rb_io_mode_enc): allow specifying external encoding in + open mode, e.g. open(path, "r:utf-8"). + Wed Dec 12 21:26:03 2007 Yukihiro Matsumoto * eval_method.ci (rb_alias): no need to skip aliasing when new diff --git a/io.c b/io.c index 2eb3305e10..5975296ac2 100644 --- a/io.c +++ b/io.c @@ -2932,14 +2932,16 @@ rb_io_mode_flags(const char *mode) while (*m) { switch (*m++) { - case 'b': + case 'b': flags |= FMODE_BINMODE; break; - case '+': + case '+': flags |= FMODE_READWRITE; break; - default: + default: goto error; + case ':': + return flags; } } @@ -3001,16 +3003,18 @@ rb_io_mode_modenum(const char *mode) while (*m) { switch (*m++) { - case 'b': + case 'b': #ifdef O_BINARY flags |= O_BINARY; #endif break; - case '+': + case '+': flags = (flags & ~O_ACCMODE) | O_RDWR; break; - default: + default: goto error; + case ':': + return flags; } } @@ -3045,6 +3049,26 @@ rb_io_modenum_mode(int flags) return NULL; /* not reached */ } +void +rb_io_mode_enc(rb_io_t *fptr, const char *mode) +{ + const char *p0, *p1; + int idx; + + p0 = strrchr(mode, ':'); + if (p0) { + idx = rb_enc_find_index(p0+1); + if (idx >= 0) { + fptr->enc = rb_enc_from_index(idx); + } +#if 0 + p1 = strchr(mode, ':'); + if (p1 < p0) { + } +#endif + } +} + struct sysopen_struct { char *fname; int flag; @@ -3163,6 +3187,7 @@ rb_file_open_internal(VALUE io, const char *fname, const char *mode) rb_io_t *fptr; MakeOpenFile(io, fptr); + rb_io_mode_enc(fptr, mode); fptr->mode = rb_io_mode_flags(mode); fptr->path = strdup(fname); fptr->fd = rb_sysopen(fptr->path, rb_io_mode_modenum(rb_io_flags_mode(fptr->mode)), 0666); @@ -3471,6 +3496,7 @@ pipe_open(const char *cmd, int argc, VALUE *argv, const char *mode) port = io_alloc(rb_cIO); MakeOpenFile(port, fptr); + rb_io_mode_enc(fptr, mode); fptr->fd = fd; fptr->stdio_file = fp; fptr->mode = modef | FMODE_SYNC|FMODE_DUPLEX; @@ -3585,7 +3611,7 @@ rb_io_s_popen(int argc, VALUE *argv, VALUE klass) mode = rb_io_modenum_mode(FIX2INT(pmode)); } else { - mode = rb_io_flags_mode(rb_io_mode_flags(StringValuePtr(pmode))); + mode = StringValuePtr(pmode); } tmp = rb_check_array_type(pname); if (!NIL_P(tmp)) { @@ -3639,6 +3665,7 @@ rb_open_file(int argc, VALUE *argv, VALUE io) rb_file_sysopen_internal(io, RSTRING_PTR(fname), flags, fmode); } else { + mode = NIL_P(vmode) ? "r" : StringValuePtr(vmode); rb_file_open_internal(io, RSTRING_PTR(fname), mode); } @@ -3975,6 +4002,7 @@ rb_io_reopen(int argc, VALUE *argv, VALUE file) rb_io_flags_mode(flags)); } fptr->mode = flags; + rb_io_mode_enc(fptr, StringValuePtr(nmode)); } if (fptr->path) {