summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--array.c20
-rw-r--r--test/ruby/test_array.rb7
3 files changed, 37 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 9b8179a093..e131bc3b33 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+Tue Feb 15 15:41:30 2011 NARUSE, Yui <naruse@ruby-lang.org>
+
+ * array.c (array_join): copy the encoding of the first element as
+ an initial encoding.
+
+ * array.c (array_join_0): ditto.
+
+ * array.c (array_join_1): ditto.
+
+ * array.c (inspect_ary): ditto.
+
+ * array.c (array_join_1): add an argument to check the appending is
+ first one or not.
+
Tue Feb 15 15:40:53 2011 NARUSE, Yui <naruse@ruby-lang.org>
* hash.c (inspect_i): copy the encoding of the first key as
diff --git a/array.c b/array.c
index f38e70609f..d505e5a3c4 100644
--- a/array.c
+++ b/array.c
@@ -14,6 +14,7 @@
#include "ruby/ruby.h"
#include "ruby/util.h"
#include "ruby/st.h"
+#include "ruby/encoding.h"
#ifndef ARRAY_DEBUG
# define NDEBUG
@@ -1590,7 +1591,7 @@ rb_ary_resurrect(VALUE ary)
extern VALUE rb_output_fs;
-static void ary_join_1(VALUE obj, VALUE ary, VALUE sep, long i, VALUE result);
+static void ary_join_1(VALUE obj, VALUE ary, VALUE sep, long i, VALUE result, int *first);
static VALUE
recursive_join(VALUE obj, VALUE argp, int recur)
@@ -1599,12 +1600,13 @@ recursive_join(VALUE obj, VALUE argp, int recur)
VALUE ary = arg[0];
VALUE sep = arg[1];
VALUE result = arg[2];
+ int *first = (int *)arg[3];
if (recur) {
rb_raise(rb_eArgError, "recursive array join");
}
else {
- ary_join_1(obj, ary, sep, 0, result);
+ ary_join_1(obj, ary, sep, 0, result, first);
}
return Qnil;
}
@@ -1615,6 +1617,7 @@ ary_join_0(VALUE ary, VALUE sep, long max, VALUE result)
long i;
VALUE val;
+ if (max > 0) rb_enc_copy(result, RARRAY_PTR(ary)[0]);
for (i=0; i<max; i++) {
val = RARRAY_PTR(ary)[i];
if (i > 0 && !NIL_P(sep))
@@ -1626,7 +1629,7 @@ ary_join_0(VALUE ary, VALUE sep, long max, VALUE result)
}
static void
-ary_join_1(VALUE obj, VALUE ary, VALUE sep, long i, VALUE result)
+ary_join_1(VALUE obj, VALUE ary, VALUE sep, long i, VALUE result, int *first)
{
VALUE val, tmp;
@@ -1652,6 +1655,7 @@ ary_join_1(VALUE obj, VALUE ary, VALUE sep, long i, VALUE result)
args[0] = val;
args[1] = sep;
args[2] = result;
+ args[3] = (VALUE)first;
rb_exec_recursive(recursive_join, obj, (VALUE)args);
}
break;
@@ -1668,6 +1672,10 @@ ary_join_1(VALUE obj, VALUE ary, VALUE sep, long i, VALUE result)
goto ary_join;
}
val = rb_obj_as_string(val);
+ if (*first) {
+ rb_enc_copy(result, val);
+ *first = FALSE;
+ }
goto str_join;
}
}
@@ -1694,11 +1702,14 @@ rb_ary_join(VALUE ary, VALUE sep)
tmp = rb_check_string_type(val);
if (NIL_P(tmp) || tmp != val) {
+ int first;
result = rb_str_buf_new(len + (RARRAY_LEN(ary)-i)*10);
+ rb_enc_associate(result, rb_usascii_encoding());
if (taint) OBJ_TAINT(result);
if (untrust) OBJ_UNTRUST(result);
ary_join_0(ary, sep, i, result);
- ary_join_1(ary, ary, sep, i, result);
+ first = i == 0;
+ ary_join_1(ary, ary, sep, i, result, &first);
return result;
}
@@ -1750,6 +1761,7 @@ inspect_ary(VALUE ary, VALUE dummy, int recur)
if (OBJ_TAINTED(s)) tainted = TRUE;
if (OBJ_UNTRUSTED(s)) untrust = TRUE;
if (i > 0) rb_str_buf_cat2(str, ", ");
+ else rb_enc_copy(str, s);
rb_str_buf_append(str, s);
}
rb_str_buf_cat2(str, "]");
diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb
index 1aa8c54f5c..703c417d32 100644
--- a/test/ruby/test_array.rb
+++ b/test/ruby/test_array.rb
@@ -914,6 +914,13 @@ class TestArray < Test::Unit::TestCase
s = a.join
assert_equal(true, s.tainted?)
assert_equal(true, s.untrusted?)
+
+ e = ''.force_encoding('EUC-JP')
+ u = ''.force_encoding('UTF-8')
+ assert_equal(Encoding::US_ASCII, [[]].join.encoding)
+ assert_equal(Encoding::US_ASCII, [1, [u]].join.encoding)
+ assert_equal(Encoding::UTF_8, [u, [e]].join.encoding)
+ assert_equal(Encoding::UTF_8, [u, [1]].join.encoding)
ensure
$, = nil
end