Project

General

Profile

Bug #9680 » ruby-579.diff

srawlins (Sam Rawlins), 03/27/2014 12:09 AM

View differences:

string.c
3855 3855
    return rb_reg_regcomp(pat);
3856 3856
}
3857 3857

  
3858
static long
3859
rb_pat_search(VALUE pat, VALUE str, long pos, int str_replace)
3860
{
3861
    if (RB_TYPE_P(pat, T_STRING))
3862
	return rb_str_index(str, pat, pos);
3863
    else
3864
	return rb_reg_search0(pat, str, pos, 0, str_replace);
3865
}
3866

  
3858 3867

  
3859 3868
/*
3860 3869
 *  call-seq:
......
3875 3884
    int tainted = 0;
3876 3885
    long plen;
3877 3886
    int min_arity = rb_block_given_p() ? 1 : 2;
3887
    long beg;
3878 3888

  
3879 3889
    rb_check_arity(argc, min_arity, 2);
3880 3890
    if (argc == 1) {
......
3889 3899
	if (OBJ_TAINTED(repl)) tainted = 1;
3890 3900
    }
3891 3901

  
3892
    pat = get_pat(argv[0], 1);
3902
    if (RB_TYPE_P(argv[0], T_STRING))
3903
	pat = argv[0];
3904
    else
3905
	pat = get_pat(argv[0], 1);
3906

  
3893 3907
    str_modifiable(str);
3894
    if (rb_reg_search(pat, str, 0, 0) >= 0) {
3908
    beg = rb_pat_search(pat, str, 0, 1);
3909
    if (beg >= 0) {
3895 3910
	rb_encoding *enc;
3896 3911
	int cr = ENC_CODERANGE(str);
3897
	VALUE match = rb_backref_get();
3898
	struct re_registers *regs = RMATCH_REGS(match);
3899
	long beg0 = BEG(0);
3900
	long end0 = END(0);
3912
	long beg0, end0;
3913
	VALUE match, match0;
3914
	struct re_registers *regs;
3901 3915
	char *p, *rp;
3902 3916
	long len, rlen;
3903 3917

  
3918
	if (RB_TYPE_P(pat, T_STRING)) {
3919
	    beg0 = beg;
3920
	    end0 = beg0 + RSTRING_LEN(pat);
3921
	    match0 = pat;
3922
	}
3923
	else {
3924
	    match = rb_backref_get();
3925
	    regs = RMATCH_REGS(match);
3926
	    beg0 = BEG(0);
3927
	    end0 = END(0);
3928
	    if (!iter && NIL_P(hash)) repl = rb_reg_regsub(repl, str, regs, pat);
3929
	    if (iter) match0 = rb_reg_nth_match(0, match);
3930
	}
3931

  
3904 3932
	if (iter || !NIL_P(hash)) {
3905 3933
	    p = RSTRING_PTR(str); len = RSTRING_LEN(str);
3906 3934

  
3907 3935
            if (iter) {
3908
                repl = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
3936
                repl = rb_obj_as_string(rb_yield(match0));
3909 3937
            }
3910 3938
            else {
3911 3939
                repl = rb_hash_aref(hash, rb_str_subseq(str, beg0, end0 - beg0));
......
3914 3942
	    str_mod_check(str, p, len);
3915 3943
	    rb_check_frozen(str);
3916 3944
	}
3917
	else {
3918
	    repl = rb_reg_regsub(repl, str, regs, pat);
3919
	}
3945

  
3920 3946
        enc = rb_enc_compatible(str, repl);
3921 3947
        if (!enc) {
3922 3948
            rb_encoding *str_enc = STR_ENC_GET(str);
......
4013 4039
static VALUE
4014 4040
str_gsub(int argc, VALUE *argv, VALUE str, int bang)
4015 4041
{
4016
    VALUE pat, val, repl, match, dest, hash = Qnil;
4042
    VALUE pat, val, repl, match, match0, dest, hash = Qnil;
4017 4043
    struct re_registers *regs;
4018 4044
    long beg, n;
4019 4045
    long beg0, end0;
......
4041 4067
	rb_check_arity(argc, 1, 2);
4042 4068
    }
4043 4069

  
4044
    pat = get_pat(argv[0], 1);
4070
    if (RB_TYPE_P(argv[0], T_STRING))
4071
	pat = argv[0];
4072
    else
4073
	pat = get_pat(argv[0], 1);
4074

  
4045 4075
    str_replace = !iter && NIL_P(hash);
4046
    beg = rb_reg_search0(pat, str, 0, 0, !str_replace);
4076
    beg = rb_pat_search(pat, str, 0, !str_replace);
4047 4077
    if (beg < 0) {
4048 4078
	if (bang) return Qnil;	/* no match, no substitution */
