summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--ext/strscan/strscan.c23
-rw-r--r--test/strscan/test_stringscanner.rb11
3 files changed, 32 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index b5ad689456..892aec8a88 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Fri May 24 16:31:23 2013 NARUSE, Yui <naruse@ruby-lang.org>
+
+ * ext/strscan/strscan.c (strscan_aref): raise error if given
+ name reference is not found.
+
Fri May 24 15:48:18 2013 Koichi Sasada <ko1@atdot.net>
* gc.c (after_gc_sweep, garbage_collect_body): do major GC (full GC)
diff --git a/ext/strscan/strscan.c b/ext/strscan/strscan.c
index 4623994612..983debe071 100644
--- a/ext/strscan/strscan.c
+++ b/ext/strscan/strscan.c
@@ -975,6 +975,25 @@ strscan_matched_size(VALUE self)
return INT2NUM(p->regs.end[0] - p->regs.beg[0]);
}
+static int
+name_to_backref_number(struct re_registers *regs, VALUE regexp, const char* name, const char* name_end)
+{
+ int num;
+
+ num = onig_name_to_backref_number(RREGEXP(regexp)->ptr,
+ (const unsigned char* )name, (const unsigned char* )name_end, regs);
+ if (num >= 1) {
+ return num;
+ }
+ else {
+ VALUE s = rb_str_new(name, (long )(name_end - name));
+ rb_raise(rb_eIndexError, "undefined group name reference: %s",
+ StringValuePtr(s));
+ }
+
+ UNREACHABLE;
+}
+
/*
* call-seq: [](n)
*
@@ -1019,9 +1038,7 @@ strscan_aref(VALUE self, VALUE idx)
case T_STRING:
name = StringValuePtr(idx);
name_to_backref:
- name_end = name + strlen(name);
- i = onig_name_to_backref_number(RREGEXP(p->regex)->ptr,
- (const unsigned char* )name, (const unsigned char* )name_end, &(p->regs));
+ i = name_to_backref_number(&(p->regs), p->regex, name, name + strlen(name));
break;
default:
i = NUM2LONG(idx);
diff --git a/test/strscan/test_stringscanner.rb b/test/strscan/test_stringscanner.rb
index 7f2e5c1ccd..be548d1938 100644
--- a/test/strscan/test_stringscanner.rb
+++ b/test/strscan/test_stringscanner.rb
@@ -402,6 +402,8 @@ class TestStringScanner < Test::Unit::TestCase
assert_equal 'stra', s[-1]
assert_equal 'stra', s[0]
assert_nil s[1]
+ assert_raise(IndexError) { s[:c] }
+ assert_raise(IndexError) { s['c'] }
assert_equal false, s[-1].tainted?
assert_equal false, s[0].tainted?
@@ -458,16 +460,17 @@ class TestStringScanner < Test::Unit::TestCase
assert_equal true, s[3].tainted?
assert_equal true, s[4].tainted?
- s = StringScanner.new("foo bar")
- s.scan /(?<a>(\w+)) (?<b>(\w+))/
+ s = StringScanner.new("foo bar baz")
+ s.scan /(?<a>\w+) (?<b>\w+) (\w+)/
assert_equal 'foo', s[1]
assert_equal 'bar', s[2]
+ assert_nil s[3]
assert_equal 'foo', s[:a]
assert_equal 'bar', s[:b]
- assert_equal nil, s[:c]
+ assert_raise(IndexError) { s[:c] }
assert_equal 'foo', s['a']
assert_equal 'bar', s['b']
- assert_equal nil, s['c']
+ assert_raise(IndexError) { s['c'] }
end
def test_pre_match