summaryrefslogtreecommitdiff
path: root/io.c
diff options
context:
space:
mode:
authoryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-19 12:12:03 +0000
committeryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-19 12:12:03 +0000
commit600a52cac12e4b38bf5ece703794b7a90def99b7 (patch)
treeb38fdbfdda435026a4a4b5f0514b19592cd1f641 /io.c
parentd82eb1a48bfd20e22f77623938e4407db2f1e6ca (diff)
merges r20870 from trunk into ruby_1_9_1.
* io.c (rb_io_extract_encoding_option): "internal_encoding: nil" to specify no-transcoding. and other corner case fixed. [ruby-dev:37496] * hash.c (rb_hash_lookup2): new function to look-up hash with default value. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_1@20886 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r--io.c81
1 files changed, 43 insertions, 38 deletions
diff --git a/io.c b/io.c
index 62f0a2152f..dc5e111dd5 100644
--- a/io.c
+++ b/io.c
@@ -3917,55 +3917,60 @@ rb_io_mode_enc(rb_io_t *fptr, const char *modestr)
int
rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p)
{
- VALUE encoding=Qnil, extenc=Qnil, intenc=Qnil;
+ VALUE encoding=Qnil, extenc=Qundef, intenc=Qundef, tmp;
int extracted = 0;
+ rb_encoding *extencoding = NULL;
+ rb_encoding *intencoding = NULL;
+
if (!NIL_P(opt)) {
VALUE v;
- v = rb_hash_aref(opt, sym_encoding);
- if (!NIL_P(v)) encoding = v;
- v = rb_hash_aref(opt, sym_extenc);
- if (!NIL_P(v)) extenc = v;
- v = rb_hash_aref(opt, sym_intenc);
- if (!NIL_P(v)) intenc = v;
- }
- if (!NIL_P(extenc)) {
- rb_encoding *extencoding = rb_to_encoding(extenc);
- rb_encoding *intencoding = NULL;
- extracted = 1;
- if (!NIL_P(encoding)) {
- rb_warn("Ignoring encoding parameter '%s': external_encoding is used",
- RSTRING_PTR(encoding));
+ v = rb_hash_lookup2(opt, sym_encoding, Qnil);
+ if (v != Qnil) encoding = v;
+ v = rb_hash_lookup2(opt, sym_extenc, Qundef);
+ if (v != Qnil) extenc = v;
+ v = rb_hash_lookup2(opt, sym_intenc, Qundef);
+ if (v != Qundef) intenc = v;
+ }
+ if ((extenc != Qundef || intenc != Qundef) && !NIL_P(encoding)) {
+ rb_warn("Ignoring encoding parameter '%s': %s_encoding is used",
+ StringValueCStr(encoding),
+ extenc == Qundef ? "internal" : "external");
+ encoding = Qnil;
+ }
+ if (extenc != Qundef && !NIL_P(extenc)) {
+ extencoding = rb_to_encoding(extenc);
+ }
+ if (intenc != Qundef) {
+ if (NIL_P(intenc)) {
+ /* internal_encoding: nil => no transcoding */
+ intencoding = (rb_encoding *)Qnil;
}
- if (!NIL_P(intenc)) {
- if (!NIL_P(encoding = rb_check_string_type(intenc))) {
- char *p = StringValueCStr(encoding);
- if (*p == '-' && *(p+1) == '\0') {
- /* Special case - "-" => no transcoding */
- intencoding = (rb_encoding *)Qnil;
- }
- else
- intencoding = rb_to_encoding(intenc);
+ else if (!NIL_P(tmp = rb_check_string_type(intenc))) {
+ char *p = StringValueCStr(tmp);
+
+ if (*p == '-' && *(p+1) == '\0') {
+ /* Special case - "-" => no transcoding */
+ intencoding = (rb_encoding *)Qnil;
}
- else
+ else {
intencoding = rb_to_encoding(intenc);
- if (extencoding == intencoding) {
- rb_warn("Ignoring internal encoding '%s': it is identical to external encoding '%s'",
- RSTRING_PTR(rb_inspect(intenc)),
- RSTRING_PTR(rb_inspect(extenc)));
- intencoding = (rb_encoding *)Qnil;
}
}
- rb_io_ext_int_to_encs(extencoding, intencoding, enc_p, enc2_p);
- }
- else {
- if (!NIL_P(intenc)) {
- rb_raise(rb_eArgError, "External encoding must be specified when internal encoding is given");
+ else {
+ intencoding = rb_to_encoding(intenc);
}
- if (!NIL_P(encoding)) {
- extracted = 1;
- parse_mode_enc(StringValueCStr(encoding), enc_p, enc2_p);
+ if (extencoding == intencoding) {
+ intencoding = (rb_encoding *)Qnil;
}
}
+ if (!NIL_P(encoding)) {
+ extracted = 1;
+ parse_mode_enc(StringValueCStr(encoding), enc_p, enc2_p);
+ }
+ else if (extenc != Qundef || intenc != Qundef) {
+ extracted = 1;
+ rb_io_ext_int_to_encs(extencoding, intencoding, enc_p, enc2_p);
+ }
return extracted;
}