1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

rb_str_subpos

* string.c (rb_str_subpos): split from rb_str_substr.  returns
  adjusted position for substring.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36124 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2012-06-18 08:10:13 +00:00
parent e2ad92a075
commit 3137b0819d
2 changed files with 48 additions and 31 deletions

View file

@ -1,3 +1,8 @@
Mon Jun 18 17:10:08 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* string.c (rb_str_subpos): split from rb_str_substr. returns
adjusted position for substring.
Mon Jun 18 10:42:57 2012 Nobuyoshi Nakada <nobu@ruby-lang.org> Mon Jun 18 10:42:57 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* ext/readline/readline.c (readline_getc): deal with ESC just followed * ext/readline/readline.c (readline_getc): deal with ESC just followed

View file

@ -1635,32 +1635,30 @@ rb_str_subseq(VALUE str, long beg, long len)
return str2; return str2;
} }
VALUE static char *
rb_str_substr(VALUE str, long beg, long len) rb_str_subpos(VALUE str, long beg, long *lenp)
{ {
long len = *lenp;
long slen = -1L;
long blen = RSTRING_LEN(str);
rb_encoding *enc = STR_ENC_GET(str); rb_encoding *enc = STR_ENC_GET(str);
VALUE str2; char *p, *s = RSTRING_PTR(str), *e = s + blen;
char *p, *s = RSTRING_PTR(str), *e = s + RSTRING_LEN(str);
if (len < 0) return Qnil; if (len < 0) return 0;
if (!RSTRING_LEN(str)) { if (!blen) {
len = 0; len = 0;
} }
if (single_byte_optimizable(str)) { if (single_byte_optimizable(str)) {
if (beg > RSTRING_LEN(str)) return Qnil; if (beg > blen) return 0;
if (beg < 0) { if (beg < 0) {
beg += RSTRING_LEN(str); beg += blen;
if (beg < 0) return Qnil; if (beg < 0) return 0;
} }
if (beg + len > RSTRING_LEN(str)) if (beg + len > blen)
len = RSTRING_LEN(str) - beg; len = blen - beg;
if (len <= 0) { if (len < 0) return 0;
len = 0;
p = 0;
}
else
p = s + beg; p = s + beg;
goto sub; goto end;
} }
if (beg < 0) { if (beg < 0) {
if (len > -beg) len = -beg; if (len > -beg) len = -beg;
@ -1668,29 +1666,32 @@ rb_str_substr(VALUE str, long beg, long len)
beg = -beg; beg = -beg;
while (beg-- > len && (e = rb_enc_prev_char(s, e, e, enc)) != 0); while (beg-- > len && (e = rb_enc_prev_char(s, e, e, enc)) != 0);
p = e; p = e;
if (!p) return Qnil; if (!p) return 0;
while (len-- > 0 && (p = rb_enc_prev_char(s, p, e, enc)) != 0); while (len-- > 0 && (p = rb_enc_prev_char(s, p, e, enc)) != 0);
if (!p) return Qnil; if (!p) return 0;
len = e - p; len = e - p;
goto sub; goto end;
} }
else { else {
beg += str_strlen(str, enc); slen = str_strlen(str, enc);
if (beg < 0) return Qnil; beg += slen;
if (beg < 0) return 0;
p = s + beg;
if (len == 0) goto end;
} }
} }
else if (beg > 0 && beg > RSTRING_LEN(str)) { else if (beg > 0 && beg > RSTRING_LEN(str)) {
return Qnil; return 0;
} }
if (len == 0) { if (len == 0) {
if (beg > str_strlen(str, enc)) return Qnil; if (beg > str_strlen(str, enc)) return 0;
p = 0; p = s + beg;
} }
#ifdef NONASCII_MASK #ifdef NONASCII_MASK
else if (ENC_CODERANGE(str) == ENC_CODERANGE_VALID && else if (ENC_CODERANGE(str) == ENC_CODERANGE_VALID &&
enc == rb_utf8_encoding()) { enc == rb_utf8_encoding()) {
p = str_utf8_nth(s, e, &beg); p = str_utf8_nth(s, e, &beg);
if (beg > 0) return Qnil; if (beg > 0) return 0;
len = str_utf8_offset(p, e, len); len = str_utf8_offset(p, e, len);
} }
#endif #endif
@ -1699,7 +1700,7 @@ rb_str_substr(VALUE str, long beg, long len)
p = s + beg * char_sz; p = s + beg * char_sz;
if (p > e) { if (p > e) {
return Qnil; return 0;
} }
else if (len * char_sz > e - p) else if (len * char_sz > e - p)
len = e - p; len = e - p;
@ -1707,14 +1708,25 @@ rb_str_substr(VALUE str, long beg, long len)
len *= char_sz; len *= char_sz;
} }
else if ((p = str_nth_len(s, e, &beg, enc)) == e) { else if ((p = str_nth_len(s, e, &beg, enc)) == e) {
if (beg > 0) return Qnil; if (beg > 0) return 0;
len = 0; len = 0;
} }
else { else {
len = str_offset(p, e, len, enc, 0); len = str_offset(p, e, len, enc, 0);
} }
sub: end:
if (len > RSTRING_EMBED_LEN_MAX && beg + len == RSTRING_LEN(str)) { *lenp = len;
return p;
}
VALUE
rb_str_substr(VALUE str, long beg, long len)
{
VALUE str2;
char *p = rb_str_subpos(str, beg, &len);
if (!p) return Qnil;
if (len > RSTRING_EMBED_LEN_MAX && p + len == RSTRING_END(str)) {
str2 = rb_str_new4(str); str2 = rb_str_new4(str);
str2 = str_new3(rb_obj_class(str2), str2); str2 = str_new3(rb_obj_class(str2), str2);
RSTRING(str2)->as.heap.ptr += RSTRING(str2)->as.heap.len - len; RSTRING(str2)->as.heap.ptr += RSTRING(str2)->as.heap.len - len;