summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-01-30 07:42:52 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-01-30 07:42:52 +0000
commit842fd42e42144a4c474f80e450033bdcb50a86d5 (patch)
treea4bb3edbaa3e30d57858d5e2f674eda284512923
parent11ab6f8cd55ca6f2c49fba2cd70ab7b296fb9f14 (diff)
merge revision(s) 48803: [Backport #10568]
* pack.c (str_associate, str_associated): keep associated objects in an instance variables, instead of in the internal structure. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_0_0@49447 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog5
-rw-r--r--pack.c35
-rw-r--r--test/ruby/test_pack.rb2
-rw-r--r--version.h2
4 files changed, 38 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index cbc3fd6848..4faf9ef3e8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Fri Jan 30 16:26:57 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * pack.c (str_associate, str_associated): keep associated objects
+ in an instance variables, instead of in the internal structure.
+
Fri Jan 30 16:11:47 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
* lib/rdoc/text.rb (expand_tabs): get rid of infinite loop with
diff --git a/pack.c b/pack.c
index fabbb7ddb0..0ed54cdcbb 100644
--- a/pack.c
+++ b/pack.c
@@ -261,6 +261,31 @@ static void qpencode(VALUE,VALUE,long);
static unsigned long utf8_to_uv(const char*,long*);
+static ID id_associated;
+
+static void
+str_associate(VALUE str, VALUE add)
+{
+ VALUE assoc;
+
+ assoc = rb_attr_get(str, id_associated);
+ if (RB_TYPE_P(assoc, T_ARRAY)) {
+ /* already associated */
+ rb_ary_concat(assoc, add);
+ }
+ else {
+ rb_ivar_set(str, id_associated, add);
+ }
+}
+
+static VALUE
+str_associated(VALUE str)
+{
+ VALUE assoc = rb_attr_get(str, id_associated);
+ if (NIL_P(assoc)) assoc = Qfalse;
+ return assoc;
+}
+
/*
* call-seq:
* arr.pack ( aTemplateString ) -> aBinaryString
@@ -1038,7 +1063,7 @@ pack_pack(VALUE ary, VALUE fmt)
}
if (associates) {
- rb_str_associate(res, associates);
+ str_associate(res, associates);
}
OBJ_INFECT(res, fmt);
switch (enc_info) {
@@ -2055,7 +2080,7 @@ pack_unpack(VALUE str, VALUE fmt)
if (t) {
VALUE a, *p, *pend;
- if (!(a = rb_str_associated(str))) {
+ if (!(a = str_associated(str))) {
rb_raise(rb_eArgError, "no associated pointer");
}
p = RARRAY_PTR(a);
@@ -2064,7 +2089,7 @@ pack_unpack(VALUE str, VALUE fmt)
if (RB_TYPE_P(*p, T_STRING) && RSTRING_PTR(*p) == t) {
if (len < RSTRING_LEN(*p)) {
tmp = rb_tainted_str_new(t, len);
- rb_str_associate(tmp, a);
+ str_associate(tmp, a);
}
else {
tmp = *p;
@@ -2097,7 +2122,7 @@ pack_unpack(VALUE str, VALUE fmt)
if (t) {
VALUE a, *p, *pend;
- if (!(a = rb_str_associated(str))) {
+ if (!(a = str_associated(str))) {
rb_raise(rb_eArgError, "no associated pointer");
}
p = RARRAY_PTR(a);
@@ -2273,4 +2298,6 @@ Init_pack(void)
{
rb_define_method(rb_cArray, "pack", pack_pack, 1);
rb_define_method(rb_cString, "unpack", pack_unpack, 1);
+
+ id_associated = rb_intern_const("__pack_associated__");
}
diff --git a/test/ruby/test_pack.rb b/test/ruby/test_pack.rb
index b3dde2058f..5fa00b58d1 100644
--- a/test/ruby/test_pack.rb
+++ b/test/ruby/test_pack.rb
@@ -181,7 +181,7 @@ class TestPack < Test::Unit::TestCase
assert_equal a[0], a.pack("p").unpack("p")[0]
assert_equal a, a.pack("p").freeze.unpack("p*")
assert_raise(ArgumentError) { (a.pack("p") + "").unpack("p*") }
- assert_raise(ArgumentError) { (a.pack("p") << "d").unpack("p*") }
+ assert_equal a, (a.pack("p") << "d").unpack("p*")
end
def test_format_string_modified
diff --git a/version.h b/version.h
index 4986fc8a99..ee120e6cff 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
#define RUBY_VERSION "2.0.0"
#define RUBY_RELEASE_DATE "2015-01-30"
-#define RUBY_PATCHLEVEL 627
+#define RUBY_PATCHLEVEL 628
#define RUBY_RELEASE_YEAR 2015
#define RUBY_RELEASE_MONTH 1