From f684d04a66b08492dd61ff1a40db289cb0daeba4 Mon Sep 17 00:00:00 2001 From: akr Date: Wed, 20 Aug 2008 10:24:37 +0000 Subject: * io.c (convconfig_t): new type. (rb_io_extract_modeenc): new function. (rb_file_open_generic): new function. (rb_file_open_internal): use rb_file_open_generic. (rb_file_sysopen_internal): use rb_file_open_generic. (rb_open_file): use rb_io_extract_modeenc and rb_file_open_generic. (rb_io_open): call rb_file_open_internal instead of rb_file_open. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18724 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- io.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 96 insertions(+), 42 deletions(-) (limited to 'io.c') diff --git a/io.c b/io.c index a21ca98a1b..ff27cd342d 100644 --- a/io.c +++ b/io.c @@ -3798,6 +3798,57 @@ io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p) return extracted; } +typedef struct convconfig_t { + rb_encoding *enc; + rb_encoding *enc2; +} convconfig_t; + +static void +rb_io_extract_modeenc(VALUE mode, VALUE opthash, + int *modenum_p, int *flags_p, convconfig_t *convconfig_p) +{ + int modenum, flags; + rb_encoding *enc, *enc2; + int has_enc = 0; + + enc = NULL; + enc2 = NULL; + + if (NIL_P(mode)) { + flags = FMODE_READABLE; + modenum = O_RDONLY; + } + else if (FIXNUM_P(mode)) { + modenum = FIX2INT(mode); + flags = rb_io_modenum_flags(modenum); + } + else { /* xxx: Bignum, to_int */ + const char *p; + SafeStringValue(mode); + p = StringValueCStr(mode); + flags = rb_io_mode_flags(p); + modenum = rb_io_flags_modenum(flags); + p = strchr(p, ':'); + if (p) { + has_enc = 1; + parse_mode_enc(p+1, &enc, &enc2); + } + } + + if (!NIL_P(opthash)) { + if (io_extract_encoding_option(opthash, &enc, &enc2)) { + if (has_enc) { + rb_raise(rb_eArgError, "encoding sepecified twice"); + } + } + } + + *modenum_p = modenum; + *flags_p = flags; + convconfig_p->enc = enc; + convconfig_p->enc2 = enc2; +} + struct sysopen_struct { char *fname; int flag; @@ -3887,20 +3938,50 @@ io_check_tty(rb_io_t *fptr) } static VALUE -rb_file_open_internal(VALUE io, const char *fname, const char *mode) +rb_file_open_generic(VALUE io, const char *fname, int modenum, int flags, convconfig_t *convconfig, int perm) { rb_io_t *fptr; MakeOpenFile(io, fptr); - fptr->mode = rb_io_mode_flags(mode); - rb_io_mode_enc(fptr, mode); + fptr->mode = flags; + if (convconfig) { + fptr->enc = convconfig->enc; + fptr->enc2 = convconfig->enc2; + } + else { + fptr->enc = NULL; + fptr->enc2 = NULL; + } fptr->path = strdup(fname); - fptr->fd = rb_sysopen(fptr->path, rb_io_mode_modenum(rb_io_flags_mode(fptr->mode)), 0666); + fptr->fd = rb_sysopen(fptr->path, modenum, perm); io_check_tty(fptr); return io; } +static VALUE +rb_file_open_internal(VALUE io, const char *fname, const char *mode) +{ + int flags; + + const char *p = strchr(mode, ':'); + convconfig_t convconfig; + if (p) { + parse_mode_enc(p+1, &convconfig.enc, &convconfig.enc2); + } + else { + convconfig.enc = NULL; + convconfig.enc2 = NULL; + } + + flags = rb_io_mode_flags(mode); + return rb_file_open_generic(io, fname, + rb_io_mode_modenum(rb_io_flags_mode(flags)), + flags, + &convconfig, + 0666); +} + VALUE rb_file_open(const char *fname, const char *mode) { @@ -3908,24 +3989,15 @@ rb_file_open(const char *fname, const char *mode) } static VALUE -rb_file_sysopen_internal(VALUE io, const char *fname, int flags, int mode) +rb_file_sysopen_internal(VALUE io, const char *fname, int modenum, int perm) { - rb_io_t *fptr; - - MakeOpenFile(io, fptr); - - fptr->path = strdup(fname); - fptr->mode = rb_io_modenum_flags(flags); - fptr->fd = rb_sysopen(fptr->path, flags, mode); - io_check_tty(fptr); - - return io; + return rb_file_open_generic(io, fname, modenum, rb_io_modenum_flags(modenum), NULL, perm); } VALUE -rb_file_sysopen(const char *fname, int flags, int mode) +rb_file_sysopen(const char *fname, int modenum, int perm) { - return rb_file_sysopen_internal(io_alloc(rb_cFile), fname, flags, mode); + return rb_file_sysopen_internal(io_alloc(rb_cFile), fname, modenum, perm); } #if defined(__CYGWIN__) || !defined(HAVE_FORK) @@ -4455,9 +4527,9 @@ static VALUE rb_open_file(int argc, VALUE *argv, VALUE io) { VALUE opt=Qnil, fname, vmode, perm; - const char *mode; - int flags; + int modenum, flags; unsigned int fmode; + convconfig_t convconfig = { NULL, NULL }; if (0 < argc) { opt = rb_check_convert_type(argv[argc-1], T_HASH, "Hash", "to_hash"); @@ -4487,31 +4559,13 @@ rb_open_file(int argc, VALUE *argv, VALUE io) } #endif FilePathValue(fname); + + rb_io_extract_modeenc(vmode, opt, &modenum, &flags, &convconfig); - if (FIXNUM_P(vmode) || !NIL_P(perm)) { - if (FIXNUM_P(vmode)) { - flags = FIX2INT(vmode); - } - else { - SafeStringValue(vmode); - flags = rb_io_mode_modenum(StringValueCStr(vmode)); - } - fmode = NIL_P(perm) ? 0666 : NUM2UINT(perm); - - rb_file_sysopen_internal(io, RSTRING_PTR(fname), flags, fmode); + fmode = NIL_P(perm) ? 0666 : NUM2UINT(perm); - if (!FIXNUM_P(vmode)) { - rb_io_t *fptr; - GetOpenFile(io, fptr); - rb_io_mode_enc(fptr, StringValueCStr(vmode)); - } - } - else { - mode = NIL_P(vmode) ? "r" : StringValueCStr(vmode); - rb_file_open_internal(io, RSTRING_PTR(fname), mode); - } + rb_file_open_generic(io, RSTRING_PTR(fname), modenum, flags, &convconfig, fmode); - io_set_encoding(io, opt); return io; } @@ -4730,7 +4784,7 @@ rb_io_open(const char *fname, const char *mode) return pipe_open_s(cmd, mode); } else { - return rb_file_open(fname, mode); + return rb_file_open_internal(io_alloc(rb_cFile), fname, mode); } } -- cgit v1.2.3