diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2000-06-22 08:29:58 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2000-06-22 08:29:58 +0000 |
commit | 44cf56d6e70dbe06a160b004494ba40dd4cfb426 (patch) | |
tree | 10e665c60414c3070ce957e5c534e30ed499bc2d /string.c | |
parent | 4b4cad81e7d2bdc4750ea5043ce44bf37adb3997 (diff) |
2000-06-22
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@775 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'string.c')
-rw-r--r-- | string.c | 33 |
1 files changed, 18 insertions, 15 deletions
@@ -181,31 +181,34 @@ rb_str_dup(str) VALUE str; { VALUE str2; + VALUE klass; if (TYPE(str) != T_STRING) str = rb_str_to_str(str); - if (OBJ_FROZEN(str)) return rb_str_new3(str); - if (FL_TEST(str, STR_NO_ORIG)) { + klass = CLASS_OF(str); + while (TYPE(klass) == T_ICLASS || FL_TEST(klass, FL_SINGLETON)) { + klass = (VALUE)RCLASS(klass)->super; + } + + if (OBJ_FROZEN(str)) str2 = rb_str_new3(str); + else if (FL_TEST(str, STR_NO_ORIG)) { str2 = rb_str_new(RSTRING(str)->ptr, RSTRING(str)->len); - OBJ_INFECT(str2, str); - return str2; } - if (RSTRING(str)->orig) { + else if (RSTRING(str)->orig) { str2 = rb_str_new3(RSTRING(str)->orig); - OBJ_INFECT(str2, str); - return str2; } - - str2 = rb_str_new4(str); - { + else { NEWOBJ(dup, struct RString); - OBJSETUP(dup, rb_cString, T_STRING); + OBJSETUP(dup, klass, T_STRING); + + str2 = rb_str_new4(str); dup->len = RSTRING(str2)->len; dup->ptr = RSTRING(str2)->ptr; dup->orig = str2; - OBJ_INFECT(dup, str); - - return (VALUE)dup; + str2 = (VALUE)dup; } + OBJ_INFECT(str2, str); + RBASIC(str2)->klass = klass; + return str2; } @@ -326,7 +329,7 @@ rb_str_substr(str, beg, len) VALUE str2; if (len < 0) return Qnil; - if (beg > RSTRING(str)->len) return Qnil; + if (beg >= RSTRING(str)->len) return Qnil; if (beg < 0) { beg += RSTRING(str)->len; if (beg < 0) return Qnil; |