diff options
author | davidflanagan <davidflanagan@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-12-22 16:21:09 +0000 |
---|---|---|
committer | davidflanagan <davidflanagan@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-12-22 16:21:09 +0000 |
commit | b83cbb0c7c873fc3c09a77019ff72f1a9a8d5837 (patch) | |
tree | a2cc4045e34f95449633c2ccc75ecf8a8fc4b5f5 /io.c | |
parent | 018bdcadac41c61445255025f1d0f7bf6afc60b0 (diff) | |
download | ruby-b83cbb0c7c873fc3c09a77019ff72f1a9a8d5837.tar.gz |
* io.c, io.h: temporary patch to partially implement transcode-on-read and transcode-on-write
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14497 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r-- | io.c | 73 |
1 files changed, 65 insertions, 8 deletions
@@ -124,7 +124,7 @@ VALUE rb_default_rs; static VALUE argf; -static ID id_write, id_read, id_getc, id_flush; +static ID id_write, id_read, id_getc, id_flush, id_encode; extern char *ruby_inplace_mode; @@ -622,6 +622,26 @@ io_fwrite(VALUE str, rb_io_t *fptr) { long len, n, r, l, offset = 0; + /* + * If an external encoding was specified and it differs from + * the strings encoding then we must transcode before writing. + * We must also transcode if two encodings were specified + */ + if (fptr->enc && (fptr->enc2 || fptr->enc != rb_enc_get(str))) { + /* transcode str before output */ + /* the methods in transcode.c are static, so call indirectly */ + /* Can't use encode! because puts writes a frozen newline */ + if (fptr->enc2) { + str = rb_funcall(str, id_encode, 2, + rb_enc_from_encoding(fptr->enc), + rb_enc_from_encoding(fptr->enc2)); + } + else { + str = rb_funcall(str, id_encode, 1, + rb_enc_from_encoding(fptr->enc)); + } + } + len = RSTRING_LEN(str); if ((n = len) <= 0) return n; if (fptr->wbuf == NULL && !(fptr->mode & FMODE_SYNC)) { @@ -1279,7 +1299,17 @@ io_enc_str(VALUE str, rb_io_t *fptr) { OBJ_TAINT(str); if (fptr->enc) { - rb_enc_associate(str, fptr->enc); + if (fptr->enc2) { + /* two encodings, so transcode from enc2 to enc */ + /* the methods in transcode.c are static, so call indirectly */ + str = rb_funcall(str, id_encode, 2, + rb_enc_from_encoding(fptr->enc2), + rb_enc_from_encoding(fptr->enc)); + } + else { + /* just one encoding, so associate it with the string */ + rb_enc_associate(str, fptr->enc); + } } return str; } @@ -2878,11 +2908,11 @@ rb_io_binmode(VALUE io) static VALUE rb_io_binmode_m(VALUE io) { + rb_io_binmode(io); + #if defined(_WIN32) || defined(DJGPP) || defined(__CYGWIN__) || defined(__human68k__) || defined(__EMX__) VALUE write_io; - rb_io_binmode(io); - write_io = GetWriteIO(io); if (write_io != io) rb_io_binmode(write_io); @@ -3063,7 +3093,8 @@ void rb_io_mode_enc(rb_io_t *fptr, const char *mode) { const char *p0, *p1; - int idx; + char *enc2name; + int idx, idx2; p0 = strrchr(mode, ':'); if (p0) { @@ -3071,13 +3102,31 @@ rb_io_mode_enc(rb_io_t *fptr, const char *mode) if (idx >= 0) { fptr->enc = rb_enc_from_index(idx); } -#if 0 + else { + rb_warn("Unsupported encoding %s ignored", p0+1); + } p1 = strchr(mode, ':'); if (p1 < p0) { + enc2name = ALLOCA_N(char, p0-p1); + strncpy(enc2name, p1+1, p0-p1-1); + enc2name[p0-p1-1] = '\0'; + idx2=rb_enc_find_index(enc2name); + if (idx2 == idx) { + rb_warn("Ignoring internal encoding %s: it is identical to external encoding %s", + enc2name, p0+1); + } + else if (idx2 >= 0) { + fptr->enc2 = rb_enc_from_index(idx2); + } + else { + rb_warn("Unsupported encoding %s ignored", enc2name); + } } -#endif } - else if (!(fptr->mode & FMODE_BINMODE)) { + else if (fptr->mode & FMODE_BINMODE) { + fptr->enc = rb_ascii_encoding(); + } + else { fptr->enc = rb_default_external_encoding(); } } @@ -5703,6 +5752,11 @@ rb_io_external_encoding(VALUE io) return rb_enc_from_encoding(fptr->enc); } +static VALUE +argf_external_encoding(void) +{ + return rb_enc_default_external(); +} static VALUE argf_tell(void) @@ -6155,6 +6209,7 @@ Init_IO(void) id_read = rb_intern("read"); id_getc = rb_intern("getc"); id_flush = rb_intern("flush"); + id_encode = rb_intern("encode"); rb_define_global_function("syscall", rb_f_syscall, -1); @@ -6339,6 +6394,8 @@ Init_IO(void) rb_define_singleton_method(argf, "lineno", argf_lineno, 0); rb_define_singleton_method(argf, "lineno=", argf_set_lineno, 1); + rb_define_singleton_method(argf, "external_encoding", argf_external_encoding, 0); + rb_global_variable(¤t_file); rb_define_readonly_variable("$FILENAME", &filename); filename = rb_str_new2("-"); |