0001-make-StringScanner-accept-names-of-named-captures.patch

Konstantin Haase, 04/28/2013 11:46 PM

Download (3.44 KB)

View differences:

ext/strscan/strscan.c
38 38

  
39 39
    /* the regexp register; legal only when MATCHED_P(s) */
40 40
    struct re_registers regs;
41

  
42
    /* regexp used for last scan */
43
    VALUE regex;
41 44
};
42 45

  
43 46
#define MATCHED_P(s)          ((s)->flags & FLAG_MATCHED)
......
456 459
    if (S_RESTLEN(p) < 0) {
457 460
        return Qnil;
458 461
    }
462

  
463
    p->regex = regex;
459 464
    re = rb_reg_prepare_re(regex, p->str);
460 465
    tmpreg = re != RREGEXP(regex)->ptr;
461 466
    if (!tmpreg) RREGEXP(regex)->usecnt++;
......
976 981
 * Return the n-th subgroup in the most recent match.
977 982
 *
978 983
 *   s = StringScanner.new("Fri Dec 12 1975 14:39")
979
 *   s.scan(/(\w+) (\w+) (\d+) /)       # -> "Fri Dec 12 "
984
 *   s.scan(/(?<wday>\w+) (?<month>\w+) (?<day>\d+) /)       # -> "Fri Dec 12 "
980 985
 *   s[0]                               # -> "Fri Dec 12 "
981 986
 *   s[1]                               # -> "Fri"
982 987
 *   s[2]                               # -> "Dec"
983 988
 *   s[3]                               # -> "12"
989
 *   s[:wday]                           # -> "Fri"
990
 *   s[:month]                          # -> "Dec"
991
 *   s[:day]                            # -> "12"
984 992
 *   s.post_match                       # -> "1975 14:39"
985 993
 *   s.pre_match                        # -> ""
986 994
 */
987 995
static VALUE
988 996
strscan_aref(VALUE self, VALUE idx)
989 997
{
998
    const char *name, *name_end;
990 999
    struct strscanner *p;
991 1000
    long i;
992 1001

  
993 1002
    GET_SCANNER(self, p);
994 1003
    if (! MATCHED_P(p))        return Qnil;
995 1004

  
996
    i = NUM2LONG(idx);
1005
    switch (TYPE(idx)) {
1006
        case T_SYMBOL:
1007
            name = rb_id2name(SYM2ID(idx));
1008
            goto name_to_backref;
1009
            break;
1010
        case T_STRING:
1011
            name = StringValuePtr(idx);
1012
        name_to_backref:
1013
            name_end = name + strlen(name);
1014
            i = onig_name_to_backref_number(RREGEXP(p->regex)->ptr,
1015
                (const unsigned char* )name, (const unsigned char* )name_end, &(p->regs));
1016
            break;
1017
        default:
1018
            i = NUM2LONG(idx);
1019
    }
1020

  
997 1021
    if (i < 0)
998 1022
        i += p->regs.num_regs;
999 1023
    if (i < 0)                 return Qnil;
test/strscan/test_stringscanner.rb
457 457
    assert_equal true, s[2].tainted?
458 458
    assert_equal true, s[3].tainted?
459 459
    assert_equal true, s[4].tainted?
460

  
461
    s = StringScanner.new("foo bar")
462
    s.scan /(?<a>(\w+)) (?<b>(\w+))/
463
    assert_equal 'foo', s[1]
464
    assert_equal 'bar', s[2]
465
    assert_equal 'foo', s[:a]
466
    assert_equal 'bar', s[:b]
467
    assert_equal nil,   s[:c]
468
    assert_equal 'foo', s['a']
469
    assert_equal 'bar', s['b']
470
    assert_equal nil,   s['c']
460 471
  end
461 472

  
462 473
  def test_pre_match
463
-