Bug #9680 » ruby-579.diff
| string.c | ||
|---|---|---|
|
return rb_reg_regcomp(pat);
|
||
|
}
|
||
|
static long
|
||
|
rb_pat_search(VALUE pat, VALUE str, long pos, int str_replace)
|
||
|
{
|
||
|
if (RB_TYPE_P(pat, T_STRING))
|
||
|
return rb_str_index(str, pat, pos);
|
||
|
else
|
||
|
return rb_reg_search0(pat, str, pos, 0, str_replace);
|
||
|
}
|
||
|
/*
|
||
|
* call-seq:
|
||
| ... | ... | |
|
int tainted = 0;
|
||
|
long plen;
|
||
|
int min_arity = rb_block_given_p() ? 1 : 2;
|
||
|
long beg;
|
||
|
rb_check_arity(argc, min_arity, 2);
|
||
|
if (argc == 1) {
|
||
| ... | ... | |
|
if (OBJ_TAINTED(repl)) tainted = 1;
|
||
|
}
|
||
|
pat = get_pat(argv[0], 1);
|
||
|
if (RB_TYPE_P(argv[0], T_STRING))
|
||
|
pat = argv[0];
|
||
|
else
|
||
|
pat = get_pat(argv[0], 1);
|
||
|
str_modifiable(str);
|
||
|
if (rb_reg_search(pat, str, 0, 0) >= 0) {
|
||
|
beg = rb_pat_search(pat, str, 0, 1);
|
||
|
if (beg >= 0) {
|
||
|
rb_encoding *enc;
|
||
|
int cr = ENC_CODERANGE(str);
|
||
|
VALUE match = rb_backref_get();
|
||
|
struct re_registers *regs = RMATCH_REGS(match);
|
||
|
long beg0 = BEG(0);
|
||
|
long end0 = END(0);
|
||
|
long beg0, end0;
|
||
|
VALUE match, match0;
|
||
|
struct re_registers *regs;
|
||
|
char *p, *rp;
|
||
|
long len, rlen;
|
||
|
if (RB_TYPE_P(pat, T_STRING)) {
|
||
|
beg0 = beg;
|
||
|
end0 = beg0 + RSTRING_LEN(pat);
|
||
|
match0 = pat;
|
||
|
}
|
||
|
else {
|
||
|
match = rb_backref_get();
|
||
|
regs = RMATCH_REGS(match);
|
||
|
beg0 = BEG(0);
|
||
|
end0 = END(0);
|
||
|
if (!iter && NIL_P(hash)) repl = rb_reg_regsub(repl, str, regs, pat);
|
||
|
if (iter) match0 = rb_reg_nth_match(0, match);
|
||
|
}
|
||
|
if (iter || !NIL_P(hash)) {
|
||
|
p = RSTRING_PTR(str); len = RSTRING_LEN(str);
|
||
|
if (iter) {
|
||
|
repl = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
|
||
|
repl = rb_obj_as_string(rb_yield(match0));
|
||
|
}
|
||
|
else {
|
||
|
repl = rb_hash_aref(hash, rb_str_subseq(str, beg0, end0 - beg0));
|
||
| ... | ... | |
|
str_mod_check(str, p, len);
|
||
|
rb_check_frozen(str);
|
||
|
}
|
||
|
else {
|
||
|
repl = rb_reg_regsub(repl, str, regs, pat);
|
||
|
}
|
||
|
enc = rb_enc_compatible(str, repl);
|
||
|
if (!enc) {
|
||
|
rb_encoding *str_enc = STR_ENC_GET(str);
|
||
| ... | ... | |
|
static VALUE
|
||
|
str_gsub(int argc, VALUE *argv, VALUE str, int bang)
|
||
|
{
|
||
|
VALUE pat, val, repl, match, dest, hash = Qnil;
|
||
|
VALUE pat, val, repl, match, match0, dest, hash = Qnil;
|
||
|
struct re_registers *regs;
|
||
|
long beg, n;
|
||
|
long beg0, end0;
|
||
| ... | ... | |
|
rb_check_arity(argc, 1, 2);
|
||
|
}
|
||
|
pat = get_pat(argv[0], 1);
|
||
|
if (RB_TYPE_P(argv[0], T_STRING))
|
||
|
pat = argv[0];
|
||
|
else
|
||
|
pat = get_pat(argv[0], 1);
|
||
|
str_replace = !iter && NIL_P(hash);
|
||
|
beg = rb_reg_search0(pat, str, 0, 0, !str_replace);
|
||
|
beg = rb_pat_search(pat, str, 0, !str_replace);
|
||
|
if (beg < 0) {
|
||
|
if (bang) return Qnil; /* no match, no substitution */
|
||
|
return rb_str_dup(str);
|
||
| ... | ... | |
|
do {
|
||
|
n++;
|
||
|
match = rb_backref_get();
|
||
|
regs = RMATCH_REGS(match);
|
||
|
beg0 = BEG(0);
|
||
|
end0 = END(0);
|
||
|
if (RB_TYPE_P(pat, T_STRING)) {
|
||
|
beg0 = beg;
|
||
|
end0 = beg0 + RSTRING_LEN(pat);
|
||
|
if (str_replace) val = repl;
|
||
|
match0 = pat;
|
||
|
}
|
||
|
else {
|
||
|
match = rb_backref_get();
|
||
|
regs = RMATCH_REGS(match);
|
||
|
beg0 = BEG(0);
|
||
|
end0 = END(0);
|
||
|
if (str_replace) val = rb_reg_regsub(repl, str, regs, pat);
|
||
|
if (iter) match0 = rb_reg_nth_match(0, match);
|
||
|
}
|
||
|
if (!str_replace) {
|
||
|
if (iter) {
|
||
|
val = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
|
||
|
val = rb_obj_as_string(rb_yield(match0));
|
||
|
}
|
||
|
else {
|
||
|
val = rb_hash_aref(hash, rb_str_subseq(str, BEG(0), END(0) - BEG(0)));
|
||
|
val = rb_hash_aref(hash, rb_str_subseq(str, beg0, end0 - beg0));
|
||
|
val = rb_obj_as_string(val);
|
||
|
}
|
||
|
str_mod_check(str, sp, slen);
|
||
| ... | ... | |
|
rb_raise(rb_eRuntimeError, "block should not cheat");
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
val = rb_reg_regsub(repl, str, regs, pat);
|
||
|
}
|
||
|
if (OBJ_TAINTED(val)) tainted = 1;
|
||
| ... | ... | |
|
}
|
||
|
cp = RSTRING_PTR(str) + offset;
|
||
|
if (offset > RSTRING_LEN(str)) break;
|
||
|
beg = rb_reg_search0(pat, str, offset, 0, !str_replace);
|
||
|
beg = rb_pat_search(pat, str, offset, !str_replace);
|
||
|
} while (beg >= 0);
|
||
|
if (RSTRING_LEN(str) > offset) {
|
||
|
rb_enc_str_buf_cat(dest, cp, RSTRING_LEN(str) - offset, str_enc);
|
||
|
}
|
||
|
rb_reg_search(pat, str, last, 0);
|
||
|
rb_pat_search(pat, str, last, 1);
|
||
|
if (bang) {
|
||
|
rb_str_shared_replace(str, dest);
|
||
|
}
|
||
| test/ruby/test_string.rb | ||
|---|---|---|
|
c.force_encoding Encoding::US_ASCII
|
||
|
assert_equal Encoding::UTF_8, a.gsub(/world/, c).encoding
|
||
|
assert_equal S("aéapos<"), S("aé'<").gsub("'", "apos")
|
||
|
end
|
||
|
def test_gsub!
|
||