summaryrefslogtreecommitdiff
path: root/string.c
diff options
context:
space:
mode:
Diffstat (limited to 'string.c')
-rw-r--r--string.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/string.c b/string.c
index ddf50e2eed..8b37a4dccb 100644
--- a/string.c
+++ b/string.c
@@ -174,7 +174,7 @@ rb_str_associate(str, add)
rb_ary_push(RSTRING(str)->orig, add);
}
-static ID to_str;
+static ID id_to_s;
VALUE
rb_obj_as_string(obj)
@@ -185,7 +185,7 @@ rb_obj_as_string(obj)
if (TYPE(obj) == T_STRING) {
return obj;
}
- str = rb_funcall(obj, to_str, 0);
+ str = rb_funcall(obj, id_to_s, 0);
if (TYPE(str) != T_STRING)
return rb_any_to_s(obj);
if (OBJ_TAINTED(obj)) OBJ_TAINT(str);
@@ -339,7 +339,6 @@ rb_str_substr(str, beg, len)
if (len < 0) return Qnil;
if (beg > RSTRING(str)->len) return Qnil;
- if (beg == RSTRING(str)->len && len > 0) return Qnil;
if (beg < 0) {
beg += RSTRING(str)->len;
if (beg < 0) return Qnil;
@@ -367,7 +366,6 @@ str_independent(str)
rb_raise(rb_eSecurityError, "Insecure: can't modify string");
if (!RSTRING(str)->orig || FL_TEST(str, STR_NO_ORIG)) return 1;
if (TYPE(RSTRING(str)->orig) != T_STRING) rb_bug("non string str->orig");
- RSTRING(str)->orig = 0;
return 0;
}
@@ -384,6 +382,7 @@ rb_str_modify(str)
}
ptr[RSTRING(str)->len] = 0;
RSTRING(str)->ptr = ptr;
+ RSTRING(str)->orig = 0;
}
VALUE
@@ -1127,7 +1126,7 @@ rb_str_sub_bang(argc, argv, str)
iter = 1;
}
else if (argc == 2) {
- repl = rb_obj_as_string(argv[1]);;
+ repl = rb_str_to_str(argv[1]);;
if (OBJ_TAINTED(repl)) tainted = 1;
}
else {
@@ -1200,7 +1199,7 @@ str_gsub(argc, argv, str, bang)
iter = 1;
}
else if (argc == 2) {
- repl = rb_obj_as_string(argv[1]);
+ repl = rb_str_to_str(argv[1]);
if (OBJ_TAINTED(repl)) tainted = 1;
}
else {
@@ -1278,6 +1277,9 @@ str_gsub(argc, argv, str, bang)
if (str_independent(str)) {
free(RSTRING(str)->ptr);
}
+ else {
+ RSTRING(str)->orig = 0;
+ }
}
else {
NEWOBJ(dup, struct RString);
@@ -1316,15 +1318,19 @@ static VALUE
rb_str_replace_m(str, str2)
VALUE str, str2;
{
+ if (str == str2) return str;
if (TYPE(str2) != T_STRING) str2 = rb_str_to_str(str2);
- rb_str_modify(str);
- if (RSTRING(str2)->orig && FL_TEST(str2, STR_NO_ORIG)) {
+ if (RSTRING(str2)->orig && !FL_TEST(str2, STR_NO_ORIG)) {
+ if (str_independent(str)) {
+ free(RSTRING(str)->ptr);
+ }
RSTRING(str)->len = RSTRING(str2)->len;
RSTRING(str)->ptr = RSTRING(str2)->ptr;
RSTRING(str)->orig = RSTRING(str2)->orig;
}
else {
+ rb_str_modify(str);
rb_str_resize(str, RSTRING(str2)->len);
memcpy(RSTRING(str)->ptr, RSTRING(str2)->ptr, RSTRING(str2)->len);
}
@@ -1395,6 +1401,7 @@ rb_str_reverse_bang(str)
char *s, *e;
char c;
+ rb_str_modify(str);
s = RSTRING(str)->ptr;
e = s + RSTRING(str)->len - 1;
while (s < e) {
@@ -1490,8 +1497,8 @@ rb_str_inspect(str)
char c = *p++;
if (ismbchar(c) && p < pend) {
int len = mbclen(c);
- rb_str_cat(result, p, len);
- p += len;
+ rb_str_cat(result, p - 1, len);
+ p += len - 1;
}
else if (c == '"'|| c == '\\') {
s[0] = '\\'; s[1] = c;
@@ -1644,7 +1651,7 @@ rb_str_upcase_bang(str)
if (ismbchar(*s)) {
s+=mbclen(*s) - 1;
}
- else if (islower(*s)) {
+ else if (ISLOWER(*s)) {
*s = toupper(*s);
modify = 1;
}
@@ -1784,7 +1791,10 @@ trnext(t)
if (!t->gen) {
if (t->p == t->pend) return -1;
t->now = *(USTR)t->p++;
- if (t->p < t->pend - 1 && *t->p == '-') {
+ if (t->p < t->pend - 1 && *t->p == '\\') {
+ t->p++;
+ }
+ else if (t->p < t->pend - 1 && *t->p == '-') {
t->p++;
if (t->p < t->pend) {
if (t->now > *(USTR)t->p) {
@@ -1965,6 +1975,9 @@ rb_str_delete_bang(argc, argv, str)
int init = 1;
int i;
+ if (argc < 1) {
+ rb_raise(rb_eArgError, "wrong # of arguments");
+ }
for (i=0; i<argc; i++) {
VALUE s = argv[i];
@@ -2877,7 +2890,7 @@ Init_String()
rb_define_method(rb_cString, "slice", rb_str_aref_m, -1);
rb_define_method(rb_cString, "slice!", rb_str_slice_bang, -1);
- to_str = rb_intern("to_s");
+ id_to_s = rb_intern("to_s");
rb_fs = Qnil;
rb_define_hooked_variable("$;", &rb_fs, 0, rb_str_setter);