summaryrefslogtreecommitdiff
path: root/string.c
diff options
context:
space:
mode:
Diffstat (limited to 'string.c')
-rw-r--r--string.c122
1 files changed, 68 insertions, 54 deletions
diff --git a/string.c b/string.c
index a60add658a..9fcb74261c 100644
--- a/string.c
+++ b/string.c
@@ -1228,6 +1228,13 @@ rb_str_new_frozen(VALUE orig)
return str_new_frozen(rb_obj_class(orig), orig);
}
+static VALUE
+rb_str_new_frozen_String(VALUE orig)
+{
+ if (OBJ_FROZEN(orig) && rb_obj_class(orig) == rb_cString) return orig;
+ return str_new_frozen(rb_cString, orig);
+}
+
VALUE
rb_str_tmp_frozen_acquire(VALUE orig)
{
@@ -1336,6 +1343,14 @@ str_new_empty(VALUE str)
return v;
}
+static VALUE
+str_new_empty_String(VALUE str)
+{
+ VALUE v = rb_str_new(0, 0);
+ rb_enc_copy(v, str);
+ return v;
+}
+
#define STR_BUF_MIN_SIZE 63
STATIC_ASSERT(STR_BUF_MIN_SIZE, STR_BUF_MIN_SIZE > RSTRING_EMBED_LEN_MAX);
@@ -2036,10 +2051,10 @@ rb_str_times(VALUE str, VALUE times)
int termlen;
if (times == INT2FIX(1)) {
- return rb_str_dup(str);
+ return str_duplicate(rb_cString, str);
}
if (times == INT2FIX(0)) {
- str2 = str_alloc(rb_obj_class(str));
+ str2 = str_alloc(rb_cString);
rb_enc_copy(str2, str);
return str2;
}
@@ -2048,7 +2063,7 @@ rb_str_times(VALUE str, VALUE times)
rb_raise(rb_eArgError, "negative argument");
}
if (RSTRING_LEN(str) == 1 && RSTRING_PTR(str)[0] == 0) {
- str2 = str_alloc(rb_obj_class(str));
+ str2 = str_alloc(rb_cString);
if (!STR_EMBEDDABLE_P(len, 1)) {
RSTRING(str2)->as.heap.aux.capa = len;
RSTRING(str2)->as.heap.ptr = ZALLOC_N(char, (size_t)len + 1);
@@ -2064,7 +2079,7 @@ rb_str_times(VALUE str, VALUE times)
len *= RSTRING_LEN(str);
termlen = TERM_LEN(str);
- str2 = str_new0(rb_obj_class(str), 0, len, termlen);
+ str2 = str_new0(rb_cString, 0, len, termlen);
ptr2 = RSTRING_PTR(str2);
if (len) {
n = RSTRING_LEN(str);
@@ -2545,13 +2560,13 @@ rb_str_subseq(VALUE str, long beg, long len)
if (!STR_EMBEDDABLE_P(len, TERM_LEN(str)) &&
SHARABLE_SUBSTRING_P(beg, len, RSTRING_LEN(str))) {
long olen;
- str2 = rb_str_new_shared(rb_str_new_frozen(str));
+ str2 = rb_str_new_shared(rb_str_new_frozen_String(str));
RSTRING(str2)->as.heap.ptr += beg;
olen = RSTRING(str2)->as.heap.len;
if (olen > len) RSTRING(str2)->as.heap.len = len;
}
else {
- str2 = rb_str_new_with_class(str, RSTRING_PTR(str)+beg, len);
+ str2 = rb_str_new(RSTRING_PTR(str)+beg, len);
RB_GC_GUARD(str);
}
@@ -2664,14 +2679,14 @@ str_substr(VALUE str, long beg, long len, int empty)
SHARABLE_SUBSTRING_P(p, len, RSTRING_END(str))) {
long ofs = p - RSTRING_PTR(str);
str2 = rb_str_new_frozen(str);
- str2 = str_new_shared(rb_obj_class(str2), str2);
+ str2 = str_new_shared(rb_cString, str2);
RSTRING(str2)->as.heap.ptr += ofs;
RSTRING(str2)->as.heap.len = len;
ENC_CODERANGE_CLEAR(str2);
}
else {
if (!len && !empty) return Qnil;
- str2 = rb_str_new_with_class(str, p, len);
+ str2 = rb_str_new(p, len);
RB_GC_GUARD(str);
}
rb_enc_cr_str_copy_for_substr(str2, str);
@@ -4215,7 +4230,7 @@ VALUE
rb_str_succ(VALUE orig)
{
VALUE str;
- str = rb_str_new_with_class(orig, RSTRING_PTR(orig), RSTRING_LEN(orig));
+ str = rb_str_new(RSTRING_PTR(orig), RSTRING_LEN(orig));
rb_enc_cr_str_copy_for_substr(str, orig);
return str_succ(str);
}
@@ -4444,7 +4459,7 @@ rb_str_upto_each(VALUE beg, VALUE end, int excl, int (*each)(VALUE, VALUE), VALU
if (n > 0 || (excl && n == 0)) return beg;
after_end = rb_funcallv(end, succ, 0, 0);
- current = rb_str_dup(beg);
+ current = str_duplicate(rb_cString, beg);
while (!rb_str_equal(current, after_end)) {
VALUE next = Qnil;
if (excl || !rb_str_equal(current, end))
@@ -4492,7 +4507,7 @@ rb_str_upto_endless_each(VALUE beg, int (*each)(VALUE, VALUE), VALUE arg)
}
}
/* normal case */
- current = rb_str_dup(beg);
+ current = str_duplicate(rb_cString, beg);
while (1) {
VALUE next = rb_funcallv(current, succ, 0, 0);
if ((*each)(current, arg)) break;
@@ -4582,7 +4597,7 @@ rb_str_aref(VALUE str, VALUE indx)
}
else if (RB_TYPE_P(indx, T_STRING)) {
if (rb_str_index(str, indx, 0) != -1)
- return rb_str_dup(indx);
+ return str_duplicate(rb_cString, indx);
return Qnil;
}
else {
@@ -5005,7 +5020,7 @@ rb_str_slice_bang(int argc, VALUE *argv, VALUE str)
beg = rb_str_index(str, indx, 0);
if (beg == -1) return Qnil;
len = RSTRING_LEN(indx);
- result = rb_str_dup(indx);
+ result = str_duplicate(rb_cString, indx);
goto squash;
}
else {
@@ -5028,7 +5043,7 @@ rb_str_slice_bang(int argc, VALUE *argv, VALUE str)
beg = p - RSTRING_PTR(str);
subseq:
- result = rb_str_new_with_class(str, RSTRING_PTR(str)+beg, len);
+ result = rb_str_new(RSTRING_PTR(str)+beg, len);
rb_enc_cr_str_copy_for_substr(result, str);
squash:
@@ -5107,7 +5122,7 @@ rb_pat_search(VALUE pat, VALUE str, long pos, int set_backref_str)
pos = rb_strseq_index(str, pat, pos, 1);
if (set_backref_str) {
if (pos >= 0) {
- str = rb_str_new_frozen(str);
+ str = rb_str_new_frozen_String(str);
rb_backref_set_string(str, pos, RSTRING_LEN(pat));
}
else {
@@ -5301,7 +5316,7 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
static VALUE
rb_str_sub(int argc, VALUE *argv, VALUE str)
{
- str = rb_str_dup(str);
+ str = str_duplicate(rb_cString, str);
rb_str_sub_bang(argc, argv, str);
return str;
}
@@ -5341,7 +5356,7 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang)
beg = rb_pat_search(pat, str, 0, need_backref);
if (beg < 0) {
if (bang) return Qnil; /* no match, no substitution */
- return rb_str_dup(str);
+ return str_duplicate(rb_cString, str);
}
offset = 0;
@@ -5422,7 +5437,6 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang)
str_shared_replace(str, dest);
}
else {
- RBASIC_SET_CLASS(dest, rb_obj_class(str));
str = dest;
}
@@ -5685,12 +5699,12 @@ str_byte_substr(VALUE str, long beg, long len, int empty)
if (!STR_EMBEDDABLE_P(len, TERM_LEN(str)) && SHARABLE_SUBSTRING_P(beg, len, n)) {
str2 = rb_str_new_frozen(str);
- str2 = str_new_shared(rb_obj_class(str2), str2);
+ str2 = str_new_shared(rb_cString, str2);
RSTRING(str2)->as.heap.ptr += beg;
RSTRING(str2)->as.heap.len = len;
}
else {
- str2 = rb_str_new_with_class(str, p, len);
+ str2 = rb_str_new(p, len);
}
str_enc_copy(str2, str);
@@ -5792,9 +5806,9 @@ rb_str_reverse(VALUE str)
char *s, *e, *p;
int cr;
- if (RSTRING_LEN(str) <= 1) return rb_str_dup(str);
+ if (RSTRING_LEN(str) <= 1) return str_duplicate(rb_cString, str);
enc = STR_ENC_GET(str);
- rev = rb_str_new_with_class(str, 0, RSTRING_LEN(str));
+ rev = rb_str_new(0, RSTRING_LEN(str));
s = RSTRING_PTR(str); e = RSTRING_END(str);
p = RSTRING_END(rev);
cr = ENC_CODERANGE(str);
@@ -6273,7 +6287,7 @@ rb_str_dump(VALUE str)
len += clen;
}
- result = rb_str_new_with_class(str, 0, len);
+ result = rb_str_new(0, len);
p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str);
q = RSTRING_PTR(result); qend = q + len + 1;
@@ -6696,7 +6710,7 @@ rb_str_casemap(VALUE source, OnigCaseFoldType *flags, rb_encoding *enc)
size_t buffer_count = 0;
int buffer_length_or_invalid;
- if (RSTRING_LEN(source) == 0) return rb_str_dup(source);
+ if (RSTRING_LEN(source) == 0) return str_duplicate(rb_cString, source);
source_current = (OnigUChar*)RSTRING_PTR(source);
source_end = (OnigUChar*)RSTRING_END(source);
@@ -6732,12 +6746,12 @@ rb_str_casemap(VALUE source, OnigCaseFoldType *flags, rb_encoding *enc)
}
if (buffer_count==1) {
- target = rb_str_new_with_class(source, (const char*)current_buffer->space, target_length);
+ target = rb_str_new((const char*)current_buffer->space, target_length);
}
else {
char *target_current;
- target = rb_str_new_with_class(source, 0, target_length);
+ target = rb_str_new(0, target_length);
target_current = RSTRING_PTR(target);
current_buffer = DATA_PTR(buffer_anchor);
while (current_buffer) {
@@ -6870,12 +6884,12 @@ rb_str_upcase(int argc, VALUE *argv, VALUE str)
flags = check_case_options(argc, argv, flags);
enc = str_true_enc(str);
if (case_option_single_p(flags, enc, str)) {
- ret = rb_str_new_with_class(str, RSTRING_PTR(str), RSTRING_LEN(str));
+ ret = rb_str_new(RSTRING_PTR(str), RSTRING_LEN(str));
str_enc_copy(ret, str);
upcase_single(ret);
}
else if (flags&ONIGENC_CASE_ASCII_ONLY) {
- ret = rb_str_new_with_class(str, 0, RSTRING_LEN(str));
+ ret = rb_str_new(0, RSTRING_LEN(str));
rb_str_ascii_casemap(str, ret, &flags, enc);
}
else {
@@ -6998,12 +7012,12 @@ rb_str_downcase(int argc, VALUE *argv, VALUE str)
flags = check_case_options(argc, argv, flags);
enc = str_true_enc(str);
if (case_option_single_p(flags, enc, str)) {
- ret = rb_str_new_with_class(str, RSTRING_PTR(str), RSTRING_LEN(str));
+ ret = rb_str_new(RSTRING_PTR(str), RSTRING_LEN(str));
str_enc_copy(ret, str);
downcase_single(ret);
}
else if (flags&ONIGENC_CASE_ASCII_ONLY) {
- ret = rb_str_new_with_class(str, 0, RSTRING_LEN(str));
+ ret = rb_str_new(0, RSTRING_LEN(str));
rb_str_ascii_casemap(str, ret, &flags, enc);
}
else {
@@ -7078,7 +7092,7 @@ rb_str_capitalize(int argc, VALUE *argv, VALUE str)
enc = str_true_enc(str);
if (RSTRING_LEN(str) == 0 || !RSTRING_PTR(str)) return str;
if (flags&ONIGENC_CASE_ASCII_ONLY) {
- ret = rb_str_new_with_class(str, 0, RSTRING_LEN(str));
+ ret = rb_str_new(0, RSTRING_LEN(str));
rb_str_ascii_casemap(str, ret, &flags, enc);
}
else {
@@ -7142,9 +7156,9 @@ rb_str_swapcase(int argc, VALUE *argv, VALUE str)
flags = check_case_options(argc, argv, flags);
enc = str_true_enc(str);
- if (RSTRING_LEN(str) == 0 || !RSTRING_PTR(str)) return str;
+ if (RSTRING_LEN(str) == 0 || !RSTRING_PTR(str)) return str_duplicate(rb_cString, str);
if (flags&ONIGENC_CASE_ASCII_ONLY) {
- ret = rb_str_new_with_class(str, 0, RSTRING_LEN(str));
+ ret = rb_str_new(0, RSTRING_LEN(str));
rb_str_ascii_casemap(str, ret, &flags, enc);
}
else {
@@ -7518,7 +7532,7 @@ rb_str_tr_bang(VALUE str, VALUE src, VALUE repl)
static VALUE
rb_str_tr(VALUE str, VALUE src, VALUE repl)
{
- str = rb_str_dup(str);
+ str = str_duplicate(rb_cString, str);
tr_trans(str, src, repl, 0);
return str;
}
@@ -7697,7 +7711,7 @@ rb_str_delete_bang(int argc, VALUE *argv, VALUE str)
static VALUE
rb_str_delete(int argc, VALUE *argv, VALUE str)
{
- str = rb_str_dup(str);
+ str = str_duplicate(rb_cString, str);
rb_str_delete_bang(argc, argv, str);
return str;
}
@@ -7805,7 +7819,7 @@ rb_str_squeeze_bang(int argc, VALUE *argv, VALUE str)
static VALUE
rb_str_squeeze(int argc, VALUE *argv, VALUE str)
{
- str = rb_str_dup(str);
+ str = str_duplicate(rb_cString, str);
rb_str_squeeze_bang(argc, argv, str);
return str;
}
@@ -7842,7 +7856,7 @@ rb_str_tr_s_bang(VALUE str, VALUE src, VALUE repl)
static VALUE
rb_str_tr_s(VALUE str, VALUE src, VALUE repl)
{
- str = rb_str_dup(str);
+ str = str_duplicate(rb_cString, str);
tr_trans(str, src, repl, 1);
return str;
}
@@ -7986,12 +8000,12 @@ split_string(VALUE result, VALUE str, long beg, long len, long empty_count)
/* make different substrings */
if (result) {
do {
- rb_ary_push(result, str_new_empty(str));
+ rb_ary_push(result, str_new_empty_String(str));
} while (--empty_count > 0);
}
else {
do {
- rb_yield(str_new_empty(str));
+ rb_yield(str_new_empty_String(str));
} while (--empty_count > 0);
}
}
@@ -8106,11 +8120,11 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str)
if (lim <= 0) limit = Qnil;
else if (lim == 1) {
if (RSTRING_LEN(str) == 0)
- return result ? rb_ary_new2(0) : str;
- tmp = rb_str_dup(str);
+ return result ? rb_ary_new2(0) : str;
+ tmp = str_duplicate(rb_cString, str);
if (!result) {
rb_yield(tmp);
- return str;
+ return str;
}
return rb_ary_new3(1, tmp);
}
@@ -9194,7 +9208,7 @@ static VALUE
rb_str_chomp(int argc, VALUE *argv, VALUE str)
{
VALUE rs = chomp_rs(argc, argv);
- if (NIL_P(rs)) return rb_str_dup(str);
+ if (NIL_P(rs)) return str_duplicate(rb_cString, str);
return rb_str_subseq(str, 0, chompped_length(str, rs));
}
@@ -9281,7 +9295,7 @@ rb_str_lstrip(VALUE str)
long len, loffset;
RSTRING_GETMEM(str, start, len);
loffset = lstrip_offset(str, start, start+len, STR_ENC_GET(str));
- if (loffset <= 0) return rb_str_dup(str);
+ if (loffset <= 0) return str_duplicate(rb_cString, str);
return rb_str_subseq(str, loffset, len - loffset);
}
@@ -9374,7 +9388,7 @@ rb_str_rstrip(VALUE str)
RSTRING_GETMEM(str, start, olen);
roffset = rstrip_offset(str, start, start+olen, enc);
- if (roffset <= 0) return rb_str_dup(str);
+ if (roffset <= 0) return str_duplicate(rb_cString, str);
return rb_str_subseq(str, 0, olen-roffset);
}
@@ -9447,7 +9461,7 @@ rb_str_strip(VALUE str)
loffset = lstrip_offset(str, start, start+olen, enc);
roffset = rstrip_offset(str, start+loffset, start+olen, enc);
- if (loffset <= 0 && roffset <= 0) return rb_str_dup(str);
+ if (loffset <= 0 && roffset <= 0) return str_duplicate(rb_cString, str);
return rb_str_subseq(str, loffset, olen-loffset-roffset);
}
@@ -9843,7 +9857,7 @@ rb_str_justify(int argc, VALUE *argv, VALUE str, char jflag)
}
}
len = str_strlen(str, enc); /* rb_enc_check */
- if (width < 0 || len >= width) return rb_str_dup(str);
+ if (width < 0 || len >= width) return str_duplicate(rb_cString, str);
n = width - len;
llen = (jflag == 'l') ? 0 : ((jflag == 'r') ? n : n/2);
rlen = n - llen;
@@ -9859,7 +9873,7 @@ rb_str_justify(int argc, VALUE *argv, VALUE str, char jflag)
rb_raise(rb_eArgError, "argument too big");
}
len += size;
- res = str_new0(rb_obj_class(str), 0, len, termlen);
+ res = str_new0(rb_cString, 0, len, termlen);
p = RSTRING_PTR(res);
if (flen <= 1) {
memset(p, *f, llen);
@@ -10006,7 +10020,7 @@ rb_str_partition(VALUE str, VALUE sep)
RSTRING_LEN(str)-pos-RSTRING_LEN(sep)));
failed:
- return rb_ary_new3(3, rb_str_dup(str), str_new_empty(str), str_new_empty(str));
+ return rb_ary_new3(3, str_duplicate(rb_cString, str), str_new_empty_String(str), str_new_empty_String(str));
}
/*
@@ -10054,7 +10068,7 @@ rb_str_rpartition(VALUE str, VALUE sep)
rb_str_subseq(str, pos+RSTRING_LEN(sep),
RSTRING_LEN(str)-pos-RSTRING_LEN(sep)));
failed:
- return rb_ary_new3(3, str_new_empty(str), str_new_empty(str), rb_str_dup(str));
+ return rb_ary_new3(3, str_new_empty_String(str), str_new_empty_String(str), str_duplicate(rb_cString, str));
}
/*
@@ -10200,7 +10214,7 @@ rb_str_delete_prefix(VALUE str, VALUE prefix)
long prefixlen;
prefixlen = deleted_prefix_length(str, prefix);
- if (prefixlen <= 0) return rb_str_dup(str);
+ if (prefixlen <= 0) return str_duplicate(rb_cString, str);
return rb_str_subseq(str, prefixlen, RSTRING_LEN(str) - prefixlen);
}
@@ -10286,7 +10300,7 @@ rb_str_delete_suffix(VALUE str, VALUE suffix)
long suffixlen;
suffixlen = deleted_suffix_length(str, suffix);
- if (suffixlen <= 0) return rb_str_dup(str);
+ if (suffixlen <= 0) return str_duplicate(rb_cString, str);
return rb_str_subseq(str, 0, RSTRING_LEN(str) - suffixlen);
}
@@ -10417,7 +10431,7 @@ rb_str_ellipsize(VALUE str, long len)
else if (len <= ellipsislen ||
!(e = rb_enc_step_back(p, e, e, len = ellipsislen, enc))) {
if (rb_enc_asciicompat(enc)) {
- ret = rb_str_new_with_class(str, ellipsis, len);
+ ret = rb_str_new(ellipsis, len);
rb_enc_associate(ret, enc);
}
else {
@@ -10742,7 +10756,7 @@ str_scrub(int argc, VALUE *argv, VALUE str)
{
VALUE repl = argc ? (rb_check_arity(argc, 0, 1), argv[0]) : Qnil;
VALUE new = rb_str_scrub(str, repl);
- return NIL_P(new) ? rb_str_dup(str): new;
+ return NIL_P(new) ? str_duplicate(rb_cString, str): new;
}
/*