summaryrefslogtreecommitdiff
path: root/io.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-04-26 15:55:21 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-04-26 15:55:21 +0000
commit876146772787599c894369801034f1fed1d16b54 (patch)
tree91f02a41b3b508bfea3bffbe4e27985cac0a75d4 /io.c
parent3b937bbdc4abc6ec1d3ec5d6b4e31714e0456e35 (diff)
* io.c (validate_enc_binmode, rb_io_extract_modeenc): set newline
decorator according to open mode. * transcode.c (rb_econv_prepare_options): new function, to prepare econv options with newline flags. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31355 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r--io.c42
1 files changed, 29 insertions, 13 deletions
diff --git a/io.c b/io.c
index 6a4ca44bf4..73a30cd305 100644
--- a/io.c
+++ b/io.c
@@ -217,15 +217,15 @@ static int max_file_descriptor = NOFILE;
# endif
#endif
+#define NEED_NEWLINE_DECORATOR_ON_READ(fptr) ((fptr)->mode & FMODE_TEXTMODE)
+#define NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) ((fptr)->mode & FMODE_TEXTMODE)
#if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
/* Windows */
-# define NEED_NEWLINE_DECORATOR_ON_READ(fptr) (!((fptr)->mode & FMODE_BINMODE))
-# define NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) (!((fptr)->mode & FMODE_BINMODE))
+# define DEFAULT_TEXTMODE FMODE_TEXTMODE
# define TEXTMODE_NEWLINE_DECORATOR_ON_WRITE ECONV_CRLF_NEWLINE_DECORATOR
#else
/* Unix */
-# define NEED_NEWLINE_DECORATOR_ON_READ(fptr) ((fptr)->mode & FMODE_TEXTMODE)
-# define NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) 0
+# define DEFAULT_TEXTMODE 0
#endif
#define NEED_READCONV(fptr) ((fptr)->encs.enc2 != NULL || NEED_NEWLINE_DECORATOR_ON_READ(fptr))
#define NEED_WRITECONV(fptr) (((fptr)->encs.enc != NULL && (fptr)->encs.enc != rb_ascii8bit_encoding()) || NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) || ((fptr)->encs.ecflags & (ECONV_DECORATOR_MASK|ECONV_STATEFUL_DECORATOR_MASK)))
@@ -1672,8 +1672,6 @@ make_readconv(rb_io_t *fptr, int size)
const char *sname, *dname;
ecflags = fptr->encs.ecflags;
ecopts = fptr->encs.ecopts;
- if (NEED_NEWLINE_DECORATOR_ON_READ(fptr))
- ecflags |= ECONV_UNIVERSAL_NEWLINE_DECORATOR;
if (fptr->encs.enc2) {
sname = rb_enc_name(fptr->encs.enc2);
dname = rb_enc_name(fptr->encs.enc);
@@ -3994,7 +3992,7 @@ rb_io_binmode(VALUE io)
rb_econv_binmode(fptr->writeconv);
fptr->mode |= FMODE_BINMODE;
fptr->mode &= ~FMODE_TEXTMODE;
- fptr->writeconv_pre_ecflags &= ~(ECONV_UNIVERSAL_NEWLINE_DECORATOR|ECONV_CRLF_NEWLINE_DECORATOR|ECONV_CR_NEWLINE_DECORATOR);
+ fptr->writeconv_pre_ecflags &= ~ECONV_NEWLINE_DECORATOR_MASK;
return io;
}
@@ -4442,13 +4440,25 @@ rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2
typedef struct rb_io_enc_t convconfig_t;
static void
-validate_enc_binmode(int fmode, rb_encoding *enc, rb_encoding *enc2)
+validate_enc_binmode(int *fmode_p, int ecflags, rb_encoding *enc, rb_encoding *enc2)
{
+ int fmode = *fmode_p;
+
if ((fmode & FMODE_READABLE) &&
!enc2 &&
!(fmode & FMODE_BINMODE) &&
!rb_enc_asciicompat(enc ? enc : rb_default_external_encoding()))
rb_raise(rb_eArgError, "ASCII incompatible encoding needs binmode");
+
+ if (!(fmode & FMODE_BINMODE) &&
+ (ecflags & ECONV_NEWLINE_DECORATOR_MASK)) {
+ fmode |= DEFAULT_TEXTMODE;
+ *fmode_p = fmode;
+ }
+ else if (!(ecflags & ECONV_NEWLINE_DECORATOR_MASK)) {
+ fmode &= ~FMODE_TEXTMODE;
+ *fmode_p = fmode;
+ }
}
static void
@@ -4516,7 +4526,9 @@ rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
}
if (NIL_P(opthash)) {
- ecflags = 0;
+ ecflags = (fmode & FMODE_READABLE) ?
+ MODE_BTMODE(ECONV_DEFAULT_NEWLINE_DECORATOR,
+ 0, ECONV_UNIVERSAL_NEWLINE_DECORATOR) : 0;
ecopts = Qnil;
}
else {
@@ -4549,7 +4561,10 @@ rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
/* perm no use, just ignore */
}
}
- ecflags = rb_econv_prepare_opts(opthash, &ecopts);
+ ecflags = (fmode & FMODE_READABLE) ?
+ MODE_BTMODE(ECONV_DEFAULT_NEWLINE_DECORATOR,
+ 0, ECONV_UNIVERSAL_NEWLINE_DECORATOR) : 0;
+ ecflags = rb_econv_prepare_options(opthash, &ecopts, ecflags);
if (rb_io_extract_encoding_option(opthash, &enc, &enc2, &fmode)) {
if (has_enc) {
@@ -4558,7 +4573,7 @@ rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
}
}
- validate_enc_binmode(fmode, enc, enc2);
+ validate_enc_binmode(&fmode, ecflags, enc, enc2);
*vmode_p = vmode;
@@ -4756,7 +4771,8 @@ rb_file_open_generic(VALUE io, VALUE filename, int oflags, int fmode, convconfig
cc.ecopts = Qnil;
convconfig = &cc;
}
- validate_enc_binmode(fmode, convconfig->enc, convconfig->enc2);
+ validate_enc_binmode(&fmode, convconfig->ecflags,
+ convconfig->enc, convconfig->enc2);
MakeOpenFile(io, fptr);
fptr->mode = fmode;
@@ -8024,7 +8040,7 @@ io_encoding_set(rb_io_t *fptr, VALUE v1, VALUE v2, VALUE opt)
}
}
}
- validate_enc_binmode(fptr->mode, enc, enc2);
+ validate_enc_binmode(&fptr->mode, ecflags, enc, enc2);
fptr->encs.enc = enc;
fptr->encs.enc2 = enc2;
fptr->encs.ecflags = ecflags;