# \[m17n\] String#chop & String#succ

**URL:** <https://www.ruby-forum.com/t/m17n-string-chop-string-succ/113823>\
**Category:** Development\
**Created:** [September 5, 2007, 9:26am UTC](https://www.ruby-forum.com/t/m17n-string-chop-string-succ/113823 "2007-09-05T09:26:33Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [September 5, 2007, 9:26am UTC](https://www.ruby-forum.com/t/m17n-string-chop-string-succ/113823/1 "2007-09-05T09:26:33Z")

</div>

e$B$J$+$@$G$9!#e(B

[http://dontstopmusic.no-ip.org/diary/20070827.html#p02](http://dontstopmusic.no-ip.org/diary/20070827.html#p02) e$B$G;XE&$5e(B  
e$B$l$F$$$ke(Bchope$B$He(Bsucce$B$K4X$9$k%Q%C%A$G$9!#e(B

succe$B$K4X$7$F$O!"1Q?t;z0J30$OC1=c$KJ8;z%3!\<%I=g$K$:$i$7$F$$$^$9$,!"e(B  
e$BK\Mh$J$i$R$i$,$J$H$+%+%?%+%J$H$+$NCf$G7+$j\>e$2$r$7$?$[$&$,$$$$$Ne(B  
e$B$+$b$7$l$^$;$s!#$?$V$s0J2\<$N$h$&$J5!G=$,I,MW$K$J$k$+$H;W$$$^$9!#e(B

1 scripte$B$rD4$Y$ke(B  
2 e$B=g=xIU2DG=$+D4$Y$ke(B  
3 e$B$“$ke(Bscripte$BCf$G$N\<!$NJ8;z$rF@$ke(B  
4 e$B$”$ke(Bscripte$BCf$G$N:G=i$NJ8;z$rF@$ke(B

# Index: string.c

— string.c (revision 13339)  
+++ string.c (working copy)  
@@ -1585,4 +1585,45 @@ succ\_char(char \*s)  
}

+static int  
+enc\_succ\_char(unsigned int c, char \*s, rb\_encoding \*enc)  
+{

- unsigned int cs;
- 
- /\* numerics \*/
- if (rb\_enc\_isdigit(c, enc)) {
- cs = c++;
- if (rb\_enc\_isdigit(c, enc)) {
- 

```
 rb_enc_mbcput(c, s, enc);

```

- 

```
 return 0;

```

- }
- do c = cs–; while (rb\_enc\_isdigit(cs, enc));
- rb\_enc\_mbcput(c, s, enc);
- return ++c;
- }
- /\* small alphabets \*/
- if (rb\_enc\_islower(c, enc)) {
- cs = c++;
- if (rb\_enc\_islower(c, enc)) {
- 

```
 rb_enc_mbcput(c, s, enc);

```

- 

```
 return 0;

```

- }
- do c = cs–; while (rb\_enc\_islower(cs, enc));
- rb\_enc\_mbcput(c, s, enc);
- return c;
- }
- /\* capital alphabets \*/
- if (rb\_enc\_isupper(c, enc)) {
- cs = c++;
- if (rb\_enc\_isupper(c, enc)) {
- 

```
 rb_enc_mbcput(c, s, enc);

```

- 

```
 return 0;

```

- }
- do c = cs–; while (rb\_enc\_isupper(cs, enc));
- rb\_enc\_mbcput(c, s, enc);
- return c;
- }
- return -1;  
+}
- 

/\*  
@@ -1618,36 +1659,49 @@ rb\_str\_succ(VALUE orig)  
char \*sbeg, \*s, \*e;  
int c = -1;

- long n = 0;

- long n = 0, o = 0, l;

- char carry[ONIGENC\_CODE\_TO\_MBC\_MAXLEN];

- rb\_enc\_copy(str, orig);  
OBJ\_INFECT(str, orig);  
if (RSTRING\_LEN(str) == 0) return str;

- sbeg = RSTRING\_PTR(str); s = sbeg + RSTRING\_LEN(str) - 1;
- e = RSTRING\_END(str);

- sbeg = RSTRING\_PTR(str);
- s = e = sbeg + RSTRING\_LEN(str);

- while (sbeg \<= s) {

- while (sbeg \<= (s = rb\_enc\_prev\_char(sbeg, s, enc))) {  
unsigned int cc = rb\_enc\_codepoint(s, e, enc);  
if (rb\_enc\_isalnum(cc, enc)) {

- 

```
 if ((c = succ_char(s)) == 0) break;

```

- 

```
 if (isascii(cc)) {

```

- if ((c = succ\_char(s)) == 0) break;
- 

```
 }

```

- 

```
 else {

```

- if ((c = enc\_succ\_char(cc, s, enc)) == 0) break;
- 

```
 }
 n = s - sbeg;

```

}

- s–;  
}  
if (c == -1) { /\* str contains no alnum \*/
- sbeg = RSTRING\_PTR(str); s = sbeg + RSTRING\_LEN(str) - 1;  
c = ‘\001’;
- while (sbeg \<= s) {
- 

```
 if ((*s += 1) != 0) break;

```

- 

```
 s--;

```

- s = e;
- while (sbeg \<= (s = rb\_enc\_prev\_char(sbeg, e, enc))) {
- 

```
 unsigned int cc = rb_enc_codepoint(s, e, enc) + 1;

```

- 

```
 l = rb_enc_mbcput(cc, carry, enc);

```

- 

```
 if (l > 0) {

```

- if (l == (o = e - s)) goto overlay;
- n = s - sbeg;
- goto insert;
- 

```
 }

```

}  
}

- if (s \< sbeg) {
- RESIZE\_CAPA(str, RSTRING\_LEN(str) + 1);

- if (s \< sbeg && (l = rb\_enc\_mbcput(c, carry, enc)) \> 0) {
- 

```
 insert:

```

- RESIZE\_CAPA(str, RSTRING\_LEN(str) + l - o);  
s = RSTRING\_PTR(str) + n;

- memmove(s+1, s, RSTRING\_LEN(str) - n);
- \*s = c;
- STR\_SET\_LEN(str, RSTRING\_LEN(str) + 1);

- memmove(s + l, s + o, RSTRING\_LEN(str) - n - o);
- 

```
 overlay:

```

- memmove(s, carry, l);
- STR\_SET\_LEN(str, RSTRING\_LEN(str) + l - o);  
RSTRING\_PTR(str)[RSTRING\_LEN(str)] = ‘\0’;  
}  
@@ -4041,4 +4095,22 @@ rb\_str\_each\_char(VALUE str)  
}

+static long  
+chopped\_length(VALUE str)  
+{

- rb\_encoding \*enc = rb\_enc\_get(str);
- const char \*p, \*p2, \*beg, \*end;
- 
- beg = RSTRING\_PTR(str);
- end = beg + RSTRING\_LEN(str);
- if (beg \> end) return 0;
- p = rb\_enc\_prev\_char(beg, end, enc);
- if (!p) return 0;
- if (p \> beg && rb\_enc\_codepoint(p, end, enc) == ‘\n’) {
- p2 = rb\_enc\_prev\_char(beg, p, enc);
- if (p2 && rb\_enc\_codepoint(p2, end, enc) == ‘\r’) p = p2;
- }
- return p - beg;  
+}
- 

/\*

- call-seq:  
@@ -4054,13 +4126,9 @@ rb\_str\_chop\_bang(VALUE str)  
{  
if (RSTRING\_LEN(str) \> 0) {

- long len;  
rb\_str\_modify(str);

- STR\_DEC\_LEN(str);
- if (RSTRING\_PTR(str)[RSTRING\_LEN(str)] == ‘\n’) {
- 

```
 if (RSTRING_LEN(str) > 0 &&

```

- RSTRING\_PTR(str)[RSTRING\_LEN(str)-1] == ‘\r’) {
- STR\_DEC\_LEN(str);
- 

```
 }

```

- }
- RSTRING\_PTR(str)[RSTRING\_LEN(str)] = ‘\0’;

- len = chopped\_length(str);
- STR\_SET\_LEN(str, len);
- RSTRING\_PTR(str)[len] = ‘\0’;  
return str;  
}  
@@ -4089,7 +4157,8 @@ static VALUE  
rb\_str\_chop(VALUE str)  
{

- str = rb\_str\_dup(str);
- rb\_str\_chop\_bang(str);
- return str;

- VALUE str2 = rb\_str\_new5(str, RSTRING\_PTR(str),  
chopped\_length(str));
- rb\_enc\_copy(str2, str);
- OBJ\_INFECT(str2, str);
- return str2;  
}

# Index: include/ruby/encoding.h

— include/ruby/encoding.h (revision 13339)  
+++ include/ruby/encoding.h (working copy)  
@@ -63,5 +63,5 @@ int rb\_enc\_codelen(int, rb\_encoding\*);

/\* ptr, ptr, encoding → prev\_char _/  
-#define rb\_enc\_prev\_char(s,p,enc)  
onigenc\_get\_prev\_char\_head(enc,(UChar_)s,(UChar\*)p)  
+#define rb\_enc\_prev\_char(s,p,enc) (char  
_)onigenc\_get\_prev\_char\_head(enc,(UChar_)s,(UChar\*)p)

#define rb\_enc\_isascii(c,enc) ONIGENC\_IS\_CODE\_ASCII(c)

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [September 5, 2007, 11:01am UTC](https://www.ruby-forum.com/t/m17n-string-chop-string-succ/113823/2 "2007-09-05T11:01:40Z")

</div>

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:31734] [m17n] String#chop & String#succ”  
on Wed, 5 Sep 2007 16:25:46 +0900, Nobuyoshi N.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

|[http://dontstopmusic.no-ip.org/diary/20070827.html#p02](http://dontstopmusic.no-ip.org/diary/20070827.html#p02) e$B$G;XE&$5e(B  
|e$B$l$F$$$ke(Bchope$B$He(Bsucce$B$K4X$9$k%Q%C%A$G$9!#e(B

e$B%3%\_%C%H$7$F$/$@$5$$!#e(B

|succe$B$K4X$7$F$O!“1Q?t;z0J30$OC1=c$KJ8;z%3!\<%I=g$K$:$i$7$F$$$^$9$,!“e(B  
|e$BK\Mh$J$i$R$i$,$J$H$+%+%?%+%J$H$+$NCf$G7+$j\>e$2$r$7$?$[$&$,$$$$$Ne(B  
|e$B$+$b$7$l$^$;$s!#$?$V$s0J2\<$N$h$&$J5!G=$,I,MW$K$J$k$+$H;W$$$^$9!#e(B  
|  
|1 scripte$B$rD4$Y$ke(B  
|2 e$B=g=xIU2DG=$+D4$Y$ke(B  
|3 e$B$”$ke(Bscripte$BCf$G$N\<!$NJ8;z$rF@$ke(B  
|4 e$B$”$ke(Bscripte$BCf$G$N:G=i$NJ8;z$rF@$ke(B

1e$B$O$9$G$K$“$k$h$&$G$9$,!”$=$l0J30$O?7@\_$9$kI,MW$,$"$j$^$9$M!#e(B  
e$B$7$+$7!"e(Bsucce$B$4$H$-$N$?$a$Ke(Bpremitivee$B$rA}$d$9$N$O;?@.$7$+$M$^$9!#e(B  
e$B!Ve(Binvalide$B$JJ8;z$r@8@.$7$J$$!W$H$$$&%A%'%C%/$@$1$G=\<J,$G$O$Je(B  
e$B$$$G$7$g$&$+!#e(B
