summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-19 08:22:45 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-19 08:22:45 +0000
commit9b87685aa2dd3351344228eb32c9b90d85994cf6 (patch)
treec182a1fc65de2b4cc91756560a12aa8b202cb9c1
parent284d42ca251cb73a939032cedf834c995b1f6145 (diff)
downloadruby-9b87685aa2dd3351344228eb32c9b90d85994cf6.tar.gz
ruby-9b87685aa2dd3351344228eb32c9b90d85994cf6.tar.xz
ruby-9b87685aa2dd3351344228eb32c9b90d85994cf6.zip
* 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: http://svn.ruby-lang.org/repos/ruby/trunk@20870 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog9
-rw-r--r--hash.c10
-rw-r--r--include/ruby/intern.h1
-rw-r--r--io.c81
4 files changed, 61 insertions, 40 deletions
diff --git a/ChangeLog b/ChangeLog
index f80d700b2..3ecef0bc3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Fri Dec 19 17:01:35 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * 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.
+
Fri Dec 19 15:51:48 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
* ruby.c (process_options): get rid of warning on DOSISH.
diff --git a/hash.c b/hash.c
index f3bd0b66b..b01c4184b 100644
--- a/hash.c
+++ b/hash.c
@@ -463,16 +463,22 @@ rb_hash_aref(VALUE hash, VALUE key)
}
VALUE
-rb_hash_lookup(VALUE hash, VALUE key)
+rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
{
VALUE val;
if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
- return Qnil; /* without Hash#default */
+ return def; /* without Hash#default */
}
return val;
}
+VALUE
+rb_hash_lookup(VALUE hash, VALUE key)
+{
+ return rb_hash_lookup2(hash, key, Qnil);
+}
+
/*
* call-seq:
* hsh.fetch(key [, default] ) => obj
diff --git a/include/ruby/intern.h b/include/ruby/intern.h
index d7ef17023..661b1a5b2 100644
--- a/include/ruby/intern.h
+++ b/include/ruby/intern.h
@@ -359,6 +359,7 @@ VALUE rb_hash_dup(VALUE);
VALUE rb_hash_freeze(VALUE);
VALUE rb_hash_aref(VALUE, VALUE);
VALUE rb_hash_lookup(VALUE, VALUE);
+VALUE rb_hash_lookup2(VALUE, VALUE, VALUE);
VALUE rb_hash_fetch(VALUE, VALUE);
VALUE rb_hash_aset(VALUE, VALUE, VALUE);
VALUE rb_hash_delete_if(VALUE);
diff --git a/io.c b/io.c
index 1b0a20d07..12c6bbba5 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;
}