summaryrefslogtreecommitdiff
path: root/array.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-05-16 09:05:54 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-05-16 09:05:54 +0000
commitf84f4aa6b375290386c0456ac02fe8f6cc2cdd2d (patch)
treefba985cc67803c80f7761462f79cf988cbf6507b /array.c
parent59d82a928a617889c18f4da6152f11c0eb6fde06 (diff)
* array.c (rb_ary_and): should not push frozen key string.
* array.c (rb_ary_or): ditto. * eval.c (rb_thread_schedule): should save context before raising deadlock, saved context for current thread might be obsolete. * time.c (make_time_t): non DST timezone shift supported (hopefully). * time.c (make_time_t): strict range detection for negative time_t. * signal.c: SIGINFO added. * eval.c (rb_ensure): should not SEGV when prot_tag is NULL. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1399 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'array.c')
-rw-r--r--array.c64
1 files changed, 35 insertions, 29 deletions
diff --git a/array.c b/array.c
index 4d6a96ef1c..1d63a9fa2b 100644
--- a/array.c
+++ b/array.c
@@ -739,11 +739,26 @@ inspect_join(ary, arg)
return rb_ary_join(arg[0], arg[1]);
}
+static long
+str_cpy(str, idx, str2)
+ VALUE str;
+ long idx;
+ VALUE str2;
+{
+ long len = idx + RSTRING(str2)->len;
+
+ if (RSTRING(str)->len < len) {
+ rb_str_resize(str, len);
+ }
+ memcpy(RSTRING(str)->ptr+idx, RSTRING(str2)->ptr, RSTRING(str2)->len);
+ return len;
+}
+
VALUE
rb_ary_join(ary, sep)
VALUE ary, sep;
{
- long i;
+ long len, i, j;
int taint = 0;
VALUE result, tmp;
@@ -751,30 +766,21 @@ rb_ary_join(ary, sep)
if (OBJ_TAINTED(ary)) taint = 1;
if (OBJ_TAINTED(sep)) taint = 1;
- tmp = RARRAY(ary)->ptr[0];
- if (OBJ_TAINTED(tmp)) taint = 1;
- switch (TYPE(tmp)) {
- case T_STRING:
- result = rb_str_dup(tmp);
- break;
- case T_ARRAY:
- if (rb_inspecting_p(tmp)) {
- result = rb_str_new2("[...]");
+ len = 1;
+ for (i=0; i<RARRAY(ary)->len; i++) {
+ if (TYPE(RARRAY(ary)->ptr[i]) == T_STRING) {
+ len += RSTRING(RARRAY(ary)->ptr[i])->len;
}
else {
- VALUE args[2];
-
- args[0] = tmp;
- args[1] = sep;
- result = rb_protect_inspect(inspect_join, ary, (VALUE)args);
+ len += 10;
}
- break;
- default:
- result = rb_str_dup(rb_obj_as_string(tmp));
- break;
}
+ if (!NIL_P(sep) && TYPE(sep) == T_STRING) {
+ len += RSTRING(sep)->len * RARRAY(ary)->len - 1;
+ }
+ result = rb_str_new(0, len);
- for (i=1; i<RARRAY(ary)->len; i++) {
+ for (i=0, j=0; i<RARRAY(ary)->len; i++) {
tmp = RARRAY(ary)->ptr[i];
switch (TYPE(tmp)) {
case T_STRING:
@@ -794,10 +800,11 @@ rb_ary_join(ary, sep)
default:
tmp = rb_obj_as_string(tmp);
}
- if (!NIL_P(sep)) rb_str_append(result, sep);
- rb_str_append(result, tmp);
+ if (i > 0 && !NIL_P(sep)) j = str_cpy(result, j, sep);
+ j = str_cpy(result, j, tmp);
if (OBJ_TAINTED(tmp)) taint = 1;
}
+ rb_str_resize(result, j);
if (taint) OBJ_TAINT(result);
return result;
@@ -1291,8 +1298,6 @@ VALUE
rb_ary_concat(x, y)
VALUE x, y;
{
- long ylen;
-
y = to_ary(y);
if (RARRAY(y)->len > 0) {
rb_ary_update(x, RARRAY(x)->len, 0, y);
@@ -1498,7 +1503,7 @@ rb_ary_and(ary1, ary2)
for (i=0; i<RARRAY(ary1)->len; i++) {
VALUE v = RARRAY(ary1)->ptr[i];
if (st_delete(RHASH(hash)->tbl, &v, 0)) {
- rb_ary_push(ary3, v);
+ rb_ary_push(ary3, RARRAY(ary1)->ptr[i]);
}
}
@@ -1520,13 +1525,13 @@ rb_ary_or(ary1, ary2)
for (i=0; i<RARRAY(ary1)->len; i++) {
v = RARRAY(ary1)->ptr[i];
if (st_delete(RHASH(hash)->tbl, &v, 0)) {
- rb_ary_push(ary3, v);
+ rb_ary_push(ary3, RARRAY(ary1)->ptr[i]);
}
}
for (i=0; i<RARRAY(ary2)->len; i++) {
v = RARRAY(ary2)->ptr[i];
if (st_delete(RHASH(hash)->tbl, &v, 0)) {
- rb_ary_push(ary3, v);
+ rb_ary_push(ary3, RARRAY(ary2)->ptr[i]);
}
}
@@ -1548,10 +1553,11 @@ rb_ary_uniq_bang(ary)
p = q = RARRAY(ary)->ptr;
end = p + RARRAY(ary)->len;
while (p < end) {
- VALUE v = *p++;
+ VALUE v = *p;
if (st_delete(RHASH(hash)->tbl, &v, 0)) {
- *q++ = v;
+ *q++ = *p;
}
+ p++;
}
RARRAY(ary)->len = (q - RARRAY(ary)->ptr);