public
Description: ruby lang (www.ruby-lang.org) svn mirror
Homepage: http://svn.ruby-lang.org/repos/ruby/
Clone URL: git://github.com/juretta/ruby.git
* string.c (str_gsub): should preserve last successful match
  data.  [ruby-dev:35182]

git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@17447 
b2dd03c8-39d4-4d8f-98ff-823fe69b080e
matz (author)
Thu Jun 19 10:11:55 -0700 2008
commit  fa01095368dfd0f9204ecb8945ebeb23b4382548
tree    f257335933c6260698e891a78e3657818e0ac5ca
parent  5494c042bb3c70131ba898e18d4f5e5b604617a8
...
 
 
 
 
 
1
2
3
...
1
2
3
4
5
6
7
8
0
@@ -1,3 +1,8 @@
0
+Fri Jun 20 02:11:01 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
0
+
0
+ * string.c (str_gsub): should preserve last successful match
0
+ data. [ruby-dev:35182]
0
+
0
 Fri Jun 20 01:07:28 2008 Koichi Sasada <ko1@atdot.net>
0
 
0
   * KNOWNBUGS.rb, bootstraptest/pending.rb: move a bug (?) to pending.
...
392
393
394
395
396
397
...
392
393
394
 
395
396
0
@@ -392,6 +392,5 @@ assert_equal 'ok', %q{
0
 
0
   f = Foo.new
0
   a_proc = give_it
0
- p :call_it
0
   f.call_it(&give_it())
0
 }, '[ruby-core:15711]'
...
3084
3085
3086
3087
3088
 
3089
3090
3091
...
3109
3110
3111
3112
3113
3114
 
 
3115
3116
3117
3118
3119
3120
3121
3122
3123
...
3126
3127
3128
3129
3130
3131
3132
...
3217
3218
3219
3220
 
 
3221
3222
3223
...
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
 
 
3251
3252
3253
...
3259
3260
3261
 
 
3262
3263
3264
3265
3266
3267
...
3273
3274
3275
3276
3277
3278
3279
...
3288
3289
3290
3291
3292
 
 
 
3293
3294
3295
3296
3297
3298
3299
3300
 
 
 
 
3301
3302
3303
...
3306
3307
3308
3309
 
3310
3311
3312
...
3084
3085
3086
 
 
3087
3088
3089
3090
...
3108
3109
3110
 
 
 
3111
3112
3113
3114
3115
3116
3117
 
3118
3119
3120
...
3123
3124
3125
 
3126
3127
3128
...
3213
3214
3215
 
3216
3217
3218
3219
3220
...
3238
3239
3240
 
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
...
3257
3258
3259
3260
3261
3262
3263
 
3264
3265
3266
...
3272
3273
3274
 
3275
3276
3277
...
3286
3287
3288
 
 
3289
3290
3291
3292
3293
3294
3295
 
 
 
 
3296
3297
3298
3299
3300
3301
3302
...
3305
3306
3307
 
3308
3309
3310
3311
0
@@ -3084,8 +3084,7 @@ get_pat(VALUE pat, int quote)
0
 static VALUE
0
 rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