4049 4079
	return rb_str_dup(str);
......
4062 4092

  
4063 4093
    do {
4064 4094
	n++;
4065
	match = rb_backref_get();
4066
	regs = RMATCH_REGS(match);
4067
	beg0 = BEG(0);
4068
	end0 = END(0);
4095

  
4096
	if (RB_TYPE_P(pat, T_STRING)) {
4097
	    beg0 = beg;
4098
	    end0 = beg0 + RSTRING_LEN(pat);
4099
	    if (str_replace) val = repl;
4100
	    match0 = pat;
4101
	}
4102
	else {
4103
	    match = rb_backref_get();
4104
	    regs = RMATCH_REGS(match);
4105
	    beg0 = BEG(0);
4106
	    end0 = END(0);
4107
	    if (str_replace) val = rb_reg_regsub(repl, str, regs, pat);
4108
	    if (iter) match0 = rb_reg_nth_match(0, match);
4109
	}
4110

  
4069 4111
	if (!str_replace) {
4070 4112
            if (iter) {
4071
                val = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
4113
                val = rb_obj_as_string(rb_yield(match0));
4072 4114
            }
4073 4115
            else {
4074
                val = rb_hash_aref(hash, rb_str_subseq(str, BEG(0), END(0) - BEG(0)));
4116
                val = rb_hash_aref(hash, rb_str_subseq(str, beg0, end0 - beg0));
4075 4117
                val = rb_obj_as_string(val);
4076 4118
            }
4077 4119
	    str_mod_check(str, sp, slen);
......
4079 4121
		rb_raise(rb_eRuntimeError, "block should not cheat");
4080 4122
	    }
4081 4123
	}
4082
	else {
4083
	    val = rb_reg_regsub(repl, str, regs, pat);
4084
	}
4085 4124

  
4086 4125
	if (OBJ_TAINTED(val)) tainted = 1;
4087 4126

  
......
4106 4145
	}
4107 4146
	cp = RSTRING_PTR(str) + offset;
4108 4147
	if (offset > RSTRING_LEN(str)) break;
4109
	beg = rb_reg_search0(pat, str, offset, 0, !str_replace);
4148
	beg = rb_pat_search(pat, str, offset, !str_replace);
4110 4149
    } while (beg >= 0);
4111 4150
    if (RSTRING_LEN(str) > offset) {
4112 4151
        rb_enc_str_buf_cat(dest, cp, RSTRING_LEN(str) - offset, str_enc);
4113 4152
    }
4114
    rb_reg_search(pat, str, last, 0);
4153
    rb_pat_search(pat, str, last, 1);
4115 4154
    if (bang) {
4116 4155
        rb_str_shared_replace(str, dest);
4117 4156
    }
test/ruby/test_string.rb
831 831
    c.force_encoding Encoding::US_ASCII
832 832

  
833 833
    assert_equal Encoding::UTF_8, a.gsub(/world/, c).encoding
834

  
835
    assert_equal S("aéapos&lt;"), S("aé'&lt;").gsub("'", "apos")
834 836
  end
835 837

  
836 838
  def test_gsub!