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:
		
							parent
							
								
									e2ad92a075
								
							
						
					
					
						commit
						3137b0819d
					
				
					 2 changed files with 48 additions and 31 deletions
				
			
		| 
						 | 
				
			
			@ -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>
 | 
			
		||||
 | 
			
		||||
	* ext/readline/readline.c (readline_getc): deal with ESC just followed
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										72
									
								
								string.c
									
										
									
									
									
								
							
							
						
						
									
										72
									
								
								string.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1635,32 +1635,30 @@ rb_str_subseq(VALUE str, long beg, long len)
 | 
			
		|||
    return str2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VALUE
 | 
			
		||||
rb_str_substr(VALUE str, long beg, long len)
 | 
			
		||||
static char *
 | 
			
		||||
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);
 | 
			
		||||
    VALUE str2;
 | 
			
		||||
    char *p, *s = RSTRING_PTR(str), *e = s + RSTRING_LEN(str);
 | 
			
		||||
    char *p, *s = RSTRING_PTR(str), *e = s + blen;
 | 
			
		||||
 | 
			
		||||
    if (len < 0) return Qnil;
 | 
			
		||||
    if (!RSTRING_LEN(str)) {
 | 
			
		||||
    if (len < 0) return 0;
 | 
			
		||||
    if (!blen) {
 | 
			
		||||
	len = 0;
 | 
			
		||||
    }
 | 
			
		||||
    if (single_byte_optimizable(str)) {
 | 
			
		||||
	if (beg > RSTRING_LEN(str)) return Qnil;
 | 
			
		||||
	if (beg > blen) return 0;
 | 
			
		||||
	if (beg < 0) {
 | 
			
		||||
	    beg += RSTRING_LEN(str);
 | 
			
		||||
	    if (beg < 0) return Qnil;
 | 
			
		||||
	    beg += blen;
 | 
			
		||||
	    if (beg < 0) return 0;
 | 
			
		||||
	}
 | 
			
		||||
	if (beg + len > RSTRING_LEN(str))
 | 
			
		||||
	    len = RSTRING_LEN(str) - beg;
 | 
			
		||||
	if (len <= 0) {
 | 
			
		||||
	    len = 0;
 | 
			
		||||
	    p = 0;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	if (beg + len > blen)
 | 
			
		||||
	    len = blen - beg;
 | 
			
		||||
	if (len < 0) return 0;
 | 
			
		||||
	p = s + beg;
 | 
			
		||||
	goto sub;
 | 
			
		||||
	goto end;
 | 
			
		||||
    }
 | 
			
		||||
    if (beg < 0) {
 | 
			
		||||
	if (len > -beg) len = -beg;
 | 
			
		||||
| 
						 | 
				
			
			@ -1668,29 +1666,32 @@ rb_str_substr(VALUE str, long beg, long len)
 | 
			
		|||
	    beg = -beg;
 | 
			
		||||
	    while (beg-- > len && (e = rb_enc_prev_char(s, e, e, enc)) != 0);
 | 
			
		||||
	    p = e;
 | 
			
		||||
	    if (!p) return Qnil;
 | 
			
		||||
	    if (!p) return 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;
 | 
			
		||||
	    goto sub;
 | 
			
		||||
	    goto end;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
	    beg += str_strlen(str, enc);
 | 
			
		||||
	    if (beg < 0) return Qnil;
 | 
			
		||||
	    slen = str_strlen(str, enc);
 | 
			
		||||
	    beg += slen;
 | 
			
		||||
	    if (beg < 0) return 0;
 | 
			
		||||
	    p = s + beg;
 | 
			
		||||
	    if (len == 0) goto end;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
    else if (beg > 0 && beg > RSTRING_LEN(str)) {
 | 
			
		||||
	return Qnil;
 | 
			
		||||
	return 0;
 | 
			
		||||
    }
 | 
			
		||||
    if (len == 0) {
 | 
			
		||||
	if (beg > str_strlen(str, enc)) return Qnil;
 | 
			
		||||
	p = 0;
 | 
			
		||||
	if (beg > str_strlen(str, enc)) return 0;
 | 
			
		||||
	p = s + beg;
 | 
			
		||||
    }
 | 
			
		||||
#ifdef NONASCII_MASK
 | 
			
		||||
    else if (ENC_CODERANGE(str) == ENC_CODERANGE_VALID &&
 | 
			
		||||
        enc == rb_utf8_encoding()) {
 | 
			
		||||
        p = str_utf8_nth(s, e, &beg);
 | 
			
		||||
        if (beg > 0) return Qnil;
 | 
			
		||||
        if (beg > 0) return 0;
 | 
			
		||||
        len = str_utf8_offset(p, e, len);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1699,7 +1700,7 @@ rb_str_substr(VALUE str, long beg, long len)
 | 
			
		|||
 | 
			
		||||
	p = s + beg * char_sz;
 | 
			
		||||
	if (p > e) {
 | 
			
		||||
	    return Qnil;
 | 
			
		||||
	    return 0;
 | 
			
		||||
	}
 | 
			
		||||
        else if (len * char_sz > e - p)
 | 
			
		||||
            len = e - p;
 | 
			
		||||
| 
						 | 
				
			
			@ -1707,14 +1708,25 @@ rb_str_substr(VALUE str, long beg, long len)
 | 
			
		|||
	    len *= char_sz;
 | 
			
		||||
    }
 | 
			
		||||
    else if ((p = str_nth_len(s, e, &beg, enc)) == e) {
 | 
			
		||||
	if (beg > 0) return Qnil;
 | 
			
		||||
	if (beg > 0) return 0;
 | 
			
		||||
	len = 0;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
	len = str_offset(p, e, len, enc, 0);
 | 
			
		||||
    }
 | 
			
		||||
  sub:
 | 
			
		||||
    if (len > RSTRING_EMBED_LEN_MAX && beg + len == RSTRING_LEN(str)) {
 | 
			
		||||
  end:
 | 
			
		||||
    *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 = str_new3(rb_obj_class(str2), str2);
 | 
			
		||||
	RSTRING(str2)->as.heap.ptr += RSTRING(str2)->as.heap.len - len;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue