23 #define BEG(no) (regs->beg[(no)]) 24 #define END(no) (regs->end[(no)]) 33 #if defined HAVE_CRYPT_R 34 # if defined HAVE_CRYPT_H 37 #elif !defined HAVE_CRYPT 39 # define HAVE_CRYPT_R 1 42 #define STRING_ENUMERATORS_WANTARRAY 0 45 #undef rb_usascii_str_new 46 #undef rb_utf8_str_new 48 #undef rb_str_new_cstr 49 #undef rb_tainted_str_new_cstr 50 #undef rb_usascii_str_new_cstr 51 #undef rb_utf8_str_new_cstr 52 #undef rb_enc_str_new_cstr 53 #undef rb_external_str_new_cstr 54 #undef rb_locale_str_new_cstr 55 #undef rb_str_dup_frozen 56 #undef rb_str_buf_new_cstr 58 #undef rb_str_buf_cat2 60 #undef rb_str_cat_cstr 61 #undef rb_fstring_cstr 62 #undef rb_fstring_enc_cstr 83 #define RUBY_MAX_CHAR_LEN 16 84 #define STR_IS_SHARED_M FL_USER6 85 #define STR_TMPLOCK FL_USER7 86 #define STR_NOFREE FL_USER18 87 #define STR_FAKESTR FL_USER19 89 #define STR_SET_NOEMBED(str) do {\ 90 FL_SET((str), STR_NOEMBED);\ 91 STR_SET_EMBED_LEN((str), 0);\ 93 #define STR_SET_EMBED(str) FL_UNSET((str), (STR_NOEMBED|STR_NOFREE)) 94 #define STR_SET_EMBED_LEN(str, n) do { \ 96 RBASIC(str)->flags &= ~RSTRING_EMBED_LEN_MASK;\ 97 RBASIC(str)->flags |= (tmp_n) << RSTRING_EMBED_LEN_SHIFT;\ 100 #define STR_SET_LEN(str, n) do { \ 101 if (STR_EMBED_P(str)) {\ 102 STR_SET_EMBED_LEN((str), (n));\ 105 RSTRING(str)->as.heap.len = (n);\ 109 #define STR_DEC_LEN(str) do {\ 110 if (STR_EMBED_P(str)) {\ 111 long n = RSTRING_LEN(str);\ 113 STR_SET_EMBED_LEN((str), n);\ 116 RSTRING(str)->as.heap.len--;\ 120 #define TERM_LEN(str) rb_enc_mbminlen(rb_enc_get(str)) 121 #define TERM_FILL(ptr, termlen) do {\ 122 char *const term_fill_ptr = (ptr);\ 123 const int term_fill_len = (termlen);\ 124 *term_fill_ptr = '\0';\ 125 if (UNLIKELY(term_fill_len > 1))\ 126 memset(term_fill_ptr, 0, term_fill_len);\ 129 #define RESIZE_CAPA(str,capacity) do {\ 130 const int termlen = TERM_LEN(str);\ 131 RESIZE_CAPA_TERM(str,capacity,termlen);\ 133 #define RESIZE_CAPA_TERM(str,capacity,termlen) do {\ 134 if (STR_EMBED_P(str)) {\ 135 if (!STR_EMBEDDABLE_P(capacity, termlen)) {\ 136 char *const tmp = ALLOC_N(char, (size_t)(capacity) + (termlen));\ 137 const long tlen = RSTRING_LEN(str);\ 138 memcpy(tmp, RSTRING_PTR(str), tlen);\ 139 RSTRING(str)->as.heap.ptr = tmp;\ 140 RSTRING(str)->as.heap.len = tlen;\ 141 STR_SET_NOEMBED(str);\ 142 RSTRING(str)->as.heap.aux.capa = (capacity);\ 146 assert(!FL_TEST((str), STR_SHARED)); \ 147 REALLOC_N(RSTRING(str)->as.heap.ptr, char, (size_t)(capacity) + (termlen));\ 148 RSTRING(str)->as.heap.aux.capa = (capacity);\ 152 #define STR_SET_SHARED(str, shared_str) do { \ 153 if (!FL_TEST(str, STR_FAKESTR)) { \ 154 RB_OBJ_WRITE((str), &RSTRING(str)->as.heap.aux.shared, (shared_str)); \ 155 FL_SET((str), STR_SHARED); \ 156 if (RBASIC_CLASS((shared_str)) == 0) \ 157 FL_SET_RAW((shared_str), STR_IS_SHARED_M); \ 161 #define STR_HEAP_PTR(str) (RSTRING(str)->as.heap.ptr) 162 #define STR_HEAP_SIZE(str) ((size_t)RSTRING(str)->as.heap.aux.capa + TERM_LEN(str)) 164 #define STR_ENC_GET(str) get_encoding(str) 166 #if !defined SHARABLE_MIDDLE_SUBSTRING 167 # define SHARABLE_MIDDLE_SUBSTRING 0 169 #if !SHARABLE_MIDDLE_SUBSTRING 170 #define SHARABLE_SUBSTRING_P(beg, len, end) ((beg) + (len) == (end)) 172 #define SHARABLE_SUBSTRING_P(beg, len, end) 1 175 #define STR_EMBEDDABLE_P(len, termlen) \ 176 ((len) <= RSTRING_EMBED_LEN_MAX + 1 - (termlen)) 181 static VALUE str_new_static(
VALUE klass,
const char *ptr,
long len,
int encindex);
182 static void str_make_independent_expand(
VALUE str,
long len,
long expand,
const int termlen);
183 static inline void str_modifiable(
VALUE str);
187 str_make_independent(
VALUE str)
191 str_make_independent_expand((str), len, 0L, termlen);
195 static VALUE sym_ascii, sym_turkic, sym_lithuanian, sym_fold;
198 get_actual_encoding(
const int encidx,
VALUE str)
200 const unsigned char *q;
206 if (q[0] == 0xFE && q[1] == 0xFF) {
209 if (q[0] == 0xFF && q[1] == 0xFE) {
216 if (q[0] == 0 && q[1] == 0 && q[2] == 0xFE && q[3] == 0xFF) {
219 if (q[3] == 0 && q[2] == 0 && q[1] == 0xFE && q[0] == 0xFF) {
228 get_encoding(
VALUE str)
234 mustnot_broken(
VALUE str)
242 mustnot_wchar(
VALUE str)
259 #define BARE_STRING_P(str) (!FL_ANY_RAW(str, FL_TAINT|FL_EXIVAR) && RBASIC_CLASS(str) == rb_cString) 290 str_make_independent(str);
299 *key = *value = *fstr = str;
322 fstr = register_fstring(str);
325 str_replace_shared_without_enc(str, fstr);
333 register_fstring(
VALUE str)
353 setup_fake_str(
struct RString *fake_str,
const char *
name,
long len,
int encidx)
361 fake_str->as.heap.len =
len;
362 fake_str->as.heap.ptr = (
char *)name;
363 fake_str->as.heap.aux.capa =
len;
364 return (
VALUE)fake_str;
410 const char *aptr, *bptr;
413 return (alen != blen ||
415 memcmp(aptr, bptr, alen) != 0);
419 single_byte_optimizable(
VALUE str)
438 static inline const char *
439 search_nonascii(
const char *p,
const char *e)
442 #if SIZEOF_VOIDP == 8 443 # define NONASCII_MASK 0x8080808080808080ULL 444 #elif SIZEOF_VOIDP == 4 445 # define NONASCII_MASK 0x80808080UL 449 #if !UNALIGNED_WORD_ACCESS 451 int l = SIZEOF_VOIDP - (
uintptr_t)p % SIZEOF_VOIDP;
456 case 7:
if (p[-7]&0x80)
return p-7;
457 case 6:
if (p[-6]&0x80)
return p-6;
458 case 5:
if (p[-5]&0x80)
return p-5;
459 case 4:
if (p[-4]&0x80)
return p-4;
461 case 3:
if (p[-3]&0x80)
return p-3;
462 case 2:
if (p[-2]&0x80)
return p-2;
463 case 1:
if (p[-1]&0x80)
return p-1;
469 t = (
const uintptr_t *)(e - (SIZEOF_VOIDP-1));
471 if (*s & NONASCII_MASK) {
472 #ifdef WORDS_BIGENDIAN 473 return (
const char *)s + (nlz_intptr(*s&NONASCII_MASK)>>3);
475 return (
const char *)s + (ntz_intptr(*s&NONASCII_MASK)>>3);
485 case 7:
if (e[-7]&0x80)
return e-7;
486 case 6:
if (e[-6]&0x80)
return e-6;
487 case 5:
if (e[-5]&0x80)
return e-5;
488 case 4:
if (e[-4]&0x80)
return e-4;
490 case 3:
if (e[-3]&0x80)
return e-3;
491 case 2:
if (e[-2]&0x80)
return e-2;
492 case 1:
if (e[-1]&0x80)
return e-1;
498 coderange_scan(
const char *p,
long len,
rb_encoding *enc)
500 const char *e = p +
len;
504 p = search_nonascii(p, e);
509 p = search_nonascii(p, e);
516 p = search_nonascii(p, e);
541 p = search_nonascii(p, e);
546 p = search_nonascii(p, e);
559 p = search_nonascii(p, e);
584 rb_enc_cr_str_copy_for_substr(
VALUE dest,
VALUE src)
589 str_enc_copy(dest, src);
614 rb_enc_cr_str_exact_copy(
VALUE dest,
VALUE src)
616 str_enc_copy(dest, src);
633 get_actual_encoding(encidx, str));
653 str_mod_check(
VALUE s,
const char *p,
long len)
661 str_capacity(
VALUE str,
const int termlen)
667 return RSTRING(str)->as.heap.len;
670 return RSTRING(str)->as.heap.aux.capa;
677 return str_capacity(str,
TERM_LEN(str));
681 must_not_null(
const char *
ptr)
689 str_alloc(
VALUE klass)
696 empty_str_alloc(
VALUE klass)
699 return str_alloc(klass);
703 str_new0(
VALUE klass,
const char *ptr,
long len,
int termlen)
713 str = str_alloc(klass);
731 str_new(
VALUE klass,
const char *ptr,
long len)
733 return str_new0(klass, ptr, len, 1);
804 str_new_static(
VALUE klass,
const char *ptr,
long len,
int encindex)
818 str = str_alloc(klass);
820 RSTRING(str)->as.heap.ptr = (
char *)ptr;
832 return str_new_static(
rb_cString, ptr, len, 0);
863 rb_tainted_str_new_with_enc(
const char *ptr,
long len,
rb_encoding *enc)
880 static VALUE str_cat_conv_enc_opts(
VALUE newstr,
long ofs,
const char *ptr,
long len,
882 int ecflags,
VALUE ecopts);
893 if (from == to)
return str;
905 from, to, ecflags, ecopts);
921 if (ofs < -olen || olen < ofs)
923 if (ofs < 0) ofs += olen;
930 return str_cat_conv_enc_opts(newstr, ofs, ptr, len, from,
945 str_cat_conv_enc_opts(
VALUE newstr,
long ofs,
const char *ptr,
long len,
947 int ecflags,
VALUE ecopts)
953 const unsigned char *start, *sp;
954 unsigned char *dest, *
dp;
955 size_t converted_output = (size_t)ofs;
962 if (!ec)
return Qnil;
965 sp = (
unsigned char*)ptr;
967 while ((dest = (
unsigned char*)
RSTRING_PTR(newstr)),
968 (dp = dest + converted_output),
972 size_t converted_input = sp - start;
973 size_t rest = len - converted_input;
974 converted_output = dp - dest;
976 if (converted_input && converted_output &&
977 rest < (
LONG_MAX / converted_output)) {
978 rest = (rest * converted_output) / converted_input;
983 olen += rest < 2 ? 2 : rest;
1021 if (!ienc || eenc == ienc) {
1022 return rb_tainted_str_new_with_enc(ptr, len, eenc);
1029 return rb_tainted_str_new_with_enc(ptr, len, ienc);
1032 str = rb_tainted_str_new_with_enc(
NULL, 0, ienc);
1109 str_replace_shared_without_enc(
VALUE str2,
VALUE str)
1117 char *ptr2 =
RSTRING(str2)->as.ary;
1137 str_replace_shared_without_enc(str2, str);
1138 rb_enc_cr_str_exact_copy(str2, str);
1145 return str_replace_shared(str_alloc(klass), str);
1176 tmp = str_new_frozen(0, orig);
1200 RSTRING(orig)->as.heap.aux.capa =
RSTRING(tmp)->as.heap.aux.capa;
1219 long ofs =
RSTRING(orig)->as.heap.ptr -
RSTRING(shared)->as.heap.ptr;
1220 long rest =
RSTRING(shared)->as.heap.len - ofs -
RSTRING(orig)->as.heap.len;
1224 if ((ofs > 0) || (rest > 0) ||
1225 (klass !=
RBASIC(shared)->klass) ||
1228 str = str_new_shared(klass, shared);
1229 RSTRING(str)->as.heap.ptr += ofs;
1230 RSTRING(str)->as.heap.len -= ofs + rest;
1239 str = str_alloc(klass);
1246 str = str_alloc(klass);
1250 RSTRING(str)->as.heap.aux.capa =
RSTRING(orig)->as.heap.aux.capa;
1259 rb_enc_cr_str_exact_copy(str, orig);
1271 str_new_empty(
VALUE str)
1279 #define STR_BUF_MIN_SIZE 127 1292 RSTRING(str)->as.heap.ptr[0] =
'\0';
1312 return str_new(0, 0, len);
1354 static inline void str_discard(
VALUE str);
1355 static void str_shared_replace(
VALUE str,
VALUE str2);
1360 if (str != str2) str_shared_replace(str, str2);
1395 RSTRING(str)->as.heap.aux.capa =
RSTRING(str2)->as.heap.aux.capa;
1445 rb_enc_cr_str_exact_copy(str, str2);
1448 str_replace_shared(str, str2);
1459 const VALUE flag_mask =
1465 VALUE dup = str_alloc(klass);
1470 str = str_new_frozen(klass, str);
1474 if (flags & STR_NOEMBED) {
1522 static ID keyword_ids[2];
1523 VALUE orig, opt, venc, vcapa;
1528 if (!keyword_ids[0]) {
1530 CONST_ID(keyword_ids[1],
"capacity");
1555 if (orig == str) n = 0;
1557 str_modifiable(str);
1559 RSTRING(str)->as.heap.ptr =
ALLOC_N(
char, (
size_t)capa + termlen);
1568 rb_enc_cr_str_exact_copy(str, orig);
1587 #ifdef NONASCII_MASK 1588 #define is_utf8_lead_byte(c) (((c)&0xC0) != 0x80) 1604 count_utf8_lead_bytes_with_word(
const uintptr_t *s)
1609 d = (d>>6) | (~d>>7);
1610 d &= NONASCII_MASK >> 7;
1613 #if defined(HAVE_BUILTIN___BUILTIN_POPCOUNT) && defined(__POPCNT__) 1615 return rb_popcount_intptr(d);
1619 # if SIZEOF_VOIDP == 8 1628 enc_strlen(
const char *p,
const char *e,
rb_encoding *enc,
int cr)
1634 long diff = (long)(e - p);
1637 #ifdef NONASCII_MASK 1640 if ((
int)
sizeof(
uintptr_t) * 2 < e - p) {
1645 while (p < (
const char *)s) {
1646 if (is_utf8_lead_byte(*p)) len++;
1650 len += count_utf8_lead_bytes_with_word(s);
1653 p = (
const char *)s;
1656 if (is_utf8_lead_byte(*p)) len++;
1667 q = search_nonascii(p, e);
1680 q = search_nonascii(p, e);
1693 for (c=0; p<e; c++) {
1717 long diff = (long)(e - p);
1724 q = search_nonascii(p, e);
1747 for (c=0; p<e; c++) {
1772 if (single_byte_optimizable(str))
return RSTRING_LEN(str);
1784 return enc_strlen(p, e, enc, cr);
1791 return str_strlen(str,
NULL);
1819 rb_str_bytesize(
VALUE str)
1836 rb_str_empty(
VALUE str)
1858 char *ptr1, *ptr2, *ptr3;
1870 str3 = str_new0(
rb_cString, 0, len1+len2, termlen);
1872 memcpy(ptr3, ptr1, len1);
1873 memcpy(ptr3+len1, ptr2, len2);
1939 while (n <= len/2) {
1940 memcpy(ptr2 + n, ptr2, n);
1943 memcpy(ptr2 + n, ptr2, len-n);
1948 rb_enc_cr_str_copy_for_substr(str2, str);
1982 rb_check_lockedtmp(
VALUE str)
1990 str_modifiable(
VALUE str)
1992 rb_check_lockedtmp(str);
1997 str_dependent_p(
VALUE str)
2008 str_independent(
VALUE str)
2010 str_modifiable(str);
2011 return !str_dependent_p(str);
2015 str_make_independent_expand(
VALUE str,
long len,
long expand,
const int termlen)
2019 long capa = len + expand;
2021 if (len > capa) len =
capa;
2024 ptr =
RSTRING(str)->as.heap.ptr;
2032 ptr =
ALLOC_N(
char, (
size_t)capa + termlen);
2035 memcpy(ptr, oldptr, len);
2048 if (!str_independent(str))
2049 str_make_independent(str);
2066 if (!str_independent(str)) {
2067 str_make_independent_expand(str, len, expand, termlen);
2069 else if (expand > 0) {
2077 str_modify_keep_cr(
VALUE str)
2079 if (!str_independent(str))
2080 str_make_independent(str);
2087 str_discard(
VALUE str)
2089 str_modifiable(str);
2092 RSTRING(str)->as.heap.ptr = 0;
2093 RSTRING(str)->as.heap.len = 0;
2125 zero_filled(
const char *s,
int n)
2127 for (; n > 0; --n) {
2134 str_null_char(
const char *s,
long len,
const int minlen,
rb_encoding *enc)
2136 const char *e = s +
len;
2139 if (zero_filled(s, minlen))
return s;
2145 str_fill_term(
VALUE str,
char *s,
long len,
int termlen)
2150 if (str_dependent_p(str)) {
2151 if (!zero_filled(s + len, termlen))
2152 str_make_independent_expand(str, len, 0L, termlen);
2164 long capa = str_capacity(str, oldtermlen) + oldtermlen;
2168 if (capa - len < termlen) {
2169 rb_check_lockedtmp(str);
2170 str_make_independent_expand(str, len, 0L, termlen);
2172 else if (str_dependent_p(str)) {
2173 if (termlen > oldtermlen)
2174 str_make_independent_expand(str, len, 0L, termlen);
2180 RSTRING(str)->as.heap.aux.capa = capa - termlen;
2182 if (termlen > oldtermlen) {
2191 str_null_check(
VALUE str,
int *w)
2200 if (str_null_char(s, len, minlen, enc)) {
2203 return str_fill_term(str, s, len, minlen);
2206 if (!s || memchr(s, 0, len)) {
2210 s = str_fill_term(str, s, len, minlen);
2219 return str_null_check(str, &w);
2227 char *s = str_null_check(str, &w);
2242 return str_fill_term(str, s, len, newminlen);
2270 str_nth_len(
const char *p,
const char *e,
long *nthp,
rb_encoding *enc)
2280 const char *p2, *e2;
2283 while (p < e && 0 < nth) {
2290 p2 = search_nonascii(p, e2);
2310 while (p < e && nth--) {
2322 return str_nth_len(p, e, &nth, enc);
2326 str_nth(
const char *p,
const char *e,
long nth,
rb_encoding *enc,
int singlebyte)
2331 p = str_nth_len(p, e, &nth, enc);
2340 str_offset(
const char *p,
const char *e,
long nth,
rb_encoding *enc,
int singlebyte)
2342 const char *pp = str_nth(p, e, nth, enc, singlebyte);
2343 if (!pp)
return e - p;
2354 #ifdef NONASCII_MASK 2356 str_utf8_nth(
const char *p,
const char *e,
long *nthp)
2359 if ((
int)SIZEOF_VOIDP * 2 < e - p && (
int)SIZEOF_VOIDP * 2 < nth) {
2361 const uintptr_t lowbits = SIZEOF_VOIDP - 1;
2364 while (p < (
const char *)s) {
2365 if (is_utf8_lead_byte(*p)) nth--;
2369 nth -= count_utf8_lead_bytes_with_word(s);
2371 }
while (s < t && (
int)SIZEOF_VOIDP <= nth);
2375 if (is_utf8_lead_byte(*p)) {
2376 if (nth == 0)
break;
2386 str_utf8_offset(
const char *p,
const char *e,
long nth)
2388 const char *pp = str_utf8_nth(p, e, &nth);
2397 if (single_byte_optimizable(str) || pos < 0)
2414 RSTRING(str2)->as.heap.ptr += beg;
2415 olen =
RSTRING(str2)->as.heap.len;
2416 if (olen > len)
RSTRING(str2)->as.heap.len =
len;
2423 rb_enc_cr_str_copy_for_substr(str2, str);
2438 if (len < 0)
return 0;
2442 if (single_byte_optimizable(str)) {
2443 if (beg > blen)
return 0;
2446 if (beg < 0)
return 0;
2448 if (len > blen - beg)
2450 if (len < 0)
return 0;
2455 if (len > -beg) len = -beg;
2467 slen = str_strlen(str, enc);
2469 if (beg < 0)
return 0;
2471 if (len == 0)
goto end;
2478 if (beg > str_strlen(str, enc))
return 0;
2481 #ifdef NONASCII_MASK 2484 p = str_utf8_nth(s, e, &beg);
2485 if (beg > 0)
return 0;
2486 len = str_utf8_offset(p, e, len);
2492 p = s + beg * char_sz;
2496 else if (len * char_sz > e - p)
2501 else if ((p = str_nth_len(s, e, &beg, enc)) == e) {
2502 if (beg > 0)
return 0;
2506 len = str_offset(p, e, len, enc, 0);
2514 static VALUE str_substr(
VALUE str,
long beg,
long len,
int empty);
2519 return str_substr(str, beg, len,
TRUE);
2523 str_substr(
VALUE str,
long beg,
long len,
int empty)
2528 if (!p)
return Qnil;
2534 RSTRING(str2)->as.heap.ptr += ofs;
2538 if (!len && !empty)
return Qnil;
2543 rb_enc_cr_str_copy_for_substr(str2, str);
2566 str_uplus(
VALUE str)
2586 str_uminus(
VALUE str)
2597 #define rb_str_dup_frozen rb_str_new_frozen 2632 str_modifiable(str);
2636 if (len > (capa = (
long)str_capacity(str, termlen)) || len < 0) {
2637 rb_bug(
"probable buffer overflow: %ld for %ld", len, capa);
2653 independent = str_independent(str);
2661 if (len == slen)
return str;
2667 str_make_independent_expand(str, slen, len - slen, termlen);
2672 if (slen > len) slen =
len;
2679 else if (!independent) {
2680 if (len == slen)
return str;
2681 str_make_independent_expand(str, slen, len - slen, termlen);
2683 else if ((capa =
RSTRING(str)->
as.heap.aux.capa) < len ||
2684 (capa - len) > (len < 1024 ? len : 1024)) {
2688 else if (len == slen)
return str;
2696 str_buf_cat(
VALUE str,
const char *ptr,
long len)
2698 long capa, total, olen, off = -1;
2704 if (ptr >= sptr && ptr <= sptr + olen) {
2708 if (len == 0)
return 0;
2715 capa =
RSTRING(str)->as.heap.aux.capa;
2716 sptr =
RSTRING(str)->as.heap.ptr;
2717 olen =
RSTRING(str)->as.heap.len;
2727 while (total > capa) {
2728 capa = 2 * capa + termlen;
2736 memcpy(sptr + olen, ptr, len);
2743 #define str_buf_cat2(str, ptr) str_buf_cat((str), (ptr), strlen(ptr)) 2748 if (len == 0)
return str;
2752 return str_buf_cat(str, ptr, len);
2767 rb_enc_cr_str_buf_cat(
VALUE str,
const char *ptr,
long len,
2768 int ptr_encindex,
int ptr_cr,
int *ptr_cr_ret)
2777 if (str_encindex == ptr_encindex) {
2796 ptr_cr = coderange_scan(ptr, len, ptr_enc);
2805 *ptr_cr_ret = ptr_cr;
2807 if (str_encindex != ptr_encindex &&
2818 res_encindex = str_encindex;
2823 res_encindex = str_encindex;
2827 res_encindex = ptr_encindex;
2832 res_encindex = str_encindex;
2839 res_encindex = str_encindex;
2847 str_buf_cat(str, ptr, len);
2855 return rb_enc_cr_str_buf_cat(str, ptr, len,
2866 return rb_enc_cr_str_buf_cat(str, ptr,
strlen(ptr),
2872 unsigned int c = (
unsigned char)*ptr;
2875 rb_enc_cr_str_buf_cat(str, buf, len,
2906 #define MIN_PRE_ALLOC_SIZE 48 2918 for (i = 0; i < num; ++i) { len +=
RSTRING_LEN(strary[i]); }
2929 for (i = s; i < num; ++i) {
2930 const VALUE v = strary[i];
2963 rb_str_concat_multi(
int argc,
VALUE *argv,
VALUE str)
2965 str_modifiable(str);
2970 else if (argc > 1) {
2974 for (i = 0; i <
argc; i++) {
3023 buf[0] = (char)code;
3076 rb_str_prepend_multi(
int argc,
VALUE *argv,
VALUE str)
3078 str_modifiable(str);
3084 for (i = 0; i <
argc; i++) {
3107 const char *ptr1, *ptr2;
3110 return (len1 != len2 ||
3112 memcmp(ptr1, ptr2, len1) != 0);
3125 rb_str_hash_m(
VALUE str)
3131 #define lesser(a,b) (((a)>(b))?(b):(a)) 3143 if (idx1 == idx2)
return TRUE;
3162 const char *ptr1, *ptr2;
3165 if (str1 == str2)
return 0;
3168 if (ptr1 == ptr2 || (retval =
memcmp(ptr1, ptr2,
lesser(len1, len2))) == 0) {
3177 if (len1 > len2)
return 1;
3180 if (retval > 0)
return 1;
3189 const char *ptr1, *ptr2;
3195 if (
memcmp(ptr1, ptr2, len) == 0)
3216 if (str1 == str2)
return Qtrue;
3223 return str_eql(str1, str2);
3236 if (str1 == str2)
return Qtrue;
3238 return str_eql(str1, str2);
3308 return str_casecmp(str1, s);
3316 char *p1, *p1end, *p2, *p2end;
3325 if (single_byte_optimizable(str1) && single_byte_optimizable(str2)) {
3326 while (p1 < p1end && p2 < p2end) {
3328 unsigned int c1 =
TOUPPER(*p1 & 0xff);
3329 unsigned int c2 =
TOUPPER(*p2 & 0xff);
3331 return INT2FIX(c1 < c2 ? -1 : 1);
3338 while (p1 < p1end && p2 < p2end) {
3342 if (0 <= c1 && 0 <= c2) {
3346 return INT2FIX(c1 < c2 ? -1 : 1);
3352 len = l1 < l2 ? l1 : l2;
3355 return INT2FIX(r < 0 ? -1 : 1);
3357 return INT2FIX(l1 < l2 ? -1 : 1);
3395 return str_casecmp_p(str1, s);
3402 VALUE folded_str1, folded_str2;
3403 VALUE fold_opt = sym_fold;
3410 folded_str1 = rb_str_downcase(1, &fold_opt, str1);
3411 folded_str2 = rb_str_downcase(1, &fold_opt, str2);
3416 #define rb_str_index(str, sub, offset) rb_strseq_index(str, sub, offset, 0) 3419 rb_strseq_index(
VALUE str,
VALUE sub,
long offset,
int in_byte)
3421 const char *str_ptr, *str_ptr_end, *sub_ptr, *search_start;
3422 long pos, str_len, sub_len, search_len;
3423 int single_byte = single_byte_optimizable(str);
3435 if (str_len < sub_len)
return -1;
3438 long str_len_char, sub_len_char;
3439 str_len_char = (in_byte || single_byte) ? str_len : str_strlen(str, enc);
3440 sub_len_char = in_byte ? sub_len : str_strlen(sub, enc);
3442 offset += str_len_char;
3443 if (offset < 0)
return -1;
3445 if (str_len_char - offset < sub_len_char)
return -1;
3446 if (!in_byte) offset = str_offset(str_ptr, str_ptr_end, offset, enc, single_byte);
3449 if (sub_len == 0)
return offset;
3453 search_start = str_ptr;
3457 pos =
rb_memsearch(sub_ptr, sub_len, search_start, search_len, enc);
3458 if (pos < 0)
return pos;
3460 if (t == search_start + pos)
break;
3461 search_len -= t - search_start;
3462 if (search_len <= 0)
return -1;
3463 offset += t - search_start;
3466 return pos + offset;
3488 rb_str_index_m(
int argc,
VALUE *argv,
VALUE str)
3494 if (
rb_scan_args(argc, argv,
"11", &sub, &initpos) == 2) {
3501 pos += str_strlen(str,
NULL);
3513 if (pos > str_strlen(str,
NULL))
3540 if (pos == -1)
return Qnil;
3548 char *hit, *adjusted;
3550 long slen, searchlen;
3554 if (slen == 0)
return pos;
3559 searchlen = s - sbeg + 1;
3562 hit = memrchr(sbeg, c, searchlen);
3565 if (hit != adjusted) {
3566 searchlen = adjusted - sbeg;
3569 if (
memcmp(hit, t, slen) == 0)
3571 searchlen = adjusted - sbeg;
3572 }
while (searchlen > 0);
3589 if (
memcmp(s, t, slen) == 0) {
3592 if (pos == 0)
break;
3602 rb_str_rindex(
VALUE str,
VALUE sub,
long pos)
3611 singlebyte = single_byte_optimizable(str);
3612 len = singlebyte ?
RSTRING_LEN(str) : str_strlen(str, enc);
3613 slen = str_strlen(sub, enc);
3616 if (len < slen)
return -1;
3617 if (len - pos < slen) pos = len - slen;
3618 if (len == 0)
return pos;
3629 s = str_nth(sbeg,
RSTRING_END(str), pos, enc, singlebyte);
3630 return str_rindex(str, sub, s, pos, enc);
3653 rb_str_rindex_m(
int argc,
VALUE *argv,
VALUE str)
3658 long pos, len = str_strlen(str, enc);
3660 if (
rb_scan_args(argc, argv,
"11", &sub, &vpos) == 2) {
3671 if (pos > len) pos =
len;
3682 enc, single_byte_optimizable(str));
3686 if (pos >= 0)
return LONG2NUM(pos);
3702 pos = rb_str_rindex(str, sub, pos);
3703 if (pos >= 0)
return LONG2NUM(pos);
3779 rb_str_match_m(
int argc,
VALUE *argv,
VALUE str)
3811 rb_str_match_m_p(
int argc,
VALUE *argv,
VALUE str)
3815 re = get_pat(argv[0]);
3826 enc_succ_char(
char *p,
long len,
rb_encoding *enc)
3849 for (i = len-1; 0 <= i && (
unsigned char)p[i] == 0xff; i--)
3853 ++((
unsigned char*)p)[i];
3861 memset(p+l, 0xff, len-l);
3867 for (len2 = len-1; 0 < len2; len2--) {
3872 memset(p+len2+1, 0xff, len-(len2+1));
3878 enc_pred_char(
char *p,
long len,
rb_encoding *enc)
3902 for (i = len-1; 0 <= i && (
unsigned char)p[i] == 0; i--)
3906 --((
unsigned char*)p)[i];
3914 memset(p+l, 0, len-l);
3920 for (len2 = len-1; 0 < len2; len2--) {
3925 memset(p+len2+1, 0, len-(len2+1));
3940 enc_succ_alnum_char(
char *p,
long len,
rb_encoding *enc,
char *carry)
3950 const int max_gaps = 1;
3960 MEMCPY(save, p,
char, len);
3961 for (
try = 0;
try <= max_gaps; ++
try) {
3962 ret = enc_succ_char(p, len, enc);
3969 MEMCPY(p, save,
char, len);
3972 MEMCPY(save, p,
char, len);
3973 ret = enc_pred_char(p, len, enc);
3977 MEMCPY(p, save,
char, len);
3982 MEMCPY(p, save,
char, len);
3992 MEMCPY(carry, p,
char, len);
3996 MEMCPY(carry, p,
char, len);
3997 enc_succ_char(carry, len, enc);
4034 rb_enc_cr_str_copy_for_substr(str, orig);
4036 return str_succ(str);
4043 char *sbeg, *s, *e, *last_alnum = 0;
4047 long carry_pos = 0, carry_len = 1;
4051 if (slen == 0)
return str;
4055 s = e = sbeg + slen;
4068 neighbor = enc_succ_alnum_char(s, l, enc, carry);
4079 carry_pos = s - sbeg;
4091 neighbor = enc_succ_char(tmp, l, enc);
4105 enc_succ_char(s, l, enc);
4108 MEMCPY(carry, s,
char, l);
4111 carry_pos = s - sbeg;
4117 s = sbeg + carry_pos;
4118 memmove(s + carry_len, s, slen - carry_pos);
4138 rb_str_succ_bang(
VALUE str)
4146 all_digits_p(
const char *s,
long len)
4197 rb_str_upto(
int argc,
VALUE *argv,
VALUE beg)
4199 VALUE end, exclusive;
4203 return str_upto_each(beg, end,
RTEST(exclusive), str_upto_i,
Qnil);
4209 VALUE current, after_end;
4223 if (c > e || (excl && c == e))
return beg;
4226 if (!excl && c == e)
break;
4228 if (excl && c == e)
break;
4248 if (excl && bi == ei)
break;
4249 if ((*each)(
rb_enc_sprintf(usascii,
"%.*ld", width, bi), arg))
break;
4254 ID op = excl ?
'<' :
idLE;
4268 if (n > 0 || (excl && n == 0))
return beg;
4276 if ((*each)(current, arg))
break;
4277 if (
NIL_P(next))
break;
4292 if (!
rb_equal(str, *argp))
return 0;
4321 if (b <= v && v < e)
return Qtrue;
4322 if (!
RTEST(exclusive) && v == e)
return Qtrue;
4336 str_upto_each(beg, end,
RTEST(exclusive), include_range_i, (
VALUE)&val);
4361 return rb_str_subpat(str, indx,
INT2FIX(0));
4370 long beg, len = str_strlen(str,
NULL);
4382 return str_substr(str, idx, 1,
FALSE);
4456 rb_str_aref_m(
int argc,
VALUE *argv,
VALUE str)
4460 return rb_str_subpat(str, argv[0], argv[1]);
4469 return rb_str_aref(str, argv[0]);
4478 str_modifiable(str);
4479 if (len > olen) len = olen;
4487 memmove(ptr, oldptr + len, nlen);
4493 RSTRING(str)->as.heap.len = nlen;
4501 rb_str_splice_0(
VALUE str,
long beg,
long len,
VALUE val)
4507 if (beg == 0 && vlen == 0) {
4513 str_modify_keep_cr(str);
4529 slen - (beg + len));
4531 if (vlen < beg && len < 0) {
4532 MEMZERO(sptr + slen,
char, -len);
4550 int singlebyte = single_byte_optimizable(str);
4557 slen = str_strlen(str, enc);
4564 if (beg + slen < 0) {
4571 if (len > slen - beg) {
4574 str_modify_keep_cr(str);
4577 e = str_nth(p,
RSTRING_END(str), len, enc, singlebyte);
4582 rb_str_splice_0(str, beg, len, val);
4589 #define rb_str_splice(str, beg, len, val) rb_str_update(str, beg, len, val) 4596 long start, end,
len;
4625 rb_str_splice_0(str, start, len, val);
4642 switch (
TYPE(indx)) {
4644 rb_str_subpat_set(str, indx,
INT2FIX(0), val);
4697 rb_str_aset_m(
int argc,
VALUE *argv,
VALUE str)
4701 rb_str_subpat_set(str, argv[0], argv[1], argv[2]);
4709 return rb_str_aset(str, argv[0], argv[1]);
4765 rb_str_slice_bang(
int argc,
VALUE *argv,
VALUE str)
4772 for (i=0; i<
argc; i++) {
4775 str_modify_keep_cr(str);
4776 result = rb_str_aref_m(argc, buf, str);
4777 if (!
NIL_P(result)) {
4779 rb_str_aset_m(argc+1, buf, str);
4810 get_pat_quoted(
VALUE pat,
int check)
4837 rb_pat_search(
VALUE pat,
VALUE str,
long pos,
int set_backref_str)
4840 pos = rb_strseq_index(str, pat, pos, 1);
4841 if (set_backref_str) {
4873 rb_str_sub_bang(
int argc,
VALUE *argv,
VALUE str)
4895 pat = get_pat_quoted(argv[0], 1);
4897 str_modifiable(str);
4898 beg = rb_pat_search(pat, str, 0, 1);
4921 if (iter || !
NIL_P(hash)) {
4931 str_mod_check(str, p, len);
4969 memmove(p + beg0 + rlen, p + beg0 + plen, len - beg0 - plen);
4971 memcpy(p + beg0, rp, rlen);
5030 rb_str_sub_bang(argc, argv, str);
5035 str_gsub(
int argc,
VALUE *argv,
VALUE str,
int bang)
5039 long beg, beg0, end0;
5040 long offset, blen, slen,
len,
last;
5041 enum {STR, ITER, MAP} mode = STR;
5044 int need_backref = -1;
5067 pat = get_pat_quoted(argv[0], 1);
5068 beg = rb_pat_search(pat, str, 0, need_backref);
5070 if (bang)
return Qnil;
5106 str_mod_check(str, sp, slen);
5111 else if (need_backref) {
5113 if (need_backref < 0) {
5114 need_backref = val != repl;
5123 len = beg0 - offset;
5140 offset = end0 +
len;
5144 beg = rb_pat_search(pat, str, offset, need_backref);
5149 rb_pat_search(pat, str, last, 1);
5151 str_shared_replace(str, dest);
5177 rb_str_gsub_bang(
int argc,
VALUE *argv,
VALUE str)
5179 str_modify_keep_cr(str);
5180 return str_gsub(argc, argv, str, 1);
5228 rb_str_gsub(
int argc,
VALUE *argv,
VALUE str)
5230 return str_gsub(argc, argv, str, 0);
5248 str_modifiable(str);
5249 if (str == str2)
return str;
5253 return str_replace(str, str2);
5267 rb_str_clear(
VALUE str)
5291 rb_str_chr(
VALUE str)
5327 char *head, *
ptr, *left = 0;
5331 if (pos < -len || len <= pos)
5336 if (!str_independent(str))
5337 str_make_independent(str);
5374 str_byte_substr(
VALUE str,
long beg,
long len,
int empty)
5380 if (beg > n || len < 0)
return Qnil;
5383 if (beg < 0)
return Qnil;
5388 if (!empty)
return Qnil;
5398 RSTRING(str2)->as.heap.ptr += beg;
5405 str_enc_copy(str2, str);
5446 return str_byte_substr(str, beg, len,
TRUE);
5451 return str_byte_substr(str, idx, 1,
FALSE);
5478 rb_str_byteslice(
int argc,
VALUE *argv,
VALUE str)
5483 return str_byte_substr(str, beg, end,
TRUE);
5486 return str_byte_aref(str, argv[0]);
5499 rb_str_reverse(
VALUE str)
5514 if (single_byte_optimizable(str)) {
5543 str_enc_copy(rev, str);
5558 rb_str_reverse_bang(
VALUE str)
5561 if (single_byte_optimizable(str)) {
5564 str_modify_keep_cr(str);
5574 str_shared_replace(str, rb_str_reverse(str));
5578 str_modify_keep_cr(str);
5604 if (i == -1)
return Qfalse;
5631 rb_str_to_i(
int argc,
VALUE *argv,
VALUE str)
5635 if (argc == 0) base = 10;
5664 rb_str_to_f(
VALUE str)
5681 rb_str_to_s(
VALUE str)
5701 #define CHAR_ESC_LEN 13 5716 else if (c < 0x10000) {
5743 const char *prev = p;
5753 if (p > prev) str_buf_cat(result, prev, p - prev);
5756 n = (int)(pend - p);
5759 str_buf_cat(result, buf,
strlen(buf));
5768 case '\n': cc =
'n';
break;
5769 case '\r': cc =
'r';
break;
5770 case '\t': cc =
't';
break;
5771 case '\f': cc =
'f';
break;
5772 case '\013': cc =
'v';
break;
5773 case '\010': cc =
'b';
break;
5774 case '\007': cc =
'a';
break;
5775 case 033: cc =
'e';
break;
5776 default: cc = 0;
break;
5779 if (p - n > prev) str_buf_cat(result, prev, p - n - prev);
5782 str_buf_cat(result, buf, 2);
5788 if (p - n > prev) str_buf_cat(result, prev, p - n - prev);
5793 if (p > prev) str_buf_cat(result, prev, p - prev);
5817 const char *p, *pend, *prev;
5831 actenc = get_actual_encoding(encidx, str);
5832 if (actenc != enc) {
5842 if (p > prev) str_buf_cat(result, prev, p - prev);
5845 n = (int)(pend - p);
5848 str_buf_cat(result, buf,
strlen(buf));
5856 if ((asciicompat || unicode_p) &&
5857 (c ==
'"'|| c ==
'\\' ||
5862 (cc ==
'$' || cc ==
'@' || cc ==
'{'))))) {
5863 if (p - n > prev) str_buf_cat(result, prev, p - n - prev);
5865 if (asciicompat || enc == resenc) {
5871 case '\n': cc =
'n';
break;
5872 case '\r': cc =
'r';
break;
5873 case '\t': cc =
't';
break;
5874 case '\f': cc =
'f';
break;
5875 case '\013': cc =
'v';
break;
5876 case '\010': cc =
'b';
break;
5877 case '\007': cc =
'a';
break;
5878 case 033: cc =
'e';
break;
5879 default: cc = 0;
break;
5882 if (p - n > prev) str_buf_cat(result, prev, p - n - prev);
5885 str_buf_cat(result, buf, 2);
5894 if (p - n > prev) str_buf_cat(result, prev, p - n - prev);
5900 if (p > prev) str_buf_cat(result, prev, p - prev);
5907 #define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{')) 5925 const char *p, *pend;
5929 static const char nonascii_suffix[] =
".force_encoding(\"%s\")";
5940 unsigned char c = *p++;
5943 case '"':
case '\\':
5944 case '\n':
case '\r':
5945 case '\t':
case '\f':
5946 case '\013':
case '\010':
case '\007':
case '\033':
5959 if (u8 && c > 0x7F) {
5965 else if (cc <= 0xFFFFF)
5990 unsigned char c = *p++;
5992 if (c ==
'"' || c ==
'\\') {
5996 else if (c ==
'#') {
5997 if (
IS_EVSTR(p, pend)) *q++ =
'\\';
6000 else if (c ==
'\n') {
6004 else if (c ==
'\r') {
6008 else if (c ==
'\t') {
6012 else if (c ==
'\f') {
6016 else if (c ==
'\013') {
6020 else if (c ==
'\010') {
6024 else if (c ==
'\007') {
6028 else if (c ==
'\033') {
6084 if (argv[0]==sym_turkic) {
6087 if (argv[1]==sym_lithuanian)
6093 else if (argv[0]==sym_lithuanian) {
6096 if (argv[1]==sym_turkic)
6104 else if (argv[0]==sym_ascii)
6106 else if (argv[0]==sym_fold) {
6118 #define CASE_MAPPING_ADDITIONAL_LENGTH 20 6119 #ifndef CASEMAP_DEBUG 6120 # define CASEMAP_DEBUG 0 6137 int target_length = 0;
6139 *current_buffer = &pre_buffer;
6140 size_t buffer_count = 0;
6141 int buffer_length_or_invalid;
6148 while (source_current < source_end) {
6152 fprintf(stderr,
"Buffer allocation, capa is %"PRIuSIZE"\n", capa);
6155 current_buffer = current_buffer->
next;
6158 buffer_length_or_invalid = enc->
case_map(flags,
6159 (
const OnigUChar**)&source_current, source_end,
6160 current_buffer->
space,
6161 current_buffer->
space+current_buffer->
capa,
6163 if (buffer_length_or_invalid < 0) {
6166 current_buffer = pre_buffer.
next;
6167 while (current_buffer) {
6168 previous_buffer = current_buffer;
6169 current_buffer = current_buffer->
next;
6170 xfree(previous_buffer);
6174 target_length += current_buffer->
used = buffer_length_or_invalid;
6177 fprintf(stderr,
"Buffer count is %"PRIuSIZE"\n", buffer_count);
6180 if (buffer_count==1) {
6182 xfree(current_buffer);
6185 char *target_current;
6190 current_buffer=pre_buffer.
next;
6191 while (current_buffer) {
6192 memcpy(target_current, current_buffer->
space, current_buffer->
used);
6193 target_current += current_buffer->
used;
6194 previous_buffer = current_buffer;
6195 current_buffer = current_buffer->
next;
6196 xfree(previous_buffer);
6202 str_enc_copy(target, source);
6213 int length_or_invalid;
6215 if (old_length == 0)
return;
6221 (
const OnigUChar**)&source_current, source_end,
6222 source_current, source_end, enc);
6223 if (length_or_invalid < 0)
6226 fprintf(stderr,
"problem with rb_str_ascii_casemap" 6227 "; old_length=%ld, new_length=%d\n", old_length, length_or_invalid);
6229 "; old_length=%ld, new_length=%d\n", old_length, length_or_invalid);
6245 rb_str_upcase_bang(
int argc,
VALUE *argv,
VALUE str)
6250 flags = check_case_options(argc, argv, flags);
6251 str_modify_keep_cr(str);
6253 rb_str_check_dummy_enc(enc);
6259 unsigned int c = *(
unsigned char*)s;
6262 *s =
'A' + (c -
'a');
6268 else if (flags&ONIGENC_CASE_ASCII_ONLY)
6269 rb_str_ascii_casemap(str, &flags, enc);
6271 str_shared_replace(str, rb_str_casemap(str, &flags, enc));
6292 rb_str_upcase(
int argc,
VALUE *argv,
VALUE str)
6295 rb_str_upcase_bang(argc, argv, str);
6311 rb_str_downcase_bang(
int argc,
VALUE *argv,
VALUE str)
6316 flags = check_case_options(argc, argv, flags);
6317 str_modify_keep_cr(str);
6319 rb_str_check_dummy_enc(enc);
6325 unsigned int c = *(
unsigned char*)s;
6328 *s =
'a' + (c -
'A');
6334 else if (flags&ONIGENC_CASE_ASCII_ONLY)
6335 rb_str_ascii_casemap(str, &flags, enc);
6337 str_shared_replace(str, rb_str_casemap(str, &flags, enc));
6395 rb_str_downcase(
int argc,
VALUE *argv,
VALUE str)
6398 rb_str_downcase_bang(argc, argv, str);
6420 rb_str_capitalize_bang(
int argc,
VALUE *argv,
VALUE str)
6425 flags = check_case_options(argc, argv, flags);
6426 str_modify_keep_cr(str);
6428 rb_str_check_dummy_enc(enc);
6431 rb_str_ascii_casemap(str, &flags, enc);
6433 str_shared_replace(str, rb_str_casemap(str, &flags, enc));
6456 rb_str_capitalize(
int argc,
VALUE *argv,
VALUE str)
6459 rb_str_capitalize_bang(argc, argv, str);
6476 rb_str_swapcase_bang(
int argc,
VALUE *argv,
VALUE str)
6481 flags = check_case_options(argc, argv, flags);
6482 str_modify_keep_cr(str);
6484 rb_str_check_dummy_enc(enc);
6486 rb_str_ascii_casemap(str, &flags, enc);
6488 str_shared_replace(str, rb_str_casemap(str, &flags, enc));
6510 rb_str_swapcase(
int argc,
VALUE *argv,
VALUE str)
6513 rb_str_swapcase_bang(argc, argv, str);
6533 if (t->
p == t->
pend)
return -1;
6541 if (t->
p < t->
pend) {
6545 if (t->
now < 0x80 && c < 0x80) {
6547 "invalid range \"%c-%c\" in string transliteration",
6584 const unsigned int errc = -1;
6585 unsigned int trans[256];
6587 struct tr trsrc, trrepl;
6589 unsigned int c, c0,
last = 0;
6590 int modify = 0, i, l;
6593 int singlebyte = single_byte_optimizable(str);
6597 #define CHECK_IF_ASCII(c) \ 6598 (void)((cr == ENC_CODERANGE_7BIT && !rb_isascii(c)) ? \ 6599 (cr = ENC_CODERANGE_VALID) : 0) 6605 return rb_str_delete_bang(1, &src, str);
6620 trsrc.
p + l < trsrc.
pend) {
6626 trsrc.
gen = trrepl.
gen = 0;
6627 trsrc.
now = trrepl.
now = 0;
6628 trsrc.
max = trrepl.
max = 0;
6631 for (i=0; i<256; i++) {
6634 while ((c = trnext(&trsrc, enc)) != errc) {
6643 while ((c = trnext(&trrepl, enc)) != errc)
6646 for (i=0; i<256; i++) {
6647 if (trans[i] != errc) {
6655 for (i=0; i<256; i++) {
6658 while ((c = trnext(&trsrc, enc)) != errc) {
6659 r = trnext(&trrepl, enc);
6660 if (r == errc) r = trrepl.
now;
6674 str_modify_keep_cr(str);
6680 unsigned int save = -1;
6696 if (cflag) c =
last;
6699 else if (cflag) c = errc;
6705 if (c != (
unsigned int)-1) {
6717 if (enc != e1) may_modify = 1;
6719 if ((offset = t - buf) + tlen > max) {
6720 max = offset + tlen + (send - s);
6725 if (may_modify &&
memcmp(s, t, tlen) != 0) {
6738 RSTRING(str)->as.heap.aux.capa = max;
6742 c = (
unsigned char)*s;
6743 if (trans[c] != errc) {
6760 long offset, max = (long)((send - s) * 1.2);
6774 if (cflag) c =
last;
6777 else if (cflag) c = errc;
6781 c = cflag ?
last : errc;
6789 if (enc != e1) may_modify = 1;
6791 if ((offset = t - buf) + tlen > max) {
6792 max = offset + tlen + (long)((send - s) * 1.2);
6798 if (may_modify &&
memcmp(s, t, tlen) != 0) {
6813 RSTRING(str)->as.heap.aux.capa = max;
6838 return tr_trans(str, src, repl, 0);
6881 tr_trans(str, src, repl, 0);
6885 #define TR_TABLE_SIZE 257 6890 const unsigned int errc = -1;
6894 VALUE table = 0, ptable = 0;
6895 int i, l, cflag = 0;
6905 for (i=0; i<256; i++) {
6908 stable[256] = cflag;
6910 else if (stable[256] && !cflag) {
6913 for (i=0; i<256; i++) {
6917 while ((c = trnext(&tr, enc)) != errc) {
6919 buf[c & 0xff] = !cflag;
6924 if (!table && (first || *tablep || stable[256])) {
6941 for (i=0; i<256; i++) {
6942 stable[i] = stable[i] && buf[i];
6944 if (!table && !cflag) {
6954 return table[c] != 0;
6981 rb_str_delete_bang(
int argc,
VALUE *argv,
VALUE str)
6986 VALUE del = 0, nodel = 0;
6988 int i, ascompat, cr;
6992 for (i=0; i<
argc; i++) {
6997 tr_setup_table(s, squeez, i==0, &del, &nodel, enc);
7000 str_modify_keep_cr(str);
7009 if (ascompat && (c = *(
unsigned char*)s) < 0x80) {
7022 if (tr_find(c, squeez, del, nodel)) {
7037 if (modify)
return str;
7057 rb_str_delete(
int argc,
VALUE *argv,
VALUE str)
7060 rb_str_delete_bang(argc, argv, str);
7074 rb_str_squeeze_bang(
int argc,
VALUE *argv,
VALUE str)
7078 VALUE del = 0, nodel = 0;
7081 int ascompat, singlebyte = single_byte_optimizable(str);
7088 for (i=0; i<
argc; i++) {
7093 if (singlebyte && !single_byte_optimizable(s))
7095 tr_setup_table(s, squeez, i==0, &del, &nodel, enc);
7099 str_modify_keep_cr(str);
7108 unsigned int c = *(
unsigned char*)s++;
7109 if (c != save || (argc > 0 && !squeez[c])) {
7119 if (ascompat && (c = *(
unsigned char*)s) < 0x80) {
7120 if (c != save || (argc > 0 && !squeez[c])) {
7128 if (c != save || (argc > 0 && !tr_find(c, squeez, del, nodel))) {
7144 if (modify)
return str;
7165 rb_str_squeeze(
int argc,
VALUE *argv,
VALUE str)
7168 rb_str_squeeze_bang(argc, argv, str);
7184 return tr_trans(str, src, repl, 1);
7205 tr_trans(str, src, repl, 1);
7238 rb_str_count(
int argc,
VALUE *argv,
VALUE str)
7242 VALUE del = 0, nodel = 0, tstr;
7266 if (*(
unsigned char*)s++ == c) n++;
7272 tr_setup_table(tstr, table,
TRUE, &del, &nodel, enc);
7273 for (i=1; i<
argc; i++) {
7277 tr_setup_table(tstr, table,
FALSE, &del, &nodel, enc);
7288 if (ascompat && (c = *(
unsigned char*)s) < 0x80) {
7297 if (tr_find(c, table, del, nodel)) {
7308 rb_fs_check(
VALUE val)
7312 if (
NIL_P(val))
return 0;
7317 static const char isspacetable[256] = {
7318 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0,
7319 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7320 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7321 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7322 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7323 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7324 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7325 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7326 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7327 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7328 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7329 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7330 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7331 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7332 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7333 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
7336 #define ascii_isspace(c) isspacetable[(unsigned char)(c)] 7390 rb_str_split_m(
int argc,
VALUE *argv,
VALUE str)
7395 enum {awk, string, regexp} split_type;
7396 long beg, end, i = 0;
7400 if (
rb_scan_args(argc, argv,
"02", &spat, &limit) == 2) {
7402 if (lim <= 0) limit =
Qnil;
7403 else if (lim == 1) {
7412 split_type = regexp;
7414 spat = get_pat_quoted(spat, 0);
7416 else if (
NIL_P(spat = rb_fs)) {
7419 else if (!(spat = rb_fs_check(spat))) {
7422 if (split_type != awk) {
7426 mustnot_broken(spat);
7427 split_type = string;
7431 split_type = regexp;
7450 if (split_type == awk) {
7459 while (ptr < eptr) {
7460 c = (
unsigned char)*ptr++;
7468 if (!
NIL_P(limit) && lim <= i)
break;
7475 if (!
NIL_P(limit)) ++i;
7483 while (ptr < eptr) {
7489 if (rb_isspace(c)) {
7495 if (!
NIL_P(limit) && lim <= i)
break;
7498 else if (rb_isspace(c)) {
7502 if (!
NIL_P(limit)) ++i;
7510 else if (split_type ==
string) {
7512 char *str_start =
ptr;
7513 char *substr_start =
ptr;
7518 mustnot_broken(str);
7520 while (ptr < eptr &&
7521 (end =
rb_memsearch(sptr, slen, ptr, eptr - ptr, enc)) >= 0) {
7524 if (t != ptr + end) {
7529 (ptr+end) - substr_start));
7532 if (!
NIL_P(limit) && lim <= ++i)
break;
7534 beg = ptr - str_start;
7546 if (start == end &&
BEG(0) ==
END(0)) {
7551 else if (last_null == 1) {
7569 beg = start =
END(0);
7573 for (idx=1; idx < regs->
num_regs; idx++) {
7574 if (
BEG(idx) == -1)
continue;
7575 if (
BEG(idx) ==
END(idx))
7576 tmp = str_new_empty(str);
7581 if (!
NIL_P(limit) && lim <= ++i)
break;
7586 tmp = str_new_empty(str);
7591 if (
NIL_P(limit) && lim == 0) {
7608 return rb_str_split_m(1, &sep, str);
7612 enumerator_wantarray(
const char *method)
7615 #if STRING_ENUMERATORS_WANTARRAY 7616 rb_warn(
"given block not used");
7618 rb_warning(
"passing a block to String#%s is deprecated", method);
7625 #define WANTARRAY(m, size) \ 7626 (enumerator_wantarray(m) ? rb_ary_new_capa(size) : 0) 7641 #define ENUM_ELEM(ary, e) enumerator_element(ary, e) 7644 chomp_newline(
const char *p,
const char *e,
rb_encoding *enc)
7661 const char *
ptr, *pend, *subptr, *subend, *rsptr, *hit, *adjusted;
7662 long pos,
len, rslen;
7668 static ID keywords[1];
7701 const char *eol =
NULL;
7703 while (subend < pend) {
7709 if (eol == subend)
break;
7711 if (subptr) eol = subend;
7714 if (!subptr) subptr = subend;
7718 }
while (subend < pend);
7721 subend - subptr + (chomp ? 0 : rslen));
7723 str_mod_check(str, ptr, len);
7725 subptr = eol =
NULL;
7744 while (subptr < pend) {
7745 pos =
rb_memsearch(rsptr, rslen, subptr, pend - subptr, enc);
7749 if (hit != adjusted) {
7753 subend = hit += rslen;
7756 subend = chomp_newline(subptr, subend, enc);
7764 str_mod_check(str, ptr, len);
7769 if (subptr != pend) {
7771 pend = chomp_newline(subptr, pend, enc);
7823 rb_str_each_line(
int argc,
VALUE *argv,
VALUE str)
7826 return rb_str_enumerate_lines(argc, argv, str, 0);
7842 rb_str_lines(
int argc,
VALUE *argv,
VALUE str)
7845 return rb_str_enumerate_lines(argc, argv, str, ary);
7884 rb_str_each_byte(
VALUE str)
7887 return rb_str_enumerate_bytes(str, 0);
7902 rb_str_bytes(
VALUE str)
7905 return rb_str_enumerate_bytes(str, ary);
7928 for (i = 0; i <
len; i += n) {
7934 for (i = 0; i <
len; i += n) {
7962 rb_str_each_char(
VALUE str)
7965 return rb_str_enumerate_chars(str, 0);
7980 rb_str_chars(
VALUE str)
7983 return rb_str_enumerate_chars(str, ary);
7987 rb_str_enumerate_codepoints(
VALUE str,
VALUE ary)
7992 const char *
ptr, *end;
7995 if (single_byte_optimizable(str))
7996 return rb_str_enumerate_bytes(str, ary);
8036 rb_str_each_codepoint(
VALUE str)
8039 return rb_str_enumerate_codepoints(str, 0);
8055 rb_str_codepoints(
VALUE str)
8058 return rb_str_enumerate_codepoints(str, ary);
8062 rb_str_enumerate_grapheme_clusters(
VALUE str,
VALUE ary)
8070 const char *
ptr, *end;
8072 if (!unicode_p || single_byte_optimizable(str)) {
8073 return rb_str_enumerate_chars(str, ary);
8078 reg_grapheme_cluster = reg_grapheme_cluster_utf8;
8080 if (!reg_grapheme_cluster) {
8082 int r =
onig_new(®_grapheme_cluster, source, source +
sizeof(source) - 1,
8085 rb_bug(
"cannot compile grapheme cluster regexp");
8088 reg_grapheme_cluster_utf8 = reg_grapheme_cluster;
8100 if (len == 0)
break;
8130 rb_str_each_grapheme_cluster(
VALUE str)
8133 return rb_str_enumerate_grapheme_clusters(str, 0);
8148 rb_str_grapheme_clusters(
VALUE str)
8151 return rb_str_enumerate_grapheme_clusters(str, ary);
8155 chopped_length(
VALUE str)
8158 const char *p, *p2, *beg, *end;
8162 if (beg > end)
return 0;
8182 rb_str_chop_bang(
VALUE str)
8184 str_modify_keep_cr(str);
8187 len = chopped_length(str);
8217 rb_str_chop(
VALUE str)
8228 char *pp, *e, *rsptr;
8233 if (len == 0)
return 0;
8254 if (--e > p && *(e-1) ==
'\r') {
8284 while (e > p && *(e-1) ==
'\n') {
8286 if (e > p && *(e-1) ==
'\r')
8292 if (rslen > len)
return len;
8295 newline = rsptr[rslen-1];
8298 if (newline ==
'\n')
8312 if (p[len-1] == newline &&
8314 memcmp(rsptr, pp, rslen) == 0)) {
8328 chomp_rs(
int argc,
const VALUE *argv)
8345 long len = chompped_length(str, rs);
8346 if (len >= olen)
return Qnil;
8347 str_modify_keep_cr(str);
8365 rb_str_chomp_bang(
int argc,
VALUE *argv,
VALUE str)
8368 str_modifiable(str);
8370 rs = chomp_rs(argc, argv);
8399 rb_str_chomp(
int argc,
VALUE *argv,
VALUE str)
8401 VALUE rs = chomp_rs(argc, argv);
8409 const char *
const start = s;
8411 if (!s || s >= e)
return 0;
8414 if (single_byte_optimizable(str)) {
8422 if (!rb_isspace(cc))
break;
8445 rb_str_lstrip_bang(
VALUE str)
8451 str_modify_keep_cr(str);
8454 loffset = lstrip_offset(str, start, start+olen, enc);
8456 long len = olen-loffset;
8457 s = start + loffset;
8460 #if !SHARABLE_MIDDLE_SUBSTRING 8483 rb_str_lstrip(
VALUE str)
8488 loffset = lstrip_offset(str, start, start+len,
STR_ENC_GET(str));
8498 rb_str_check_dummy_enc(enc);
8499 if (!s || s >= e)
return 0;
8503 if (single_byte_optimizable(str)) {
8505 while (s < t && ((c = *(t-1)) ==
'\0' ||
ascii_isspace(c))) t--;
8512 if (c && !rb_isspace(c))
break;
8535 rb_str_rstrip_bang(
VALUE str)
8541 str_modify_keep_cr(str);
8544 roffset = rstrip_offset(str, start, start+olen, enc);
8546 long len = olen - roffset;
8549 #if !SHARABLE_MIDDLE_SUBSTRING 8572 rb_str_rstrip(
VALUE str)
8580 roffset = rstrip_offset(str, start, start+olen, enc);
8598 rb_str_strip_bang(
VALUE str)
8601 long olen, loffset, roffset;
8604 str_modify_keep_cr(str);
8607 loffset = lstrip_offset(str, start, start+olen, enc);
8608 roffset = rstrip_offset(str, start+loffset, start+olen, enc);
8610 if (loffset > 0 || roffset > 0) {
8611 long len = olen-roffset;
8614 memmove(start, start + loffset, len);
8617 #if !SHARABLE_MIDDLE_SUBSTRING 8641 rb_str_strip(
VALUE str)
8644 long olen, loffset, roffset;
8648 loffset = lstrip_offset(str, start, start+olen, enc);
8649 roffset = rstrip_offset(str, start+loffset, start+olen, enc);
8651 if (loffset <= 0 && roffset <= 0)
return rb_str_dup(str);
8656 scan_once(
VALUE str,
VALUE pat,
long *start,
int set_backref_str)
8658 VALUE result, match;
8661 long end, pos = rb_pat_search(pat, str, *start, set_backref_str);
8686 if (!regs || regs->
num_regs == 1) {
8692 for (i=1; i < regs->
num_regs; i++) {
8743 long last = -1, prev = 0;
8746 pat = get_pat_quoted(pat, 1);
8747 mustnot_broken(str);
8751 while (!
NIL_P(result = scan_once(str, pat, &start, 0))) {
8756 if (last >= 0) rb_pat_search(pat, str, last, 1);
8761 while (!
NIL_P(result = scan_once(str, pat, &start, 1))) {
8765 str_mod_check(str, p, len);
8767 if (last >= 0) rb_pat_search(pat, str, last, 1);
8787 rb_str_hex(
VALUE str)
8811 rb_str_oct(
VALUE str)
8837 #undef LARGE_CRYPT_DATA 8839 # if defined SIZEOF_CRYPT_DATA && SIZEOF_CRYPT_DATA <= 256 8840 struct crypt_data cdata, *
const data = &cdata;
8842 # define LARGE_CRYPT_DATA 8846 extern char *
crypt(
const char *,
const char *);
8849 const char *s, *saltp;
8852 char salt_8bit_clean[3];
8857 mustnot_wchar(salt);
8865 if (!saltp[0] || !saltp[1])
goto short_salt;
8867 if (!
ISASCII((
unsigned char)saltp[0]) || !
ISASCII((
unsigned char)saltp[1])) {
8868 salt_8bit_clean[0] = saltp[0] & 0x7f;
8869 salt_8bit_clean[1] = saltp[1] & 0x7f;
8870 salt_8bit_clean[2] =
'\0';
8871 saltp = salt_8bit_clean;
8875 # ifdef HAVE_STRUCT_CRYPT_DATA_INITIALIZED 8876 data->initialized = 0;
8878 res =
crypt_r(s, saltp, data);
8880 res =
crypt(s, saltp);
8883 #ifdef LARGE_CRYPT_DATA 8891 #ifdef LARGE_CRYPT_DATA 8932 char *
ptr, *p, *pend;
8935 unsigned long sum0 = 0;
8953 str_mod_check(str, ptr, len);
8956 sum0 += (
unsigned char)*p;
8967 if (bits < (
int)
sizeof(
long)*
CHAR_BIT) {
8968 sum0 &= (((
unsigned long)1)<<bits)-1;
8988 rb_str_justify(
int argc,
VALUE *argv,
VALUE str,
char jflag)
8992 long width,
len, flen = 1, fclen = 1;
8995 const char *
f =
" ";
8996 long n,
size, llen, rlen, llen2 = 0, rlen2 = 0;
8998 int singlebyte = 1, cr;
9010 fclen = str_strlen(pad, enc);
9011 singlebyte = single_byte_optimizable(pad);
9012 if (flen == 0 || fclen == 0) {
9016 len = str_strlen(str, enc);
9017 if (width < 0 || len >= width)
return rb_str_dup(str);
9019 llen = (jflag ==
'l') ? 0 : ((jflag ==
'r') ? n : n/2);
9023 llen2 = str_offset(f, f + flen, llen % fclen, enc, singlebyte);
9024 rlen2 = str_offset(f, f + flen, rlen % fclen, enc, singlebyte);
9027 if ((len = llen / fclen + rlen / fclen) >=
LONG_MAX / flen ||
9028 (len *= flen) >=
LONG_MAX - llen2 - rlen2 ||
9029 (len += llen2 + rlen2) >=
LONG_MAX - size) {
9036 memset(p, *f, llen);
9040 while (llen >= fclen) {
9046 memcpy(p, f, llen2);
9053 memset(p, *f, rlen);
9057 while (rlen >= fclen) {
9063 memcpy(p, f, rlen2);
9096 rb_str_ljust(
int argc,
VALUE *argv,
VALUE str)
9098 return rb_str_justify(argc, argv, str,
'l');
9116 rb_str_rjust(
int argc,
VALUE *argv,
VALUE str)
9118 return rb_str_justify(argc, argv, str,
'r');
9136 rb_str_center(
int argc,
VALUE *argv,
VALUE str)
9138 return rb_str_justify(argc, argv, str,
'c');
9161 sep = get_pat_quoted(sep, 0);
9168 sep = rb_str_subpat(str, sep,
INT2FIX(0));
9169 if (pos == 0 &&
RSTRING_LEN(sep) == 0)
goto failed;
9173 if (pos < 0)
goto failed;
9216 pos = rb_str_rindex(str, sep, pos);
9247 rb_str_start_with(
int argc,
VALUE *argv,
VALUE str)
9251 for (i=0; i<
argc; i++) {
9252 VALUE tmp = argv[i];
9253 switch (
TYPE(tmp)) {
9257 if (r)
return Qtrue;
9285 rb_str_end_with(
int argc,
VALUE *argv,
VALUE str)
9291 for (i=0; i<
argc; i++) {
9292 VALUE tmp = argv[i];
9317 deleted_prefix_length(
VALUE str,
VALUE prefix)
9319 char *strptr, *prefixptr;
9320 long olen, prefixlen;
9328 if (prefixlen <= 0)
return 0;
9330 if (olen < prefixlen)
return 0;
9333 if (
memcmp(strptr, prefixptr, prefixlen) != 0)
return 0;
9350 rb_str_delete_prefix_bang(
VALUE str,
VALUE prefix)
9353 str_modify_keep_cr(str);
9355 prefixlen = deleted_prefix_length(str, prefix);
9356 if (prefixlen <= 0)
return Qnil;
9372 rb_str_delete_prefix(
VALUE str,
VALUE prefix)
9376 prefixlen = deleted_prefix_length(str, prefix);
9392 deleted_suffix_length(
VALUE str,
VALUE suffix)
9394 char *strptr, *suffixptr, *s;
9395 long olen, suffixlen;
9404 if (suffixlen <= 0)
return 0;
9406 if (olen < suffixlen)
return 0;
9409 s = strptr + olen - suffixlen;
9410 if (
memcmp(s, suffixptr, suffixlen) != 0)
return 0;
9428 rb_str_delete_suffix_bang(
VALUE str,
VALUE suffix)
9430 long olen, suffixlen,
len;
9431 str_modifiable(str);
9433 suffixlen = deleted_suffix_length(str, suffix);
9434 if (suffixlen <= 0)
return Qnil;
9437 str_modify_keep_cr(str);
9438 len = olen - suffixlen;
9458 rb_str_delete_suffix(
VALUE str,
VALUE suffix)
9462 suffixlen = deleted_suffix_length(str, suffix);
9480 val = rb_fs_check(val);
9483 "value of %"PRIsVALUE" must be String or Regexp",
9500 str_modifiable(str);
9517 str_replace_shared_without_enc(str2, str);
9535 rb_str_valid_encoding_p(
VALUE str)
9553 rb_str_is_ascii_only_p(
VALUE str)
9577 static const char ellipsis[] =
"...";
9578 const long ellipsislen =
sizeof(ellipsis) - 1;
9581 const char *
const p =
RSTRING_PTR(str), *e = p + blen;
9582 VALUE estr, ret = 0;
9586 (e =
rb_enc_nth(p, e, len, enc)) - p == blen) {
9589 else if (len <= ellipsislen ||
9653 return enc_str_scrub(enc, str, repl, cr);
9675 repl = str_compat_and_valid(repl, enc);
9684 #define DEFAULT_REPLACE_CHAR(str) do { \ 9685 static const char replace[sizeof(str)-1] = str; \ 9686 rep = replace; replen = (int)sizeof(replace); \ 9698 else if (!
NIL_P(repl)) {
9713 p = search_nonascii(p, e);
9737 if (e - p < clen) clen = e - p;
9744 for (; clen > 1; clen--) {
9757 repl = str_compat_and_valid(repl, enc);
9765 p = search_nonascii(p, e);
9792 repl = str_compat_and_valid(repl, enc);
9809 else if (!
NIL_P(repl)) {
9843 if (e - p < clen) clen = e - p;
9844 if (clen <= mbminlen * 2) {
9849 for (; clen > mbminlen; clen-=mbminlen) {
9861 repl = str_compat_and_valid(repl, enc);
9888 repl = str_compat_and_valid(repl, enc);
9937 str_scrub_bang(
int argc,
VALUE *argv,
VALUE str)
9945 static ID id_normalize;
9946 static ID id_normalized_p;
9947 static VALUE mUnicodeNormalize;
9950 unicode_normalize_common(
int argc,
VALUE *argv,
VALUE str,
ID id)
9952 static int UnicodeNormalizeRequired = 0;
9955 if (!UnicodeNormalizeRequired) {
9956 rb_require(
"unicode_normalize/normalize.rb");
9957 UnicodeNormalizeRequired = 1;
9961 return rb_funcallv(mUnicodeNormalize,
id, argc+1, argv2);
9987 rb_str_unicode_normalize(
int argc,
VALUE *argv,
VALUE str)
9989 return unicode_normalize_common(argc, argv, str, id_normalize);
10000 rb_str_unicode_normalize_bang(
int argc,
VALUE *argv,
VALUE str)
10002 return rb_str_replace(str, unicode_normalize_common(argc, argv, str, id_normalize));
10023 rb_str_unicode_normalized_p(
int argc,
VALUE *argv,
VALUE str)
10025 return unicode_normalize_common(argc, argv, str, id_normalized_p);
10070 #define sym_equal rb_obj_equal 10073 sym_printable(
const char *s,
const char *send,
rb_encoding *enc)
10100 if ((resenc != enc && !rb_str_is_ascii_only_p(sym)) || len != (
long)
strlen(ptr) ||
10121 if ((resenc != enc && !rb_str_is_ascii_only_p(str)) ||
10122 !sym_printable(ptr, ptr + len, enc)) {
10156 memmove(dest + 1, dest, len);
10163 memcpy(dest + 1, ptr, len);
10200 sym_to_sym(
VALUE sym)
10242 sym_succ(
VALUE sym)
10338 return rb_str_match(
rb_sym2str(sym), other);
10350 sym_match_m(
int argc,
VALUE *argv,
VALUE sym)
10352 return rb_str_match_m(argc, argv,
rb_sym2str(sym));
10364 sym_match_m_p(
int argc,
VALUE *argv,
VALUE sym)
10366 return rb_str_match_m_p(argc, argv, sym);
10382 return rb_str_aref_m(argc, argv,
rb_sym2str(sym));
10394 sym_length(
VALUE sym)
10407 sym_empty(
VALUE sym)
10421 sym_upcase(
int argc,
VALUE *argv,
VALUE sym)
10435 sym_downcase(
int argc,
VALUE *argv,
VALUE sym)
10449 sym_capitalize(
int argc,
VALUE *argv,
VALUE sym)
10463 sym_swapcase(
int argc,
VALUE *argv,
VALUE sym)
10476 sym_encoding(
VALUE sym)
10482 string_for_symbol(
VALUE name)
10501 name = string_for_symbol(name);
10511 name = string_for_symbol(name);
10532 #define rb_intern(str) rb_intern_const(str) 10685 id_normalized_p =
rb_intern(
"normalized?");
#define RBASIC_CLEAR_CLASS(obj)
int rb_enc_str_asciionly_p(VALUE str)
VALUE rb_utf8_str_new(const char *ptr, long len)
VALUE rb_str_resize(VALUE str, long len)
#define ENCINDEX_US_ASCII
VALUE rb_external_str_with_enc(VALUE str, rb_encoding *eenc)
int rb_enc_codelen(int c, rb_encoding *enc)
int rb_enc_get_index(VALUE obj)
int rb_reg_backref_number(VALUE match, VALUE backref)
#define BARE_STRING_P(str)
#define ONIGENC_CODE_TO_MBCLEN(enc, code)
#define is_broken_string(str)
#define MBCLEN_CHARFOUND_P(ret)
void rb_warn(const char *fmt,...)
rb_encoding * rb_enc_check(VALUE str1, VALUE str2)
VALUE rb_ary_pop(VALUE ary)
void rb_bug(const char *fmt,...)
#define MBCLEN_CHARFOUND_LEN(ret)
#define RESIZE_CAPA(str, capacity)
#define rb_enc_mbc_to_codepoint(p, e, enc)
VALUE rb_usascii_str_new_static(const char *ptr, long len)
void rb_enc_copy(VALUE obj1, VALUE obj2)
size_t strlen(const char *)
VALUE rb_enc_str_scrub(rb_encoding *enc, VALUE str, VALUE repl)
#define CHECK_IF_ASCII(c)
void rb_backref_set(VALUE)
#define ENCODING_CODERANGE_SET(obj, encindex, cr)
RUBY_FUNC_EXPORTED VALUE rb_str_locktmp_ensure(VALUE str, VALUE(*func)(VALUE), VALUE arg)
VALUE rb_str_equal(VALUE str1, VALUE str2)
char * rb_str_to_cstr(VALUE str)
VALUE rb_str_new_static(const char *ptr, long len)
VALUE rb_str_eql(VALUE str1, VALUE str2)
VALUE rb_locale_str_new_cstr(const char *ptr)
#define ENCINDEX_UTF_16LE
VALUE rb_sym_to_s(VALUE sym)
VALUE rb_external_str_new_with_enc(const char *ptr, long len, rb_encoding *eenc)
void rb_undef_alloc_func(VALUE)
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
VALUE rb_setup_fake_str(struct RString *fake_str, const char *name, long len, rb_encoding *enc)
int rb_block_given_p(void)
Determines if the current method is given a block.
VALUE rb_str_new_frozen(VALUE orig)
st_index_t rb_str_hash(VALUE str)
VALUE rb_enc_str_buf_cat(VALUE str, const char *ptr, long len, rb_encoding *ptr_enc)
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_locale_str_new(const char *ptr, long len)
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
VALUE rb_reg_check_preprocess(VALUE)
void rb_str_set_len(VALUE str, long len)
#define is_ascii_string(str)
ONIG_EXTERN int onig_new(OnigRegex *, const OnigUChar *pattern, const OnigUChar *pattern_end, OnigOptionType option, OnigEncoding enc, const OnigSyntaxType *syntax, OnigErrorInfo *einfo)
#define ONIGERR_INVALID_CODE_POINT_VALUE
#define ENC_CODERANGE_SET(obj, cr)
VALUE rb_enc_str_new_static(const char *ptr, long len, rb_encoding *enc)
VALUE rb_fstring_enc_new(const char *ptr, long len, rb_encoding *enc)
#define ZALLOC_N(type, n)
void rb_str_change_terminator_length(VALUE str, const int oldtermlen, const int termlen)
rb_encoding * rb_to_encoding(VALUE enc)
int rb_enc_dummy_p(rb_encoding *enc)
#define ENC_CODERANGE_CLEAR(obj)
void rb_econv_close(rb_econv_t *ec)
#define ONIGENC_IS_ALLOWED_REVERSE_MATCH(enc, s, end)
VALUE rb_str_escape(VALUE str)
VALUE rb_enc_from_encoding(rb_encoding *encoding)
bool rb_reg_start_with_p(VALUE re, VALUE str)
VALUE rb_reg_match(VALUE, VALUE)
long rb_memsearch(const void *, long, const void *, long, rb_encoding *)
VALUE rb_check_convert_type_with_id(VALUE, int, const char *, ID)
rb_encoding * rb_default_internal_encoding(void)
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rb_reg_regsub(VALUE, VALUE, struct re_registers *, VALUE)
RUBY_EXTERN char * crypt(const char *, const char *)
st_index_t rb_memhash(const void *ptr, long len)
int rb_usascii_encindex(void)
VALUE rb_str_split(VALUE str, const char *sep0)
rb_encoding * rb_enc_compatible(VALUE str1, VALUE str2)
VALUE rb_str_export_to_enc(VALUE str, rb_encoding *enc)
#define ONIGENC_CTYPE_ALPHA
void ruby_sized_xfree(void *x, size_t size)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
#define str_buf_cat2(str, ptr)
#define ENCINDEX_UTF_16BE
VALUE rb_filesystem_str_new(const char *ptr, long len)
VALUE rb_str_export(VALUE str)
#define RGENGC_WB_PROTECTED_STRING
unsigned int OnigCaseFoldType
#define RBASIC_SET_CLASS(obj, cls)
VALUE rb_backref_get(void)
VALUE rb_str_freeze(VALUE str)
#define ENCODING_GET_INLINED(obj)
long rb_enc_strlen(const char *p, const char *e, rb_encoding *enc)
unsigned int rb_enc_codepoint_len(const char *p, const char *e, int *len_p, rb_encoding *enc)
long rb_enc_strlen_cr(const char *p, const char *e, rb_encoding *enc, int *cr)
#define RSTRING_GETMEM(str, ptrvar, lenvar)
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
VALUE rb_funcall_with_block(VALUE, ID, int, const VALUE *, VALUE)
VALUE rb_str_initialize(VALUE str, const char *ptr, long len, rb_encoding *enc)
int rb_objspace_garbage_object_p(VALUE obj)
char * rb_string_value_ptr(volatile VALUE *ptr)
VALUE rb_utf8_str_new_static(const char *ptr, long len)
VALUE rb_str_concat_literals(size_t num, const VALUE *strary)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
int rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc)
#define ENC_CODERANGE_MASK
void rb_include_module(VALUE klass, VALUE module)
#define FL_TEST_RAW(x, f)
VALUE rb_hash_lookup(VALUE hash, VALUE key)
VALUE rb_sym_proc_call(ID mid, int argc, const VALUE *argv, VALUE passed_proc)
VALUE rb_range_beg_len(VALUE, long *, long *, long, int)
#define DEFAULT_REPLACE_CHAR(str)
void rb_gc_register_address(VALUE *addr)
RUBY_FUNC_EXPORTED size_t rb_str_memsize(VALUE str)
int st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data_t arg)
VALUE rb_str_new(const char *ptr, long len)
#define rb_enc_mbmaxlen(enc)
#define STR_SET_NOEMBED(str)
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
An equivalent to ensure clause.
void rb_gc_force_recycle(VALUE obj)
rb_encoding * rb_utf8_encoding(void)
VALUE rb_str_export_locale(VALUE str)
VALUE rb_str_new_shared(VALUE str)
void rb_undef_method(VALUE klass, const char *name)
#define ONIGENC_CASE_MODIFIED
#define ENC_CODERANGE_7BIT
const char * rb_obj_classname(VALUE)
int rb_enc_symname_p(const char *, rb_encoding *)
VALUE rb_enc_sprintf(rb_encoding *enc, const char *format,...)
RUBY_EXTERN void * memmove(void *, const void *, size_t)
#define ONIGENC_CASE_FOLD_LITHUANIAN
#define ONIGENC_CODE_TO_MBC_MAXLEN
VALUE rb_str_append(VALUE str, VALUE str2)
char * crypt_r(const char *key, const char *setting, struct crypt_data *data)
VALUE rb_str_buf_cat(VALUE, const char *, long)
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
VALUE rb_fstring_enc_cstr(const char *ptr, rb_encoding *enc)
#define NEWOBJ_OF(obj, type, klass, flags)
int rb_str_hash_cmp(VALUE str1, VALUE str2)
#define OBJ_TAINTED_RAW(x)
#define STR_EMBEDDABLE_P(len, termlen)
#define rb_enc_isctype(c, t, enc)
#define RBASIC_SET_CLASS_RAW(obj, cls)
VALUE rb_obj_class(VALUE)
call-seq: obj.class -> class
#define RB_TYPE_P(obj, type)
#define RB_DEBUG_COUNTER_INC_IF(type, cond)
int rb_enc_str_coderange(VALUE str)
#define MEMZERO(p, type, n)
VALUE rb_str_plus(VALUE str1, VALUE str2)
VALUE rb_require(const char *)
rb_encoding * rb_default_external_encoding(void)
int rb_enc_to_index(rb_encoding *enc)
#define WANTARRAY(m, size)
#define rb_intern_str(string)
VALUE rb_equal(VALUE, VALUE)
call-seq: obj === other -> true or false
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
VALUE rb_convert_type_with_id(VALUE, int, const char *, ID)
int rb_enc_fast_mbclen(const char *p, const char *e, rb_encoding *enc)
RUBY_EXTERN VALUE rb_cObject
#define rb_enc_isascii(c, enc)
VALUE rb_str_to_inum(VALUE str, int base, int badcheck)
#define MBCLEN_NEEDMORE_P(ret)
VALUE rb_str_length(VALUE str)
VALUE rb_str_cat_cstr(VALUE str, const char *ptr)
VALUE rb_str_cat2(VALUE, const char *)
int rb_str_symname_p(VALUE sym)
VALUE rb_str_new_cstr(const char *ptr)
VALUE rb_str_buf_cat2(VALUE, const char *)
rb_econv_t * rb_econv_open_opts(const char *source_encoding, const char *destination_encoding, int ecflags, VALUE ecopts)
int rb_ascii8bit_encindex(void)
#define STR_SET_EMBED(str)
VALUE rb_any_to_s(VALUE)
call-seq: obj.to_s -> string
#define OBJ_FROZEN_RAW(x)
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
#define rb_enc_step_back(s, p, e, n, enc)
#define ENC_CODERANGE_CLEAN_P(cr)
void rb_enc_set_index(VALUE obj, int idx)
VALUE rb_str_concat(VALUE str1, VALUE str2)
#define offsetof(p_type, field)
#define ENUM_ELEM(ary, e)
st_table * rb_vm_fstring_table(void)
RUBY_ALIAS_FUNCTION(rb_str_dup_frozen(VALUE str), rb_str_new_frozen,(str))
VALUE rb_str_scrub(VALUE str, VALUE repl)
char ary[RSTRING_EMBED_LEN_MAX+1]
long rb_str_offset(VALUE str, long pos)
#define STR_SET_EMBED_LEN(str, n)
#define ALLOCA_N(type, n)
#define range(low, item, hi)
#define ENC_CODERANGE_UNKNOWN
#define rb_enc_isprint(c, enc)
#define RUBY_FUNC_EXPORTED
#define MEMCPY(p1, p2, type, n)
#define ENC_CODERANGE_BROKEN
VALUE rb_enc_associate_index(VALUE obj, int idx)
#define rb_str_index(str, sub, offset)
#define OBJ_FREEZE_RAW(x)
#define rb_enc_codepoint(p, e, enc)
void rb_str_update(VALUE str, long beg, long len, VALUE val)
#define rb_enc_mbminlen(enc)
VALUE rb_utf8_str_new_cstr(const char *ptr)
#define ENC_CODERANGE_VALID
#define RUBY_DTRACE_CREATE_HOOK(name, arg)
long rb_str_sublen(VALUE str, long pos)
RUBY_FUNC_EXPORTED VALUE rb_fstring(VALUE str)
VALUE rb_str_times(VALUE str, VALUE times)
VALUE rb_str_tmp_frozen_acquire(VALUE orig)
void rb_sys_fail(const char *mesg)
struct mapping_buffer mapping_buffer
int rb_enc_ascget(const char *p, const char *e, int *len, rb_encoding *enc)
void rb_str_modify_expand(VALUE str, long expand)
VALUE rb_obj_as_string(VALUE obj)
#define RARRAY_CONST_PTR(a)
VALUE rb_str_subseq(VALUE str, long beg, long len)
#define REALLOC_N(var, type, n)
char * rb_string_value_cstr(volatile VALUE *ptr)
#define RUBY_MAX_CHAR_LEN
long rb_reg_search0(VALUE, VALUE, long, int, int)
VALUE rb_obj_freeze(VALUE)
call-seq: obj.freeze -> obj
int(* case_map)(OnigCaseFoldType *flagP, const OnigUChar **pp, const OnigUChar *end, OnigUChar *to, OnigUChar *to_end, const struct OnigEncodingTypeST *enc)
VALUE rb_str_format(int, const VALUE *, VALUE)
int rb_enc_precise_mbclen(const char *p, const char *e, rb_encoding *enc)
int rb_enc_unicode_p(rb_encoding *enc)
#define rb_strlen_lit(str)
#define ONIGENC_CASE_UPCASE
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
long rb_reg_search(VALUE, VALUE, long, int)
VALUE rb_check_hash_type(VALUE hash)
#define ONIGENC_CASE_FOLD
int rb_str_cmp(VALUE str1, VALUE str2)
unsigned char buf[MIME_BUF_SIZE]
VALUE rb_str_buf_new_cstr(const char *ptr)
rb_encoding * rb_usascii_encoding(void)
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
VALUE rb_sym_to_proc(VALUE sym)
rb_encoding * rb_locale_encoding(void)
VALUE rb_str_replace(VALUE str, VALUE str2)
#define rb_enc_is_newline(p, end, enc)
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
#define ONIGENC_CASE_DOWNCASE
#define ENC_CODERANGE_AND(a, b)
int rb_utf8_encindex(void)
void rb_str_shared_replace(VALUE str, VALUE str2)
#define ENCODING_SET_INLINED(obj, i)
VALUE rb_obj_encoding(VALUE obj)
#define TERM_FILL(ptr, termlen)
#define ONIGENC_CASE_ASCII_ONLY
#define ONIGENC_CASE_TITLECASE
#define rb_enc_asciicompat(enc)
VALUE rb_str_buf_cat_ascii(VALUE str, const char *ptr)
int memcmp(const void *s1, const void *s2, size_t len)
VALUE rb_str_quote_unprintable(VALUE str)
long rb_str_coderange_scan_restartable(const char *s, const char *e, rb_encoding *enc, int *cr)
#define RARRAY_LENINT(ary)
void rb_str_tmp_frozen_release(VALUE orig, VALUE tmp)
#define ENCODING_IS_ASCII8BIT(obj)
#define ONIG_OPTION_DEFAULT
VALUE rb_cEncodingConverter
VALUE rb_str_to_str(VALUE str)
VALUE rb_str_chomp_string(VALUE str, VALUE rs)
void rb_define_hooked_variable(const char *, VALUE *, VALUE(*)(ANYARGS), void(*)(ANYARGS))
VALUE rb_string_value(volatile VALUE *ptr)
VALUE rb_tainted_str_new_cstr(const char *ptr)
int rb_respond_to(VALUE, ID)
#define RUBY_ASSERT(expr)
register unsigned int len
#define StringValueCStr(v)
VALUE rb_usascii_str_new(const char *ptr, long len)
VALUE rb_str_buf_append(VALUE str, VALUE str2)
RUBY_EXTERN VALUE rb_default_rs
void rb_str_free(VALUE str)
VALUE rb_filesystem_str_new_cstr(const char *ptr)
struct mapping_buffer * next
#define rb_enc_right_char_head(s, p, e, enc)
#define RB_OBJ_WRITE(a, slot, b)
#define ENCODING_GET(obj)
rb_encoding * rb_enc_get(VALUE obj)
#define STR_SET_SHARED(str, shared_str)
#define STR_HEAP_PTR(str)
char * rb_enc_nth(const char *p, const char *e, long nth, rb_encoding *enc)
#define UNLIMITED_ARGUMENTS
char * rb_str_subpos(VALUE str, long beg, long *lenp)
VALUE rb_str_unlocktmp(VALUE str)
VALUE rb_tainted_str_new(const char *ptr, long len)
#define CASE_MAPPING_ADDITIONAL_LENGTH
#define MBCLEN_INVALID_P(ret)
#define RARRAY_AREF(a, i)
rb_econv_result_t rb_econv_convert(rb_econv_t *ec, const unsigned char **source_buffer_ptr, const unsigned char *source_buffer_end, unsigned char **destination_buffer_ptr, unsigned char *destination_buffer_end, int flags)
double rb_str_to_dbl(VALUE, int)
Parses a string representation of a floating point number.
#define STR_SET_LEN(str, n)
#define RBASIC_CLASS(obj)
#define ONIGENC_MBCLEN_CHARFOUND_LEN(r)
#define RESIZE_CAPA_TERM(str, capacity, termlen)
VALUE rb_check_array_type(VALUE ary)
VALUE rb_hash_aref(VALUE hash, VALUE key)
#define UNALIGNED_WORD_ACCESS
#define ONIGERR_TOO_BIG_WIDE_CHAR_VALUE
#define ENC_CODERANGE(obj)
VALUE rb_to_symbol(VALUE name)
VALUE rb_str_cat(VALUE str, const char *ptr, long len)
long rb_str_strlen(VALUE str)
VALUE rb_str_conv_enc_opts(VALUE str, rb_encoding *from, rb_encoding *to, int ecflags, VALUE ecopts)
int rb_str_buf_cat_escaped_char(VALUE result, unsigned int c, int unicode_p)
void rb_warning(const char *fmt,...)
#define ONIGENC_CASE_FOLD_TURKISH_AZERI
VALUE rb_str_locktmp(VALUE)
const struct st_hash_type rb_fstring_hash_type
VALUE rb_str_drop_bytes(VALUE str, long len)
size_t rb_str_capacity(VALUE str)
VALUE rb_fstring_new(const char *ptr, long len)
VALUE rb_enc_str_new_cstr(const char *ptr, rb_encoding *enc)
rb_encoding * rb_filesystem_encoding(void)
rb_encoding * rb_enc_get_from_index(int index)
void rb_str_setter(VALUE val, ID id, VALUE *var)
VALUE rb_str_tmp_new(long len)
VALUE rb_obj_as_string_result(VALUE str, VALUE obj)
#define rb_enc_left_char_head(s, p, e, enc)
VALUE rb_reg_match_p(VALUE re, VALUE str, long pos)
VALUE rb_str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to)
void rb_backref_set_string(VALUE string, long pos, long len)
#define rb_str_splice(str, beg, len, val)
#define SHARABLE_SUBSTRING_P(beg, len, end)
#define FL_UNSET_RAW(x, f)
#define RETURN_ENUMERATOR(obj, argc, argv)
VALUE rb_fstring_cstr(const char *ptr)
#define RB_DEBUG_COUNTER_INC(type)
VALUE rb_str_substr(VALUE str, long beg, long len)
ONIG_EXTERN const OnigSyntaxType * OnigDefaultSyntax
void rb_must_asciicompat(VALUE str)
VALUE rb_sym_all_symbols(void)
VALUE rb_str_cat_conv_enc_opts(VALUE newstr, long ofs, const char *ptr, long len, rb_encoding *from, int ecflags, VALUE ecopts)
VALUE rb_external_str_new(const char *ptr, long len)
ONIG_EXTERN OnigPosition onig_match(OnigRegex, const OnigUChar *str, const OnigUChar *end, const OnigUChar *at, OnigRegion *region, OnigOptionType option)
VALUE rb_str_include_range_p(VALUE beg, VALUE end, VALUE val, VALUE exclusive)
VALUE rb_str_succ(VALUE orig)
rb_encoding * rb_ascii8bit_encoding(void)
#define MIN_PRE_ALLOC_SIZE
#define RSTRING_LENINT(str)
ONIG_EXTERN int onigenc_ascii_only_case_map(OnigCaseFoldType *flagP, const OnigUChar **pp, const OnigUChar *end, OnigUChar *to, OnigUChar *to_end, const struct OnigEncodingTypeST *enc)
rb_encoding * rb_enc_check_str(VALUE str1, VALUE str2)
#define rb_check_frozen(obj)
#define CONST_ID(var, str)
VALUE rb_str_intern(VALUE)
VALUE rb_str_inspect(VALUE str)
#define rb_intern_const(str)
#define RSTRING_EMBED_LEN(str)
#define SPECIAL_CONST_P(x)
VALUE rb_str_encode(VALUE str, VALUE to, int ecflags, VALUE ecopts)
VALUE rb_str_buf_new(long capa)
int rb_num_to_uint(VALUE val, unsigned int *ret)
VALUE rb_define_module(const char *name)
int rb_str_comparable(VALUE str1, VALUE str2)
#define rb_enc_mbcput(c, buf, enc)
VALUE rb_str_ord(VALUE s)
#define RB_INTEGER_TYPE_P(obj)
#define rb_str_dup_frozen
#define ONIGENC_CTYPE_DIGIT
#define OBJ_INFECT_RAW(x, s)
VALUE rb_invcmp(VALUE x, VALUE y)
VALUE rb_str_resurrect(VALUE str)
VALUE rb_check_string_type(VALUE str)
VALUE rb_usascii_str_new_cstr(const char *ptr)
VALUE rb_id_quote_unprintable(ID id)
VALUE rb_reg_regcomp(VALUE)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
#define ENCINDEX_UTF_32LE
VALUE rb_str_ellipsize(VALUE str, long len)
Shortens str and adds three dots, an ellipsis, if it is longer than len characters.
#define ENCINDEX_UTF_32BE
#define rb_enc_prev_char(s, p, e, enc)
#define STR_HEAP_SIZE(str)
VALUE rb_str_dump(VALUE str)
VALUE rb_reg_nth_match(int, VALUE)
#define rb_enc_code_to_mbclen(c, enc)
void rb_str_modify(VALUE str)
#define ONIGENC_MBCLEN_CHARFOUND_P(r)
VALUE rb_enc_str_new(const char *ptr, long len, rb_encoding *enc)
VALUE rb_external_str_new_cstr(const char *ptr)
rb_encoding * rb_enc_from_index(int index)
VALUE rb_str_dup(VALUE str)
VALUE rb_str_new_with_class(VALUE obj, const char *ptr, long len)
char * rb_str_fill_terminator(VALUE str, const int newminlen)