1 /**********************************************************************
6 created at: Mon Aug 9 17:12:58 JST 1993
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
9 Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
10 Copyright (C) 2000 Information-technology Promotion Agency, Japan
12 **********************************************************************/
14 #include "ruby/ruby.h"
16 #include "ruby/encoding.h"
18 #define BEG(no) regs->beg[no]
19 #define END(no) regs->end[no]
28 #undef rb_str_new_cstr
29 #undef rb_tainted_str_new_cstr
30 #undef rb_usascii_str_new_cstr
35 #undef rb_tainted_str_new2
36 #undef rb_usascii_str_new2
37 #undef rb_str_dup_frozen
38 #undef rb_str_buf_new_cstr
39 #undef rb_str_buf_new2
40 #undef rb_str_buf_cat2
46 #define STR_TMPLOCK FL_USER7
47 #define STR_NOEMBED FL_USER1
48 #define STR_SHARED FL_USER2 /* = ELTS_SHARED */
49 #define STR_ASSOC FL_USER3
50 #define STR_SHARED_P(s) FL_ALL(s, STR_NOEMBED|ELTS_SHARED)
51 #define STR_ASSOC_P(s) FL_ALL(s, STR_NOEMBED|STR_ASSOC)
52 #define STR_NOCAPA (STR_NOEMBED|ELTS_SHARED|STR_ASSOC)
53 #define STR_NOCAPA_P(s) (FL_TEST(s,STR_NOEMBED) && FL_ANY(s,ELTS_SHARED|STR_ASSOC))
54 #define STR_UNSET_NOCAPA(s) do {\
55 if (FL_TEST(s,STR_NOEMBED)) FL_UNSET(s,(ELTS_SHARED|STR_ASSOC));\
59 #define STR_SET_NOEMBED(str) do {\
60 FL_SET(str, STR_NOEMBED);\
61 STR_SET_EMBED_LEN(str, 0);\
63 #define STR_SET_EMBED(str) FL_UNSET(str, STR_NOEMBED)
64 #define STR_EMBED_P(str) (!FL_TEST(str, STR_NOEMBED))
65 #define STR_SET_EMBED_LEN(str, n) do { \
67 RBASIC(str)->flags &= ~RSTRING_EMBED_LEN_MASK;\
68 RBASIC(str)->flags |= (tmp_n) << RSTRING_EMBED_LEN_SHIFT;\
71 #define STR_SET_LEN(str, n) do { \
72 if (STR_EMBED_P(str)) {\
73 STR_SET_EMBED_LEN(str, n);\
76 RSTRING(str)->as.heap.len = (n);\
80 #define STR_DEC_LEN(str) do {\
81 if (STR_EMBED_P(str)) {\
82 long n = RSTRING_LEN(str);\
84 STR_SET_EMBED_LEN(str, n);\
87 RSTRING(str)->as.heap.len--;\
91 #define RESIZE_CAPA(str,capacity) do {\
92 if (STR_EMBED_P(str)) {\
93 if ((capacity) > RSTRING_EMBED_LEN_MAX) {\
94 char *tmp = ALLOC_N(char, capacity+1);\
95 memcpy(tmp, RSTRING_PTR(str), RSTRING_LEN(str));\
96 RSTRING(str)->as.heap.ptr = tmp;\
97 RSTRING(str)->as.heap.len = RSTRING_LEN(str);\
98 STR_SET_NOEMBED(str);\
99 RSTRING(str)->as.heap.aux.capa = (capacity);\
103 REALLOC_N(RSTRING(str)->as.heap.ptr, char, (capacity)+1);\
104 if (!STR_NOCAPA_P(str))\
105 RSTRING(str)->as.heap.aux.capa = (capacity);\
109 #define is_ascii_string(str) (rb_enc_str_coderange(str) == ENC_CODERANGE_7BIT)
110 #define is_broken_string(str) (rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN)
112 #define STR_ENC_GET(str) rb_enc_from_index(ENCODING_GET(str))
115 single_byte_optimizable(VALUE str
)
117 rb_encoding
*enc
= STR_ENC_GET(str
);
119 if (rb_enc_mbmaxlen(enc
) == 1)
122 /* Conservative. It may be ENC_CODERANGE_UNKNOWN. */
123 if (ENC_CODERANGE(str
) == ENC_CODERANGE_7BIT
)
126 /* Conservative. Possibly single byte.
127 * "\xa1" in Shift_JIS for example. */
133 static inline const char *
134 search_nonascii(const char *p
, const char *e
)
136 #if SIZEOF_VALUE == 8
137 # define NONASCII_MASK 0x8080808080808080LL
138 #elif SIZEOF_VALUE == 4
139 # define NONASCII_MASK 0x80808080UL
142 if (sizeof(VALUE
) * 2 < e
- p
) {
144 const VALUE lowbits
= sizeof(VALUE
) - 1;
145 s
= (const VALUE
*)(~lowbits
& ((VALUE
)p
+ lowbits
));
146 while (p
< (const char *)s
) {
151 t
= (const VALUE
*)(~lowbits
& (VALUE
)e
);
153 if (*s
& NONASCII_MASK
) {
171 coderange_scan(const char *p
, long len
, rb_encoding
*enc
)
173 const char *e
= p
+ len
;
175 if (rb_enc_to_index(enc
) == 0) {
176 /* enc is ASCII-8BIT. ASCII-8BIT string never be broken. */
177 p
= search_nonascii(p
, e
);
178 return p
? ENC_CODERANGE_VALID
: ENC_CODERANGE_7BIT
;
181 if (rb_enc_asciicompat(enc
)) {
182 p
= search_nonascii(p
, e
);
184 return ENC_CODERANGE_7BIT
;
187 int ret
= rb_enc_precise_mbclen(p
, e
, enc
);
188 if (!MBCLEN_CHARFOUND_P(ret
)) {
189 return ENC_CODERANGE_BROKEN
;
191 p
+= MBCLEN_CHARFOUND_LEN(ret
);
193 p
= search_nonascii(p
, e
);
195 return ENC_CODERANGE_VALID
;
200 return ENC_CODERANGE_BROKEN
;
202 return ENC_CODERANGE_VALID
;
206 int ret
= rb_enc_precise_mbclen(p
, e
, enc
);
208 if (!MBCLEN_CHARFOUND_P(ret
)) {
209 return ENC_CODERANGE_BROKEN
;
211 p
+= MBCLEN_CHARFOUND_LEN(ret
);
214 return ENC_CODERANGE_BROKEN
;
216 return ENC_CODERANGE_VALID
;
220 rb_str_coderange_scan_restartable(const char *s
, const char *e
, rb_encoding
*enc
, int *cr
)
224 if (*cr
== ENC_CODERANGE_BROKEN
)
227 if (rb_enc_to_index(enc
) == 0) {
228 /* enc is ASCII-8BIT. ASCII-8BIT string never be broken. */
229 p
= search_nonascii(p
, e
);
230 *cr
= (!p
&& *cr
!= ENC_CODERANGE_VALID
) ? ENC_CODERANGE_7BIT
: ENC_CODERANGE_VALID
;
233 else if (rb_enc_asciicompat(enc
)) {
234 p
= search_nonascii(p
, e
);
236 if (*cr
!= ENC_CODERANGE_VALID
) *cr
= ENC_CODERANGE_7BIT
;
240 int ret
= rb_enc_precise_mbclen(p
, e
, enc
);
241 if (!MBCLEN_CHARFOUND_P(ret
)) {
242 *cr
= MBCLEN_INVALID_P(ret
) ? ENC_CODERANGE_BROKEN
: ENC_CODERANGE_UNKNOWN
;
245 p
+= MBCLEN_CHARFOUND_LEN(ret
);
247 p
= search_nonascii(p
, e
);
249 *cr
= ENC_CODERANGE_VALID
;
254 *cr
= e
< p
? ENC_CODERANGE_BROKEN
: ENC_CODERANGE_VALID
;
259 int ret
= rb_enc_precise_mbclen(p
, e
, enc
);
260 if (!MBCLEN_CHARFOUND_P(ret
)) {
261 *cr
= MBCLEN_INVALID_P(ret
) ? ENC_CODERANGE_BROKEN
: ENC_CODERANGE_UNKNOWN
;
264 p
+= MBCLEN_CHARFOUND_LEN(ret
);
266 *cr
= e
< p
? ENC_CODERANGE_BROKEN
: ENC_CODERANGE_VALID
;
272 str_enc_copy(VALUE str1
, VALUE str2
)
274 rb_enc_set_index(str1
, ENCODING_GET(str2
));
278 rb_enc_cr_str_copy_for_substr(VALUE dest
, VALUE src
)
280 /* this function is designed for copying encoding and coderange
281 * from src to new string "dest" which is made from the part of src.
283 str_enc_copy(dest
, src
);
284 switch (ENC_CODERANGE(src
)) {
285 case ENC_CODERANGE_7BIT
:
286 ENC_CODERANGE_SET(dest
, ENC_CODERANGE_7BIT
);
288 case ENC_CODERANGE_VALID
:
289 if (!rb_enc_asciicompat(STR_ENC_GET(src
)) ||
290 search_nonascii(RSTRING_PTR(dest
), RSTRING_END(dest
)))
291 ENC_CODERANGE_SET(dest
, ENC_CODERANGE_VALID
);
293 ENC_CODERANGE_SET(dest
, ENC_CODERANGE_7BIT
);
296 if (RSTRING_LEN(dest
) == 0) {
297 if (!rb_enc_asciicompat(STR_ENC_GET(src
)))
298 ENC_CODERANGE_SET(dest
, ENC_CODERANGE_VALID
);
300 ENC_CODERANGE_SET(dest
, ENC_CODERANGE_7BIT
);
307 rb_enc_cr_str_exact_copy(VALUE dest
, VALUE src
)
309 str_enc_copy(dest
, src
);
310 ENC_CODERANGE_SET(dest
, ENC_CODERANGE(src
));
314 rb_enc_str_coderange(VALUE str
)
316 int cr
= ENC_CODERANGE(str
);
318 if (cr
== ENC_CODERANGE_UNKNOWN
) {
319 rb_encoding
*enc
= STR_ENC_GET(str
);
320 cr
= coderange_scan(RSTRING_PTR(str
), RSTRING_LEN(str
), enc
);
321 ENC_CODERANGE_SET(str
, cr
);
327 rb_enc_str_asciionly_p(VALUE str
)
329 rb_encoding
*enc
= STR_ENC_GET(str
);
331 if (!rb_enc_asciicompat(enc
))
333 else if (rb_enc_str_coderange(str
) == ENC_CODERANGE_7BIT
)
339 str_mod_check(VALUE s
, const char *p
, long len
)
341 if (RSTRING_PTR(s
) != p
|| RSTRING_LEN(s
) != len
){
342 rb_raise(rb_eRuntimeError
, "string modified");
347 str_frozen_check(VALUE s
)
350 rb_raise(rb_eRuntimeError
, "string frozen");
355 rb_str_capacity(VALUE str
)
357 if (STR_EMBED_P(str
)) {
358 return RSTRING_EMBED_LEN_MAX
;
360 else if (STR_NOCAPA_P(str
)) {
361 return RSTRING(str
)->as
.heap
.len
;
364 return RSTRING(str
)->as
.heap
.aux
.capa
;
369 str_alloc(VALUE klass
)
371 NEWOBJ(str
, struct RString
);
372 OBJSETUP(str
, klass
, T_STRING
);
374 str
->as
.heap
.ptr
= 0;
375 str
->as
.heap
.len
= 0;
376 str
->as
.heap
.aux
.capa
= 0;
382 str_new(VALUE klass
, const char *ptr
, long len
)
387 rb_raise(rb_eArgError
, "negative string size (or size too big)");
390 str
= str_alloc(klass
);
391 if (len
> RSTRING_EMBED_LEN_MAX
) {
392 RSTRING(str
)->as
.heap
.aux
.capa
= len
;
393 RSTRING(str
)->as
.heap
.ptr
= ALLOC_N(char,len
+1);
394 STR_SET_NOEMBED(str
);
397 memcpy(RSTRING_PTR(str
), ptr
, len
);
399 STR_SET_LEN(str
, len
);
400 RSTRING_PTR(str
)[len
] = '\0';
405 rb_str_new(const char *ptr
, long len
)
407 return str_new(rb_cString
, ptr
, len
);
411 rb_usascii_str_new(const char *ptr
, long len
)
413 VALUE str
= rb_str_new(ptr
, len
);
414 ENCODING_CODERANGE_SET(str
, rb_usascii_encindex(), ENC_CODERANGE_7BIT
);
419 rb_enc_str_new(const char *ptr
, long len
, rb_encoding
*enc
)
421 VALUE str
= rb_str_new(ptr
, len
);
422 rb_enc_associate(str
, enc
);
427 rb_str_new_cstr(const char *ptr
)
430 rb_raise(rb_eArgError
, "NULL pointer given");
432 return rb_str_new(ptr
, strlen(ptr
));
435 RUBY_ALIAS_FUNCTION(rb_str_new2(const char *ptr
), rb_str_new_cstr
, (ptr
))
436 #define rb_str_new2 rb_str_new_cstr
439 rb_usascii_str_new_cstr(const char *ptr
)
441 VALUE str
= rb_str_new2(ptr
);
442 ENCODING_CODERANGE_SET(str
, rb_usascii_encindex(), ENC_CODERANGE_7BIT
);
446 RUBY_ALIAS_FUNCTION(rb_usascii_str_new2(const char *ptr
), rb_usascii_str_new_cstr
, (ptr
))
447 #define rb_usascii_str_new2 rb_usascii_str_new_cstr
450 rb_tainted_str_new(const char *ptr
, long len
)
452 VALUE str
= rb_str_new(ptr
, len
);
459 rb_tainted_str_new_cstr(const char *ptr
)
461 VALUE str
= rb_str_new2(ptr
);
467 RUBY_ALIAS_FUNCTION(rb_tainted_str_new2(const char *ptr
), rb_tainted_str_new_cstr
, (ptr
))
468 #define rb_tainted_str_new2 rb_tainted_str_new_cstr
471 str_replace_shared(VALUE str2
, VALUE str
)
473 if (RSTRING_LEN(str
) <= RSTRING_EMBED_LEN_MAX
) {
475 memcpy(RSTRING_PTR(str2
), RSTRING_PTR(str
), RSTRING_LEN(str
)+1);
476 STR_SET_EMBED_LEN(str2
, RSTRING_LEN(str
));
479 FL_SET(str2
, STR_NOEMBED
);
480 RSTRING(str2
)->as
.heap
.len
= RSTRING_LEN(str
);
481 RSTRING(str2
)->as
.heap
.ptr
= RSTRING_PTR(str
);
482 RSTRING(str2
)->as
.heap
.aux
.shared
= str
;
483 FL_SET(str2
, ELTS_SHARED
);
485 rb_enc_cr_str_exact_copy(str2
, str
);
491 str_new_shared(VALUE klass
, VALUE str
)
493 return str_replace_shared(str_alloc(klass
), str
);
497 str_new3(VALUE klass
, VALUE str
)
499 return str_new_shared(klass
, str
);
503 rb_str_new_shared(VALUE str
)
505 VALUE str2
= str_new3(rb_obj_class(str
), str
);
507 OBJ_INFECT(str2
, str
);
511 RUBY_ALIAS_FUNCTION(rb_str_new3(VALUE str
), rb_str_new_shared
, (str
))
512 #define rb_str_new3 rb_str_new_shared
515 str_new4(VALUE klass
, VALUE str
)
519 str2
= str_alloc(klass
);
520 STR_SET_NOEMBED(str2
);
521 RSTRING(str2
)->as
.heap
.len
= RSTRING_LEN(str
);
522 RSTRING(str2
)->as
.heap
.ptr
= RSTRING_PTR(str
);
523 if (STR_SHARED_P(str
)) {
524 FL_SET(str2
, ELTS_SHARED
);
525 RSTRING(str2
)->as
.heap
.aux
.shared
= RSTRING(str
)->as
.heap
.aux
.shared
;
528 FL_SET(str
, ELTS_SHARED
);
529 RSTRING(str
)->as
.heap
.aux
.shared
= str2
;
531 rb_enc_cr_str_exact_copy(str2
, str
);
532 OBJ_INFECT(str2
, str
);
537 rb_str_new_frozen(VALUE orig
)
541 if (OBJ_FROZEN(orig
)) return orig
;
542 klass
= rb_obj_class(orig
);
543 if (STR_SHARED_P(orig
) && (str
= RSTRING(orig
)->as
.heap
.aux
.shared
)) {
545 ofs
= RSTRING_LEN(str
) - RSTRING_LEN(orig
);
546 if ((ofs
> 0) || (klass
!= RBASIC(str
)->klass
) ||
547 (!OBJ_TAINTED(str
) && OBJ_TAINTED(orig
))) {
548 str
= str_new3(klass
, str
);
549 RSTRING(str
)->as
.heap
.ptr
+= ofs
;
550 RSTRING(str
)->as
.heap
.len
-= ofs
;
552 rb_enc_cr_str_exact_copy(str
, orig
);
553 OBJ_INFECT(str
, orig
);
555 else if (STR_EMBED_P(orig
)) {
556 str
= str_new(klass
, RSTRING_PTR(orig
), RSTRING_LEN(orig
));
557 rb_enc_cr_str_exact_copy(str
, orig
);
558 OBJ_INFECT(str
, orig
);
560 else if (STR_ASSOC_P(orig
)) {
561 VALUE assoc
= RSTRING(orig
)->as
.heap
.aux
.shared
;
562 FL_UNSET(orig
, STR_ASSOC
);
563 str
= str_new4(klass
, orig
);
564 FL_SET(str
, STR_ASSOC
);
565 RSTRING(str
)->as
.heap
.aux
.shared
= assoc
;
568 str
= str_new4(klass
, orig
);
574 RUBY_ALIAS_FUNCTION(rb_str_new4(VALUE orig
), rb_str_new_frozen
, (orig
))
575 #define rb_str_new4 rb_str_new_frozen
578 rb_str_new_with_class(VALUE obj
, const char *ptr
, long len
)
580 return str_new(rb_obj_class(obj
), ptr
, len
);
583 RUBY_ALIAS_FUNCTION(rb_str_new5(VALUE obj
, const char *ptr
, long len
),
584 rb_str_new_with_class
, (obj
, ptr
, len
))
585 #define rb_str_new5 rb_str_new_with_class
587 #define STR_BUF_MIN_SIZE 128
590 rb_str_buf_new(long capa
)
592 VALUE str
= str_alloc(rb_cString
);
594 if (capa
< STR_BUF_MIN_SIZE
) {
595 capa
= STR_BUF_MIN_SIZE
;
597 FL_SET(str
, STR_NOEMBED
);
598 RSTRING(str
)->as
.heap
.aux
.capa
= capa
;
599 RSTRING(str
)->as
.heap
.ptr
= ALLOC_N(char, capa
+1);
600 RSTRING(str
)->as
.heap
.ptr
[0] = '\0';
606 rb_str_buf_new_cstr(const char *ptr
)
609 long len
= strlen(ptr
);
611 str
= rb_str_buf_new(len
);
612 rb_str_buf_cat(str
, ptr
, len
);
617 RUBY_ALIAS_FUNCTION(rb_str_buf_new2(const char *ptr
), rb_str_buf_new_cstr
, (ptr
))
618 #define rb_str_buf_new2 rb_str_buf_new_cstr
621 rb_str_tmp_new(long len
)
623 return str_new(0, 0, len
);
627 rb_str_free(VALUE str
)
629 if (!STR_EMBED_P(str
) && !STR_SHARED_P(str
)) {
630 xfree(RSTRING(str
)->as
.heap
.ptr
);
635 rb_str_to_str(VALUE str
)
637 return rb_convert_type(str
, T_STRING
, "String", "to_str");
641 rb_str_shared_replace(VALUE str
, VALUE str2
)
645 if (str
== str2
) return;
646 enc
= STR_ENC_GET(str2
);
647 cr
= ENC_CODERANGE(str2
);
649 OBJ_INFECT(str
, str2
);
650 if (!STR_SHARED_P(str
) && !STR_EMBED_P(str
)) {
651 xfree(RSTRING_PTR(str
));
653 if (RSTRING_LEN(str2
) <= RSTRING_EMBED_LEN_MAX
) {
655 memcpy(RSTRING_PTR(str
), RSTRING_PTR(str2
), RSTRING_LEN(str2
)+1);
656 STR_SET_EMBED_LEN(str
, RSTRING_LEN(str2
));
657 rb_enc_associate(str
, enc
);
658 ENC_CODERANGE_SET(str
, cr
);
661 STR_SET_NOEMBED(str
);
662 STR_UNSET_NOCAPA(str
);
663 RSTRING(str
)->as
.heap
.ptr
= RSTRING_PTR(str2
);
664 RSTRING(str
)->as
.heap
.len
= RSTRING_LEN(str2
);
665 if (STR_NOCAPA_P(str2
)) {
666 FL_SET(str
, RBASIC(str2
)->flags
& STR_NOCAPA
);
667 RSTRING(str
)->as
.heap
.aux
.shared
= RSTRING(str2
)->as
.heap
.aux
.shared
;
670 RSTRING(str
)->as
.heap
.aux
.capa
= RSTRING(str2
)->as
.heap
.aux
.capa
;
672 RSTRING(str2
)->as
.heap
.ptr
= 0; /* abandon str2 */
673 RSTRING(str2
)->as
.heap
.len
= 0;
674 RSTRING(str2
)->as
.heap
.aux
.capa
= 0;
675 STR_UNSET_NOCAPA(str2
);
676 rb_enc_associate(str
, enc
);
677 ENC_CODERANGE_SET(str
, cr
);
683 rb_obj_as_string(VALUE obj
)
687 if (TYPE(obj
) == T_STRING
) {
690 str
= rb_funcall(obj
, id_to_s
, 0);
691 if (TYPE(str
) != T_STRING
)
692 return rb_any_to_s(obj
);
693 if (OBJ_TAINTED(obj
)) OBJ_TAINT(str
);
697 static VALUE
rb_str_replace(VALUE
, VALUE
);
700 rb_str_dup(VALUE str
)
702 VALUE dup
= str_alloc(rb_obj_class(str
));
703 rb_str_replace(dup
, str
);
710 * String.new(str="") => new_str
712 * Returns a new string object containing a copy of <i>str</i>.
716 rb_str_init(int argc
, VALUE
*argv
, VALUE str
)
720 if (argc
> 0 && rb_scan_args(argc
, argv
, "01", &orig
) == 1)
721 rb_str_replace(str
, orig
);
726 rb_enc_strlen(const char *p
, const char *e
, rb_encoding
*enc
)
731 if (rb_enc_mbmaxlen(enc
) == rb_enc_mbminlen(enc
)) {
732 return (e
- p
+ rb_enc_mbminlen(enc
) - 1) / rb_enc_mbminlen(enc
);
734 else if (rb_enc_asciicompat(enc
)) {
738 q
= search_nonascii(p
, e
);
744 p
+= rb_enc_mbclen(p
, e
, enc
);
750 for (c
=0; p
<e
; c
++) {
751 p
+= rb_enc_mbclen(p
, e
, enc
);
757 rb_enc_strlen_cr(const char *p
, const char *e
, rb_encoding
*enc
, int *cr
)
764 if (rb_enc_mbmaxlen(enc
) == rb_enc_mbminlen(enc
)) {
765 return (e
- p
+ rb_enc_mbminlen(enc
) - 1) / rb_enc_mbminlen(enc
);
767 else if (rb_enc_asciicompat(enc
)) {
771 q
= search_nonascii(p
, e
);
773 if (!*cr
) *cr
= ENC_CODERANGE_7BIT
;
779 ret
= rb_enc_precise_mbclen(p
, e
, enc
);
780 if (MBCLEN_CHARFOUND_P(ret
)) {
781 *cr
|= ENC_CODERANGE_VALID
;
782 p
+= MBCLEN_CHARFOUND_LEN(ret
);
785 *cr
= ENC_CODERANGE_BROKEN
;
790 if (!*cr
) *cr
= ENC_CODERANGE_7BIT
;
794 for (c
=0; p
<e
; c
++) {
795 ret
= rb_enc_precise_mbclen(p
, e
, enc
);
796 if (MBCLEN_CHARFOUND_P(ret
)) {
797 *cr
|= ENC_CODERANGE_VALID
;
798 p
+= MBCLEN_CHARFOUND_LEN(ret
);
801 *cr
= ENC_CODERANGE_BROKEN
;
805 if (!*cr
) *cr
= ENC_CODERANGE_7BIT
;
810 #define is_utf8_lead_byte(c) (((c)&0xC0) != 0x80)
812 count_utf8_lead_bytes_with_word(const VALUE
*s
)
817 d
&= NONASCII_MASK
>> 7;
820 #if SIZEOF_VALUE == 8
828 str_strlen(VALUE str
, rb_encoding
*enc
)
833 if (single_byte_optimizable(str
)) return RSTRING_LEN(str
);
834 if (!enc
) enc
= STR_ENC_GET(str
);
835 p
= RSTRING_PTR(str
);
836 e
= RSTRING_END(str
);
838 if (ENC_CODERANGE(str
) == ENC_CODERANGE_VALID
&&
839 enc
== rb_utf8_encoding()) {
841 if (sizeof(VALUE
) * 2 < e
- p
) {
843 const VALUE lowbits
= sizeof(VALUE
) - 1;
844 s
= (const VALUE
*)(~lowbits
& ((VALUE
)p
+ lowbits
));
845 t
= (const VALUE
*)(~lowbits
& (VALUE
)e
);
846 while (p
< (const char *)s
) {
847 if (is_utf8_lead_byte(*p
)) len
++;
851 len
+= count_utf8_lead_bytes_with_word(s
);
857 if (is_utf8_lead_byte(*p
)) len
++;
863 n
= rb_enc_strlen_cr(p
, e
, enc
, &cr
);
865 ENC_CODERANGE_SET(str
, cr
);
872 * str.length => integer
873 * str.size => integer
875 * Returns the character length of <i>str</i>.
879 rb_str_length(VALUE str
)
883 len
= str_strlen(str
, STR_ENC_GET(str
));
889 * str.bytesize => integer
891 * Returns the length of <i>str</i> in bytes.
895 rb_str_bytesize(VALUE str
)
897 return INT2NUM(RSTRING_LEN(str
));
902 * str.empty? => true or false
904 * Returns <code>true</code> if <i>str</i> has a length of zero.
906 * "hello".empty? #=> false
911 rb_str_empty(VALUE str
)
913 if (RSTRING_LEN(str
) == 0)
920 * str + other_str => new_str
922 * Concatenation---Returns a new <code>String</code> containing
923 * <i>other_str</i> concatenated to <i>str</i>.
925 * "Hello from " + self.to_s #=> "Hello from main"
929 rb_str_plus(VALUE str1
, VALUE str2
)
935 enc
= rb_enc_check(str1
, str2
);
936 str3
= rb_str_new(0, RSTRING_LEN(str1
)+RSTRING_LEN(str2
));
937 memcpy(RSTRING_PTR(str3
), RSTRING_PTR(str1
), RSTRING_LEN(str1
));
938 memcpy(RSTRING_PTR(str3
) + RSTRING_LEN(str1
),
939 RSTRING_PTR(str2
), RSTRING_LEN(str2
));
940 RSTRING_PTR(str3
)[RSTRING_LEN(str3
)] = '\0';
942 if (OBJ_TAINTED(str1
) || OBJ_TAINTED(str2
))
944 ENCODING_CODERANGE_SET(str3
, rb_enc_to_index(enc
),
945 ENC_CODERANGE_AND(ENC_CODERANGE(str1
), ENC_CODERANGE(str2
)));
951 * str * integer => new_str
953 * Copy---Returns a new <code>String</code> containing <i>integer</i> copies of
956 * "Ho! " * 3 #=> "Ho! Ho! Ho! "
960 rb_str_times(VALUE str
, VALUE times
)
965 len
= NUM2LONG(times
);
967 rb_raise(rb_eArgError
, "negative argument");
969 if (len
&& LONG_MAX
/len
< RSTRING_LEN(str
)) {
970 rb_raise(rb_eArgError
, "argument too big");
973 str2
= rb_str_new5(str
, 0, len
*= RSTRING_LEN(str
));
975 n
= RSTRING_LEN(str
);
976 memcpy(RSTRING_PTR(str2
), RSTRING_PTR(str
), n
);
978 memcpy(RSTRING_PTR(str2
) + n
, RSTRING_PTR(str2
), n
);
981 memcpy(RSTRING_PTR(str2
) + n
, RSTRING_PTR(str2
), len
-n
);
983 RSTRING_PTR(str2
)[RSTRING_LEN(str2
)] = '\0';
984 OBJ_INFECT(str2
, str
);
985 rb_enc_cr_str_copy_for_substr(str2
, str
);
992 * str % arg => new_str
994 * Format---Uses <i>str</i> as a format specification, and returns the result
995 * of applying it to <i>arg</i>. If the format specification contains more than
996 * one substitution, then <i>arg</i> must be an <code>Array</code> containing
997 * the values to be substituted. See <code>Kernel::sprintf</code> for details
998 * of the format string.
1000 * "%05d" % 123 #=> "00123"
1001 * "%-5s: %08x" % [ "ID", self.object_id ] #=> "ID : 200e14d6"
1005 rb_str_format_m(VALUE str
, VALUE arg
)
1007 volatile VALUE tmp
= rb_check_array_type(arg
);
1010 return rb_str_format(RARRAY_LEN(tmp
), RARRAY_PTR(tmp
), str
);
1012 return rb_str_format(1, &arg
, str
);
1016 str_modifiable(VALUE str
)
1018 if (FL_TEST(str
, STR_TMPLOCK
)) {
1019 rb_raise(rb_eRuntimeError
, "can't modify string; temporarily locked");
1021 if (OBJ_FROZEN(str
)) rb_error_frozen("string");
1022 if (!OBJ_UNTRUSTED(str
) && rb_safe_level() >= 4)
1023 rb_raise(rb_eSecurityError
, "Insecure: can't modify string");
1027 str_independent(VALUE str
)
1029 str_modifiable(str
);
1030 if (!STR_SHARED_P(str
)) return 1;
1031 if (STR_EMBED_P(str
)) return 1;
1036 str_make_independent(VALUE str
)
1039 long len
= RSTRING_LEN(str
);
1041 ptr
= ALLOC_N(char, len
+1);
1042 if (RSTRING_PTR(str
)) {
1043 memcpy(ptr
, RSTRING_PTR(str
), len
);
1045 STR_SET_NOEMBED(str
);
1047 RSTRING(str
)->as
.heap
.ptr
= ptr
;
1048 RSTRING(str
)->as
.heap
.len
= len
;
1049 RSTRING(str
)->as
.heap
.aux
.capa
= len
;
1050 STR_UNSET_NOCAPA(str
);
1054 rb_str_modify(VALUE str
)
1056 if (!str_independent(str
))
1057 str_make_independent(str
);
1058 ENC_CODERANGE_CLEAR(str
);
1062 rb_str_associate(VALUE str
, VALUE add
)
1065 if (OBJ_FROZEN(str
)) rb_error_frozen("string");
1066 if (STR_ASSOC_P(str
)) {
1067 /* already associated */
1068 rb_ary_concat(RSTRING(str
)->as
.heap
.aux
.shared
, add
);
1071 if (STR_SHARED_P(str
)) {
1072 VALUE assoc
= RSTRING(str
)->as
.heap
.aux
.shared
;
1073 str_make_independent(str
);
1074 if (STR_ASSOC_P(assoc
)) {
1075 assoc
= RSTRING(assoc
)->as
.heap
.aux
.shared
;
1076 rb_ary_concat(assoc
, add
);
1080 else if (STR_EMBED_P(str
)) {
1081 str_make_independent(str
);
1083 else if (RSTRING(str
)->as
.heap
.aux
.capa
!= RSTRING_LEN(str
)) {
1084 RESIZE_CAPA(str
, RSTRING_LEN(str
));
1086 FL_SET(str
, STR_ASSOC
);
1087 RBASIC(add
)->klass
= 0;
1088 RSTRING(str
)->as
.heap
.aux
.shared
= add
;
1093 rb_str_associated(VALUE str
)
1095 if (STR_SHARED_P(str
)) str
= RSTRING(str
)->as
.heap
.aux
.shared
;
1096 if (STR_ASSOC_P(str
)) {
1097 return RSTRING(str
)->as
.heap
.aux
.shared
;
1103 rb_string_value(volatile VALUE
*ptr
)
1106 if (TYPE(s
) != T_STRING
) {
1107 s
= rb_str_to_str(s
);
1114 rb_string_value_ptr(volatile VALUE
*ptr
)
1116 return RSTRING_PTR(rb_string_value(ptr
));
1120 rb_string_value_cstr(volatile VALUE
*ptr
)
1122 VALUE str
= rb_string_value(ptr
);
1123 char *s
= RSTRING_PTR(str
);
1125 if (!s
|| RSTRING_LEN(str
) != strlen(s
)) {
1126 rb_raise(rb_eArgError
, "string contains null byte");
1132 rb_check_string_type(VALUE str
)
1134 str
= rb_check_convert_type(str
, T_STRING
, "String", "to_str");
1140 * String.try_convert(obj) -> string or nil
1142 * Try to convert <i>obj</i> into a String, using to_str method.
1143 * Returns converted regexp or nil if <i>obj</i> cannot be converted
1146 * String.try_convert("str") # => str
1147 * String.try_convert(/re/) # => nil
1150 rb_str_s_try_convert(VALUE dummy
, VALUE str
)
1152 return rb_check_string_type(str
);
1156 rb_enc_nth(const char *p
, const char *e
, int nth
, rb_encoding
*enc
)
1158 if (rb_enc_mbmaxlen(enc
) == 1) {
1161 else if (rb_enc_mbmaxlen(enc
) == rb_enc_mbminlen(enc
)) {
1162 p
+= nth
* rb_enc_mbmaxlen(enc
);
1164 else if (rb_enc_asciicompat(enc
)) {
1165 const char *p2
, *e2
;
1168 while (p
< e
&& 0 < nth
) {
1173 p2
= search_nonascii(p
, e2
);
1179 n
= rb_enc_mbclen(p
, e
, enc
);
1188 while (p
<e
&& nth
--) {
1189 p
+= rb_enc_mbclen(p
, e
, enc
);
1197 str_nth(const char *p
, const char *e
, int nth
, rb_encoding
*enc
, int singlebyte
)
1202 p
= rb_enc_nth(p
, e
, nth
, enc
);
1209 /* char offset to byte offset */
1211 str_offset(const char *p
, const char *e
, int nth
, rb_encoding
*enc
, int singlebyte
)
1213 const char *pp
= str_nth(p
, e
, nth
, enc
, singlebyte
);
1214 if (!pp
) return e
- p
;
1218 #ifdef NONASCII_MASK
1220 str_utf8_nth(const char *p
, const char *e
, int nth
)
1222 if (sizeof(VALUE
) * 2 < nth
) {
1224 const VALUE lowbits
= sizeof(VALUE
) - 1;
1225 s
= (const VALUE
*)(~lowbits
& ((VALUE
)p
+ lowbits
));
1226 t
= (const VALUE
*)(~lowbits
& (VALUE
)e
);
1227 while (p
< (const char *)s
) {
1228 if (is_utf8_lead_byte(*p
)) nth
--;
1232 nth
-= count_utf8_lead_bytes_with_word(s
);
1234 } while (s
< t
&& sizeof(VALUE
) <= nth
);
1238 if (is_utf8_lead_byte(*p
)) {
1239 if (nth
== 0) break;
1248 str_utf8_offset(const char *p
, const char *e
, int nth
)
1250 const char *pp
= str_utf8_nth(p
, e
, nth
);
1251 if (!pp
) return e
- p
;
1256 /* byte offset to char offset */
1258 rb_str_sublen(VALUE str
, long pos
)
1260 if (single_byte_optimizable(str
) || pos
< 0)
1263 char *p
= RSTRING_PTR(str
);
1264 return rb_enc_strlen(p
, p
+ pos
, STR_ENC_GET(str
));
1269 rb_str_subseq(VALUE str
, long beg
, long len
)
1271 VALUE str2
= rb_str_new5(str
, RSTRING_PTR(str
)+beg
, len
);
1273 rb_enc_cr_str_copy_for_substr(str2
, str
);
1274 OBJ_INFECT(str2
, str
);
1280 rb_str_substr(VALUE str
, long beg
, long len
)
1282 rb_encoding
*enc
= STR_ENC_GET(str
);
1284 char *p
, *s
= RSTRING_PTR(str
), *e
= s
+ RSTRING_LEN(str
);
1287 if (len
< 0) return Qnil
;
1288 if (!RSTRING_LEN(str
)) {
1292 if (len
> -beg
) len
= -beg
;
1293 if (-beg
* rb_enc_mbmaxlen(enc
) < RSTRING_LEN(str
) / 8) {
1295 while (beg
-- > len
&& (e
= rb_enc_prev_char(s
, e
, enc
)) != 0);
1297 if (!p
) return Qnil
;
1298 while (len
-- > 0 && (p
= rb_enc_prev_char(s
, p
, enc
)) != 0);
1299 if (!p
) return Qnil
;
1304 beg
+= str_strlen(str
, enc
);
1305 if (beg
< 0) return Qnil
;
1308 else if (beg
> 0 && beg
> str_strlen(str
, enc
)) {
1311 singlebyte
= single_byte_optimizable(str
);
1315 #ifdef NONASCII_MASK
1316 else if (ENC_CODERANGE(str
) == ENC_CODERANGE_VALID
&&
1317 enc
== rb_utf8_encoding()) {
1318 p
= str_utf8_nth(s
, e
, beg
);
1319 len
= str_utf8_offset(p
, e
, len
);
1322 else if ((p
= str_nth(s
, e
, beg
, enc
, singlebyte
)) == e
) {
1325 else if (rb_enc_mbmaxlen(enc
) == rb_enc_mbminlen(enc
)) {
1326 if (len
* rb_enc_mbmaxlen(enc
) > e
- p
)
1329 len
*= rb_enc_mbmaxlen(enc
);
1332 len
= str_offset(p
, e
, len
, enc
, singlebyte
);
1335 if (len
> RSTRING_EMBED_LEN_MAX
&& beg
+ len
== RSTRING_LEN(str
)) {
1336 str2
= rb_str_new4(str
);
1337 str2
= str_new3(rb_obj_class(str2
), str2
);
1338 RSTRING(str2
)->as
.heap
.ptr
+= RSTRING(str2
)->as
.heap
.len
- len
;
1339 RSTRING(str2
)->as
.heap
.len
= len
;
1342 str2
= rb_str_new5(str
, p
, len
);
1343 rb_enc_cr_str_copy_for_substr(str2
, str
);
1344 OBJ_INFECT(str2
, str
);
1351 rb_str_freeze(VALUE str
)
1353 if (STR_ASSOC_P(str
)) {
1354 VALUE ary
= RSTRING(str
)->as
.heap
.aux
.shared
;
1357 return rb_obj_freeze(str
);
1360 RUBY_ALIAS_FUNCTION(rb_str_dup_frozen(VALUE str
), rb_str_new_frozen
, (str
))
1361 #define rb_str_dup_frozen rb_str_new_frozen
1364 rb_str_locktmp(VALUE str
)
1366 if (FL_TEST(str
, STR_TMPLOCK
)) {
1367 rb_raise(rb_eRuntimeError
, "temporal locking already locked string");
1369 FL_SET(str
, STR_TMPLOCK
);
1374 rb_str_unlocktmp(VALUE str
)
1376 if (!FL_TEST(str
, STR_TMPLOCK
)) {
1377 rb_raise(rb_eRuntimeError
, "temporal unlocking already unlocked string");
1379 FL_UNSET(str
, STR_TMPLOCK
);
1384 rb_str_set_len(VALUE str
, long len
)
1386 STR_SET_LEN(str
, len
);
1387 RSTRING_PTR(str
)[len
] = '\0';
1391 rb_str_resize(VALUE str
, long len
)
1396 rb_raise(rb_eArgError
, "negative string size (or size too big)");
1400 slen
= RSTRING_LEN(str
);
1402 if (STR_EMBED_P(str
)) {
1404 if (len
<= RSTRING_EMBED_LEN_MAX
) {
1405 STR_SET_EMBED_LEN(str
, len
);
1406 RSTRING(str
)->as
.ary
[len
] = '\0';
1409 ptr
= ALLOC_N(char,len
+1);
1410 MEMCPY(ptr
, RSTRING(str
)->as
.ary
, char, slen
);
1411 RSTRING(str
)->as
.heap
.ptr
= ptr
;
1412 STR_SET_NOEMBED(str
);
1414 else if (len
<= RSTRING_EMBED_LEN_MAX
) {
1415 char *ptr
= RSTRING(str
)->as
.heap
.ptr
;
1417 if (slen
> 0) MEMCPY(RSTRING(str
)->as
.ary
, ptr
, char, len
);
1418 RSTRING(str
)->as
.ary
[len
] = '\0';
1419 STR_SET_EMBED_LEN(str
, len
);
1423 else if (slen
< len
|| slen
- len
> 1024) {
1424 REALLOC_N(RSTRING(str
)->as
.heap
.ptr
, char, len
+1);
1426 if (!STR_NOCAPA_P(str
)) {
1427 RSTRING(str
)->as
.heap
.aux
.capa
= len
;
1429 RSTRING(str
)->as
.heap
.len
= len
;
1430 RSTRING(str
)->as
.heap
.ptr
[len
] = '\0'; /* sentinel */
1436 str_buf_cat(VALUE str
, const char *ptr
, long len
)
1438 long capa
, total
, off
= -1;
1440 if (ptr
>= RSTRING_PTR(str
) && ptr
<= RSTRING_END(str
)) {
1441 off
= ptr
- RSTRING_PTR(str
);
1444 if (len
== 0) return 0;
1445 if (STR_ASSOC_P(str
)) {
1446 FL_UNSET(str
, STR_ASSOC
);
1447 capa
= RSTRING(str
)->as
.heap
.aux
.capa
= RSTRING_LEN(str
);
1449 else if (STR_EMBED_P(str
)) {
1450 capa
= RSTRING_EMBED_LEN_MAX
;
1453 capa
= RSTRING(str
)->as
.heap
.aux
.capa
;
1455 if (RSTRING_LEN(str
) >= LONG_MAX
- len
) {
1456 rb_raise(rb_eArgError
, "string sizes too big");
1458 total
= RSTRING_LEN(str
)+len
;
1459 if (capa
<= total
) {
1460 while (total
> capa
) {
1461 if (capa
+ 1 >= LONG_MAX
/ 2) {
1462 capa
= (total
+ 4095) / 4096;
1465 capa
= (capa
+ 1) * 2;
1467 RESIZE_CAPA(str
, capa
);
1470 ptr
= RSTRING_PTR(str
) + off
;
1472 memcpy(RSTRING_PTR(str
) + RSTRING_LEN(str
), ptr
, len
);
1473 STR_SET_LEN(str
, total
);
1474 RSTRING_PTR(str
)[total
] = '\0'; /* sentinel */
1480 rb_str_buf_cat(VALUE str
, const char *ptr
, long len
)
1482 if (len
== 0) return str
;
1484 rb_raise(rb_eArgError
, "negative string size (or size too big)");
1486 return str_buf_cat(str
, ptr
, len
);
1490 rb_str_buf_cat2(VALUE str
, const char *ptr
)
1492 return rb_str_buf_cat(str
, ptr
, strlen(ptr
));
1496 rb_str_cat(VALUE str
, const char *ptr
, long len
)
1499 rb_raise(rb_eArgError
, "negative string size (or size too big)");
1501 if (STR_ASSOC_P(str
)) {
1503 if (STR_EMBED_P(str
)) str_make_independent(str
);
1504 REALLOC_N(RSTRING(str
)->as
.heap
.ptr
, char, RSTRING(str
)->as
.heap
.len
+len
+1);
1505 memcpy(RSTRING(str
)->as
.heap
.ptr
+ RSTRING(str
)->as
.heap
.len
, ptr
, len
);
1506 RSTRING(str
)->as
.heap
.len
+= len
;
1507 RSTRING(str
)->as
.heap
.ptr
[RSTRING(str
)->as
.heap
.len
] = '\0'; /* sentinel */
1511 return rb_str_buf_cat(str
, ptr
, len
);
1515 rb_str_cat2(VALUE str
, const char *ptr
)
1517 return rb_str_cat(str
, ptr
, strlen(ptr
));
1521 rb_enc_cr_str_buf_cat(VALUE str
, const char *ptr
, long len
,
1522 int ptr_encindex
, int ptr_cr
, int *ptr_cr_ret
)
1524 int str_encindex
= ENCODING_GET(str
);
1527 int str_a8
= ENCODING_IS_ASCII8BIT(str
);
1528 int ptr_a8
= ptr_encindex
== 0;
1530 str_cr
= ENC_CODERANGE(str
);
1532 if (str_encindex
== ptr_encindex
) {
1533 if (str_cr
== ENC_CODERANGE_UNKNOWN
||
1534 (ptr_a8
&& str_cr
!= ENC_CODERANGE_7BIT
)) {
1535 ptr_cr
= ENC_CODERANGE_UNKNOWN
;
1537 else if (ptr_cr
== ENC_CODERANGE_UNKNOWN
) {
1538 ptr_cr
= coderange_scan(ptr
, len
, rb_enc_from_index(ptr_encindex
));
1542 rb_encoding
*str_enc
= rb_enc_from_index(str_encindex
);
1543 rb_encoding
*ptr_enc
= rb_enc_from_index(ptr_encindex
);
1544 if (!rb_enc_asciicompat(str_enc
) || !rb_enc_asciicompat(ptr_enc
)) {
1547 if (RSTRING_LEN(str
) == 0) {
1548 rb_str_buf_cat(str
, ptr
, len
);
1549 ENCODING_CODERANGE_SET(str
, ptr_encindex
, ptr_cr
);
1554 if (ptr_cr
== ENC_CODERANGE_UNKNOWN
) {
1555 ptr_cr
= coderange_scan(ptr
, len
, ptr_enc
);
1557 if (str_cr
== ENC_CODERANGE_UNKNOWN
) {
1558 if (str_a8
|| ptr_cr
!= ENC_CODERANGE_7BIT
) {
1559 str_cr
= rb_enc_str_coderange(str
);
1564 *ptr_cr_ret
= ptr_cr
;
1566 if (str_encindex
!= ptr_encindex
&&
1567 str_cr
!= ENC_CODERANGE_7BIT
&&
1568 ptr_cr
!= ENC_CODERANGE_7BIT
) {
1570 rb_raise(rb_eEncCompatError
, "incompatible character encodings: %s and %s",
1571 rb_enc_name(rb_enc_from_index(str_encindex
)),
1572 rb_enc_name(rb_enc_from_index(ptr_encindex
)));
1575 if (str_cr
== ENC_CODERANGE_UNKNOWN
) {
1576 res_encindex
= str_encindex
;
1577 res_cr
= ENC_CODERANGE_UNKNOWN
;
1579 else if (str_cr
== ENC_CODERANGE_7BIT
) {
1580 if (ptr_cr
== ENC_CODERANGE_7BIT
) {
1581 res_encindex
= !str_a8
? str_encindex
: ptr_encindex
;
1582 res_cr
= ENC_CODERANGE_7BIT
;
1585 res_encindex
= ptr_encindex
;
1589 else if (str_cr
== ENC_CODERANGE_VALID
) {
1590 res_encindex
= str_encindex
;
1593 else { /* str_cr == ENC_CODERANGE_BROKEN */
1594 res_encindex
= str_encindex
;
1596 if (0 < len
) res_cr
= ENC_CODERANGE_UNKNOWN
;
1600 rb_raise(rb_eArgError
, "negative string size (or size too big)");
1602 str_buf_cat(str
, ptr
, len
);
1603 ENCODING_CODERANGE_SET(str
, res_encindex
, res_cr
);
1608 rb_enc_str_buf_cat(VALUE str
, const char *ptr
, long len
, rb_encoding
*ptr_enc
)
1610 return rb_enc_cr_str_buf_cat(str
, ptr
, len
,
1611 rb_enc_to_index(ptr_enc
), ENC_CODERANGE_UNKNOWN
, NULL
);
1615 rb_str_buf_cat_ascii(VALUE str
, const char *ptr
)
1617 /* ptr must reference NUL terminated ASCII string. */
1618 int encindex
= ENCODING_GET(str
);
1619 rb_encoding
*enc
= rb_enc_from_index(encindex
);
1620 if (rb_enc_asciicompat(enc
)) {
1621 return rb_enc_cr_str_buf_cat(str
, ptr
, strlen(ptr
),
1622 encindex
, ENC_CODERANGE_7BIT
, 0);
1625 char *buf
= ALLOCA_N(char, rb_enc_mbmaxlen(enc
));
1627 int c
= (unsigned char)*ptr
;
1628 int len
= rb_enc_codelen(c
, enc
);
1629 rb_enc_mbcput(c
, buf
, enc
);
1630 rb_enc_cr_str_buf_cat(str
, buf
, len
,
1631 encindex
, ENC_CODERANGE_VALID
, 0);
1639 rb_str_buf_append(VALUE str
, VALUE str2
)
1643 str2_cr
= ENC_CODERANGE(str2
);
1645 rb_enc_cr_str_buf_cat(str
, RSTRING_PTR(str2
), RSTRING_LEN(str2
),
1646 ENCODING_GET(str2
), str2_cr
, &str2_cr
);
1648 OBJ_INFECT(str
, str2
);
1649 ENC_CODERANGE_SET(str2
, str2_cr
);
1655 rb_str_append(VALUE str
, VALUE str2
)
1661 if (RSTRING_LEN(str2
) > 0 && STR_ASSOC_P(str
)) {
1662 long len
= RSTRING_LEN(str
)+RSTRING_LEN(str2
);
1663 enc
= rb_enc_check(str
, str2
);
1664 cr
= ENC_CODERANGE(str
);
1665 if ((cr2
= ENC_CODERANGE(str2
)) > cr
) cr
= cr2
;
1667 REALLOC_N(RSTRING(str
)->as
.heap
.ptr
, char, len
+1);
1668 memcpy(RSTRING(str
)->as
.heap
.ptr
+ RSTRING(str
)->as
.heap
.len
,
1669 RSTRING_PTR(str2
), RSTRING_LEN(str2
)+1);
1670 RSTRING(str
)->as
.heap
.len
= len
;
1671 rb_enc_associate(str
, enc
);
1672 ENC_CODERANGE_SET(str
, cr
);
1673 OBJ_INFECT(str
, str2
);
1676 return rb_str_buf_append(str
, str2
);
1682 * str << fixnum => str
1683 * str.concat(fixnum) => str
1685 * str.concat(obj) => str
1687 * Append---Concatenates the given object to <i>str</i>. If the object is a
1688 * <code>Fixnum</code>, it is considered as a codepoint, and is converted
1689 * to a character before concatenation.
1692 * a << "world" #=> "hello world"
1693 * a.concat(33) #=> "hello world!"
1697 rb_str_concat(VALUE str1
, VALUE str2
)
1699 if (FIXNUM_P(str2
)) {
1700 rb_encoding
*enc
= STR_ENC_GET(str1
);
1701 int c
= FIX2INT(str2
);
1702 int pos
= RSTRING_LEN(str1
);
1703 int len
= rb_enc_codelen(c
, enc
);
1704 int cr
= ENC_CODERANGE(str1
);
1706 rb_str_resize(str1
, pos
+len
);
1707 rb_enc_mbcput(c
, RSTRING_PTR(str1
)+pos
, enc
);
1708 ENC_CODERANGE_SET(str1
, cr
);
1711 return rb_str_append(str1
, str2
);
1714 #if defined __i386__ || defined _M_IX86
1715 #define UNALIGNED_WORD_ACCESS 1
1717 #ifndef UNALIGNED_WORD_ACCESS
1718 #define UNALIGNED_WORD_ACCESS 0
1721 /* MurmurHash described in http://murmurhash.googlepages.com/ */
1723 hash(const unsigned char * data
, int len
, unsigned int h
)
1725 const unsigned int m
= 0x7fd652ad;
1731 #if !UNALIGNED_WORD_ACCESS
1732 int align
= (VALUE
)data
& 3;
1734 uint32_t t
= 0, d
= 0;
1738 #ifdef WORDS_BIGENDIAN
1739 case 1: t
|= data
[2];
1740 case 2: t
|= data
[1] << 8;
1741 case 3: t
|= data
[0] << 16;
1743 case 1: t
|= data
[2] << 16;
1744 case 2: t
|= data
[1] << 8;
1745 case 3: t
|= data
[0];
1749 #ifdef WORDS_BIGENDIAN
1750 t
>>= (8 * align
) - 8;
1762 d
= *(uint32_t *)data
;
1763 #ifdef WORDS_BIGENDIAN
1764 t
= (t
<< sr
) | (d
>> sl
);
1766 t
= (t
>> sr
) | (d
<< sl
);
1777 pack
= len
< align
? len
: align
;
1780 #ifdef WORDS_BIGENDIAN
1781 case 3: d
|= data
[2] << 8;
1782 case 2: d
|= data
[1] << 16;
1783 case 1: d
|= data
[0] << 24;
1785 h
+= (t
<< sr
) | (d
>> sl
);
1787 case 3: d
|= data
[2] << 16;
1788 case 2: d
|= data
[1] << 8;
1789 case 1: d
|= data
[0];
1791 h
+= (t
>> sr
) | (d
<< sl
);
1804 h
+= *(uint32_t *)data
;
1815 #ifdef WORDS_BIGENDIAN
1843 rb_memhash(const void *ptr
, long len
)
1845 static int hashseed_init
= 0;
1846 static unsigned int hashseed
;
1848 if (!hashseed_init
) {
1849 hashseed
= rb_genrand_int32();
1853 return hash(ptr
, len
, hashseed
);
1857 rb_str_hash(VALUE str
)
1859 return rb_memhash((const void *)RSTRING_PTR(str
), RSTRING_LEN(str
));
1863 rb_str_hash_cmp(VALUE str1
, VALUE str2
)
1867 if (!rb_str_comparable(str1
, str2
)) return 1;
1868 if (RSTRING_LEN(str1
) == (len
= RSTRING_LEN(str2
)) &&
1869 memcmp(RSTRING_PTR(str1
), RSTRING_PTR(str2
), len
) == 0) {
1877 * str.hash => fixnum
1879 * Return a hash based on the string's length and content.
1883 rb_str_hash_m(VALUE str
)
1885 int hval
= rb_str_hash(str
);
1886 return INT2FIX(hval
);
1889 #define lesser(a,b) (((a)>(b))?(b):(a))
1892 rb_str_comparable(VALUE str1
, VALUE str2
)
1897 if (RSTRING_LEN(str1
) == 0) return Qtrue
;
1898 if (RSTRING_LEN(str2
) == 0) return Qtrue
;
1899 idx1
= ENCODING_GET(str1
);
1900 idx2
= ENCODING_GET(str2
);
1901 if (idx1
== idx2
) return Qtrue
;
1902 rc1
= rb_enc_str_coderange(str1
);
1903 rc2
= rb_enc_str_coderange(str2
);
1904 if (rc1
== ENC_CODERANGE_7BIT
) {
1905 if (rc2
== ENC_CODERANGE_7BIT
) return Qtrue
;
1906 if (rb_enc_asciicompat(rb_enc_from_index(idx2
)))
1909 if (rc2
== ENC_CODERANGE_7BIT
) {
1910 if (rb_enc_asciicompat(rb_enc_from_index(idx1
)))
1917 rb_str_cmp(VALUE str1
, VALUE str2
)
1922 len
= lesser(RSTRING_LEN(str1
), RSTRING_LEN(str2
));
1923 retval
= memcmp(RSTRING_PTR(str1
), RSTRING_PTR(str2
), len
);
1925 if (RSTRING_LEN(str1
) == RSTRING_LEN(str2
)) {
1926 if (!rb_enc_compatible(str1
, str2
)) {
1927 if (ENCODING_GET(str1
) - ENCODING_GET(str2
) > 0)
1933 if (RSTRING_LEN(str1
) > RSTRING_LEN(str2
)) return 1;
1936 if (retval
> 0) return 1;
1943 * str == obj => true or false
1945 * Equality---If <i>obj</i> is not a <code>String</code>, returns
1946 * <code>false</code>. Otherwise, returns <code>true</code> if <i>str</i>
1947 * <code><=></code> <i>obj</i> returns zero.
1951 rb_str_equal(VALUE str1
, VALUE str2
)
1955 if (str1
== str2
) return Qtrue
;
1956 if (TYPE(str2
) != T_STRING
) {
1957 if (!rb_respond_to(str2
, rb_intern("to_str"))) {
1960 return rb_equal(str2
, str1
);
1962 if (!rb_str_comparable(str1
, str2
)) return Qfalse
;
1963 if (RSTRING_LEN(str1
) == (len
= RSTRING_LEN(str2
)) &&
1964 memcmp(RSTRING_PTR(str1
), RSTRING_PTR(str2
), len
) == 0) {
1972 * str.eql?(other) => true or false
1974 * Two strings are equal if the have the same length and content.
1978 rb_str_eql(VALUE str1
, VALUE str2
)
1980 if (TYPE(str2
) != T_STRING
|| RSTRING_LEN(str1
) != RSTRING_LEN(str2
))
1983 if (!rb_str_comparable(str1
, str2
)) return Qfalse
;
1984 if (memcmp(RSTRING_PTR(str1
), RSTRING_PTR(str2
),
1985 lesser(RSTRING_LEN(str1
), RSTRING_LEN(str2
))) == 0)
1993 * str <=> other_str => -1, 0, +1
1995 * Comparison---Returns -1 if <i>other_str</i> is less than, 0 if
1996 * <i>other_str</i> is equal to, and +1 if <i>other_str</i> is greater than
1997 * <i>str</i>. If the strings are of different lengths, and the strings are
1998 * equal when compared up to the shortest length, then the longer string is
1999 * considered greater than the shorter one. In older versions of Ruby, setting
2000 * <code>$=</code> allowed case-insensitive comparisons; this is now deprecated
2001 * in favor of using <code>String#casecmp</code>.
2003 * <code><=></code> is the basis for the methods <code><</code>,
2004 * <code><=</code>, <code>></code>, <code>>=</code>, and <code>between?</code>,
2005 * included from module <code>Comparable</code>. The method
2006 * <code>String#==</code> does not use <code>Comparable#==</code>.
2008 * "abcdef" <=> "abcde" #=> 1
2009 * "abcdef" <=> "abcdef" #=> 0
2010 * "abcdef" <=> "abcdefg" #=> -1
2011 * "abcdef" <=> "ABCDEF" #=> 1
2015 rb_str_cmp_m(VALUE str1
, VALUE str2
)
2019 if (TYPE(str2
) != T_STRING
) {
2020 if (!rb_respond_to(str2
, rb_intern("to_str"))) {
2023 else if (!rb_respond_to(str2
, rb_intern("<=>"))) {
2027 VALUE tmp
= rb_funcall(str2
, rb_intern("<=>"), 1, str1
);
2029 if (NIL_P(tmp
)) return Qnil
;
2030 if (!FIXNUM_P(tmp
)) {
2031 return rb_funcall(LONG2FIX(0), '-', 1, tmp
);
2033 result
= -FIX2LONG(tmp
);
2037 result
= rb_str_cmp(str1
, str2
);
2039 return LONG2NUM(result
);
2044 * str.casecmp(other_str) => -1, 0, +1
2046 * Case-insensitive version of <code>String#<=></code>.
2048 * "abcdef".casecmp("abcde") #=> 1
2049 * "aBcDeF".casecmp("abcdef") #=> 0
2050 * "abcdef".casecmp("abcdefg") #=> -1
2051 * "abcdef".casecmp("ABCDEF") #=> 0
2055 rb_str_casecmp(VALUE str1
, VALUE str2
)
2059 char *p1
, *p1end
, *p2
, *p2end
;
2062 enc
= rb_enc_compatible(str1
, str2
);
2067 p1
= RSTRING_PTR(str1
); p1end
= RSTRING_END(str1
);
2068 p2
= RSTRING_PTR(str2
); p2end
= RSTRING_END(str2
);
2069 while (p1
< p1end
&& p2
< p2end
) {
2070 int c1
= rb_enc_codepoint(p1
, p1end
, enc
);
2071 int c2
= rb_enc_codepoint(p2
, p2end
, enc
);
2074 c1
= rb_enc_toupper(c1
, enc
);
2075 c2
= rb_enc_toupper(c2
, enc
);
2076 if (c1
> c2
) return INT2FIX(1);
2077 if (c1
< c2
) return INT2FIX(-1);
2079 len
= rb_enc_codelen(c1
, enc
);
2083 if (RSTRING_LEN(str1
) == RSTRING_LEN(str2
)) return INT2FIX(0);
2084 if (RSTRING_LEN(str1
) > RSTRING_LEN(str2
)) return INT2FIX(1);
2089 rb_str_index(VALUE str
, VALUE sub
, long offset
)
2096 enc
= rb_enc_check(str
, sub
);
2097 if (is_broken_string(sub
)) {
2100 len
= str_strlen(str
, enc
);
2101 slen
= str_strlen(sub
, enc
);
2104 if (offset
< 0) return -1;
2106 if (len
- offset
< slen
) return -1;
2107 s
= RSTRING_PTR(str
);
2109 offset
= str_offset(s
, RSTRING_END(str
), offset
, enc
, single_byte_optimizable(str
));
2112 if (slen
== 0) return offset
;
2113 /* need proceed one character at a time */
2114 sptr
= RSTRING_PTR(sub
);
2115 slen
= RSTRING_LEN(sub
);
2116 len
= RSTRING_LEN(str
) - offset
;
2119 pos
= rb_memsearch(sptr
, slen
, s
, len
, enc
);
2120 if (pos
< 0) return pos
;
2121 t
= rb_enc_right_char_head(s
, s
+pos
, enc
);
2122 if (t
== s
+ pos
) break;
2123 if ((len
-= t
- s
) <= 0) return -1;
2127 return pos
+ offset
;
2133 * str.index(substring [, offset]) => fixnum or nil
2134 * str.index(regexp [, offset]) => fixnum or nil
2136 * Returns the index of the first occurrence of the given <i>substring</i> or
2137 * pattern (<i>regexp</i>) in <i>str</i>. Returns <code>nil</code> if not
2138 * found. If the second parameter is present, it specifies the position in the
2139 * string to begin the search.
2141 * "hello".index('e') #=> 1
2142 * "hello".index('lo') #=> 3
2143 * "hello".index('a') #=> nil
2144 * "hello".index(?e) #=> 1
2145 * "hello".index(/[aeiou]/, -3) #=> 4
2149 rb_str_index_m(int argc
, VALUE
*argv
, VALUE str
)
2155 if (rb_scan_args(argc
, argv
, "11", &sub
, &initpos
) == 2) {
2156 pos
= NUM2LONG(initpos
);
2162 pos
+= str_strlen(str
, STR_ENC_GET(str
));
2164 if (TYPE(sub
) == T_REGEXP
) {
2165 rb_backref_set(Qnil
);
2171 switch (TYPE(sub
)) {
2173 pos
= rb_reg_adjust_startpos(sub
, str
, pos
, 0);
2174 pos
= rb_reg_search(sub
, str
, pos
, 0);
2175 pos
= rb_str_sublen(str
, pos
);
2181 tmp
= rb_check_string_type(sub
);
2183 rb_raise(rb_eTypeError
, "type mismatch: %s given",
2184 rb_obj_classname(sub
));
2190 pos
= rb_str_index(str
, sub
, pos
);
2191 pos
= rb_str_sublen(str
, pos
);
2195 if (pos
== -1) return Qnil
;
2196 return LONG2NUM(pos
);
2200 rb_str_rindex(VALUE str
, VALUE sub
, long pos
)
2203 char *s
, *sbeg
, *e
, *t
;
2205 int singlebyte
= single_byte_optimizable(str
);
2207 enc
= rb_enc_check(str
, sub
);
2208 if (is_broken_string(sub
)) {
2211 len
= str_strlen(str
, enc
);
2212 slen
= str_strlen(sub
, enc
);
2213 /* substring longer than string */
2214 if (len
< slen
) return -1;
2215 if (len
- pos
< slen
) {
2221 sbeg
= RSTRING_PTR(str
);
2222 e
= RSTRING_END(str
);
2223 t
= RSTRING_PTR(sub
);
2224 slen
= RSTRING_LEN(sub
);
2226 s
= str_nth(sbeg
, e
, pos
, enc
, singlebyte
);
2228 if (memcmp(s
, t
, slen
) == 0) {
2231 if (pos
== 0) break;
2240 * str.rindex(substring [, fixnum]) => fixnum or nil
2241 * str.rindex(regexp [, fixnum]) => fixnum or nil
2243 * Returns the index of the last occurrence of the given <i>substring</i> or
2244 * pattern (<i>regexp</i>) in <i>str</i>. Returns <code>nil</code> if not
2245 * found. If the second parameter is present, it specifies the position in the
2246 * string to end the search---characters beyond this point will not be
2249 * "hello".rindex('e') #=> 1
2250 * "hello".rindex('l') #=> 3
2251 * "hello".rindex('a') #=> nil
2252 * "hello".rindex(?e) #=> 1
2253 * "hello".rindex(/[aeiou]/, -2) #=> 1
2257 rb_str_rindex_m(int argc
, VALUE
*argv
, VALUE str
)
2261 rb_encoding
*enc
= STR_ENC_GET(str
);
2262 long pos
, len
= str_strlen(str
, enc
);
2264 if (rb_scan_args(argc
, argv
, "11", &sub
, &vpos
) == 2) {
2265 pos
= NUM2LONG(vpos
);
2269 if (TYPE(sub
) == T_REGEXP
) {
2270 rb_backref_set(Qnil
);
2275 if (pos
> len
) pos
= len
;
2281 switch (TYPE(sub
)) {
2283 /* enc = rb_get_check(str, sub); */
2284 if (!RREGEXP(sub
)->ptr
|| RREGEXP_SRC_LEN(sub
)) {
2285 pos
= rb_reg_adjust_startpos(sub
, str
, pos
, 1);
2286 pos
= rb_reg_search(sub
, str
, pos
, 1);
2287 pos
= rb_str_sublen(str
, pos
);
2289 if (pos
>= 0) return LONG2NUM(pos
);
2295 tmp
= rb_check_string_type(sub
);
2297 rb_raise(rb_eTypeError
, "type mismatch: %s given",
2298 rb_obj_classname(sub
));
2304 pos
= rb_str_rindex(str
, sub
, pos
);
2305 if (pos
>= 0) return LONG2NUM(pos
);
2313 * str =~ obj => fixnum or nil
2315 * Match---If <i>obj</i> is a <code>Regexp</code>, use it as a pattern to match
2316 * against <i>str</i>,and returns the position the match starts, or
2317 * <code>nil</code> if there is no match. Otherwise, invokes
2318 * <i>obj.=~</i>, passing <i>str</i> as an argument. The default
2319 * <code>=~</code> in <code>Object</code> returns <code>false</code>.
2321 * "cat o' 9 tails" =~ /\d/ #=> 7
2322 * "cat o' 9 tails" =~ 9 #=> nil
2326 rb_str_match(VALUE x
, VALUE y
)
2330 rb_raise(rb_eTypeError
, "type mismatch: String given");
2333 return rb_reg_match(y
, x
);
2336 return rb_funcall(y
, rb_intern("=~"), 1, x
);
2341 static VALUE
get_pat(VALUE
, int);
2346 * str.match(pattern) => matchdata or nil
2348 * Converts <i>pattern</i> to a <code>Regexp</code> (if it isn't already one),
2349 * then invokes its <code>match</code> method on <i>str</i>. If the second
2350 * parameter is present, it specifies the position in the string to begin the
2353 * 'hello'.match('(.)\1') #=> #<MatchData "ll" 1:"l">
2354 * 'hello'.match('(.)\1')[0] #=> "ll"
2355 * 'hello'.match(/(.)\1/)[0] #=> "ll"
2356 * 'hello'.match('xx') #=> nil
2358 * If a block is given, invoke the block with MatchData if match succeed, so
2359 * that you can write
2361 * str.match(pat) {|m| ...}
2365 * if m = str.match(pat)
2369 * The return value is a value from block execution in this case.
2373 rb_str_match_m(int argc
, VALUE
*argv
, VALUE str
)
2377 rb_raise(rb_eArgError
, "wrong number of arguments (%d for 1)", argc
);
2380 result
= rb_funcall2(get_pat(re
, 0), rb_intern("match"), argc
, argv
);
2381 if (!NIL_P(result
) && rb_block_given_p()) {
2382 return rb_yield(result
);
2387 enum neighbor_char
{
2393 static enum neighbor_char
2394 enc_succ_char(char *p
, int len
, rb_encoding
*enc
)
2398 for (i
= len
-1; 0 <= i
&& (unsigned char)p
[i
] == 0xff; i
--)
2401 return NEIGHBOR_WRAPPED
;
2402 ++((unsigned char*)p
)[i
];
2403 l
= rb_enc_precise_mbclen(p
, p
+len
, enc
);
2404 if (MBCLEN_CHARFOUND_P(l
)) {
2405 l
= MBCLEN_CHARFOUND_LEN(l
);
2407 return NEIGHBOR_FOUND
;
2410 memset(p
+l
, 0xff, len
-l
);
2413 if (MBCLEN_INVALID_P(l
) && i
< len
-1) {
2415 for (len2
= len
-1; 0 < len2
; len2
--) {
2416 l2
= rb_enc_precise_mbclen(p
, p
+len2
, enc
);
2417 if (!MBCLEN_INVALID_P(l2
))
2420 memset(p
+len2
+1, 0xff, len
-(len2
+1));
2425 static enum neighbor_char
2426 enc_pred_char(char *p
, int len
, rb_encoding
*enc
)
2430 for (i
= len
-1; 0 <= i
&& (unsigned char)p
[i
] == 0; i
--)
2433 return NEIGHBOR_WRAPPED
;
2434 --((unsigned char*)p
)[i
];
2435 l
= rb_enc_precise_mbclen(p
, p
+len
, enc
);
2436 if (MBCLEN_CHARFOUND_P(l
)) {
2437 l
= MBCLEN_CHARFOUND_LEN(l
);
2439 return NEIGHBOR_FOUND
;
2442 memset(p
+l
, 0, len
-l
);
2445 if (MBCLEN_INVALID_P(l
) && i
< len
-1) {
2447 for (len2
= len
-1; 0 < len2
; len2
--) {
2448 l2
= rb_enc_precise_mbclen(p
, p
+len2
, enc
);
2449 if (!MBCLEN_INVALID_P(l2
))
2452 memset(p
+len2
+1, 0, len
-(len2
+1));
2458 overwrite +p+ by succeeding letter in +enc+ and returns
2459 NEIGHBOR_FOUND or NEIGHBOR_WRAPPED.
2460 When NEIGHBOR_WRAPPED, carried-out letter is stored into carry.
2461 assuming each ranges are successive, and mbclen
2462 never change in each ranges.
2463 NEIGHBOR_NOT_CHAR is returned if invalid character or the range has only one
2466 static enum neighbor_char
2467 enc_succ_alnum_char(char *p
, int len
, rb_encoding
*enc
, char *carry
)
2469 enum neighbor_char ret
;
2473 char save
[ONIGENC_CODE_TO_MBC_MAXLEN
];
2475 c
= rb_enc_mbc_to_codepoint(p
, p
+len
, enc
);
2476 if (rb_enc_isctype(c
, ONIGENC_CTYPE_DIGIT
, enc
))
2477 ctype
= ONIGENC_CTYPE_DIGIT
;
2478 else if (rb_enc_isctype(c
, ONIGENC_CTYPE_ALPHA
, enc
))
2479 ctype
= ONIGENC_CTYPE_ALPHA
;
2481 return NEIGHBOR_NOT_CHAR
;
2483 MEMCPY(save
, p
, char, len
);
2484 ret
= enc_succ_char(p
, len
, enc
);
2485 if (ret
== NEIGHBOR_FOUND
) {
2486 c
= rb_enc_mbc_to_codepoint(p
, p
+len
, enc
);
2487 if (rb_enc_isctype(c
, ctype
, enc
))
2488 return NEIGHBOR_FOUND
;
2490 MEMCPY(p
, save
, char, len
);
2493 MEMCPY(save
, p
, char, len
);
2494 ret
= enc_pred_char(p
, len
, enc
);
2495 if (ret
== NEIGHBOR_FOUND
) {
2496 c
= rb_enc_mbc_to_codepoint(p
, p
+len
, enc
);
2497 if (!rb_enc_isctype(c
, ctype
, enc
)) {
2498 MEMCPY(p
, save
, char, len
);
2503 MEMCPY(p
, save
, char, len
);
2509 return NEIGHBOR_NOT_CHAR
;
2512 if (ctype
!= ONIGENC_CTYPE_DIGIT
) {
2513 MEMCPY(carry
, p
, char, len
);
2514 return NEIGHBOR_WRAPPED
;
2517 MEMCPY(carry
, p
, char, len
);
2518 enc_succ_char(carry
, len
, enc
);
2519 return NEIGHBOR_WRAPPED
;
2525 * str.succ => new_str
2526 * str.next => new_str
2528 * Returns the successor to <i>str</i>. The successor is calculated by
2529 * incrementing characters starting from the rightmost alphanumeric (or
2530 * the rightmost character if there are no alphanumerics) in the
2531 * string. Incrementing a digit always results in another digit, and
2532 * incrementing a letter results in another letter of the same case.
2533 * Incrementing nonalphanumerics uses the underlying character set's
2534 * collating sequence.
2536 * If the increment generates a ``carry,'' the character to the left of
2537 * it is incremented. This process repeats until there is no carry,
2538 * adding an additional character if necessary.
2540 * "abcd".succ #=> "abce"
2541 * "THX1138".succ #=> "THX1139"
2542 * "<<koala>>".succ #=> "<<koalb>>"
2543 * "1999zzz".succ #=> "2000aaa"
2544 * "ZZZ9999".succ #=> "AAAA0000"
2545 * "***".succ #=> "**+"
2549 rb_str_succ(VALUE orig
)
2553 char *sbeg
, *s
, *e
, *last_alnum
= 0;
2556 char carry
[ONIGENC_CODE_TO_MBC_MAXLEN
] = "\1";
2557 int carry_pos
= 0, carry_len
= 1;
2558 enum neighbor_char neighbor
= NEIGHBOR_FOUND
;
2560 str
= rb_str_new5(orig
, RSTRING_PTR(orig
), RSTRING_LEN(orig
));
2561 rb_enc_cr_str_copy_for_substr(str
, orig
);
2562 OBJ_INFECT(str
, orig
);
2563 if (RSTRING_LEN(str
) == 0) return str
;
2565 enc
= STR_ENC_GET(orig
);
2566 sbeg
= RSTRING_PTR(str
);
2567 s
= e
= sbeg
+ RSTRING_LEN(str
);
2569 while ((s
= rb_enc_prev_char(sbeg
, s
, enc
)) != 0) {
2570 if (neighbor
== NEIGHBOR_NOT_CHAR
&& last_alnum
) {
2571 if (ISALPHA(*last_alnum
) ? ISDIGIT(*s
) :
2572 ISDIGIT(*last_alnum
) ? ISALPHA(*s
) : 0) {
2577 if ((l
= rb_enc_precise_mbclen(s
, e
, enc
)) <= 0) continue;
2578 neighbor
= enc_succ_alnum_char(s
, l
, enc
, carry
);
2580 case NEIGHBOR_NOT_CHAR
:
2582 case NEIGHBOR_FOUND
:
2584 case NEIGHBOR_WRAPPED
:
2589 carry_pos
= s
- sbeg
;
2592 if (c
== -1) { /* str contains no alnum */
2594 while ((s
= rb_enc_prev_char(sbeg
, s
, enc
)) != 0) {
2595 enum neighbor_char neighbor
;
2596 if ((l
= rb_enc_precise_mbclen(s
, e
, enc
)) <= 0) continue;
2597 neighbor
= enc_succ_char(s
, l
, enc
);
2598 if (neighbor
== NEIGHBOR_FOUND
)
2600 if (rb_enc_precise_mbclen(s
, s
+l
, enc
) != l
) {
2601 /* wrapped to \0...\0. search next valid char. */
2602 enc_succ_char(s
, l
, enc
);
2604 if (!rb_enc_asciicompat(enc
)) {
2605 MEMCPY(carry
, s
, char, l
);
2608 carry_pos
= s
- sbeg
;
2611 RESIZE_CAPA(str
, RSTRING_LEN(str
) + carry_len
);
2612 s
= RSTRING_PTR(str
) + carry_pos
;
2613 memmove(s
+ carry_len
, s
, RSTRING_LEN(str
) - carry_pos
);
2614 memmove(s
, carry
, carry_len
);
2615 STR_SET_LEN(str
, RSTRING_LEN(str
) + carry_len
);
2616 RSTRING_PTR(str
)[RSTRING_LEN(str
)] = '\0';
2617 rb_enc_str_coderange(str
);
2627 * Equivalent to <code>String#succ</code>, but modifies the receiver in
2632 rb_str_succ_bang(VALUE str
)
2634 rb_str_shared_replace(str
, rb_str_succ(str
));
2642 * str.upto(other_str, exclusive=false) {|s| block } => str
2644 * Iterates through successive values, starting at <i>str</i> and
2645 * ending at <i>other_str</i> inclusive, passing each value in turn to
2646 * the block. The <code>String#succ</code> method is used to generate
2647 * each value. If optional second argument exclusive is omitted or is <code>false</code>,
2648 * the last value will be included; otherwise it will be excluded.
2650 * "a8".upto("b6") {|s| print s, ' ' }
2651 * for s in "a8".."b6"
2655 * <em>produces:</em>
2657 * a8 a9 b0 b1 b2 b3 b4 b5 b6
2658 * a8 a9 b0 b1 b2 b3 b4 b5 b6
2662 rb_str_upto(int argc
, VALUE
*argv
, VALUE beg
)
2664 VALUE end
, exclusive
;
2665 VALUE current
, after_end
;
2670 rb_scan_args(argc
, argv
, "11", &end
, &exclusive
);
2671 excl
= RTEST(exclusive
);
2672 CONST_ID(succ
, "succ");
2674 enc
= rb_enc_check(beg
, end
);
2675 if (RSTRING_LEN(beg
) == 1 && RSTRING_LEN(end
) == 1 &&
2676 is_ascii_string(beg
) && is_ascii_string(end
)) {
2677 char c
= RSTRING_PTR(beg
)[0];
2678 char e
= RSTRING_PTR(end
)[0];
2680 if (c
> e
|| (excl
&& c
== e
)) return beg
;
2682 rb_yield(rb_enc_str_new(&c
, 1, enc
));
2683 if (!excl
&& c
== e
) break;
2685 if (excl
&& c
== e
) break;
2689 n
= rb_str_cmp(beg
, end
);
2690 if (n
> 0 || (excl
&& n
== 0)) return beg
;
2692 after_end
= rb_funcall(end
, succ
, 0, 0);
2694 while (!rb_str_equal(current
, after_end
)) {
2696 if (!excl
&& rb_str_equal(current
, end
)) break;
2697 current
= rb_funcall(current
, succ
, 0, 0);
2698 StringValue(current
);
2699 if (excl
&& rb_str_equal(current
, end
)) break;
2700 if (RSTRING_LEN(current
) > RSTRING_LEN(end
) || RSTRING_LEN(current
) == 0)
2708 rb_str_subpat(VALUE str
, VALUE re
, int nth
)
2710 if (rb_reg_search(re
, str
, 0, 0) >= 0) {
2711 return rb_reg_nth_match(nth
, rb_backref_get());
2717 rb_str_aref(VALUE str
, VALUE indx
)
2721 switch (TYPE(indx
)) {
2723 idx
= FIX2LONG(indx
);
2726 str
= rb_str_substr(str
, idx
, 1);
2727 if (!NIL_P(str
) && RSTRING_LEN(str
) == 0) return Qnil
;
2731 return rb_str_subpat(str
, indx
, 0);
2734 if (rb_str_index(str
, indx
, 0) != -1)
2735 return rb_str_dup(indx
);
2739 /* check if indx is Range */
2744 len
= str_strlen(str
, STR_ENC_GET(str
));
2745 switch (rb_range_beg_len(indx
, &beg
, &len
, len
, 0)) {
2751 tmp
= rb_str_substr(str
, beg
, len
);
2755 idx
= NUM2LONG(indx
);
2758 return Qnil
; /* not reached */
2764 * str[fixnum] => new_str or nil
2765 * str[fixnum, fixnum] => new_str or nil
2766 * str[range] => new_str or nil
2767 * str[regexp] => new_str or nil
2768 * str[regexp, fixnum] => new_str or nil
2769 * str[other_str] => new_str or nil
2770 * str.slice(fixnum) => new_str or nil
2771 * str.slice(fixnum, fixnum) => new_str or nil
2772 * str.slice(range) => new_str or nil
2773 * str.slice(regexp) => new_str or nil
2774 * str.slice(regexp, fixnum) => new_str or nil
2775 * str.slice(other_str) => new_str or nil
2777 * Element Reference---If passed a single <code>Fixnum</code>, returns a
2778 * substring of one character at that position. If passed two <code>Fixnum</code>
2779 * objects, returns a substring starting at the offset given by the first, and
2780 * a length given by the second. If given a range, a substring containing
2781 * characters at offsets given by the range is returned. In all three cases, if
2782 * an offset is negative, it is counted from the end of <i>str</i>. Returns
2783 * <code>nil</code> if the initial offset falls outside the string, the length
2784 * is negative, or the beginning of the range is greater than the end.
2786 * If a <code>Regexp</code> is supplied, the matching portion of <i>str</i> is
2787 * returned. If a numeric parameter follows the regular expression, that
2788 * component of the <code>MatchData</code> is returned instead. If a
2789 * <code>String</code> is given, that string is returned if it occurs in
2790 * <i>str</i>. In both cases, <code>nil</code> is returned if there is no
2798 * a[-4..-2] #=> "her"
2801 * a[/[aeiou](.)\1/] #=> "ell"
2802 * a[/[aeiou](.)\1/, 0] #=> "ell"
2803 * a[/[aeiou](.)\1/, 1] #=> "l"
2804 * a[/[aeiou](.)\1/, 2] #=> nil
2810 rb_str_aref_m(int argc
, VALUE
*argv
, VALUE str
)
2813 if (TYPE(argv
[0]) == T_REGEXP
) {
2814 return rb_str_subpat(str
, argv
[0], NUM2INT(argv
[1]));
2816 return rb_str_substr(str
, NUM2LONG(argv
[0]), NUM2LONG(argv
[1]));
2819 rb_raise(rb_eArgError
, "wrong number of arguments (%d for 1)", argc
);
2821 return rb_str_aref(str
, argv
[0]);
2825 rb_str_drop_bytes(VALUE str
, long len
)
2827 char *ptr
= RSTRING_PTR(str
);
2828 long olen
= RSTRING_LEN(str
), nlen
;
2830 str_modifiable(str
);
2831 if (len
> olen
) len
= olen
;
2833 if (nlen
<= RSTRING_EMBED_LEN_MAX
) {
2835 int fl
= (RBASIC(str
)->flags
& (STR_NOEMBED
|ELTS_SHARED
));
2837 STR_SET_EMBED_LEN(str
, nlen
);
2838 ptr
= RSTRING(str
)->as
.ary
;
2839 memcpy(ptr
, oldptr
+ len
, nlen
);
2840 if (fl
== STR_NOEMBED
) xfree(oldptr
);
2843 if (!STR_SHARED_P(str
)) rb_str_new4(str
);
2844 ptr
= RSTRING(str
)->as
.heap
.ptr
+= len
;
2845 RSTRING(str
)->as
.heap
.len
= nlen
;
2848 ENC_CODERANGE_CLEAR(str
);
2853 rb_str_splice_0(VALUE str
, long beg
, long len
, VALUE val
)
2855 if (beg
== 0 && RSTRING_LEN(val
) == 0) {
2856 rb_str_drop_bytes(str
, len
);
2857 OBJ_INFECT(str
, val
);
2862 if (len
< RSTRING_LEN(val
)) {
2864 RESIZE_CAPA(str
, RSTRING_LEN(str
) + RSTRING_LEN(val
) - len
+ 1);
2867 if (RSTRING_LEN(val
) != len
) {
2868 memmove(RSTRING_PTR(str
) + beg
+ RSTRING_LEN(val
),
2869 RSTRING_PTR(str
) + beg
+ len
,
2870 RSTRING_LEN(str
) - (beg
+ len
));
2872 if (RSTRING_LEN(val
) < beg
&& len
< 0) {
2873 MEMZERO(RSTRING_PTR(str
) + RSTRING_LEN(str
), char, -len
);
2875 if (RSTRING_LEN(val
) > 0) {
2876 memmove(RSTRING_PTR(str
)+beg
, RSTRING_PTR(val
), RSTRING_LEN(val
));
2878 STR_SET_LEN(str
, RSTRING_LEN(str
) + RSTRING_LEN(val
) - len
);
2879 if (RSTRING_PTR(str
)) {
2880 RSTRING_PTR(str
)[RSTRING_LEN(str
)] = '\0';
2882 OBJ_INFECT(str
, val
);
2886 rb_str_splice(VALUE str
, long beg
, long len
, VALUE val
)
2891 int singlebyte
= single_byte_optimizable(str
);
2893 if (len
< 0) rb_raise(rb_eIndexError
, "negative length %ld", len
);
2897 enc
= rb_enc_check(str
, val
);
2898 slen
= str_strlen(str
, enc
);
2902 rb_raise(rb_eIndexError
, "index %ld out of string", beg
);
2910 if (slen
< len
|| slen
< beg
+ len
) {
2913 p
= str_nth(RSTRING_PTR(str
), RSTRING_END(str
), beg
, enc
, singlebyte
);
2914 if (!p
) p
= RSTRING_END(str
);
2915 e
= str_nth(p
, RSTRING_END(str
), len
, enc
, singlebyte
);
2916 if (!e
) e
= RSTRING_END(str
);
2918 beg
= p
- RSTRING_PTR(str
); /* physical position */
2919 len
= e
- p
; /* physical length */
2920 rb_str_splice_0(str
, beg
, len
, val
);
2921 rb_enc_associate(str
, enc
);
2925 rb_str_update(VALUE str
, long beg
, long len
, VALUE val
)
2927 rb_str_splice(str
, beg
, len
, val
);
2931 rb_str_subpat_set(VALUE str
, VALUE re
, int nth
, VALUE val
)
2934 long start
, end
, len
;
2936 struct re_registers
*regs
;
2938 if (rb_reg_search(re
, str
, 0, 0) < 0) {
2939 rb_raise(rb_eIndexError
, "regexp not matched");
2941 match
= rb_backref_get();
2942 regs
= RMATCH_REGS(match
);
2943 if (nth
>= regs
->num_regs
) {
2945 rb_raise(rb_eIndexError
, "index %d out of regexp", nth
);
2948 if (-nth
>= regs
->num_regs
) {
2951 nth
+= regs
->num_regs
;
2956 rb_raise(rb_eIndexError
, "regexp group %d not matched", nth
);
2961 enc
= rb_enc_check(str
, val
);
2962 rb_str_splice_0(str
, start
, len
, val
);
2963 rb_enc_associate(str
, enc
);
2967 rb_str_aset(VALUE str
, VALUE indx
, VALUE val
)
2971 switch (TYPE(indx
)) {
2973 idx
= FIX2LONG(indx
);
2975 rb_str_splice(str
, idx
, 1, val
);
2979 rb_str_subpat_set(str
, indx
, 0, val
);
2983 beg
= rb_str_index(str
, indx
, 0);
2985 rb_raise(rb_eIndexError
, "string not matched");
2987 beg
= rb_str_sublen(str
, beg
);
2988 rb_str_splice(str
, beg
, str_strlen(indx
, 0), val
);
2992 /* check if indx is Range */
2995 if (rb_range_beg_len(indx
, &beg
, &len
, str_strlen(str
, 0), 2)) {
2996 rb_str_splice(str
, beg
, len
, val
);
3000 idx
= NUM2LONG(indx
);
3007 * str[fixnum] = new_str
3008 * str[fixnum, fixnum] = new_str
3009 * str[range] = aString
3010 * str[regexp] = new_str
3011 * str[regexp, fixnum] = new_str
3012 * str[other_str] = new_str
3014 * Element Assignment---Replaces some or all of the content of <i>str</i>. The
3015 * portion of the string affected is determined using the same criteria as
3016 * <code>String#[]</code>. If the replacement string is not the same length as
3017 * the text it is replacing, the string will be adjusted accordingly. If the
3018 * regular expression or string is used as the index doesn't match a position
3019 * in the string, <code>IndexError</code> is raised. If the regular expression
3020 * form is used, the optional second <code>Fixnum</code> allows you to specify
3021 * which portion of the match to replace (effectively using the
3022 * <code>MatchData</code> indexing rules. The forms that take a
3023 * <code>Fixnum</code> will raise an <code>IndexError</code> if the value is
3024 * out of range; the <code>Range</code> form will raise a
3025 * <code>RangeError</code>, and the <code>Regexp</code> and <code>String</code>
3026 * forms will silently ignore the assignment.
3030 rb_str_aset_m(int argc
, VALUE
*argv
, VALUE str
)
3033 if (TYPE(argv
[0]) == T_REGEXP
) {
3034 rb_str_subpat_set(str
, argv
[0], NUM2INT(argv
[1]), argv
[2]);
3037 rb_str_splice(str
, NUM2LONG(argv
[0]), NUM2LONG(argv
[1]), argv
[2]);
3042 rb_raise(rb_eArgError
, "wrong number of arguments (%d for 2)", argc
);
3044 return rb_str_aset(str
, argv
[0], argv
[1]);
3049 * str.insert(index, other_str) => str
3051 * Inserts <i>other_str</i> before the character at the given
3052 * <i>index</i>, modifying <i>str</i>. Negative indices count from the
3053 * end of the string, and insert <em>after</em> the given character.
3054 * The intent is insert <i>aString</i> so that it starts at the given
3057 * "abcd".insert(0, 'X') #=> "Xabcd"
3058 * "abcd".insert(3, 'X') #=> "abcXd"
3059 * "abcd".insert(4, 'X') #=> "abcdX"
3060 * "abcd".insert(-3, 'X') #=> "abXcd"
3061 * "abcd".insert(-1, 'X') #=> "abcdX"
3065 rb_str_insert(VALUE str
, VALUE idx
, VALUE str2
)
3067 long pos
= NUM2LONG(idx
);
3070 return rb_str_append(str
, str2
);
3075 rb_str_splice(str
, pos
, 0, str2
);
3082 * str.slice!(fixnum) => fixnum or nil
3083 * str.slice!(fixnum, fixnum) => new_str or nil
3084 * str.slice!(range) => new_str or nil
3085 * str.slice!(regexp) => new_str or nil
3086 * str.slice!(other_str) => new_str or nil
3088 * Deletes the specified portion from <i>str</i>, and returns the portion
3091 * string = "this is a string"
3092 * string.slice!(2) #=> "i"
3093 * string.slice!(3..6) #=> " is "
3094 * string.slice!(/s.*t/) #=> "sa st"
3095 * string.slice!("r") #=> "r"
3096 * string #=> "thing"
3100 rb_str_slice_bang(int argc
, VALUE
*argv
, VALUE str
)
3106 if (argc
< 1 || 2 < argc
) {
3107 rb_raise(rb_eArgError
, "wrong number of arguments (%d for 1)", argc
);
3109 for (i
=0; i
<argc
; i
++) {
3113 buf
[i
] = rb_str_new(0,0);
3114 result
= rb_str_aref_m(argc
, buf
, str
);
3115 if (!NIL_P(result
)) {
3116 rb_str_aset_m(argc
+1, buf
, str
);
3122 get_pat(VALUE pat
, int quote
)
3126 switch (TYPE(pat
)) {
3134 val
= rb_check_string_type(pat
);
3136 Check_Type(pat
, T_REGEXP
);
3142 pat
= rb_reg_quote(pat
);
3145 return rb_reg_regcomp(pat
);
3151 * str.sub!(pattern, replacement) => str or nil
3152 * str.sub!(pattern) {|match| block } => str or nil
3154 * Performs the substitutions of <code>String#sub</code> in place,
3155 * returning <i>str</i>, or <code>nil</code> if no substitutions were
3160 rb_str_sub_bang(int argc
, VALUE
*argv
, VALUE str
)
3162 VALUE pat
, repl
, hash
= Qnil
;
3168 if (argc
== 1 && rb_block_given_p()) {
3171 else if (argc
== 2) {
3173 hash
= rb_check_convert_type(argv
[1], T_HASH
, "Hash", "to_hash");
3177 if (OBJ_TAINTED(repl
)) tainted
= 1;
3178 if (OBJ_UNTRUSTED(repl
)) untrusted
= 1;
3181 rb_raise(rb_eArgError
, "wrong number of arguments (%d for 2)", argc
);
3184 pat
= get_pat(argv
[0], 1);
3185 if (rb_reg_search(pat
, str
, 0, 0) >= 0) {
3187 int cr
= ENC_CODERANGE(str
);
3188 VALUE match
= rb_backref_get();
3189 struct re_registers
*regs
= RMATCH_REGS(match
);
3193 if (iter
|| !NIL_P(hash
)) {
3194 char *p
= RSTRING_PTR(str
); long len
= RSTRING_LEN(str
);
3197 repl
= rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match
)));
3200 repl
= rb_hash_aref(hash
, rb_str_subseq(str
, beg0
, end0
- beg0
));
3201 repl
= rb_obj_as_string(repl
);
3203 str_mod_check(str
, p
, len
);
3204 str_frozen_check(str
);
3207 repl
= rb_reg_regsub(repl
, str
, regs
, pat
);
3209 enc
= rb_enc_compatible(str
, repl
);
3211 rb_encoding
*str_enc
= STR_ENC_GET(str
);
3212 if (coderange_scan(RSTRING_PTR(str
), beg0
, str_enc
) != ENC_CODERANGE_7BIT
||
3213 coderange_scan(RSTRING_PTR(str
)+end0
,
3214 RSTRING_LEN(str
)-end0
, str_enc
) != ENC_CODERANGE_7BIT
) {
3215 rb_raise(rb_eEncCompatError
, "incompatible character encodings: %s and %s",
3216 rb_enc_name(str_enc
),
3217 rb_enc_name(STR_ENC_GET(repl
)));
3219 enc
= STR_ENC_GET(repl
);
3222 rb_enc_associate(str
, enc
);
3223 if (OBJ_TAINTED(repl
)) tainted
= 1;
3224 if (OBJ_UNTRUSTED(repl
)) untrusted
= 1;
3225 if (ENC_CODERANGE_UNKNOWN
< cr
&& cr
< ENC_CODERANGE_BROKEN
) {
3226 int cr2
= ENC_CODERANGE(repl
);
3227 if (cr2
== ENC_CODERANGE_UNKNOWN
|| cr2
> cr
) cr
= cr2
;
3230 if (RSTRING_LEN(repl
) > plen
) {
3231 RESIZE_CAPA(str
, RSTRING_LEN(str
) + RSTRING_LEN(repl
) - plen
);
3233 if (RSTRING_LEN(repl
) != plen
) {
3234 memmove(RSTRING_PTR(str
) + beg0
+ RSTRING_LEN(repl
),
3235 RSTRING_PTR(str
) + beg0
+ plen
,
3236 RSTRING_LEN(str
) - beg0
- plen
);
3238 memcpy(RSTRING_PTR(str
) + beg0
,
3239 RSTRING_PTR(repl
), RSTRING_LEN(repl
));
3240 STR_SET_LEN(str
, RSTRING_LEN(str
) + RSTRING_LEN(repl
) - plen
);
3241 RSTRING_PTR(str
)[RSTRING_LEN(str
)] = '\0';
3242 ENC_CODERANGE_SET(str
, cr
);
3243 if (tainted
) OBJ_TAINT(str
);
3244 if (untrusted
) OBJ_UNTRUST(str
);
3254 * str.sub(pattern, replacement) => new_str
3255 * str.sub(pattern) {|match| block } => new_str
3257 * Returns a copy of <i>str</i> with the <em>first</em> occurrence of
3258 * <i>pattern</i> replaced with either <i>replacement</i> or the value of the
3259 * block. The <i>pattern</i> will typically be a <code>Regexp</code>; if it is
3260 * a <code>String</code> then no regular expression metacharacters will be
3261 * interpreted (that is <code>/\d/</code> will match a digit, but
3262 * <code>'\d'</code> will match a backslash followed by a 'd').
3264 * If the method call specifies <i>replacement</i>, special variables such as
3265 * <code>$&</code> will not be useful, as substitution into the string occurs
3266 * before the pattern match starts. However, the sequences <code>\1</code>,
3267 * <code>\2</code>, <code>\k<group_name></code>, etc., may be used.
3269 * In the block form, the current match string is passed in as a parameter, and
3270 * variables such as <code>$1</code>, <code>$2</code>, <code>$`</code>,
3271 * <code>$&</code>, and <code>$'</code> will be set appropriately. The value
3272 * returned by the block will be substituted for the match on each call.
3274 * The result inherits any tainting in the original string or any supplied
3275 * replacement string.
3277 * "hello".sub(/[aeiou]/, '*') #=> "h*llo"
3278 * "hello".sub(/([aeiou])/, '<\1>') #=> "h<e>llo"
3279 * "hello".sub(/./) {|s| s[0].ord.to_s + ' ' } #=> "104 ello"
3280 * "hello".sub(/(?<foo>[aeiou])/, '*\k<foo>*') #=> "h*e*llo"
3284 rb_str_sub(int argc
, VALUE
*argv
, VALUE str
)
3286 str
= rb_str_dup(str
);
3287 rb_str_sub_bang(argc
, argv
, str
);
3292 str_gsub(int argc
, VALUE
*argv
, VALUE str
, int bang
)
3294 VALUE pat
, val
, repl
, match
, dest
, hash
= Qnil
;
3295 struct re_registers
*regs
;
3298 long offset
, blen
, slen
, len
, last
;
3302 rb_encoding
*str_enc
;
3306 RETURN_ENUMERATOR(str
, argc
, argv
);
3311 hash
= rb_check_convert_type(argv
[1], T_HASH
, "Hash", "to_hash");
3315 if (OBJ_TAINTED(repl
)) tainted
= 1;
3318 rb_raise(rb_eArgError
, "wrong number of arguments (%d for 2)", argc
);
3321 pat
= get_pat(argv
[0], 1);
3322 beg
= rb_reg_search(pat
, str
, 0, 0);
3324 if (bang
) return Qnil
; /* no match, no substitution */
3325 return rb_str_dup(str
);
3330 blen
= RSTRING_LEN(str
) + 30; /* len + margin */
3331 dest
= rb_str_buf_new(blen
);
3332 sp
= RSTRING_PTR(str
);
3333 slen
= RSTRING_LEN(str
);
3335 str_enc
= STR_ENC_GET(str
);
3339 match
= rb_backref_get();
3340 regs
= RMATCH_REGS(match
);
3343 if (iter
|| !NIL_P(hash
)) {
3345 val
= rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match
)));
3348 val
= rb_hash_aref(hash
, rb_str_subseq(str
, BEG(0), END(0) - BEG(0)));
3349 val
= rb_obj_as_string(val
);
3351 str_mod_check(str
, sp
, slen
);
3352 if (bang
) str_frozen_check(str
);
3353 if (val
== dest
) { /* paranoid check [ruby-dev:24827] */
3354 rb_raise(rb_eRuntimeError
, "block should not cheat");
3358 val
= rb_reg_regsub(repl
, str
, regs
, pat
);
3361 if (OBJ_TAINTED(val
)) tainted
= 1;
3363 len
= beg
- offset
; /* copy pre-match substr */
3365 rb_enc_str_buf_cat(dest
, cp
, len
, str_enc
);
3368 rb_str_buf_append(dest
, val
);
3374 * Always consume at least one character of the input string
3375 * in order to prevent infinite loops.
3377 if (RSTRING_LEN(str
) <= end0
) break;
3378 len
= rb_enc_mbclen(RSTRING_PTR(str
)+end0
, RSTRING_END(str
), str_enc
);
3379 rb_enc_str_buf_cat(dest
, RSTRING_PTR(str
)+end0
, len
, str_enc
);
3380 offset
= end0
+ len
;
3382 cp
= RSTRING_PTR(str
) + offset
;
3383 if (offset
> RSTRING_LEN(str
)) break;
3384 beg
= rb_reg_search(pat
, str
, offset
, 0);
3386 if (RSTRING_LEN(str
) > offset
) {
3387 rb_enc_str_buf_cat(dest
, cp
, RSTRING_LEN(str
) - offset
, str_enc
);
3389 rb_reg_search(pat
, str
, last
, 0);
3391 rb_str_shared_replace(str
, dest
);
3394 RBASIC(dest
)->klass
= rb_obj_class(str
);
3395 OBJ_INFECT(dest
, str
);
3399 if (tainted
) OBJ_TAINT(str
);
3406 * str.gsub!(pattern, replacement) => str or nil
3407 * str.gsub!(pattern) {|match| block } => str or nil
3409 * Performs the substitutions of <code>String#gsub</code> in place, returning
3410 * <i>str</i>, or <code>nil</code> if no substitutions were performed.
3414 rb_str_gsub_bang(int argc
, VALUE
*argv
, VALUE str
)
3416 return str_gsub(argc
, argv
, str
, 1);
3422 * str.gsub(pattern, replacement) => new_str
3423 * str.gsub(pattern) {|match| block } => new_str
3425 * Returns a copy of <i>str</i> with <em>all</em> occurrences of <i>pattern</i>
3426 * replaced with either <i>replacement</i> or the value of the block. The
3427 * <i>pattern</i> will typically be a <code>Regexp</code>; if it is a
3428 * <code>String</code> then no regular expression metacharacters will be
3429 * interpreted (that is <code>/\d/</code> will match a digit, but
3430 * <code>'\d'</code> will match a backslash followed by a 'd').
3432 * If a string is used as the replacement, special variables from the match
3433 * (such as <code>$&</code> and <code>$1</code>) cannot be substituted into it,
3434 * as substitution into the string occurs before the pattern match
3435 * starts. However, the sequences <code>\1</code>, <code>\2</code>,
3436 * <code>\k<group_name></code>, and so on may be used to interpolate
3437 * successive groups in the match.
3439 * In the block form, the current match string is passed in as a parameter, and
3440 * variables such as <code>$1</code>, <code>$2</code>, <code>$`</code>,
3441 * <code>$&</code>, and <code>$'</code> will be set appropriately. The value
3442 * returned by the block will be substituted for the match on each call.
3444 * The result inherits any tainting in the original string or any supplied
3445 * replacement string.
3447 * "hello".gsub(/[aeiou]/, '*') #=> "h*ll*"
3448 * "hello".gsub(/([aeiou])/, '<\1>') #=> "h<e>ll<o>"
3449 * "hello".gsub(/./) {|s| s[0].ord.to_s + ' '} #=> "104 101 108 108 111 "
3450 * "hello".gsub(/(?<foo>[aeiou])/, '{\k<foo>}') #=> "h{e}ll{o}"
3454 rb_str_gsub(int argc
, VALUE
*argv
, VALUE str
)
3456 return str_gsub(argc
, argv
, str
, 0);
3462 * str.replace(other_str) => str
3464 * Replaces the contents and taintedness of <i>str</i> with the corresponding
3465 * values in <i>other_str</i>.
3467 * s = "hello" #=> "hello"
3468 * s.replace "world" #=> "world"
3472 rb_str_replace(VALUE str
, VALUE str2
)
3475 if (str
== str2
) return str
;
3478 len
= RSTRING_LEN(str2
);
3479 if (STR_ASSOC_P(str2
)) {
3480 str2
= rb_str_new4(str2
);
3482 if (str_independent(str
) && !STR_EMBED_P(str
)) {
3483 xfree(RSTRING_PTR(str
));
3485 if (STR_SHARED_P(str2
)) {
3486 STR_SET_NOEMBED(str
);
3487 RSTRING(str
)->as
.heap
.len
= len
;
3488 RSTRING(str
)->as
.heap
.ptr
= RSTRING_PTR(str2
);
3489 FL_SET(str
, ELTS_SHARED
);
3490 FL_UNSET(str
, STR_ASSOC
);
3491 RSTRING(str
)->as
.heap
.aux
.shared
= RSTRING(str2
)->as
.heap
.aux
.shared
;
3494 str_replace_shared(str
, rb_str_new4(str2
));
3497 OBJ_INFECT(str
, str2
);
3498 rb_enc_cr_str_exact_copy(str
, str2
);
3504 * string.clear -> string
3506 * Makes string empty.
3513 rb_str_clear(VALUE str
)
3515 /* rb_str_modify() */ /* no need for str_make_independent */
3516 if (str_independent(str
) && !STR_EMBED_P(str
)) {
3517 xfree(RSTRING_PTR(str
));
3520 STR_SET_EMBED_LEN(str
, 0);
3521 RSTRING_PTR(str
)[0] = 0;
3522 ENC_CODERANGE_CLEAR(str
);
3528 * string.chr -> string
3530 * Returns a one-character string at the beginning of the string.
3537 rb_str_chr(VALUE str
)
3539 return rb_str_substr(str
, 0, 1);
3544 * str.getbyte(index) => 0 .. 255
3546 * returns the <i>index</i>th byte as an integer.
3549 rb_str_getbyte(VALUE str
, VALUE index
)
3551 long pos
= NUM2LONG(index
);
3554 pos
+= RSTRING_LEN(str
);
3555 if (pos
< 0 || RSTRING_LEN(str
) <= pos
)
3558 return INT2FIX((unsigned char)RSTRING_PTR(str
)[pos
]);
3563 * str.setbyte(index, int) => int
3565 * modifies the <i>index</i>th byte as <i>int</i>.
3568 rb_str_setbyte(VALUE str
, VALUE index
, VALUE value
)
3570 long pos
= NUM2LONG(index
);
3571 int byte
= NUM2INT(value
);
3575 if (pos
< -RSTRING_LEN(str
) || RSTRING_LEN(str
) <= pos
)
3576 rb_raise(rb_eIndexError
, "index %ld out of string", pos
);
3578 pos
+= RSTRING_LEN(str
);
3580 RSTRING_PTR(str
)[pos
] = byte
;
3587 * str.reverse => new_str
3589 * Returns a new string with the characters from <i>str</i> in reverse order.
3591 * "stressed".reverse #=> "desserts"
3595 rb_str_reverse(VALUE str
)
3602 if (RSTRING_LEN(str
) <= 1) return rb_str_dup(str
);
3603 enc
= STR_ENC_GET(str
);
3604 rev
= rb_str_new5(str
, 0, RSTRING_LEN(str
));
3605 s
= RSTRING_PTR(str
); e
= RSTRING_END(str
);
3606 p
= RSTRING_END(rev
);
3608 if (RSTRING_LEN(str
) > 1) {
3609 if (single_byte_optimizable(str
)) {
3616 int clen
= rb_enc_mbclen(s
, e
, enc
);
3618 if (clen
> 1 || (*s
& 0x80)) single
= 0;
3625 STR_SET_LEN(rev
, RSTRING_LEN(str
));
3626 OBJ_INFECT(rev
, str
);
3627 if (ENC_CODERANGE(str
) == ENC_CODERANGE_UNKNOWN
) {
3629 ENC_CODERANGE_SET(str
, ENC_CODERANGE_7BIT
);
3632 ENC_CODERANGE_SET(str
, ENC_CODERANGE_VALID
);
3635 rb_enc_cr_str_copy_for_substr(rev
, str
);
3643 * str.reverse! => str
3645 * Reverses <i>str</i> in place.
3649 rb_str_reverse_bang(VALUE str
)
3651 if (RSTRING_LEN(str
) > 1) {
3652 if (single_byte_optimizable(str
)) {
3654 int cr
= ENC_CODERANGE(str
);
3658 s
= RSTRING_PTR(str
);
3659 e
= RSTRING_END(str
) - 1;
3662 if (*s
& 0x80) single
= 0;
3666 if (cr
== ENC_CODERANGE_UNKNOWN
&& single
) {
3667 cr
= ENC_CODERANGE_7BIT
;
3669 ENC_CODERANGE_SET(str
, cr
);
3672 rb_str_shared_replace(str
, rb_str_reverse(str
));
3681 * str.include? other_str => true or false
3683 * Returns <code>true</code> if <i>str</i> contains the given string or
3686 * "hello".include? "lo" #=> true
3687 * "hello".include? "ol" #=> false
3688 * "hello".include? ?h #=> true
3692 rb_str_include(VALUE str
, VALUE arg
)
3697 i
= rb_str_index(str
, arg
, 0);
3699 if (i
== -1) return Qfalse
;
3706 * str.to_i(base=10) => integer
3708 * Returns the result of interpreting leading characters in <i>str</i> as an
3709 * integer base <i>base</i> (between 2 and 36). Extraneous characters past the
3710 * end of a valid number are ignored. If there is not a valid number at the
3711 * start of <i>str</i>, <code>0</code> is returned. This method never raises an
3714 * "12345".to_i #=> 12345
3715 * "99 red balloons".to_i #=> 99
3717 * "0a".to_i(16) #=> 10
3718 * "hello".to_i #=> 0
3719 * "1100101".to_i(2) #=> 101
3720 * "1100101".to_i(8) #=> 294977
3721 * "1100101".to_i(10) #=> 1100101
3722 * "1100101".to_i(16) #=> 17826049
3726 rb_str_to_i(int argc
, VALUE
*argv
, VALUE str
)
3730 if (argc
== 0) base
= 10;
3734 rb_scan_args(argc
, argv
, "01", &b
);
3738 rb_raise(rb_eArgError
, "invalid radix %d", base
);
3740 return rb_str_to_inum(str
, base
, Qfalse
);
3748 * Returns the result of interpreting leading characters in <i>str</i> as a
3749 * floating point number. Extraneous characters past the end of a valid number
3750 * are ignored. If there is not a valid number at the start of <i>str</i>,
3751 * <code>0.0</code> is returned. This method never raises an exception.
3753 * "123.45e1".to_f #=> 1234.5
3754 * "45.67 degrees".to_f #=> 45.67
3755 * "thx1138".to_f #=> 0.0
3759 rb_str_to_f(VALUE str
)
3761 return DOUBLE2NUM(rb_str_to_dbl(str
, Qfalse
));
3770 * Returns the receiver.
3774 rb_str_to_s(VALUE str
)
3776 if (rb_obj_class(str
) != rb_cString
) {
3777 VALUE dup
= str_alloc(rb_cString
);
3778 rb_str_replace(dup
, str
);
3785 str_cat_char(VALUE str
, int c
, rb_encoding
*enc
)
3788 int n
= rb_enc_codelen(c
, enc
);
3790 rb_enc_mbcput(c
, s
, enc
);
3791 rb_enc_str_buf_cat(str
, s
, n
, enc
);
3795 prefix_escape(VALUE str
, int c
, rb_encoding
*enc
)
3797 str_cat_char(str
, '\\', enc
);
3798 str_cat_char(str
, c
, enc
);
3803 * str.inspect => string
3805 * Returns a printable version of _str_, surrounded by quote marks,
3806 * with special characters escaped.
3810 * str.inspect #=> "\"hel\\bo\""
3814 rb_str_inspect(VALUE str
)
3816 rb_encoding
*enc
= STR_ENC_GET(str
);
3818 VALUE result
= rb_str_buf_new(0);
3820 if (!rb_enc_asciicompat(enc
)) enc
= rb_usascii_encoding();
3821 rb_enc_associate(result
, enc
);
3822 str_cat_char(result
, '"', enc
);
3823 p
= RSTRING_PTR(str
); pend
= RSTRING_END(str
);
3829 n
= rb_enc_precise_mbclen(p
, pend
, enc
);
3830 if (!MBCLEN_CHARFOUND_P(n
)) {
3833 goto escape_codepoint
;
3835 n
= MBCLEN_CHARFOUND_LEN(n
);
3837 c
= rb_enc_codepoint(p
, pend
, enc
);
3838 n
= rb_enc_codelen(c
, enc
);
3841 if (c
== '"'|| c
== '\\' ||
3844 MBCLEN_CHARFOUND_P(rb_enc_precise_mbclen(p
,pend
,enc
)) &&
3845 (cc
= rb_enc_codepoint(p
,pend
,enc
),
3846 (cc
== '$' || cc
== '@' || cc
== '{')))) {
3847 prefix_escape(result
, c
, enc
);
3849 else if (c
== '\n') {
3850 prefix_escape(result
, 'n', enc
);
3852 else if (c
== '\r') {
3853 prefix_escape(result
, 'r', enc
);
3855 else if (c
== '\t') {
3856 prefix_escape(result
, 't', enc
);
3858 else if (c
== '\f') {
3859 prefix_escape(result
, 'f', enc
);
3861 else if (c
== '\013') {
3862 prefix_escape(result
, 'v', enc
);
3864 else if (c
== '\010') {
3865 prefix_escape(result
, 'b', enc
);
3867 else if (c
== '\007') {
3868 prefix_escape(result
, 'a', enc
);
3870 else if (c
== 033) {
3871 prefix_escape(result
, 'e', enc
);
3873 else if (rb_enc_isprint(c
, enc
)) {
3874 rb_enc_str_buf_cat(result
, p
-n
, n
, enc
);
3882 for (q
= p
-n
; q
< p
; q
++) {
3884 sprintf(buf
, "\\x%02X", *q
& 0377);
3886 str_cat_char(result
, *s
++, enc
);
3891 str_cat_char(result
, '"', enc
);
3893 OBJ_INFECT(result
, str
);
3897 #define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{'))
3901 * str.dump => new_str
3903 * Produces a version of <i>str</i> with all nonprinting characters replaced by
3904 * <code>\nnn</code> notation and all special characters escaped.
3908 rb_str_dump(VALUE str
)
3910 rb_encoding
*enc0
= rb_enc_get(str
);
3912 const char *p
, *pend
;
3917 p
= RSTRING_PTR(str
); pend
= p
+ RSTRING_LEN(str
);
3919 unsigned char c
= *p
++;
3921 case '"': case '\\':
3922 case '\n': case '\r':
3923 case '\t': case '\f':
3924 case '\013': case '\010': case '\007': case '\033':
3929 len
+= IS_EVSTR(p
, pend
) ? 2 : 1;
3937 len
+= 4; /* \xNN */
3942 if (!rb_enc_asciicompat(enc0
)) {
3943 len
+= 19; /* ".force_encoding('')" */
3944 len
+= strlen(enc0
->name
);
3947 result
= rb_str_new5(str
, 0, len
);
3948 p
= RSTRING_PTR(str
); pend
= p
+ RSTRING_LEN(str
);
3949 q
= RSTRING_PTR(result
); qend
= q
+ len
;
3953 unsigned char c
= *p
++;
3955 if (c
== '"' || c
== '\\') {
3959 else if (c
== '#') {
3960 if (IS_EVSTR(p
, pend
)) *q
++ = '\\';
3963 else if (c
== '\n') {
3967 else if (c
== '\r') {
3971 else if (c
== '\t') {
3975 else if (c
== '\f') {
3979 else if (c
== '\013') {
3983 else if (c
== '\010') {
3987 else if (c
== '\007') {
3991 else if (c
== '\033') {
3995 else if (ISPRINT(c
)) {
4000 sprintf(q
, "x%02X", c
);
4005 if (!rb_enc_asciicompat(enc0
)) {
4006 sprintf(q
, ".force_encoding(\"%s\")", enc0
->name
);
4007 enc0
= rb_ascii8bit_encoding();
4010 OBJ_INFECT(result
, str
);
4011 /* result from dump is ASCII */
4012 rb_enc_associate(result
, enc0
);
4019 * str.upcase! => str or nil
4021 * Upcases the contents of <i>str</i>, returning <code>nil</code> if no changes
4023 * Note: case replacement is effective only in ASCII region.
4027 rb_str_upcase_bang(VALUE str
)
4032 int cr
= ENC_CODERANGE(str
);
4035 enc
= STR_ENC_GET(str
);
4036 s
= RSTRING_PTR(str
); send
= RSTRING_END(str
);
4038 int c
= rb_enc_codepoint(s
, send
, enc
);
4040 if (rb_enc_islower(c
, enc
)) {
4041 /* assuming toupper returns codepoint with same size */
4042 rb_enc_mbcput(rb_enc_toupper(c
, enc
), s
, enc
);
4045 s
+= rb_enc_codelen(c
, enc
);
4048 ENC_CODERANGE_SET(str
, cr
);
4049 if (modify
) return str
;
4056 * str.upcase => new_str
4058 * Returns a copy of <i>str</i> with all lowercase letters replaced with their
4059 * uppercase counterparts. The operation is locale insensitive---only
4060 * characters ``a'' to ``z'' are affected.
4061 * Note: case replacement is effective only in ASCII region.
4063 * "hEllO".upcase #=> "HELLO"
4067 rb_str_upcase(VALUE str
)
4069 str
= rb_str_dup(str
);
4070 rb_str_upcase_bang(str
);
4077 * str.downcase! => str or nil
4079 * Downcases the contents of <i>str</i>, returning <code>nil</code> if no
4080 * changes were made.
4081 * Note: case replacement is effective only in ASCII region.
4085 rb_str_downcase_bang(VALUE str
)
4090 int cr
= ENC_CODERANGE(str
);
4093 enc
= STR_ENC_GET(str
);
4094 s
= RSTRING_PTR(str
); send
= RSTRING_END(str
);
4096 int c
= rb_enc_codepoint(s
, send
, enc
);
4098 if (rb_enc_isupper(c
, enc
)) {
4099 /* assuming toupper returns codepoint with same size */
4100 rb_enc_mbcput(rb_enc_tolower(c
, enc
), s
, enc
);
4103 s
+= rb_enc_codelen(c
, enc
);
4106 ENC_CODERANGE_SET(str
, cr
);
4107 if (modify
) return str
;
4114 * str.downcase => new_str
4116 * Returns a copy of <i>str</i> with all uppercase letters replaced with their
4117 * lowercase counterparts. The operation is locale insensitive---only
4118 * characters ``A'' to ``Z'' are affected.
4119 * Note: case replacement is effective only in ASCII region.
4121 * "hEllO".downcase #=> "hello"
4125 rb_str_downcase(VALUE str
)
4127 str
= rb_str_dup(str
);
4128 rb_str_downcase_bang(str
);
4135 * str.capitalize! => str or nil
4137 * Modifies <i>str</i> by converting the first character to uppercase and the
4138 * remainder to lowercase. Returns <code>nil</code> if no changes are made.
4139 * Note: case conversion is effective only in ASCII region.
4142 * a.capitalize! #=> "Hello"
4144 * a.capitalize! #=> nil
4148 rb_str_capitalize_bang(VALUE str
)
4154 int cr
= ENC_CODERANGE(str
);
4157 enc
= STR_ENC_GET(str
);
4158 if (RSTRING_LEN(str
) == 0 || !RSTRING_PTR(str
)) return Qnil
;
4159 s
= RSTRING_PTR(str
); send
= RSTRING_END(str
);
4161 c
= rb_enc_codepoint(s
, send
, enc
);
4162 if (rb_enc_islower(c
, enc
)) {
4163 rb_enc_mbcput(rb_enc_toupper(c
, enc
), s
, enc
);
4166 s
+= rb_enc_codelen(c
, enc
);
4168 c
= rb_enc_codepoint(s
, send
, enc
);
4169 if (rb_enc_isupper(c
, enc
)) {
4170 rb_enc_mbcput(rb_enc_tolower(c
, enc
), s
, enc
);
4173 s
+= rb_enc_codelen(c
, enc
);
4176 ENC_CODERANGE_SET(str
, cr
);
4177 if (modify
) return str
;
4184 * str.capitalize => new_str
4186 * Returns a copy of <i>str</i> with the first character converted to uppercase
4187 * and the remainder to lowercase.
4188 * Note: case conversion is effective only in ASCII region.
4190 * "hello".capitalize #=> "Hello"
4191 * "HELLO".capitalize #=> "Hello"
4192 * "123ABC".capitalize #=> "123abc"
4196 rb_str_capitalize(VALUE str
)
4198 str
= rb_str_dup(str
);
4199 rb_str_capitalize_bang(str
);
4206 * str.swapcase! => str or nil
4208 * Equivalent to <code>String#swapcase</code>, but modifies the receiver in
4209 * place, returning <i>str</i>, or <code>nil</code> if no changes were made.
4210 * Note: case conversion is effective only in ASCII region.
4214 rb_str_swapcase_bang(VALUE str
)
4219 int cr
= ENC_CODERANGE(str
);
4222 enc
= STR_ENC_GET(str
);
4223 s
= RSTRING_PTR(str
); send
= RSTRING_END(str
);
4225 int c
= rb_enc_codepoint(s
, send
, enc
);
4227 if (rb_enc_isupper(c
, enc
)) {
4228 /* assuming toupper returns codepoint with same size */
4229 rb_enc_mbcput(rb_enc_tolower(c
, enc
), s
, enc
);
4232 else if (rb_enc_islower(c
, enc
)) {
4233 /* assuming toupper returns codepoint with same size */
4234 rb_enc_mbcput(rb_enc_toupper(c
, enc
), s
, enc
);
4237 s
+= rb_enc_codelen(c
, enc
);
4240 ENC_CODERANGE_SET(str
, cr
);
4241 if (modify
) return str
;
4248 * str.swapcase => new_str
4250 * Returns a copy of <i>str</i> with uppercase alphabetic characters converted
4251 * to lowercase and lowercase characters converted to uppercase.
4252 * Note: case conversion is effective only in ASCII region.
4254 * "Hello".swapcase #=> "hELLO"
4255 * "cYbEr_PuNk11".swapcase #=> "CyBeR_pUnK11"
4259 rb_str_swapcase(VALUE str
)
4261 str
= rb_str_dup(str
);
4262 rb_str_swapcase_bang(str
);
4266 typedef unsigned char *USTR
;
4274 trnext(struct tr
*t
, rb_encoding
*enc
)
4278 if (t
->p
== t
->pend
) return -1;
4279 if (t
->p
< t
->pend
- 1 && *t
->p
== '\\') {
4282 t
->now
= rb_enc_codepoint(t
->p
, t
->pend
, enc
);
4283 t
->p
+= rb_enc_codelen(t
->now
, enc
);
4284 if (t
->p
< t
->pend
- 1 && *t
->p
== '-') {
4286 if (t
->p
< t
->pend
) {
4287 int c
= rb_enc_codepoint(t
->p
, t
->pend
, enc
);
4288 t
->p
+= rb_enc_codelen(c
, enc
);
4289 if (t
->now
> c
) continue;
4296 else if (++t
->now
< t
->max
) {
4306 static VALUE
rb_str_delete_bang(int,VALUE
*,VALUE
);
4309 tr_trans(VALUE str
, VALUE src
, VALUE repl
, int sflag
)
4312 rb_encoding
*enc
, *e1
, *e2
;
4313 struct tr trsrc
, trrepl
;
4315 int c
, c0
, last
= 0, modify
= 0, i
, l
;
4318 int singlebyte
= single_byte_optimizable(str
);
4322 if (RSTRING_LEN(str
) == 0 || !RSTRING_PTR(str
)) return Qnil
;
4323 if (RSTRING_LEN(repl
) == 0) {
4324 return rb_str_delete_bang(1, &src
, str
);
4327 e1
= rb_enc_check(str
, src
);
4328 e2
= rb_enc_check(str
, repl
);
4333 enc
= rb_enc_check(src
, repl
);
4335 trsrc
.p
= RSTRING_PTR(src
); trsrc
.pend
= trsrc
.p
+ RSTRING_LEN(src
);
4336 if (RSTRING_LEN(src
) > 1 &&
4337 rb_enc_ascget(trsrc
.p
, trsrc
.pend
, &l
, enc
) == '^' &&
4338 trsrc
.p
+ l
< trsrc
.pend
) {
4342 trrepl
.p
= RSTRING_PTR(repl
);
4343 trrepl
.pend
= trrepl
.p
+ RSTRING_LEN(repl
);
4344 trsrc
.gen
= trrepl
.gen
= 0;
4345 trsrc
.now
= trrepl
.now
= 0;
4346 trsrc
.max
= trrepl
.max
= 0;
4349 for (i
=0; i
<256; i
++) {
4352 while ((c
= trnext(&trsrc
, enc
)) >= 0) {
4357 if (!hash
) hash
= rb_hash_new();
4358 rb_hash_aset(hash
, INT2NUM(c
), Qtrue
);
4361 while ((c
= trnext(&trrepl
, enc
)) >= 0)
4362 /* retrieve last replacer */;
4364 for (i
=0; i
<256; i
++) {
4365 if (trans
[i
] >= 0) {
4373 for (i
=0; i
<256; i
++) {
4376 while ((c
= trnext(&trsrc
, enc
)) >= 0) {
4377 r
= trnext(&trrepl
, enc
);
4378 if (r
== -1) r
= trrepl
.now
;
4381 if (r
> 255) singlebyte
= 0;
4384 if (!hash
) hash
= rb_hash_new();
4385 rb_hash_aset(hash
, INT2NUM(c
), INT2NUM(r
));
4391 s
= RSTRING_PTR(str
); send
= RSTRING_END(str
);
4393 int clen
, tlen
, max
= RSTRING_LEN(str
);
4394 int offset
, save
= -1;
4395 char *buf
= ALLOC_N(char, max
), *t
= buf
;
4398 c0
= c
= rb_enc_codepoint(s
, send
, enc
);
4399 tlen
= clen
= rb_enc_codelen(c
, enc
);
4406 VALUE tmp
= rb_hash_lookup(hash
, INT2NUM(c
));
4408 if (cflag
) c
= last
;
4411 else if (cflag
) c
= -1;
4412 else c
= NUM2INT(tmp
);
4418 if (save
== c
) continue;
4420 tlen
= rb_enc_codelen(c
, enc
);
4427 while (t
- buf
+ tlen
>= max
) {
4430 REALLOC_N(buf
, char, max
);
4433 rb_enc_mbcput(c
, t
, enc
);
4437 RSTRING(str
)->as
.heap
.ptr
= buf
;
4438 RSTRING(str
)->as
.heap
.len
= t
- buf
;
4439 STR_SET_NOEMBED(str
);
4440 RSTRING(str
)->as
.heap
.aux
.capa
= max
;
4442 else if (rb_enc_mbmaxlen(enc
) == 1 || (singlebyte
&& !hash
)) {
4444 c
= (unsigned char)*s
;
4445 if (trans
[c
] >= 0) {
4460 int clen
, tlen
, max
= RSTRING_LEN(str
) * 1.2;
4462 char *buf
= ALLOC_N(char, max
), *t
= buf
;
4465 c0
= c
= rb_enc_codepoint(s
, send
, enc
);
4466 tlen
= clen
= rb_enc_codelen(c
, enc
);
4472 VALUE tmp
= rb_hash_lookup(hash
, INT2NUM(c
));
4474 if (cflag
) c
= last
;
4477 else if (cflag
) c
= -1;
4478 else c
= NUM2INT(tmp
);
4484 tlen
= rb_enc_codelen(c
, enc
);
4491 while (t
- buf
+ tlen
>= max
) {
4494 REALLOC_N(buf
, char, max
);
4497 if (s
!= t
) rb_enc_mbcput(c
, t
, enc
);
4501 if (!STR_EMBED_P(str
)) {
4502 xfree(RSTRING(str
)->as
.heap
.ptr
);
4505 RSTRING(str
)->as
.heap
.ptr
= buf
;
4506 RSTRING(str
)->as
.heap
.len
= t
- buf
;
4507 STR_SET_NOEMBED(str
);
4508 RSTRING(str
)->as
.heap
.aux
.capa
= max
;
4512 rb_enc_associate(str
, enc
);
4521 * str.tr!(from_str, to_str) => str or nil
4523 * Translates <i>str</i> in place, using the same rules as
4524 * <code>String#tr</code>. Returns <i>str</i>, or <code>nil</code> if no
4525 * changes were made.
4529 rb_str_tr_bang(VALUE str
, VALUE src
, VALUE repl
)
4531 return tr_trans(str
, src
, repl
, 0);
4537 * str.tr(from_str, to_str) => new_str
4539 * Returns a copy of <i>str</i> with the characters in <i>from_str</i> replaced
4540 * by the corresponding characters in <i>to_str</i>. If <i>to_str</i> is
4541 * shorter than <i>from_str</i>, it is padded with its last character. Both
4542 * strings may use the c1--c2 notation to denote ranges of characters, and
4543 * <i>from_str</i> may start with a <code>^</code>, which denotes all
4544 * characters except those listed.
4546 * "hello".tr('aeiou', '*') #=> "h*ll*"
4547 * "hello".tr('^aeiou', '*') #=> "*e**o"
4548 * "hello".tr('el', 'ip') #=> "hippo"
4549 * "hello".tr('a-y', 'b-z') #=> "ifmmp"
4553 rb_str_tr(VALUE str
, VALUE src
, VALUE repl
)
4555 str
= rb_str_dup(str
);
4556 tr_trans(str
, src
, repl
, 0);
4561 tr_setup_table(VALUE str
, char stable
[256], int first
,
4562 VALUE
*tablep
, VALUE
*ctablep
, rb_encoding
*enc
)
4567 VALUE table
= 0, ptable
= 0;
4570 tr
.p
= RSTRING_PTR(str
); tr
.pend
= tr
.p
+ RSTRING_LEN(str
);
4571 tr
.gen
= tr
.now
= tr
.max
= 0;
4573 if (RSTRING_LEN(str
) > 1 && rb_enc_ascget(tr
.p
, tr
.pend
, &l
, enc
) == '^') {
4578 for (i
=0; i
<256; i
++) {
4582 for (i
=0; i
<256; i
++) {
4586 while ((c
= trnext(&tr
, enc
)) >= 0) {
4588 buf
[c
& 0xff] = !cflag
;
4591 VALUE key
= INT2NUM(c
);
4594 table
= rb_hash_new();
4604 if (!ptable
|| !NIL_P(rb_hash_aref(ptable
, key
))) {
4605 rb_hash_aset(table
, key
, Qtrue
);
4609 for (i
=0; i
<256; i
++) {
4610 stable
[i
] = stable
[i
] && buf
[i
];
4616 tr_find(int c
, char table
[256], VALUE del
, VALUE nodel
)
4619 return table
[c
] ? Qtrue
: Qfalse
;
4622 VALUE v
= INT2NUM(c
);
4624 if (del
&& !NIL_P(rb_hash_lookup(del
, v
))) {
4625 if (!nodel
|| NIL_P(rb_hash_lookup(nodel
, v
))) {
4635 * str.delete!([other_str]+) => str or nil
4637 * Performs a <code>delete</code> operation in place, returning <i>str</i>, or
4638 * <code>nil</code> if <i>str</i> was not modified.
4642 rb_str_delete_bang(int argc
, VALUE
*argv
, VALUE str
)
4645 rb_encoding
*enc
= 0;
4647 VALUE del
= 0, nodel
= 0;
4652 if (RSTRING_LEN(str
) == 0 || !RSTRING_PTR(str
)) return Qnil
;
4653 cr
= ENC_CODERANGE(str
);
4655 rb_raise(rb_eArgError
, "wrong number of arguments");
4657 for (i
=0; i
<argc
; i
++) {
4661 enc
= rb_enc_check(str
, s
);
4662 tr_setup_table(s
, squeez
, i
==0, &del
, &nodel
, enc
);
4666 s
= t
= RSTRING_PTR(str
);
4667 if (!s
|| RSTRING_LEN(str
) == 0) return Qnil
;
4668 send
= RSTRING_END(str
);
4670 int c
= rb_enc_codepoint(s
, send
, enc
);
4671 int clen
= rb_enc_codelen(c
, enc
);
4673 if (tr_find(c
, squeez
, del
, nodel
)) {
4677 if (t
!= s
) rb_enc_mbcput(c
, t
, enc
);
4683 STR_SET_LEN(str
, t
- RSTRING_PTR(str
));
4685 ENC_CODERANGE_SET(str
, cr
);
4686 if (modify
) return str
;
4693 * str.delete([other_str]+) => new_str
4695 * Returns a copy of <i>str</i> with all characters in the intersection of its
4696 * arguments deleted. Uses the same rules for building the set of characters as
4697 * <code>String#count</code>.
4699 * "hello".delete "l","lo" #=> "heo"
4700 * "hello".delete "lo" #=> "he"
4701 * "hello".delete "aeiou", "^e" #=> "hell"
4702 * "hello".delete "ej-m" #=> "ho"
4706 rb_str_delete(int argc
, VALUE
*argv
, VALUE str
)
4708 str
= rb_str_dup(str
);
4709 rb_str_delete_bang(argc
, argv
, str
);
4716 * str.squeeze!([other_str]*) => str or nil
4718 * Squeezes <i>str</i> in place, returning either <i>str</i>, or
4719 * <code>nil</code> if no changes were made.
4723 rb_str_squeeze_bang(int argc
, VALUE
*argv
, VALUE str
)
4726 rb_encoding
*enc
= 0;
4727 VALUE del
= 0, nodel
= 0;
4729 int save
, modify
= 0;
4733 enc
= STR_ENC_GET(str
);
4736 for (i
=0; i
<argc
; i
++) {
4740 enc
= rb_enc_check(str
, s
);
4741 tr_setup_table(s
, squeez
, i
==0, &del
, &nodel
, enc
);
4746 s
= t
= RSTRING_PTR(str
);
4747 if (!s
|| RSTRING_LEN(str
) == 0) return Qnil
;
4748 send
= RSTRING_END(str
);
4751 int c
= rb_enc_codepoint(s
, send
, enc
);
4752 int clen
= rb_enc_codelen(c
, enc
);
4754 if (c
!= save
|| (argc
> 0 && !tr_find(c
, squeez
, del
, nodel
))) {
4755 if (t
!= s
) rb_enc_mbcput(c
, t
, enc
);
4762 if (t
- RSTRING_PTR(str
) != RSTRING_LEN(str
)) {
4763 STR_SET_LEN(str
, t
- RSTRING_PTR(str
));
4767 if (modify
) return str
;
4774 * str.squeeze([other_str]*) => new_str
4776 * Builds a set of characters from the <i>other_str</i> parameter(s) using the
4777 * procedure described for <code>String#count</code>. Returns a new string
4778 * where runs of the same character that occur in this set are replaced by a
4779 * single character. If no arguments are given, all runs of identical
4780 * characters are replaced by a single character.
4782 * "yellow moon".squeeze #=> "yelow mon"
4783 * " now is the".squeeze(" ") #=> " now is the"
4784 * "putters shoot balls".squeeze("m-z") #=> "puters shot balls"
4788 rb_str_squeeze(int argc
, VALUE
*argv
, VALUE str
)
4790 str
= rb_str_dup(str
);
4791 rb_str_squeeze_bang(argc
, argv
, str
);
4798 * str.tr_s!(from_str, to_str) => str or nil
4800 * Performs <code>String#tr_s</code> processing on <i>str</i> in place,
4801 * returning <i>str</i>, or <code>nil</code> if no changes were made.
4805 rb_str_tr_s_bang(VALUE str
, VALUE src
, VALUE repl
)
4807 return tr_trans(str
, src
, repl
, 1);
4813 * str.tr_s(from_str, to_str) => new_str
4815 * Processes a copy of <i>str</i> as described under <code>String#tr</code>,
4816 * then removes duplicate characters in regions that were affected by the
4819 * "hello".tr_s('l', 'r') #=> "hero"
4820 * "hello".tr_s('el', '*') #=> "h*o"
4821 * "hello".tr_s('el', 'hx') #=> "hhxo"
4825 rb_str_tr_s(VALUE str
, VALUE src
, VALUE repl
)
4827 str
= rb_str_dup(str
);
4828 tr_trans(str
, src
, repl
, 1);
4835 * str.count([other_str]+) => fixnum
4837 * Each <i>other_str</i> parameter defines a set of characters to count. The
4838 * intersection of these sets defines the characters to count in
4839 * <i>str</i>. Any <i>other_str</i> that starts with a caret (^) is
4840 * negated. The sequence c1--c2 means all characters between c1 and c2.
4843 * a.count "lo" #=> 5
4844 * a.count "lo", "o" #=> 2
4845 * a.count "hello", "^l" #=> 4
4846 * a.count "ej-m" #=> 4
4850 rb_str_count(int argc
, VALUE
*argv
, VALUE str
)
4853 rb_encoding
*enc
= 0;
4854 VALUE del
= 0, nodel
= 0;
4859 rb_raise(rb_eArgError
, "wrong number of arguments");
4861 for (i
=0; i
<argc
; i
++) {
4865 enc
= rb_enc_check(str
, s
);
4866 tr_setup_table(s
, table
,i
==0, &del
, &nodel
, enc
);
4869 s
= RSTRING_PTR(str
);
4870 if (!s
|| RSTRING_LEN(str
) == 0) return INT2FIX(0);
4871 send
= RSTRING_END(str
);
4874 int c
= rb_enc_codepoint(s
, send
, enc
);
4875 int clen
= rb_enc_codelen(c
, enc
);
4877 if (tr_find(c
, table
, del
, nodel
)) {
4888 * str.split(pattern=$;, [limit]) => anArray
4890 * Divides <i>str</i> into substrings based on a delimiter, returning an array
4891 * of these substrings.
4893 * If <i>pattern</i> is a <code>String</code>, then its contents are used as
4894 * the delimiter when splitting <i>str</i>. If <i>pattern</i> is a single
4895 * space, <i>str</i> is split on whitespace, with leading whitespace and runs
4896 * of contiguous whitespace characters ignored.
4898 * If <i>pattern</i> is a <code>Regexp</code>, <i>str</i> is divided where the
4899 * pattern matches. Whenever the pattern matches a zero-length string,
4900 * <i>str</i> is split into individual characters. If <i>pattern</i> contains
4901 * groups, the respective matches will be returned in the array as well.
4903 * If <i>pattern</i> is omitted, the value of <code>$;</code> is used. If
4904 * <code>$;</code> is <code>nil</code> (which is the default), <i>str</i> is
4905 * split on whitespace as if ` ' were specified.
4907 * If the <i>limit</i> parameter is omitted, trailing null fields are
4908 * suppressed. If <i>limit</i> is a positive number, at most that number of
4909 * fields will be returned (if <i>limit</i> is <code>1</code>, the entire
4910 * string is returned as the only entry in an array). If negative, there is no
4911 * limit to the number of fields returned, and trailing null fields are not
4914 * " now's the time".split #=> ["now's", "the", "time"]
4915 * " now's the time".split(' ') #=> ["now's", "the", "time"]
4916 * " now's the time".split(/ /) #=> ["", "now's", "", "the", "time"]
4917 * "1, 2.34,56, 7".split(%r{,\s*}) #=> ["1", "2.34", "56", "7"]
4918 * "hello".split(//) #=> ["h", "e", "l", "l", "o"]
4919 * "hello".split(//, 3) #=> ["h", "e", "llo"]
4920 * "hi mom".split(%r{\s*}) #=> ["h", "i", "m", "o", "m"]
4922 * "mellow yellow".split("ello") #=> ["m", "w y", "w"]
4923 * "1,2,,3,4,,".split(',') #=> ["1", "2", "", "3", "4"]
4924 * "1,2,,3,4,,".split(',', 4) #=> ["1", "2", "", "3,4,,"]
4925 * "1,2,,3,4,,".split(',', -4) #=> ["1", "2", "", "3", "4", "", ""]
4929 rb_str_split_m(int argc
, VALUE
*argv
, VALUE str
)
4934 int awk_split
= Qfalse
;
4935 long beg
, end
, i
= 0;
4939 if (rb_scan_args(argc
, argv
, "02", &spat
, &limit
) == 2) {
4940 lim
= NUM2INT(limit
);
4941 if (lim
<= 0) limit
= Qnil
;
4942 else if (lim
== 1) {
4943 if (RSTRING_LEN(str
) == 0)
4944 return rb_ary_new2(0);
4945 return rb_ary_new3(1, str
);
4950 enc
= STR_ENC_GET(str
);
4952 if (!NIL_P(rb_fs
)) {
4960 if (TYPE(spat
) == T_STRING
) {
4961 rb_encoding
*enc2
= STR_ENC_GET(spat
);
4963 if (rb_enc_mbminlen(enc2
) == 1) {
4964 if (RSTRING_LEN(spat
) == 1 && RSTRING_PTR(spat
)[0] == ' '){
4970 if (rb_enc_ascget(RSTRING_PTR(spat
), RSTRING_END(spat
), &l
, enc2
) == ' ' &&
4971 RSTRING_LEN(spat
) == l
) {
4976 spat
= rb_reg_regcomp(rb_reg_quote(spat
));
4980 spat
= get_pat(spat
, 1);
4984 result
= rb_ary_new();
4987 char *ptr
= RSTRING_PTR(str
);
4988 char *eptr
= RSTRING_END(str
);
4994 while (ptr
< eptr
) {
4995 c
= rb_enc_codepoint(ptr
, eptr
, enc
);
4996 ptr
+= rb_enc_mbclen(ptr
, eptr
, enc
);
4998 if (rb_enc_isspace(c
, enc
)) {
5004 if (!NIL_P(limit
) && lim
<= i
) break;
5008 if (rb_enc_isspace(c
, enc
)) {
5009 rb_ary_push(result
, rb_str_subseq(str
, beg
, end
-beg
));
5012 if (!NIL_P(limit
)) ++i
;
5024 struct re_registers
*regs
;
5026 while ((end
= rb_reg_search(spat
, str
, start
, 0)) >= 0) {
5027 regs
= RMATCH_REGS(rb_backref_get());
5028 if (start
== end
&& BEG(0) == END(0)) {
5029 if (!RSTRING_PTR(str
)) {
5030 rb_ary_push(result
, rb_str_new("", 0));
5033 else if (last_null
== 1) {
5034 rb_ary_push(result
, rb_str_subseq(str
, beg
,
5035 rb_enc_mbclen(RSTRING_PTR(str
)+beg
,
5041 if (RSTRING_PTR(str
)+start
== RSTRING_END(str
))
5044 start
+= rb_enc_mbclen(RSTRING_PTR(str
)+start
,RSTRING_END(str
),enc
);
5050 rb_ary_push(result
, rb_str_subseq(str
, beg
, end
-beg
));
5051 beg
= start
= END(0);
5055 for (idx
=1; idx
< regs
->num_regs
; idx
++) {
5056 if (BEG(idx
) == -1) continue;
5057 if (BEG(idx
) == END(idx
))
5058 tmp
= rb_str_new5(str
, 0, 0);
5060 tmp
= rb_str_subseq(str
, BEG(idx
), END(idx
)-BEG(idx
));
5061 rb_ary_push(result
, tmp
);
5063 if (!NIL_P(limit
) && lim
<= ++i
) break;
5066 if (RSTRING_LEN(str
) > 0 && (!NIL_P(limit
) || RSTRING_LEN(str
) > beg
|| lim
< 0)) {
5067 if (RSTRING_LEN(str
) == beg
)
5068 tmp
= rb_str_new5(str
, 0, 0);
5070 tmp
= rb_str_subseq(str
, beg
, RSTRING_LEN(str
)-beg
);
5071 rb_ary_push(result
, tmp
);
5073 if (NIL_P(limit
) && lim
== 0) {
5074 while (RARRAY_LEN(result
) > 0 &&
5075 RSTRING_LEN(RARRAY_PTR(result
)[RARRAY_LEN(result
)-1]) == 0)
5083 rb_str_split(VALUE str
, const char *sep0
)
5088 sep
= rb_str_new2(sep0
);
5089 return rb_str_split_m(1, &sep
, str
);
5094 * Document-method: lines
5096 * str.lines(separator=$/) => anEnumerator
5097 * str.lines(separator=$/) {|substr| block } => str
5099 * Returns an enumerator that gives each line in the string. If a block is
5100 * given, it iterates over each line in the string.
5102 * "foo\nbar\n".lines.to_a #=> ["foo\n", "bar\n"]
5103 * "foo\nb ar".lines.sort #=> ["b ar", "foo\n"]
5107 * Document-method: each_line
5109 * str.each_line(separator=$/) {|substr| block } => str
5111 * Splits <i>str</i> using the supplied parameter as the record separator
5112 * (<code>$/</code> by default), passing each substring in turn to the supplied
5113 * block. If a zero-length record separator is supplied, the string is split
5114 * into paragraphs delimited by multiple successive newlines.
5116 * print "Example one\n"
5117 * "hello\nworld".each {|s| p s}
5118 * print "Example two\n"
5119 * "hello\nworld".each('l') {|s| p s}
5120 * print "Example three\n"
5121 * "hello\n\n\nworld".each('') {|s| p s}
5123 * <em>produces:</em>
5139 rb_str_each_line(int argc
, VALUE
*argv
, VALUE str
)
5144 char *p
, *pend
, *s
, *ptr
;
5154 rb_scan_args(argc
, argv
, "01", &rs
);
5156 RETURN_ENUMERATOR(str
, argc
, argv
);
5161 str
= rb_str_new4(str
);
5162 ptr
= p
= s
= RSTRING_PTR(str
);
5163 pend
= p
+ RSTRING_LEN(str
);
5164 len
= RSTRING_LEN(str
);
5166 if (rs
== rb_default_rs
) {
5167 enc
= rb_enc_get(str
);
5171 p
= memchr(p
, '\n', pend
- p
);
5173 p0
= rb_enc_left_char_head(s
, p
, enc
);
5174 if (!rb_enc_is_newline(p0
, pend
, enc
)) {
5178 p
= p0
+ rb_enc_mbclen(p0
, pend
, enc
);
5179 line
= rb_str_new5(str
, s
, p
- s
);
5180 OBJ_INFECT(line
, str
);
5181 rb_enc_cr_str_copy_for_substr(line
, str
);
5183 str_mod_check(str
, ptr
, len
);
5189 enc
= rb_enc_check(str
, rs
);
5190 rslen
= RSTRING_LEN(rs
);
5195 newline
= rb_enc_codepoint(RSTRING_PTR(rs
), RSTRING_END(rs
), enc
);
5199 int c
= rb_enc_codepoint(p
, pend
, enc
);
5202 n
= rb_enc_codelen(c
, enc
);
5203 if (rslen
== 0 && c
== newline
) {
5205 if (p
< pend
&& (c
= rb_enc_codepoint(p
, pend
, enc
)) != newline
) {
5208 while (p
< pend
&& rb_enc_codepoint(p
, pend
, enc
) == newline
) {
5214 (rslen
<= 1 || memcmp(RSTRING_PTR(rs
), p
, rslen
) == 0)) {
5215 line
= rb_str_new5(str
, s
, p
- s
+ (rslen
? rslen
: n
));
5216 OBJ_INFECT(line
, str
);
5217 rb_enc_cr_str_copy_for_substr(line
, str
);
5219 str_mod_check(str
, ptr
, len
);
5220 s
= p
+ (rslen
? rslen
: n
);
5227 line
= rb_str_new5(str
, s
, pend
- s
);
5228 OBJ_INFECT(line
, str
);
5229 rb_enc_cr_str_copy_for_substr(line
, str
);
5238 * Document-method: bytes
5240 * str.bytes => anEnumerator
5241 * str.bytes {|fixnum| block } => str
5243 * Returns an enumerator that gives each byte in the string. If a block is
5244 * given, it iterates over each byte in the string.
5246 * "hello".bytes.to_a #=> [104, 101, 108, 108, 111]
5250 * Document-method: each_byte
5252 * str.each_byte {|fixnum| block } => str
5254 * Passes each byte in <i>str</i> to the given block.
5256 * "hello".each_byte {|c| print c, ' ' }
5258 * <em>produces:</em>
5260 * 104 101 108 108 111
5264 rb_str_each_byte(VALUE str
)
5268 RETURN_ENUMERATOR(str
, 0, 0);
5269 for (i
=0; i
<RSTRING_LEN(str
); i
++) {
5270 rb_yield(INT2FIX(RSTRING_PTR(str
)[i
] & 0xff));
5277 * Document-method: chars
5279 * str.chars => anEnumerator
5280 * str.chars {|substr| block } => str
5282 * Returns an enumerator that gives each character in the string.
5283 * If a block is given, it iterates over each character in the string.
5285 * "foo".chars.to_a #=> ["f","o","o"]
5289 * Document-method: each_char
5291 * str.each_char {|cstr| block } => str
5293 * Passes each character in <i>str</i> to the given block.
5295 * "hello".each_char {|c| print c, ' ' }
5297 * <em>produces:</em>
5303 rb_str_each_char(VALUE str
)
5309 RETURN_ENUMERATOR(str
, 0, 0);
5310 str
= rb_str_new4(str
);
5311 ptr
= RSTRING_PTR(str
);
5312 len
= RSTRING_LEN(str
);
5313 enc
= rb_enc_get(str
);
5314 for (i
= 0; i
< len
; i
+= n
) {
5315 n
= rb_enc_mbclen(ptr
+ i
, ptr
+ len
, enc
);
5316 rb_yield(rb_str_subseq(str
, i
, n
));
5322 chopped_length(VALUE str
)
5324 rb_encoding
*enc
= STR_ENC_GET(str
);
5325 const char *p
, *p2
, *beg
, *end
;
5327 beg
= RSTRING_PTR(str
);
5328 end
= beg
+ RSTRING_LEN(str
);
5329 if (beg
> end
) return 0;
5330 p
= rb_enc_prev_char(beg
, end
, enc
);
5332 if (p
> beg
&& rb_enc_codepoint(p
, end
, enc
) == '\n') {
5333 p2
= rb_enc_prev_char(beg
, p
, enc
);
5334 if (p2
&& rb_enc_codepoint(p2
, end
, enc
) == '\r') p
= p2
;
5341 * str.chop! => str or nil
5343 * Processes <i>str</i> as for <code>String#chop</code>, returning <i>str</i>,
5344 * or <code>nil</code> if <i>str</i> is the empty string. See also
5345 * <code>String#chomp!</code>.
5349 rb_str_chop_bang(VALUE str
)
5351 if (RSTRING_LEN(str
) > 0) {
5354 len
= chopped_length(str
);
5355 STR_SET_LEN(str
, len
);
5356 RSTRING_PTR(str
)[len
] = '\0';
5365 * str.chop => new_str
5367 * Returns a new <code>String</code> with the last character removed. If the
5368 * string ends with <code>\r\n</code>, both characters are removed. Applying
5369 * <code>chop</code> to an empty string returns an empty
5370 * string. <code>String#chomp</code> is often a safer alternative, as it leaves
5371 * the string unchanged if it doesn't end in a record separator.
5373 * "string\r\n".chop #=> "string"
5374 * "string\n\r".chop #=> "string\n"
5375 * "string\n".chop #=> "string"
5376 * "string".chop #=> "strin"
5377 * "x".chop.chop #=> ""
5381 rb_str_chop(VALUE str
)
5383 VALUE str2
= rb_str_new5(str
, RSTRING_PTR(str
), chopped_length(str
));
5384 rb_enc_cr_str_copy_for_substr(str2
, str
);
5385 OBJ_INFECT(str2
, str
);
5392 * str.chomp!(separator=$/) => str or nil
5394 * Modifies <i>str</i> in place as described for <code>String#chomp</code>,
5395 * returning <i>str</i>, or <code>nil</code> if no modifications were made.
5399 rb_str_chomp_bang(int argc
, VALUE
*argv
, VALUE str
)
5407 len
= RSTRING_LEN(str
);
5408 if (len
== 0) return Qnil
;
5409 p
= RSTRING_PTR(str
);
5413 if (rs
== rb_default_rs
) {
5416 enc
= rb_enc_get(str
);
5417 if (rb_enc_mbminlen(enc
) > 1) {
5418 pp
= rb_enc_left_char_head(p
, e
-rb_enc_mbminlen(enc
), enc
);
5419 if (rb_enc_is_newline(pp
, e
, enc
)) {
5422 pp
= e
- rb_enc_mbminlen(enc
);
5424 pp
= rb_enc_left_char_head(p
, pp
, enc
);
5425 if (rb_enc_ascget(pp
, e
, 0, enc
) == '\r') {
5429 if (e
== RSTRING_END(str
)) {
5432 len
= e
- RSTRING_PTR(str
);
5433 STR_SET_LEN(str
, len
);
5436 if (RSTRING_PTR(str
)[len
-1] == '\n') {
5438 if (RSTRING_LEN(str
) > 0 &&
5439 RSTRING_PTR(str
)[RSTRING_LEN(str
)-1] == '\r') {
5443 else if (RSTRING_PTR(str
)[len
-1] == '\r') {
5450 RSTRING_PTR(str
)[RSTRING_LEN(str
)] = '\0';
5455 rb_scan_args(argc
, argv
, "01", &rs
);
5457 if (NIL_P(rs
)) return Qnil
;
5459 rslen
= RSTRING_LEN(rs
);
5461 while (len
>0 && p
[len
-1] == '\n') {
5463 if (len
>0 && p
[len
-1] == '\r')
5466 if (len
< RSTRING_LEN(str
)) {
5468 STR_SET_LEN(str
, len
);
5469 RSTRING_PTR(str
)[len
] = '\0';
5474 if (rslen
> len
) return Qnil
;
5475 newline
= RSTRING_PTR(rs
)[rslen
-1];
5476 if (rslen
== 1 && newline
== '\n')
5479 enc
= rb_enc_check(str
, rs
);
5480 if (is_broken_string(rs
)) {
5484 if (p
[len
-1] == newline
&&
5486 memcmp(RSTRING_PTR(rs
), pp
, rslen
) == 0)) {
5487 if (rb_enc_left_char_head(p
, pp
, enc
) != pp
)
5490 STR_SET_LEN(str
, RSTRING_LEN(str
) - rslen
);
5491 RSTRING_PTR(str
)[RSTRING_LEN(str
)] = '\0';
5500 * str.chomp(separator=$/) => new_str
5502 * Returns a new <code>String</code> with the given record separator removed
5503 * from the end of <i>str</i> (if present). If <code>$/</code> has not been
5504 * changed from the default Ruby record separator, then <code>chomp</code> also
5505 * removes carriage return characters (that is it will remove <code>\n</code>,
5506 * <code>\r</code>, and <code>\r\n</code>).
5508 * "hello".chomp #=> "hello"
5509 * "hello\n".chomp #=> "hello"
5510 * "hello\r\n".chomp #=> "hello"
5511 * "hello\n\r".chomp #=> "hello\n"
5512 * "hello\r".chomp #=> "hello"
5513 * "hello \n there".chomp #=> "hello \n there"
5514 * "hello".chomp("llo") #=> "he"
5518 rb_str_chomp(int argc
, VALUE
*argv
, VALUE str
)
5520 str
= rb_str_dup(str
);
5521 rb_str_chomp_bang(argc
, argv
, str
);
5527 * str.lstrip! => self or nil
5529 * Removes leading whitespace from <i>str</i>, returning <code>nil</code> if no
5530 * change was made. See also <code>String#rstrip!</code> and
5531 * <code>String#strip!</code>.
5533 * " hello ".lstrip #=> "hello "
5534 * "hello".lstrip! #=> nil
5538 rb_str_lstrip_bang(VALUE str
)
5544 enc
= STR_ENC_GET(str
);
5545 s
= RSTRING_PTR(str
);
5546 if (!s
|| RSTRING_LEN(str
) == 0) return Qnil
;
5547 e
= t
= RSTRING_END(str
);
5548 /* remove spaces at head */
5550 int cc
= rb_enc_codepoint(s
, e
, enc
);
5552 if (!rb_enc_isspace(cc
, enc
)) break;
5553 s
+= rb_enc_codelen(cc
, enc
);
5556 if (s
> RSTRING_PTR(str
)) {
5558 STR_SET_LEN(str
, t
-s
);
5559 memmove(RSTRING_PTR(str
), s
, RSTRING_LEN(str
));
5560 RSTRING_PTR(str
)[RSTRING_LEN(str
)] = '\0';
5569 * str.lstrip => new_str
5571 * Returns a copy of <i>str</i> with leading whitespace removed. See also
5572 * <code>String#rstrip</code> and <code>String#strip</code>.
5574 * " hello ".lstrip #=> "hello "
5575 * "hello".lstrip #=> "hello"
5579 rb_str_lstrip(VALUE str
)
5581 str
= rb_str_dup(str
);
5582 rb_str_lstrip_bang(str
);
5589 * str.rstrip! => self or nil
5591 * Removes trailing whitespace from <i>str</i>, returning <code>nil</code> if
5592 * no change was made. See also <code>String#lstrip!</code> and
5593 * <code>String#strip!</code>.
5595 * " hello ".rstrip #=> " hello"
5596 * "hello".rstrip! #=> nil
5600 rb_str_rstrip_bang(VALUE str
)
5604 int space_seen
= Qfalse
;
5607 enc
= STR_ENC_GET(str
);
5608 s
= RSTRING_PTR(str
);
5609 if (!s
|| RSTRING_LEN(str
) == 0) return Qnil
;
5610 t
= e
= RSTRING_END(str
);
5612 int cc
= rb_enc_codepoint(s
, e
, enc
);
5614 if (!cc
|| rb_enc_isspace(cc
, enc
)) {
5615 if (!space_seen
) t
= s
;
5619 space_seen
= Qfalse
;
5621 s
+= rb_enc_codelen(cc
, enc
);
5623 if (!space_seen
) t
= s
;
5626 STR_SET_LEN(str
, t
-RSTRING_PTR(str
));
5627 RSTRING_PTR(str
)[RSTRING_LEN(str
)] = '\0';
5636 * str.rstrip => new_str
5638 * Returns a copy of <i>str</i> with trailing whitespace removed. See also
5639 * <code>String#lstrip</code> and <code>String#strip</code>.
5641 * " hello ".rstrip #=> " hello"
5642 * "hello".rstrip #=> "hello"
5646 rb_str_rstrip(VALUE str
)
5648 str
= rb_str_dup(str
);
5649 rb_str_rstrip_bang(str
);
5656 * str.strip! => str or nil
5658 * Removes leading and trailing whitespace from <i>str</i>. Returns
5659 * <code>nil</code> if <i>str</i> was not altered.
5663 rb_str_strip_bang(VALUE str
)
5665 VALUE l
= rb_str_lstrip_bang(str
);
5666 VALUE r
= rb_str_rstrip_bang(str
);
5668 if (NIL_P(l
) && NIL_P(r
)) return Qnil
;
5675 * str.strip => new_str
5677 * Returns a copy of <i>str</i> with leading and trailing whitespace removed.
5679 * " hello ".strip #=> "hello"
5680 * "\tgoodbye\r\n".strip #=> "goodbye"
5684 rb_str_strip(VALUE str
)
5686 str
= rb_str_dup(str
);
5687 rb_str_strip_bang(str
);
5692 scan_once(VALUE str
, VALUE pat
, long *start
)
5694 VALUE result
, match
;
5695 struct re_registers
*regs
;
5698 if (rb_reg_search(pat
, str
, *start
, 0) >= 0) {
5699 match
= rb_backref_get();
5700 regs
= RMATCH_REGS(match
);
5701 if (BEG(0) == END(0)) {
5702 rb_encoding
*enc
= STR_ENC_GET(str
);
5704 * Always consume at least one character of the input string
5706 if (RSTRING_LEN(str
) > END(0))
5707 *start
= END(0)+rb_enc_mbclen(RSTRING_PTR(str
)+END(0),
5708 RSTRING_END(str
), enc
);
5715 if (regs
->num_regs
== 1) {
5716 return rb_reg_nth_match(0, match
);
5718 result
= rb_ary_new2(regs
->num_regs
);
5719 for (i
=1; i
< regs
->num_regs
; i
++) {
5720 rb_ary_push(result
, rb_reg_nth_match(i
, match
));
5731 * str.scan(pattern) => array
5732 * str.scan(pattern) {|match, ...| block } => str
5734 * Both forms iterate through <i>str</i>, matching the pattern (which may be a
5735 * <code>Regexp</code> or a <code>String</code>). For each match, a result is
5736 * generated and either added to the result array or passed to the block. If
5737 * the pattern contains no groups, each individual result consists of the
5738 * matched string, <code>$&</code>. If the pattern contains groups, each
5739 * individual result is itself an array containing one entry per group.
5742 * a.scan(/\w+/) #=> ["cruel", "world"]
5743 * a.scan(/.../) #=> ["cru", "el ", "wor"]
5744 * a.scan(/(...)/) #=> [["cru"], ["el "], ["wor"]]
5745 * a.scan(/(..)(..)/) #=> [["cr", "ue"], ["l ", "wo"]]
5747 * And the block form:
5749 * a.scan(/\w+/) {|w| print "<<#{w}>> " }
5751 * a.scan(/(.)(.)/) {|x,y| print y, x }
5754 * <em>produces:</em>
5756 * <<cruel>> <<world>>
5761 rb_str_scan(VALUE str
, VALUE pat
)
5765 long last
= -1, prev
= 0;
5766 char *p
= RSTRING_PTR(str
); long len
= RSTRING_LEN(str
);
5768 pat
= get_pat(pat
, 1);
5769 if (!rb_block_given_p()) {
5770 VALUE ary
= rb_ary_new();
5772 while (!NIL_P(result
= scan_once(str
, pat
, &start
))) {
5775 rb_ary_push(ary
, result
);
5777 if (last
>= 0) rb_reg_search(pat
, str
, last
, 0);
5781 while (!NIL_P(result
= scan_once(str
, pat
, &start
))) {
5785 str_mod_check(str
, p
, len
);
5787 if (last
>= 0) rb_reg_search(pat
, str
, last
, 0);
5794 * str.hex => integer
5796 * Treats leading characters from <i>str</i> as a string of hexadecimal digits
5797 * (with an optional sign and an optional <code>0x</code>) and returns the
5798 * corresponding number. Zero is returned on error.
5801 * "-1234".hex #=> -4660
5803 * "wombat".hex #=> 0
5807 rb_str_hex(VALUE str
)
5809 rb_encoding
*enc
= rb_enc_get(str
);
5811 if (!rb_enc_asciicompat(enc
)) {
5812 rb_raise(rb_eEncCompatError
, "ASCII incompatible encoding: %s", rb_enc_name(enc
));
5814 return rb_str_to_inum(str
, 16, Qfalse
);
5820 * str.oct => integer
5822 * Treats leading characters of <i>str</i> as a string of octal digits (with an
5823 * optional sign) and returns the corresponding number. Returns 0 if the
5827 * "-377".oct #=> -255
5829 * "0377bad".oct #=> 255
5833 rb_str_oct(VALUE str
)
5835 rb_encoding
*enc
= rb_enc_get(str
);
5837 if (!rb_enc_asciicompat(enc
)) {
5838 rb_raise(rb_eEncCompatError
, "ASCII incompatible encoding: %s", rb_enc_name(enc
));
5840 return rb_str_to_inum(str
, -8, Qfalse
);
5846 * str.crypt(other_str) => new_str
5848 * Applies a one-way cryptographic hash to <i>str</i> by invoking the standard
5849 * library function <code>crypt</code>. The argument is the salt string, which
5850 * should be two characters long, each character drawn from
5851 * <code>[a-zA-Z0-9./]</code>.
5855 rb_str_crypt(VALUE str
, VALUE salt
)
5857 extern char *crypt(const char *, const char *);
5862 if (RSTRING_LEN(salt
) < 2)
5863 rb_raise(rb_eArgError
, "salt too short (need >=2 bytes)");
5865 if (RSTRING_PTR(str
)) s
= RSTRING_PTR(str
);
5867 result
= rb_str_new2(crypt(s
, RSTRING_PTR(salt
)));
5868 OBJ_INFECT(result
, str
);
5869 OBJ_INFECT(result
, salt
);
5876 * str.intern => symbol
5877 * str.to_sym => symbol
5879 * Returns the <code>Symbol</code> corresponding to <i>str</i>, creating the
5880 * symbol if it did not previously exist. See <code>Symbol#id2name</code>.
5882 * "Koala".intern #=> :Koala
5883 * s = 'cat'.to_sym #=> :cat
5884 * s == :cat #=> true
5885 * s = '@cat'.to_sym #=> :@cat
5886 * s == :@cat #=> true
5888 * This can also be used to create symbols that cannot be represented using the
5889 * <code>:xxx</code> notation.
5891 * 'cat and dog'.to_sym #=> :"cat and dog"
5895 rb_str_intern(VALUE s
)
5897 VALUE str
= RB_GC_GUARD(s
);
5901 id
= rb_intern_str(str
);
5905 const char *name
= rb_id2name(id2
);
5908 rb_raise(rb_eRuntimeError
, "symbol table overflow (%s given for %s)",
5909 name
, RSTRING_PTR(str
));
5912 rb_raise(rb_eRuntimeError
, "symbol table overflow (symbol %s)",
5922 * str.ord => integer
5924 * Return the <code>Integer</code> ordinal of a one-character string.
5934 c
= rb_enc_codepoint(RSTRING_PTR(s
), RSTRING_END(s
), STR_ENC_GET(s
));
5939 * str.sum(n=16) => integer
5941 * Returns a basic <em>n</em>-bit checksum of the characters in <i>str</i>,
5942 * where <em>n</em> is the optional <code>Fixnum</code> parameter, defaulting
5943 * to 16. The result is simply the sum of the binary value of each character in
5944 * <i>str</i> modulo <code>2n - 1</code>. This is not a particularly good
5949 rb_str_sum(int argc
, VALUE
*argv
, VALUE str
)
5953 char *ptr
, *p
, *pend
;
5960 rb_scan_args(argc
, argv
, "01", &vbits
);
5961 bits
= NUM2INT(vbits
);
5963 ptr
= p
= RSTRING_PTR(str
);
5964 len
= RSTRING_LEN(str
);
5966 if (bits
>= sizeof(long)*CHAR_BIT
) {
5967 VALUE sum
= INT2FIX(0);
5970 str_mod_check(str
, ptr
, len
);
5971 sum
= rb_funcall(sum
, '+', 1, INT2FIX((unsigned char)*p
));
5977 mod
= rb_funcall(INT2FIX(1), rb_intern("<<"), 1, INT2FIX(bits
));
5978 mod
= rb_funcall(mod
, '-', 1, INT2FIX(1));
5979 sum
= rb_funcall(sum
, '&', 1, mod
);
5984 unsigned long sum
= 0;
5987 str_mod_check(str
, ptr
, len
);
5988 sum
+= (unsigned char)*p
;
5992 sum
&= (((unsigned long)1)<<bits
)-1;
5994 return rb_int2inum(sum
);
5999 rb_str_justify(int argc
, VALUE
*argv
, VALUE str
, char jflag
)
6003 long width
, len
, flen
= 1, fclen
= 1;
6006 const char *f
= " ";
6011 rb_scan_args(argc
, argv
, "11", &w
, &pad
);
6012 enc
= STR_ENC_GET(str
);
6013 width
= NUM2LONG(w
);
6016 enc
= rb_enc_check(str
, pad
);
6017 f
= RSTRING_PTR(pad
);
6018 flen
= RSTRING_LEN(pad
);
6019 fclen
= str_strlen(pad
, enc
);
6020 singlebyte
= single_byte_optimizable(pad
);
6021 if (flen
== 0 || fclen
== 0) {
6022 rb_raise(rb_eArgError
, "zero width padding");
6025 len
= str_strlen(str
, enc
);
6026 if (width
< 0 || len
>= width
) return rb_str_dup(str
);
6028 llen
= (jflag
== 'l') ? 0 : ((jflag
== 'r') ? n
: n
/2);
6030 res
= rb_str_new5(str
, 0, RSTRING_LEN(str
)+n
*flen
/fclen
+2);
6031 p
= RSTRING_PTR(res
);
6037 else if (llen
> fclen
) {
6043 char *fp
= str_nth(f
, f
+flen
, llen
, enc
, singlebyte
);
6050 memcpy(p
, RSTRING_PTR(str
), RSTRING_LEN(str
));
6051 p
+=RSTRING_LEN(str
);
6057 else if (rlen
> fclen
) {
6063 char *fp
= str_nth(f
, f
+flen
, rlen
, enc
, singlebyte
);
6071 STR_SET_LEN(res
, p
-RSTRING_PTR(res
));
6072 OBJ_INFECT(res
, str
);
6073 if (!NIL_P(pad
)) OBJ_INFECT(res
, pad
);
6074 rb_enc_associate(res
, enc
);
6081 * str.ljust(integer, padstr=' ') => new_str
6083 * If <i>integer</i> is greater than the length of <i>str</i>, returns a new
6084 * <code>String</code> of length <i>integer</i> with <i>str</i> left justified
6085 * and padded with <i>padstr</i>; otherwise, returns <i>str</i>.
6087 * "hello".ljust(4) #=> "hello"
6088 * "hello".ljust(20) #=> "hello "
6089 * "hello".ljust(20, '1234') #=> "hello123412341234123"
6093 rb_str_ljust(int argc
, VALUE
*argv
, VALUE str
)
6095 return rb_str_justify(argc
, argv
, str
, 'l');
6101 * str.rjust(integer, padstr=' ') => new_str
6103 * If <i>integer</i> is greater than the length of <i>str</i>, returns a new
6104 * <code>String</code> of length <i>integer</i> with <i>str</i> right justified
6105 * and padded with <i>padstr</i>; otherwise, returns <i>str</i>.
6107 * "hello".rjust(4) #=> "hello"
6108 * "hello".rjust(20) #=> " hello"
6109 * "hello".rjust(20, '1234') #=> "123412341234123hello"
6113 rb_str_rjust(int argc
, VALUE
*argv
, VALUE str
)
6115 return rb_str_justify(argc
, argv
, str
, 'r');
6121 * str.center(integer, padstr) => new_str
6123 * If <i>integer</i> is greater than the length of <i>str</i>, returns a new
6124 * <code>String</code> of length <i>integer</i> with <i>str</i> centered and
6125 * padded with <i>padstr</i>; otherwise, returns <i>str</i>.
6127 * "hello".center(4) #=> "hello"
6128 * "hello".center(20) #=> " hello "
6129 * "hello".center(20, '123') #=> "1231231hello12312312"
6133 rb_str_center(int argc
, VALUE
*argv
, VALUE str
)
6135 return rb_str_justify(argc
, argv
, str
, 'c');
6140 * str.partition(sep) => [head, sep, tail]
6142 * Searches the string for <i>sep</i> and returns the part before
6143 * it, the <i>sep</i>, and the part after it. If <i>sep</i> is not found,
6144 * returns <i>str</i> and two empty strings.
6146 * "hello".partition("l") #=> ["he", "l", "lo"]
6147 * "hello".partition("x") #=> ["hello", "", ""]
6151 rb_str_partition(VALUE str
, VALUE sep
)
6156 if (TYPE(sep
) == T_REGEXP
) {
6157 pos
= rb_reg_search(sep
, str
, 0, 0);
6163 tmp
= rb_check_string_type(sep
);
6165 rb_raise(rb_eTypeError
, "type mismatch: %s given",
6166 rb_obj_classname(sep
));
6168 pos
= rb_str_index(str
, sep
, 0);
6172 return rb_ary_new3(3, str
, rb_str_new(0,0),rb_str_new(0,0));
6175 sep
= rb_str_subpat(str
, sep
, 0);
6176 if (pos
== 0 && RSTRING_LEN(sep
) == 0) goto failed
;
6178 return rb_ary_new3(3, rb_str_subseq(str
, 0, pos
),
6180 rb_str_subseq(str
, pos
+RSTRING_LEN(sep
),
6181 RSTRING_LEN(str
)-pos
-RSTRING_LEN(sep
)));
6186 * str.rpartition(sep) => [head, sep, tail]
6188 * Searches <i>sep</i> in the string from the end of the string, and
6189 * returns the part before it, the <i>sep</i>, and the part after it.
6190 * If <i>sep</i> is not found, returns two empty strings and
6193 * "hello".rpartition("l") #=> ["hel", "l", "o"]
6194 * "hello".rpartition("x") #=> ["", "", "hello"]
6198 rb_str_rpartition(VALUE str
, VALUE sep
)
6200 long pos
= RSTRING_LEN(str
);
6203 if (TYPE(sep
) == T_REGEXP
) {
6204 pos
= rb_reg_search(sep
, str
, pos
, 1);
6210 tmp
= rb_check_string_type(sep
);
6212 rb_raise(rb_eTypeError
, "type mismatch: %s given",
6213 rb_obj_classname(sep
));
6215 pos
= rb_str_sublen(str
, pos
);
6216 pos
= rb_str_rindex(str
, sep
, pos
);
6219 return rb_ary_new3(3, rb_str_new(0,0),rb_str_new(0,0), str
);
6222 sep
= rb_reg_nth_match(0, rb_backref_get());
6224 return rb_ary_new3(3, rb_str_substr(str
, 0, pos
),
6226 rb_str_substr(str
,pos
+str_strlen(sep
,STR_ENC_GET(sep
)),RSTRING_LEN(str
)));
6231 * str.start_with?([prefix]+) => true or false
6233 * Returns true if <i>str</i> starts with the prefix given.
6237 rb_str_start_with(int argc
, VALUE
*argv
, VALUE str
)
6241 for (i
=0; i
<argc
; i
++) {
6242 VALUE tmp
= rb_check_string_type(argv
[i
]);
6243 if (NIL_P(tmp
)) continue;
6244 rb_enc_check(str
, tmp
);
6245 if (RSTRING_LEN(str
) < RSTRING_LEN(tmp
)) continue;
6246 if (memcmp(RSTRING_PTR(str
), RSTRING_PTR(tmp
), RSTRING_LEN(tmp
)) == 0)
6254 * str.end_with?([suffix]+) => true or false
6256 * Returns true if <i>str</i> ends with the suffix given.
6260 rb_str_end_with(int argc
, VALUE
*argv
, VALUE str
)
6266 for (i
=0; i
<argc
; i
++) {
6267 VALUE tmp
= rb_check_string_type(argv
[i
]);
6268 if (NIL_P(tmp
)) continue;
6269 enc
= rb_enc_check(str
, tmp
);
6270 if (RSTRING_LEN(str
) < RSTRING_LEN(tmp
)) continue;
6271 p
= RSTRING_PTR(str
);
6272 s
= p
+ RSTRING_LEN(str
) - RSTRING_LEN(tmp
);
6273 if (rb_enc_left_char_head(p
, s
, enc
) != s
)
6275 if (memcmp(s
, RSTRING_PTR(tmp
), RSTRING_LEN(tmp
)) == 0)
6282 rb_str_setter(VALUE val
, ID id
, VALUE
*var
)
6284 if (!NIL_P(val
) && TYPE(val
) != T_STRING
) {
6285 rb_raise(rb_eTypeError
, "value of %s must be String", rb_id2name(id
));
6293 * str.force_encoding(encoding) => str
6295 * Changes the encoding to +encoding+ and returns self.
6299 rb_str_force_encoding(VALUE str
, VALUE enc
)
6301 str_modifiable(str
);
6302 rb_enc_associate(str
, rb_to_encoding(enc
));
6308 * str.valid_encoding? => true or false
6310 * Returns true for a string which encoded correctly.
6312 * "\xc2\xa1".force_encoding("UTF-8").valid_encoding? => true
6313 * "\xc2".force_encoding("UTF-8").valid_encoding? => false
6314 * "\x80".force_encoding("UTF-8").valid_encoding? => false
6318 rb_str_valid_encoding_p(VALUE str
)
6320 int cr
= rb_enc_str_coderange(str
);
6322 return cr
== ENC_CODERANGE_BROKEN
? Qfalse
: Qtrue
;
6327 * str.ascii_only? => true or false
6329 * Returns true for a string which has only ASCII characters.
6331 * "abc".force_encoding("UTF-8").ascii_only? => true
6332 * "abc\u{6666}".force_encoding("UTF-8").ascii_only? => false
6336 rb_str_is_ascii_only_p(VALUE str
)
6338 int cr
= rb_enc_str_coderange(str
);
6340 return cr
== ENC_CODERANGE_7BIT
? Qtrue
: Qfalse
;
6343 /**********************************************************************
6344 * Document-class: Symbol
6346 * <code>Symbol</code> objects represent names and some strings
6348 * interpreter. They are generated using the <code>:name</code> and
6349 * <code>:"string"</code> literals
6350 * syntax, and by the various <code>to_sym</code> methods. The same
6351 * <code>Symbol</code> object will be created for a given name or string
6352 * for the duration of a program's execution, regardless of the context
6353 * or meaning of that name. Thus if <code>Fred</code> is a constant in
6354 * one context, a method in another, and a class in a third, the
6355 * <code>Symbol</code> <code>:Fred</code> will be the same object in
6356 * all three contexts.
6370 * $f1.object_id #=> 2514190
6371 * $f2.object_id #=> 2514190
6372 * $f3.object_id #=> 2514190
6379 * sym == obj => true or false
6381 * Equality---If <i>sym</i> and <i>obj</i> are exactly the same
6382 * symbol, returns <code>true</code>. Otherwise, compares them
6387 sym_equal(VALUE sym1
, VALUE sym2
)
6389 if (sym1
== sym2
) return Qtrue
;
6396 * sym.inspect => string
6398 * Returns the representation of <i>sym</i> as a symbol literal.
6400 * :fred.inspect #=> ":fred"
6404 sym_inspect(VALUE sym
)
6407 ID id
= SYM2ID(sym
);
6410 sym
= rb_id2str(id
);
6411 enc
= STR_ENC_GET(sym
);
6412 str
= rb_enc_str_new(0, RSTRING_LEN(sym
)+1, enc
);
6413 RSTRING_PTR(str
)[0] = ':';
6414 memcpy(RSTRING_PTR(str
)+1, RSTRING_PTR(sym
), RSTRING_LEN(sym
));
6415 if (RSTRING_LEN(sym
) != strlen(RSTRING_PTR(sym
)) ||
6416 !rb_enc_symname_p(RSTRING_PTR(sym
), enc
)) {
6417 str
= rb_str_inspect(str
);
6418 strncpy(RSTRING_PTR(str
), ":\"", 2);
6426 * sym.id2name => string
6427 * sym.to_s => string
6429 * Returns the name or string corresponding to <i>sym</i>.
6431 * :fred.id2name #=> "fred"
6436 rb_sym_to_s(VALUE sym
)
6438 ID id
= SYM2ID(sym
);
6440 return str_new3(rb_cString
, rb_id2str(id
));
6449 * In general, <code>to_sym</code> returns the <code>Symbol</code> corresponding
6450 * to an object. As <i>sym</i> is already a symbol, <code>self</code> is returned
6455 sym_to_sym(VALUE sym
)
6461 sym_call(VALUE args
, VALUE sym
, int argc
, VALUE
*argv
)
6466 rb_raise(rb_eArgError
, "no receiver given");
6469 return rb_funcall3(obj
, (ID
)sym
, argc
- 1, argv
+ 1);
6476 * Returns a _Proc_ object which respond to the given method by _sym_.
6478 * (1..3).collect(&:to_s) #=> ["1", "2", "3"]
6482 sym_to_proc(VALUE sym
)
6484 return rb_proc_new(sym_call
, (VALUE
)SYM2ID(sym
));
6491 return rb_str_intern(rb_str_succ(rb_sym_to_s(sym
)));
6495 sym_cmp(VALUE sym
, VALUE other
)
6497 if (!SYMBOL_P(other
)) {
6500 return rb_str_cmp_m(rb_sym_to_s(sym
), rb_sym_to_s(other
));
6504 sym_casecmp(VALUE sym
, VALUE other
)
6506 if (!SYMBOL_P(other
)) {
6509 return rb_str_casecmp(rb_sym_to_s(sym
), rb_sym_to_s(other
));
6513 sym_match(VALUE sym
, VALUE other
)
6515 return rb_str_match(rb_sym_to_s(sym
), other
);
6519 sym_eqq(VALUE sym
, VALUE other
)
6521 if (sym
== other
) return Qtrue
;
6522 return rb_str_equal(rb_sym_to_s(sym
), other
);
6526 sym_aref(int argc
, VALUE
*argv
, VALUE sym
)
6528 return rb_str_aref_m(argc
, argv
, rb_sym_to_s(sym
));
6532 sym_length(VALUE sym
)
6534 return rb_str_length(rb_id2str(SYM2ID(sym
)));
6538 sym_empty(VALUE sym
)
6540 return rb_str_empty(rb_id2str(SYM2ID(sym
)));
6544 sym_upcase(VALUE sym
)
6546 return rb_str_intern(rb_str_upcase(rb_id2str(SYM2ID(sym
))));
6550 sym_downcase(VALUE sym
)
6552 return rb_str_intern(rb_str_downcase(rb_id2str(SYM2ID(sym
))));
6556 sym_capitalize(VALUE sym
)
6558 return rb_str_intern(rb_str_capitalize(rb_id2str(SYM2ID(sym
))));
6562 sym_swapcase(VALUE sym
)
6564 return rb_str_intern(rb_str_swapcase(rb_id2str(SYM2ID(sym
))));
6568 sym_encoding(VALUE sym
)
6570 return rb_obj_encoding(rb_id2str(SYM2ID(sym
)));
6574 rb_to_id(VALUE name
)
6579 switch (TYPE(name
)) {
6581 tmp
= rb_check_string_type(name
);
6583 rb_raise(rb_eTypeError
, "%s is not a symbol",
6584 RSTRING_PTR(rb_inspect(name
)));
6589 name
= rb_str_intern(name
);
6592 return SYM2ID(name
);
6598 * A <code>String</code> object holds and manipulates an arbitrary sequence of
6599 * bytes, typically representing characters. String objects may be created
6600 * using <code>String::new</code> or as literals.
6602 * Because of aliasing issues, users of strings should be aware of the methods
6603 * that modify the contents of a <code>String</code> object. Typically,
6604 * methods with names ending in ``!'' modify their receiver, while those
6605 * without a ``!'' return a new <code>String</code>. However, there are
6606 * exceptions, such as <code>String#[]=</code>.
6615 rb_cString
= rb_define_class("String", rb_cObject
);
6616 rb_include_module(rb_cString
, rb_mComparable
);
6617 rb_define_alloc_func(rb_cString
, str_alloc
);
6618 rb_define_singleton_method(rb_cString
, "try_convert", rb_str_s_try_convert
, 1);
6619 rb_define_method(rb_cString
, "initialize", rb_str_init
, -1);
6620 rb_define_method(rb_cString
, "initialize_copy", rb_str_replace
, 1);
6621 rb_define_method(rb_cString
, "<=>", rb_str_cmp_m
, 1);
6622 rb_define_method(rb_cString
, "==", rb_str_equal
, 1);
6623 rb_define_method(rb_cString
, "eql?", rb_str_eql
, 1);
6624 rb_define_method(rb_cString
, "hash", rb_str_hash_m
, 0);
6625 rb_define_method(rb_cString
, "casecmp", rb_str_casecmp
, 1);
6626 rb_define_method(rb_cString
, "+", rb_str_plus
, 1);
6627 rb_define_method(rb_cString
, "*", rb_str_times
, 1);
6628 rb_define_method(rb_cString
, "%", rb_str_format_m
, 1);
6629 rb_define_method(rb_cString
, "[]", rb_str_aref_m
, -1);
6630 rb_define_method(rb_cString
, "[]=", rb_str_aset_m
, -1);
6631 rb_define_method(rb_cString
, "insert", rb_str_insert
, 2);
6632 rb_define_method(rb_cString
, "length", rb_str_length
, 0);
6633 rb_define_method(rb_cString
, "size", rb_str_length
, 0);
6634 rb_define_method(rb_cString
, "bytesize", rb_str_bytesize
, 0);
6635 rb_define_method(rb_cString
, "empty?", rb_str_empty
, 0);
6636 rb_define_method(rb_cString
, "=~", rb_str_match
, 1);
6637 rb_define_method(rb_cString
, "match", rb_str_match_m
, -1);
6638 rb_define_method(rb_cString
, "succ", rb_str_succ
, 0);
6639 rb_define_method(rb_cString
, "succ!", rb_str_succ_bang
, 0);
6640 rb_define_method(rb_cString
, "next", rb_str_succ
, 0);
6641 rb_define_method(rb_cString
, "next!", rb_str_succ_bang
, 0);
6642 rb_define_method(rb_cString
, "upto", rb_str_upto
, -1);
6643 rb_define_method(rb_cString
, "index", rb_str_index_m
, -1);
6644 rb_define_method(rb_cString
, "rindex", rb_str_rindex_m
, -1);
6645 rb_define_method(rb_cString
, "replace", rb_str_replace
, 1);
6646 rb_define_method(rb_cString
, "clear", rb_str_clear
, 0);
6647 rb_define_method(rb_cString
, "chr", rb_str_chr
, 0);
6648 rb_define_method(rb_cString
, "getbyte", rb_str_getbyte
, 1);
6649 rb_define_method(rb_cString
, "setbyte", rb_str_setbyte
, 2);
6651 rb_define_method(rb_cString
, "to_i", rb_str_to_i
, -1);
6652 rb_define_method(rb_cString
, "to_f", rb_str_to_f
, 0);
6653 rb_define_method(rb_cString
, "to_s", rb_str_to_s
, 0);
6654 rb_define_method(rb_cString
, "to_str", rb_str_to_s
, 0);
6655 rb_define_method(rb_cString
, "inspect", rb_str_inspect
, 0);
6656 rb_define_method(rb_cString
, "dump", rb_str_dump
, 0);
6658 rb_define_method(rb_cString
, "upcase", rb_str_upcase
, 0);
6659 rb_define_method(rb_cString
, "downcase", rb_str_downcase
, 0);
6660 rb_define_method(rb_cString
, "capitalize", rb_str_capitalize
, 0);
6661 rb_define_method(rb_cString
, "swapcase", rb_str_swapcase
, 0);
6663 rb_define_method(rb_cString
, "upcase!", rb_str_upcase_bang
, 0);
6664 rb_define_method(rb_cString
, "downcase!", rb_str_downcase_bang
, 0);
6665 rb_define_method(rb_cString
, "capitalize!", rb_str_capitalize_bang
, 0);
6666 rb_define_method(rb_cString
, "swapcase!", rb_str_swapcase_bang
, 0);
6668 rb_define_method(rb_cString
, "hex", rb_str_hex
, 0);
6669 rb_define_method(rb_cString
, "oct", rb_str_oct
, 0);
6670 rb_define_method(rb_cString
, "split", rb_str_split_m
, -1);
6671 rb_define_method(rb_cString
, "lines", rb_str_each_line
, -1);
6672 rb_define_method(rb_cString
, "bytes", rb_str_each_byte
, 0);
6673 rb_define_method(rb_cString
, "chars", rb_str_each_char
, 0);
6674 rb_define_method(rb_cString
, "reverse", rb_str_reverse
, 0);
6675 rb_define_method(rb_cString
, "reverse!", rb_str_reverse_bang
, 0);
6676 rb_define_method(rb_cString
, "concat", rb_str_concat
, 1);
6677 rb_define_method(rb_cString
, "<<", rb_str_concat
, 1);
6678 rb_define_method(rb_cString
, "crypt", rb_str_crypt
, 1);
6679 rb_define_method(rb_cString
, "intern", rb_str_intern
, 0);
6680 rb_define_method(rb_cString
, "to_sym", rb_str_intern
, 0);
6681 rb_define_method(rb_cString
, "ord", rb_str_ord
, 0);
6683 rb_define_method(rb_cString
, "include?", rb_str_include
, 1);
6684 rb_define_method(rb_cString
, "start_with?", rb_str_start_with
, -1);
6685 rb_define_method(rb_cString
, "end_with?", rb_str_end_with
, -1);
6687 rb_define_method(rb_cString
, "scan", rb_str_scan
, 1);
6689 rb_define_method(rb_cString
, "ljust", rb_str_ljust
, -1);
6690 rb_define_method(rb_cString
, "rjust", rb_str_rjust
, -1);
6691 rb_define_method(rb_cString
, "center", rb_str_center
, -1);
6693 rb_define_method(rb_cString
, "sub", rb_str_sub
, -1);
6694 rb_define_method(rb_cString
, "gsub", rb_str_gsub
, -1);
6695 rb_define_method(rb_cString
, "chop", rb_str_chop
, 0);
6696 rb_define_method(rb_cString
, "chomp", rb_str_chomp
, -1);
6697 rb_define_method(rb_cString
, "strip", rb_str_strip
, 0);
6698 rb_define_method(rb_cString
, "lstrip", rb_str_lstrip
, 0);
6699 rb_define_method(rb_cString
, "rstrip", rb_str_rstrip
, 0);
6701 rb_define_method(rb_cString
, "sub!", rb_str_sub_bang
, -1);
6702 rb_define_method(rb_cString
, "gsub!", rb_str_gsub_bang
, -1);
6703 rb_define_method(rb_cString
, "chop!", rb_str_chop_bang
, 0);
6704 rb_define_method(rb_cString
, "chomp!", rb_str_chomp_bang
, -1);
6705 rb_define_method(rb_cString
, "strip!", rb_str_strip_bang
, 0);
6706 rb_define_method(rb_cString
, "lstrip!", rb_str_lstrip_bang
, 0);
6707 rb_define_method(rb_cString
, "rstrip!", rb_str_rstrip_bang
, 0);
6709 rb_define_method(rb_cString
, "tr", rb_str_tr
, 2);
6710 rb_define_method(rb_cString
, "tr_s", rb_str_tr_s
, 2);
6711 rb_define_method(rb_cString
, "delete", rb_str_delete
, -1);
6712 rb_define_method(rb_cString
, "squeeze", rb_str_squeeze
, -1);
6713 rb_define_method(rb_cString
, "count", rb_str_count
, -1);
6715 rb_define_method(rb_cString
, "tr!", rb_str_tr_bang
, 2);
6716 rb_define_method(rb_cString
, "tr_s!", rb_str_tr_s_bang
, 2);
6717 rb_define_method(rb_cString
, "delete!", rb_str_delete_bang
, -1);
6718 rb_define_method(rb_cString
, "squeeze!", rb_str_squeeze_bang
, -1);
6720 rb_define_method(rb_cString
, "each_line", rb_str_each_line
, -1);
6721 rb_define_method(rb_cString
, "each_byte", rb_str_each_byte
, 0);
6722 rb_define_method(rb_cString
, "each_char", rb_str_each_char
, 0);
6724 rb_define_method(rb_cString
, "sum", rb_str_sum
, -1);
6726 rb_define_method(rb_cString
, "slice", rb_str_aref_m
, -1);
6727 rb_define_method(rb_cString
, "slice!", rb_str_slice_bang
, -1);
6729 rb_define_method(rb_cString
, "partition", rb_str_partition
, 1);
6730 rb_define_method(rb_cString
, "rpartition", rb_str_rpartition
, 1);
6732 rb_define_method(rb_cString
, "encoding", rb_obj_encoding
, 0); /* in encoding.c */
6733 rb_define_method(rb_cString
, "force_encoding", rb_str_force_encoding
, 1);
6734 rb_define_method(rb_cString
, "valid_encoding?", rb_str_valid_encoding_p
, 0);
6735 rb_define_method(rb_cString
, "ascii_only?", rb_str_is_ascii_only_p
, 0);
6737 id_to_s
= rb_intern("to_s");
6740 rb_define_variable("$;", &rb_fs
);
6741 rb_define_variable("$-F", &rb_fs
);
6743 rb_cSymbol
= rb_define_class("Symbol", rb_cObject
);
6744 rb_include_module(rb_cSymbol
, rb_mComparable
);
6745 rb_undef_alloc_func(rb_cSymbol
);
6746 rb_undef_method(CLASS_OF(rb_cSymbol
), "new");
6747 rb_define_singleton_method(rb_cSymbol
, "all_symbols", rb_sym_all_symbols
, 0); /* in parse.y */
6749 rb_define_method(rb_cSymbol
, "==", sym_equal
, 1);
6750 rb_define_method(rb_cSymbol
, "inspect", sym_inspect
, 0);
6751 rb_define_method(rb_cSymbol
, "to_s", rb_sym_to_s
, 0);
6752 rb_define_method(rb_cSymbol
, "id2name", rb_sym_to_s
, 0);
6753 rb_define_method(rb_cSymbol
, "intern", sym_to_sym
, 0);
6754 rb_define_method(rb_cSymbol
, "to_sym", sym_to_sym
, 0);
6755 rb_define_method(rb_cSymbol
, "to_proc", sym_to_proc
, 0);
6756 rb_define_method(rb_cSymbol
, "succ", sym_succ
, 0);
6757 rb_define_method(rb_cSymbol
, "next", sym_succ
, 0);
6759 rb_define_method(rb_cSymbol
, "<=>", sym_cmp
, 1);
6760 rb_define_method(rb_cSymbol
, "casecmp", sym_casecmp
, 1);
6761 rb_define_method(rb_cSymbol
, "=~", sym_match
, 1);
6762 rb_define_method(rb_cSymbol
, "===", sym_eqq
, 1);
6764 rb_define_method(rb_cSymbol
, "[]", sym_aref
, -1);
6765 rb_define_method(rb_cSymbol
, "slice", sym_aref
, -1);
6766 rb_define_method(rb_cSymbol
, "length", sym_length
, 0);
6767 rb_define_method(rb_cSymbol
, "size", sym_length
, 0);
6768 rb_define_method(rb_cSymbol
, "empty?", sym_empty
, 0);
6769 rb_define_method(rb_cSymbol
, "match", sym_match
, 1);
6771 rb_define_method(rb_cSymbol
, "upcase", sym_upcase
, 0);
6772 rb_define_method(rb_cSymbol
, "downcase", sym_downcase
, 0);
6773 rb_define_method(rb_cSymbol
, "capitalize", sym_capitalize
, 0);
6774 rb_define_method(rb_cSymbol
, "swapcase", sym_swapcase
, 0);
6776 rb_define_method(rb_cSymbol
, "encoding", sym_encoding
, 0);