1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* include/ruby/encoding.h (rb_econv_option_t): removed. Since

rb_econv_option_t has only one field, int flags, rb_econv_option_t is
  replaced by int.

* include/ruby/io.h: follow the above change.

* io.c: ditto.

* transcode.c: ditto.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19103 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2008-09-03 15:11:46 +00:00
parent b00710df4e
commit 56343375b8
5 changed files with 103 additions and 109 deletions

View file

@ -1,3 +1,15 @@
Thu Sep 4 00:09:05 2008 Tanaka Akira <akr@fsij.org>
* include/ruby/encoding.h (rb_econv_option_t): removed. Since
rb_econv_option_t has only one field, int flags, rb_econv_option_t is
replaced by int.
* include/ruby/io.h: follow the above change.
* io.c: ditto.
* transcode.c: ditto.
Thu Sep 4 00:04:59 2008 Koichi Sasada <ko1@atdot.net> Thu Sep 4 00:04:59 2008 Koichi Sasada <ko1@atdot.net>
* win32/win32.c: fix ruby/signal.h depending codes. * win32/win32.c: fix ruby/signal.h depending codes.

View file

@ -206,25 +206,20 @@ typedef enum {
econv_incomplete_input, econv_incomplete_input,
} rb_econv_result_t; } rb_econv_result_t;
typedef struct {
int flags;
/* replacement character, etc. */
} rb_econv_option_t;
typedef struct rb_econv_t rb_econv_t; typedef struct rb_econv_t rb_econv_t;
VALUE rb_str_transcode(VALUE str, VALUE to, rb_econv_option_t *ecopts); VALUE rb_str_transcode(VALUE str, VALUE to, int ecflags);
void rb_econv_opts(VALUE hash, rb_econv_option_t *opts); int rb_econv_flags(VALUE hash);
rb_econv_t *rb_econv_open(const char *source_encoding, const char *destination_encoding, rb_econv_option_t *opts); rb_econv_t *rb_econv_open(const char *source_encoding, const char *destination_encoding, int ecflags);
rb_econv_result_t rb_econv_convert(rb_econv_t *ec, rb_econv_result_t rb_econv_convert(rb_econv_t *ec,
const unsigned char **source_buffer_ptr, const unsigned char *source_buffer_end, const unsigned char **source_buffer_ptr, const unsigned char *source_buffer_end,
unsigned char **destination_buffer_ptr, unsigned char *destination_buffer_end, unsigned char **destination_buffer_ptr, unsigned char *destination_buffer_end,
int flags); int flags);
void rb_econv_close(rb_econv_t *ec); void rb_econv_close(rb_econv_t *ec);
VALUE rb_econv_open_exc(const char *senc, const char *denc, rb_econv_option_t *opts); VALUE rb_econv_open_exc(const char *senc, const char *denc, int ecflags);
/* result: 0:success -1:failure */ /* result: 0:success -1:failure */
int rb_econv_insert_output(rb_econv_t *ec, int rb_econv_insert_output(rb_econv_t *ec,

View file

@ -57,7 +57,7 @@ typedef struct rb_io_t {
struct rb_io_enc_t { struct rb_io_enc_t {
rb_encoding *enc; rb_encoding *enc;
rb_encoding *enc2; rb_encoding *enc2;
rb_econv_option_t opts; int flags;
} encs; } encs;
rb_econv_t *readconv; rb_econv_t *readconv;
@ -68,7 +68,7 @@ typedef struct rb_io_t {
rb_econv_t *writeconv; rb_econv_t *writeconv;
VALUE writeconv_stateless; VALUE writeconv_stateless;
rb_econv_option_t writeconv_pre_opts; int writeconv_pre_flags;
int writeconv_initialized; int writeconv_initialized;
} rb_io_t; } rb_io_t;
@ -127,7 +127,7 @@ typedef struct rb_io_t {
fp->tied_io_for_writing = 0;\ fp->tied_io_for_writing = 0;\
fp->encs.enc = NULL;\ fp->encs.enc = NULL;\
fp->encs.enc2 = NULL;\ fp->encs.enc2 = NULL;\
fp->encs.opts.flags = 0;\ fp->encs.flags = 0;\
} while (0) } while (0)
FILE *rb_io_stdio_file(rb_io_t *fptr); FILE *rb_io_stdio_file(rb_io_t *fptr);

56
io.c
View file

@ -690,22 +690,22 @@ make_writeconv(rb_io_t *fptr)
if (!fptr->writeconv_initialized) { if (!fptr->writeconv_initialized) {
const char *senc, *denc; const char *senc, *denc;
rb_encoding *enc; rb_encoding *enc;
rb_econv_option_t ecopts; int ecflags;
fptr->writeconv_initialized = 1; fptr->writeconv_initialized = 1;
/* ECONV_INVALID_XXX and ECONV_UNDEF_XXX should be set both. /* ECONV_INVALID_XXX and ECONV_UNDEF_XXX should be set both.
* But ECONV_CRLF_NEWLINE_ENCODER should be set only for the first. */ * But ECONV_CRLF_NEWLINE_ENCODER should be set only for the first. */
fptr->writeconv_pre_opts = fptr->encs.opts; fptr->writeconv_pre_flags = fptr->encs.flags;
ecopts = fptr->encs.opts; ecflags = fptr->encs.flags;
#ifdef TEXTMODE_NEWLINE_ENCODER #ifdef TEXTMODE_NEWLINE_ENCODER
if (!fptr->encs.enc) { if (!fptr->encs.enc) {
if (NEED_NEWLINE_ENCODER(fptr)) if (NEED_NEWLINE_ENCODER(fptr))
ecopts.flags |= TEXTMODE_NEWLINE_ENCODER; ecflags |= TEXTMODE_NEWLINE_ENCODER;
fptr->writeconv = rb_econv_open("", "", &ecopts); fptr->writeconv = rb_econv_open("", "", ecflags);
if (!fptr->writeconv) if (!fptr->writeconv)
rb_exc_raise(rb_econv_open_exc("", "", &ecopts)); rb_exc_raise(rb_econv_open_exc("", "", ecflags));
fptr->writeconv_stateless = Qnil; fptr->writeconv_stateless = Qnil;
return; return;
} }
@ -719,9 +719,9 @@ make_writeconv(rb_io_t *fptr)
if (senc) { if (senc) {
denc = enc->name; denc = enc->name;
fptr->writeconv_stateless = rb_str_new2(senc); fptr->writeconv_stateless = rb_str_new2(senc);
fptr->writeconv = rb_econv_open(senc, denc, &ecopts); fptr->writeconv = rb_econv_open(senc, denc, ecflags);
if (!fptr->writeconv) if (!fptr->writeconv)
rb_exc_raise(rb_econv_open_exc(senc, denc, &ecopts)); rb_exc_raise(rb_econv_open_exc(senc, denc, ecflags));
} }
else { else {
denc = NULL; denc = NULL;
@ -753,7 +753,7 @@ io_fwrite(VALUE str, rb_io_t *fptr)
} }
if (!NIL_P(common_encoding)) { if (!NIL_P(common_encoding)) {
str = rb_str_transcode(str, common_encoding, &fptr->writeconv_pre_opts); str = rb_str_transcode(str, common_encoding, fptr->writeconv_pre_flags);
} }
if (fptr->writeconv) { if (fptr->writeconv) {
@ -1437,11 +1437,11 @@ static void
make_readconv(rb_io_t *fptr) make_readconv(rb_io_t *fptr)
{ {
if (!fptr->readconv) { if (!fptr->readconv) {
rb_econv_option_t ecopts; int ecflags;
const char *sname, *dname; const char *sname, *dname;
ecopts = fptr->encs.opts; ecflags = fptr->encs.flags;
if (NEED_NEWLINE_DECODER(fptr)) if (NEED_NEWLINE_DECODER(fptr))
ecopts.flags |= ECONV_UNIVERSAL_NEWLINE_DECODER; ecflags |= ECONV_UNIVERSAL_NEWLINE_DECODER;
if (fptr->encs.enc2) { if (fptr->encs.enc2) {
sname = fptr->encs.enc2->name; sname = fptr->encs.enc2->name;
dname = fptr->encs.enc->name; dname = fptr->encs.enc->name;
@ -1449,9 +1449,9 @@ make_readconv(rb_io_t *fptr)
else { else {
sname = dname = ""; sname = dname = "";
} }
fptr->readconv = rb_econv_open(sname, dname, &ecopts); fptr->readconv = rb_econv_open(sname, dname, ecflags);
if (!fptr->readconv) if (!fptr->readconv)
rb_exc_raise(rb_econv_open_exc(sname, dname, &ecopts)); rb_exc_raise(rb_econv_open_exc(sname, dname, ecflags));
fptr->cbuf_off = 0; fptr->cbuf_off = 0;
fptr->cbuf_len = 0; fptr->cbuf_len = 0;
fptr->cbuf_capa = 1024; fptr->cbuf_capa = 1024;
@ -3832,7 +3832,7 @@ rb_io_extract_modeenc(VALUE *mode_p, VALUE opthash,
VALUE mode; VALUE mode;
int modenum, flags; int modenum, flags;
rb_encoding *enc, *enc2; rb_encoding *enc, *enc2;
rb_econv_option_t ecopts; int ecflags;
int has_enc = 0; int has_enc = 0;
VALUE intmode; VALUE intmode;
@ -3864,7 +3864,7 @@ rb_io_extract_modeenc(VALUE *mode_p, VALUE opthash,
} }
if (NIL_P(opthash)) { if (NIL_P(opthash)) {
rb_econv_opts(Qnil, &ecopts); ecflags = 0;
} }
else { else {
VALUE v; VALUE v;
@ -3878,7 +3878,7 @@ rb_io_extract_modeenc(VALUE *mode_p, VALUE opthash,
modenum |= O_BINARY; modenum |= O_BINARY;
#endif #endif
} }
rb_econv_opts(opthash, &ecopts); ecflags = rb_econv_flags(opthash);
if (io_extract_encoding_option(opthash, &enc, &enc2)) { if (io_extract_encoding_option(opthash, &enc, &enc2)) {
if (has_enc) { if (has_enc) {
@ -3896,7 +3896,7 @@ rb_io_extract_modeenc(VALUE *mode_p, VALUE opthash,
*flags_p = flags; *flags_p = flags;
convconfig_p->enc = enc; convconfig_p->enc = enc;
convconfig_p->enc2 = enc2; convconfig_p->enc2 = enc2;
convconfig_p->opts = ecopts; convconfig_p->flags = ecflags;
} }
struct sysopen_struct { struct sysopen_struct {
@ -4004,7 +4004,7 @@ rb_file_open_generic(VALUE io, VALUE filename, int modenum, int flags, convconfi
else { else {
fptr->encs.enc = NULL; fptr->encs.enc = NULL;
fptr->encs.enc2 = NULL; fptr->encs.enc2 = NULL;
rb_econv_opts(Qnil, &fptr->encs.opts); fptr->encs.flags = 0;
} }
fptr->pathv = rb_str_new_frozen(filename); fptr->pathv = rb_str_new_frozen(filename);
fptr->fd = rb_sysopen(RSTRING_PTR(fptr->pathv), modenum, perm); fptr->fd = rb_sysopen(RSTRING_PTR(fptr->pathv), modenum, perm);
@ -4026,7 +4026,7 @@ rb_file_open_internal(VALUE io, VALUE filename, const char *mode)
else { else {
convconfig.enc = NULL; convconfig.enc = NULL;
convconfig.enc2 = NULL; convconfig.enc2 = NULL;
rb_econv_opts(Qnil, &convconfig.opts); convconfig.flags = 0;
} }
flags = rb_io_mode_flags(mode); flags = rb_io_mode_flags(mode);
@ -5011,7 +5011,7 @@ rb_io_reopen(int argc, VALUE *argv, VALUE file)
} }
fptr->mode = flags; fptr->mode = flags;
rb_io_mode_enc(fptr, StringValueCStr(nmode)); rb_io_mode_enc(fptr, StringValueCStr(nmode));
rb_econv_opts(Qnil, &fptr->encs.opts); fptr->encs.flags = 0;
} }
fptr->pathv = rb_str_new_frozen(fname); fptr->pathv = rb_str_new_frozen(fname);
@ -5698,7 +5698,7 @@ argf_alloc(VALUE klass)
#define argf_binmode ARGF.binmode #define argf_binmode ARGF.binmode
#define argf_enc ARGF.encs.enc #define argf_enc ARGF.encs.enc
#define argf_enc2 ARGF.encs.enc2 #define argf_enc2 ARGF.encs.enc2
#define argf_ecopts ARGF.encs.opts #define argf_ecflags ARGF.encs.flags
#define rb_argv ARGF.argv #define rb_argv ARGF.argv
static VALUE static VALUE
@ -5870,7 +5870,7 @@ argf_next_argv(VALUE argf)
GetOpenFile(current_file, fptr); GetOpenFile(current_file, fptr);
fptr->encs.enc = argf_enc; fptr->encs.enc = argf_enc;
fptr->encs.enc2 = argf_enc2; fptr->encs.enc2 = argf_enc2;
fptr->encs.opts = argf_ecopts; fptr->encs.flags = argf_ecflags;
clear_codeconv(fptr); clear_codeconv(fptr);
} }
} }
@ -6595,26 +6595,26 @@ io_encoding_set(rb_io_t *fptr, int argc, VALUE v1, VALUE v2, VALUE opt)
if (argc == 2) { if (argc == 2) {
fptr->encs.enc2 = rb_to_encoding(v1); fptr->encs.enc2 = rb_to_encoding(v1);
fptr->encs.enc = rb_to_encoding(v2); fptr->encs.enc = rb_to_encoding(v2);
rb_econv_opts(opt, &fptr->encs.opts); fptr->encs.flags = rb_econv_flags(opt);
clear_codeconv(fptr); clear_codeconv(fptr);
} }
else if (argc == 1) { else if (argc == 1) {
if (NIL_P(v1)) { if (NIL_P(v1)) {
fptr->encs.enc = NULL; fptr->encs.enc = NULL;
fptr->encs.enc2 = NULL; fptr->encs.enc2 = NULL;
rb_econv_opts(Qnil, &fptr->encs.opts); fptr->encs.flags = 0;
clear_codeconv(fptr); clear_codeconv(fptr);
} }
else { else {
VALUE tmp = rb_check_string_type(v1); VALUE tmp = rb_check_string_type(v1);
if (!NIL_P(tmp)) { if (!NIL_P(tmp)) {
mode_enc(fptr, StringValueCStr(tmp)); mode_enc(fptr, StringValueCStr(tmp));
rb_econv_opts(opt, &fptr->encs.opts); fptr->encs.flags = rb_econv_flags(opt);
} }
else { else {
fptr->encs.enc = rb_to_encoding(v1); fptr->encs.enc = rb_to_encoding(v1);
fptr->encs.enc2 = NULL; fptr->encs.enc2 = NULL;
rb_econv_opts(Qnil, &fptr->encs.opts); fptr->encs.flags = 0;
clear_codeconv(fptr); clear_codeconv(fptr);
} }
} }
@ -7547,7 +7547,7 @@ argf_set_encoding(int argc, VALUE *argv, VALUE argf)
GetOpenFile(current_file, fptr); GetOpenFile(current_file, fptr);
argf_enc = fptr->encs.enc; argf_enc = fptr->encs.enc;
argf_enc2 = fptr->encs.enc2; argf_enc2 = fptr->encs.enc2;
argf_ecopts = fptr->encs.opts; argf_ecflags = fptr->encs.flags;
return argf; return argf;
} }

View file

@ -83,7 +83,7 @@ typedef struct {
} rb_econv_elem_t; } rb_econv_elem_t;
struct rb_econv_t { struct rb_econv_t {
rb_econv_option_t opts; int flags;
const char *source_encoding_name; const char *source_encoding_name;
const char *destination_encoding_name; const char *destination_encoding_name;
@ -790,7 +790,7 @@ rb_econv_open_by_transcoder_entries(int n, transcoder_entry_t **entries)
} }
ec = ALLOC(rb_econv_t); ec = ALLOC(rb_econv_t);
ec->opts.flags = 0; ec->flags = 0;
ec->source_encoding_name = NULL; ec->source_encoding_name = NULL;
ec->destination_encoding_name = NULL; ec->destination_encoding_name = NULL;
ec->in_buf_start = NULL; ec->in_buf_start = NULL;
@ -855,13 +855,12 @@ trans_open_i(const char *from, const char *to, int depth, void *arg)
} }
rb_econv_t * rb_econv_t *
rb_econv_open(const char *from, const char *to, rb_econv_option_t *opts) rb_econv_open(const char *from, const char *to, int ecflags)
{ {
transcoder_entry_t **entries = NULL; transcoder_entry_t **entries = NULL;
int num_trans; int num_trans;
int num_additional; int num_additional;
static rb_econv_t *ec; static rb_econv_t *ec;
int flags = opts ? opts->flags : 0;
int universal_newline_decoder_added = 0; int universal_newline_decoder_added = 0;
rb_encoding *senc, *denc; rb_encoding *senc, *denc;
@ -898,13 +897,13 @@ rb_econv_open(const char *from, const char *to, rb_econv_option_t *opts)
num_additional = 0; num_additional = 0;
if ((!*from || (senc && rb_enc_asciicompat(senc))) && if ((!*from || (senc && rb_enc_asciicompat(senc))) &&
(flags & (ECONV_CRLF_NEWLINE_ENCODER|ECONV_CR_NEWLINE_ENCODER))) { (ecflags & (ECONV_CRLF_NEWLINE_ENCODER|ECONV_CR_NEWLINE_ENCODER))) {
const char *name = (flags & ECONV_CRLF_NEWLINE_ENCODER) ? "crlf_newline" : "cr_newline"; const char *name = (ecflags & ECONV_CRLF_NEWLINE_ENCODER) ? "crlf_newline" : "cr_newline";
transcoder_entry_t *e = get_transcoder_entry("", name); transcoder_entry_t *e = get_transcoder_entry("", name);
if (flags & ECONV_CRLF_NEWLINE_ENCODER) if (ecflags & ECONV_CRLF_NEWLINE_ENCODER)
flags &= ~ECONV_CR_NEWLINE_ENCODER; ecflags &= ~ECONV_CR_NEWLINE_ENCODER;
else else
flags &= ~ECONV_CRLF_NEWLINE_ENCODER; ecflags &= ~ECONV_CRLF_NEWLINE_ENCODER;
if (!e) { if (!e) {
xfree(entries); xfree(entries);
return NULL; return NULL;
@ -915,11 +914,11 @@ rb_econv_open(const char *from, const char *to, rb_econv_option_t *opts)
num_additional++; num_additional++;
} }
else { else {
flags &= ~(ECONV_CRLF_NEWLINE_ENCODER|ECONV_CR_NEWLINE_ENCODER); ecflags &= ~(ECONV_CRLF_NEWLINE_ENCODER|ECONV_CR_NEWLINE_ENCODER);
} }
if ((!*to || (denc && rb_enc_asciicompat(denc))) && if ((!*to || (denc && rb_enc_asciicompat(denc))) &&
(flags & ECONV_UNIVERSAL_NEWLINE_DECODER)) { (ecflags & ECONV_UNIVERSAL_NEWLINE_DECODER)) {
transcoder_entry_t *e = get_transcoder_entry("universal_newline", ""); transcoder_entry_t *e = get_transcoder_entry("universal_newline", "");
if (!e) { if (!e) {
xfree(entries); xfree(entries);
@ -930,7 +929,7 @@ rb_econv_open(const char *from, const char *to, rb_econv_option_t *opts)
universal_newline_decoder_added = 1; universal_newline_decoder_added = 1;
} }
else { else {
flags &= ~ECONV_UNIVERSAL_NEWLINE_DECODER; ecflags &= ~ECONV_UNIVERSAL_NEWLINE_DECODER;
} }
ec = rb_econv_open_by_transcoder_entries(num_trans, entries); ec = rb_econv_open_by_transcoder_entries(num_trans, entries);
@ -938,11 +937,7 @@ rb_econv_open(const char *from, const char *to, rb_econv_option_t *opts)
if (!ec) if (!ec)
return NULL; return NULL;
if (!opts) ec->flags = ecflags;
ec->opts.flags = 0;
else
ec->opts = *opts;
ec->opts.flags = flags;
ec->source_encoding_name = from; ec->source_encoding_name = from;
ec->destination_encoding_name = to; ec->destination_encoding_name = to;
@ -1283,10 +1278,10 @@ rb_econv_convert(rb_econv_t *ec,
ret == econv_incomplete_input) { ret == econv_incomplete_input) {
/* deal with invalid byte sequence */ /* deal with invalid byte sequence */
/* todo: add more alternative behaviors */ /* todo: add more alternative behaviors */
if (ec->opts.flags&ECONV_INVALID_IGNORE) { if (ec->flags&ECONV_INVALID_IGNORE) {
goto resume; goto resume;
} }
else if (ec->opts.flags&ECONV_INVALID_REPLACE) { else if (ec->flags&ECONV_INVALID_REPLACE) {
if (output_replacement_character(ec) == 0) if (output_replacement_character(ec) == 0)
goto resume; goto resume;
} }
@ -1296,10 +1291,10 @@ rb_econv_convert(rb_econv_t *ec,
/* valid character in source encoding /* valid character in source encoding
* but no related character(s) in destination encoding */ * but no related character(s) in destination encoding */
/* todo: add more alternative behaviors */ /* todo: add more alternative behaviors */
if (ec->opts.flags&ECONV_UNDEF_IGNORE) { if (ec->flags&ECONV_UNDEF_IGNORE) {
goto resume; goto resume;
} }
else if (ec->opts.flags&ECONV_UNDEF_REPLACE) { else if (ec->flags&ECONV_UNDEF_REPLACE) {
if (output_replacement_character(ec) == 0) if (output_replacement_character(ec) == 0)
goto resume; goto resume;
} }
@ -1342,7 +1337,7 @@ allocate_converted_string(const char *str_encoding, const char *insert_encoding,
if (dst_bufsize == 0) if (dst_bufsize == 0)
dst_bufsize += 1; dst_bufsize += 1;
ec = rb_econv_open(str_encoding, insert_encoding, NULL); ec = rb_econv_open(str_encoding, insert_encoding, 0);
if (ec == NULL) if (ec == NULL)
return NULL; return NULL;
dst_str = xmalloc(dst_bufsize); dst_str = xmalloc(dst_bufsize);
@ -1615,7 +1610,7 @@ rb_econv_str_convert(rb_econv_t *ec, VALUE src, int flags)
void void
rb_econv_binmode(rb_econv_t *ec) rb_econv_binmode(rb_econv_t *ec)
{ {
if (ec->opts.flags & ECONV_UNIVERSAL_NEWLINE_DECODER) { if (ec->flags & ECONV_UNIVERSAL_NEWLINE_DECODER) {
int i = ec->num_trans-1; int i = ec->num_trans-1;
rb_transcoding_close(ec->elems[i].tc); rb_transcoding_close(ec->elems[i].tc);
xfree(ec->elems[i].out_buf_start); xfree(ec->elems[i].out_buf_start);
@ -1625,21 +1620,20 @@ rb_econv_binmode(rb_econv_t *ec)
ec->elems[i].out_data_end = NULL; ec->elems[i].out_data_end = NULL;
ec->elems[i].out_buf_end = NULL; ec->elems[i].out_buf_end = NULL;
ec->num_trans--; ec->num_trans--;
ec->opts.flags &= ~ECONV_UNIVERSAL_NEWLINE_DECODER; ec->flags &= ~ECONV_UNIVERSAL_NEWLINE_DECODER;
} }
if (ec->opts.flags & (ECONV_CRLF_NEWLINE_ENCODER|ECONV_CR_NEWLINE_ENCODER)) { if (ec->flags & (ECONV_CRLF_NEWLINE_ENCODER|ECONV_CR_NEWLINE_ENCODER)) {
rb_transcoding_close(ec->elems[0].tc); rb_transcoding_close(ec->elems[0].tc);
xfree(ec->elems[0].out_buf_start); xfree(ec->elems[0].out_buf_start);
MEMMOVE(&ec->elems[0], &ec->elems[1], rb_econv_elem_t, ec->num_trans-1); MEMMOVE(&ec->elems[0], &ec->elems[1], rb_econv_elem_t, ec->num_trans-1);
ec->num_trans--; ec->num_trans--;
ec->opts.flags &= ~(ECONV_CRLF_NEWLINE_ENCODER|ECONV_CR_NEWLINE_ENCODER); ec->flags &= ~(ECONV_CRLF_NEWLINE_ENCODER|ECONV_CR_NEWLINE_ENCODER);
} }
} }
static VALUE static VALUE
econv_description(const char *senc, const char *denc, rb_econv_option_t *opts, VALUE mesg) econv_description(const char *senc, const char *denc, int ecflags, VALUE mesg)
{ {
int flags = opts ? opts->flags : 0;
int has_description = 0; int has_description = 0;
if (NIL_P(mesg)) if (NIL_P(mesg))
@ -1655,21 +1649,21 @@ econv_description(const char *senc, const char *denc, rb_econv_option_t *opts, V
has_description = 1; has_description = 1;
} }
if (flags & (ECONV_UNIVERSAL_NEWLINE_DECODER| if (ecflags & (ECONV_UNIVERSAL_NEWLINE_DECODER|
ECONV_CRLF_NEWLINE_ENCODER| ECONV_CRLF_NEWLINE_ENCODER|
ECONV_CR_NEWLINE_ENCODER)) { ECONV_CR_NEWLINE_ENCODER)) {
const char *pre = ""; const char *pre = "";
if (has_description) if (has_description)
rb_str_cat2(mesg, " with "); rb_str_cat2(mesg, " with ");
if (flags & ECONV_UNIVERSAL_NEWLINE_DECODER) { if (ecflags & ECONV_UNIVERSAL_NEWLINE_DECODER) {
rb_str_cat2(mesg, pre); pre = ","; rb_str_cat2(mesg, pre); pre = ",";
rb_str_cat2(mesg, "Universal-newline"); rb_str_cat2(mesg, "Universal-newline");
} }
if (flags & ECONV_CRLF_NEWLINE_ENCODER) { if (ecflags & ECONV_CRLF_NEWLINE_ENCODER) {
rb_str_cat2(mesg, pre); pre = ","; rb_str_cat2(mesg, pre); pre = ",";
rb_str_cat2(mesg, "CRLF-newline"); rb_str_cat2(mesg, "CRLF-newline");
} }
if (flags & ECONV_CR_NEWLINE_ENCODER) { if (ecflags & ECONV_CR_NEWLINE_ENCODER) {
rb_str_cat2(mesg, pre); pre = ","; rb_str_cat2(mesg, pre); pre = ",";
rb_str_cat2(mesg, "CR-newline"); rb_str_cat2(mesg, "CR-newline");
} }
@ -1683,11 +1677,11 @@ econv_description(const char *senc, const char *denc, rb_econv_option_t *opts, V
} }
VALUE VALUE
rb_econv_open_exc(const char *senc, const char *denc, rb_econv_option_t *opts) rb_econv_open_exc(const char *senc, const char *denc, int ecflags)
{ {
VALUE mesg, exc; VALUE mesg, exc;
mesg = rb_str_new_cstr("code converter open failed ("); mesg = rb_str_new_cstr("code converter open failed (");
econv_description(senc, denc, opts, mesg); econv_description(senc, denc, ecflags, mesg);
rb_str_cat2(mesg, ")"); rb_str_cat2(mesg, ")");
exc = rb_exc_new3(rb_eNoConverter, mesg); exc = rb_exc_new3(rb_eNoConverter, mesg);
return exc; return exc;
@ -1816,7 +1810,7 @@ transcode_loop(const unsigned char **in_pos, unsigned char **out_pos,
unsigned char *(*resize_destination)(VALUE, int, int), unsigned char *(*resize_destination)(VALUE, int, int),
const char *from_encoding, const char *from_encoding,
const char *to_encoding, const char *to_encoding,
rb_econv_option_t *ecopts) int ecflags)
{ {
rb_econv_t *ec; rb_econv_t *ec;
rb_transcoding *last_tc; rb_transcoding *last_tc;
@ -1825,9 +1819,9 @@ transcode_loop(const unsigned char **in_pos, unsigned char **out_pos,
int max_output; int max_output;
VALUE exc; VALUE exc;
ec = rb_econv_open(from_encoding, to_encoding, ecopts); ec = rb_econv_open(from_encoding, to_encoding, ecflags);
if (!ec) if (!ec)
rb_exc_raise(rb_econv_open_exc(from_encoding, to_encoding, ecopts)); rb_exc_raise(rb_econv_open_exc(from_encoding, to_encoding, ecflags));
last_tc = ec->last_tc; last_tc = ec->last_tc;
max_output = last_tc ? last_tc->transcoder->max_output : 1; max_output = last_tc ? last_tc->transcoder->max_output : 1;
@ -1860,7 +1854,7 @@ transcode_loop(const unsigned char **in_pos, unsigned char **out_pos,
unsigned char *(*resize_destination)(VALUE, int, int), unsigned char *(*resize_destination)(VALUE, int, int),
const char *from_encoding, const char *from_encoding,
const char *to_encoding, const char *to_encoding,
rb_econv_option_t *ecopts) int ecflags)
{ {
rb_econv_t *ec; rb_econv_t *ec;
rb_transcoding *last_tc; rb_transcoding *last_tc;
@ -1870,9 +1864,9 @@ transcode_loop(const unsigned char **in_pos, unsigned char **out_pos,
int max_output; int max_output;
VALUE exc; VALUE exc;
ec = rb_econv_open(from_encoding, to_encoding, ecopts); ec = rb_econv_open(from_encoding, to_encoding, ecflags);
if (!ec) if (!ec)
rb_exc_raise(rb_econv_open_exc(from_encoding, to_encoding, ecopts)); rb_exc_raise(rb_econv_open_exc(from_encoding, to_encoding, ecflags));
last_tc = ec->last_tc; last_tc = ec->last_tc;
max_output = last_tc ? last_tc->transcoder->max_output : 1; max_output = last_tc ? last_tc->transcoder->max_output : 1;
@ -1968,13 +1962,13 @@ econv_opts(VALUE opt)
return options; return options;
} }
void int
rb_econv_opts(VALUE hash, rb_econv_option_t *opts) rb_econv_flags(VALUE hash)
{ {
if (NIL_P(hash)) if (NIL_P(hash))
opts->flags = 0; return 0;
else else
opts->flags = econv_opts(hash); return econv_opts(hash);
} }
static int static int
@ -2018,7 +2012,7 @@ str_transcode_enc_args(VALUE str, VALUE arg1, VALUE arg2,
} }
static int static int
str_transcode0(int argc, VALUE *argv, VALUE *self, rb_econv_option_t *ecopts_arg) str_transcode0(int argc, VALUE *argv, VALUE *self, int ecflags)
{ {
VALUE dest; VALUE dest;
VALUE str = *self; VALUE str = *self;
@ -2028,7 +2022,6 @@ str_transcode0(int argc, VALUE *argv, VALUE *self, rb_econv_option_t *ecopts_arg
rb_encoding *from_enc, *to_enc; rb_encoding *from_enc, *to_enc;
const char *from_e, *to_e; const char *from_e, *to_e;
int to_encidx; int to_encidx;
rb_econv_option_t ecopts;
if (argc < 1 || argc > 2) { if (argc < 1 || argc > 2) {
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..2)", argc); rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..2)", argc);
@ -2036,14 +2029,9 @@ str_transcode0(int argc, VALUE *argv, VALUE *self, rb_econv_option_t *ecopts_arg
to_encidx = str_transcode_enc_args(str, argv[0], argc==1 ? Qnil : argv[1], &from_e, &from_enc, &to_e, &to_enc); to_encidx = str_transcode_enc_args(str, argv[0], argc==1 ? Qnil : argv[1], &from_e, &from_enc, &to_e, &to_enc);
if (ecopts_arg) if ((ecflags & (ECONV_UNIVERSAL_NEWLINE_DECODER|
ecopts = *ecopts_arg; ECONV_CRLF_NEWLINE_ENCODER|
else ECONV_CR_NEWLINE_ENCODER)) == 0) {
rb_econv_opts(Qnil, &ecopts);
if ((ecopts.flags & (ECONV_UNIVERSAL_NEWLINE_DECODER|
ECONV_CRLF_NEWLINE_ENCODER|
ECONV_CR_NEWLINE_ENCODER)) == 0) {
if (from_enc && from_enc == to_enc) { if (from_enc && from_enc == to_enc) {
return -1; return -1;
} }
@ -2069,7 +2057,7 @@ str_transcode0(int argc, VALUE *argv, VALUE *self, rb_econv_option_t *ecopts_arg
dest = rb_str_tmp_new(blen); dest = rb_str_tmp_new(blen);
bp = (unsigned char *)RSTRING_PTR(dest); bp = (unsigned char *)RSTRING_PTR(dest);
transcode_loop(&fromp, &bp, (sp+slen), (bp+blen), dest, str_transcoding_resize, from_e, to_e, &ecopts); transcode_loop(&fromp, &bp, (sp+slen), (bp+blen), dest, str_transcoding_resize, from_e, to_e, ecflags);
if (fromp != sp+slen) { if (fromp != sp+slen) {
rb_raise(rb_eArgError, "not fully converted, %"PRIdPTRDIFF" bytes left", sp+slen-fromp); rb_raise(rb_eArgError, "not fully converted, %"PRIdPTRDIFF" bytes left", sp+slen-fromp);
} }
@ -2090,17 +2078,16 @@ static int
str_transcode(int argc, VALUE *argv, VALUE *self) str_transcode(int argc, VALUE *argv, VALUE *self)
{ {
VALUE opt; VALUE opt;
rb_econv_option_t ecopts; int ecflags = 0;
ecopts.flags = 0;
if (0 < argc) { if (0 < argc) {
opt = rb_check_convert_type(argv[argc-1], T_HASH, "Hash", "to_hash"); opt = rb_check_convert_type(argv[argc-1], T_HASH, "Hash", "to_hash");
if (!NIL_P(opt)) { if (!NIL_P(opt)) {
argc--; argc--;
rb_econv_opts(opt, &ecopts); ecflags = rb_econv_flags(opt);
} }
} }
return str_transcode0(argc, argv, self, &ecopts); return str_transcode0(argc, argv, self, ecflags);
} }
static inline VALUE static inline VALUE
@ -2171,12 +2158,12 @@ str_encode(int argc, VALUE *argv, VALUE str)
} }
VALUE VALUE
rb_str_transcode(VALUE str, VALUE to, rb_econv_option_t *ecopts) rb_str_transcode(VALUE str, VALUE to, int ecflags)
{ {
int argc = 1; int argc = 1;
VALUE *argv = &to; VALUE *argv = &to;
VALUE newstr = str; VALUE newstr = str;
int encidx = str_transcode0(argc, argv, &newstr, ecopts); int encidx = str_transcode0(argc, argv, &newstr, ecflags);
if (encidx < 0) return rb_str_dup(str); if (encidx < 0) return rb_str_dup(str);
RBASIC(newstr)->klass = rb_obj_class(str); RBASIC(newstr)->klass = rb_obj_class(str);
@ -2243,14 +2230,14 @@ econv_init(int argc, VALUE *argv, VALUE self)
const char *sname, *dname; const char *sname, *dname;
rb_encoding *senc, *denc; rb_encoding *senc, *denc;
rb_econv_t *ec; rb_econv_t *ec;
rb_econv_option_t ecopts; int ecflags;
rb_scan_args(argc, argv, "21", &source_encoding, &destination_encoding, &flags_v); rb_scan_args(argc, argv, "21", &source_encoding, &destination_encoding, &flags_v);
if (flags_v == Qnil) if (flags_v == Qnil)
ecopts.flags = 0; ecflags = 0;
else else
ecopts.flags = NUM2INT(flags_v); ecflags = NUM2INT(flags_v);
senc = NULL; senc = NULL;
sidx = rb_to_encoding_index(source_encoding); sidx = rb_to_encoding_index(source_encoding);
@ -2277,9 +2264,9 @@ econv_init(int argc, VALUE *argv, VALUE self)
rb_raise(rb_eTypeError, "already initialized"); rb_raise(rb_eTypeError, "already initialized");
} }
ec = rb_econv_open(sname, dname, &ecopts); ec = rb_econv_open(sname, dname, ecflags);
if (!ec) { if (!ec) {
rb_exc_raise(rb_econv_open_exc(sname, dname, &ecopts)); rb_exc_raise(rb_econv_open_exc(sname, dname, ecflags));
} }
if (*sname && *dname) { /* check "" to "universal_newline" */ if (*sname && *dname) { /* check "" to "universal_newline" */
@ -2329,7 +2316,7 @@ econv_inspect(VALUE self)
const char *dname = ec->destination_encoding_name; const char *dname = ec->destination_encoding_name;
VALUE str; VALUE str;
str = rb_sprintf("#<%s: ", cname); str = rb_sprintf("#<%s: ", cname);
econv_description(sname, dname, &ec->opts, str); econv_description(sname, dname, ec->flags, str);
rb_str_cat2(str, ">"); rb_str_cat2(str, ">");
return str; return str;
} }