0
 {
0
- VALUE pat, repl, match, hash = Qnil;
0
- struct re_registers *regs;
0
+ VALUE pat, repl, hash = Qnil;
0
     int iter = 0;
0
     int tainted = 0;
0
     long plen;
0
@@ -3109,15 +3108,13 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
0
     if (rb_reg_search(pat, str, 0, 0) >= 0) {
0
   rb_encoding *enc;
0
   int cr = ENC_CODERANGE(str);
0
-
0
- match = rb_backref_get();
0
- regs = RMATCH_REGS(match);
0
+ VALUE match = rb_backref_get();
0
+ struct re_registers *regs = RMATCH_REGS(match);
0
 
0
   if (iter || !NIL_P(hash)) {
0
    char *p = RSTRING_PTR(str); long len = RSTRING_LEN(str);
0
 
0
             if (iter) {
0
- rb_match_busy(match);
0
                 repl = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
0
             }
0
             else {
0
@@ -3126,7 +3123,6 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
0
             }
0
    str_mod_check(str, p, len);
0
    str_frozen_check(str);
0
- if (iter) rb_backref_set(match);
0
   }
0
   else {
0
    repl = rb_reg_regsub(repl, str, regs, pat);
0
@@ -3217,7 +3213,8 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang)
0
     VALUE pat, val, repl, match, dest, hash = Qnil;
0
     struct re_registers *regs;
0
     long beg, n;
0
- long offset, blen, slen, len;
0
+ long beg0, end0;
0
+ long offset, blen, slen, len, last;
0
     int iter = 0;
0
     char *sp, *cp;
0
     int tainted = 0;
0
@@ -3241,13 +3238,14 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang)
0
     }
0
 
0
     pat = get_pat(argv[0], 1);
0
- offset=0; n=0;
0
     beg = rb_reg_search(pat, str, 0, 0);
0
     if (beg < 0) {
0
   if (bang) return Qnil;  /* no match, no substitution */
0
   return rb_str_dup(str);
0
     }
0
 
0
+ offset = 0;
0
+ n = 0;
0
     blen = RSTRING_LEN(str) + 30; /* len + margin */
0
     dest = rb_str_buf_new(blen);
0
     sp = RSTRING_PTR(str);
0
@@ -3259,9 +3257,10 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang)
0
   n++;
0
   match = rb_backref_get();
0
   regs = RMATCH_REGS(match);
0
+ beg0 = BEG(0);
0
+ end0 = END(0);
0
   if (iter || !NIL_P(hash)) {
0
             if (iter) {
0
- rb_match_busy(match);
0
                 val = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
0
             }
0
             else {
0
@@ -3273,7 +3272,6 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang)
0
    if (val == dest) {   /* paranoid check [ruby-dev:24827] */
0
     rb_raise(rb_eRuntimeError, "block should not cheat");
0
    }
0
- if (iter) rb_backref_set(match);
0
   }
0
   else {
0
    val = rb_reg_regsub(repl, str, regs, pat);
0
@@ -3288,16 +3286,17 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang)
0
 
0
         rb_str_buf_append(dest, val);
0
 
0
- offset = END(0);
0
- if (BEG(0) == END(0)) {
0
+ last = offset;
0
+ offset = end0;
0
+ if (beg0 == end0) {
0
    /*
0
    * Always consume at least one character of the input string
0
    * in order to prevent infinite loops.
0
    */
0
- if (RSTRING_LEN(str) <= END(0)) break;
0
- len = rb_enc_mbclen(RSTRING_PTR(str)+END(0), RSTRING_END(str), str_enc);
0
- rb_enc_str_buf_cat(dest, RSTRING_PTR(str)+END(0), len, str_enc);
0
- offset = END(0) + len;
0
+ if (RSTRING_LEN(str) <= end0) break;
0
+ len = rb_enc_mbclen(RSTRING_PTR(str)+end0, RSTRING_END(str), str_enc);
0
+ rb_enc_str_buf_cat(dest, RSTRING_PTR(str)+end0, len, str_enc);
0
+ offset = end0 + len;
0
   }
0
   cp = RSTRING_PTR(str) + offset;
0
   if (offset > RSTRING_LEN(str)) break;
0
@@ -3306,7 +3305,7 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang)
0
     if (RSTRING_LEN(str) > offset) {
0
         rb_enc_str_buf_cat(dest, cp, RSTRING_LEN(str) - offset, str_enc);
0
     }
0
- rb_backref_set(match);
0
+ rb_reg_search(pat, str, last, 0);
0
     if (bang) {
0
         rb_str_shared_replace(str, dest);
0
     }

Comments

    No one has commented yet.