summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-09-04 23:51:44 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-09-04 23:51:44 +0000
commit605e7d4a603adcdbe1c2bde969c5f95938873ee2 (patch)
tree832d0fad8b0c7d5c4486307fa0c703e70ac512e9
parent7633eb4c51fd088ad1f85109929b0a93c4d7e3fb (diff)
* re.c (update_char_offset): position should be long.
* re.c (match_hash, match_equal): new methods. [ruby-core:24748] * re.c (reg_match_pos, rb_reg_eqq, rb_reg_s_quote): get rid of use VALUE as int. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24754 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog17
-rw-r--r--re.c49
-rw-r--r--test/ruby/test_regexp.rb8
3 files changed, 65 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index dbbb6816ef..77462f5d92 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,12 +1,11 @@
-Sat Sep 5 08:49:16 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
-
- * re.c (update_char_offset):
- * re.c (rb_reg_equal):
- * re.c (reg_match_pos):
- * re.c (rb_reg_eqq):
- * re.c (static VALUE):
- * re.c (Init_Regexp):
- [ruby-core:24748]
+Sat Sep 5 08:51:43 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * re.c (update_char_offset): position should be long.
+
+ * re.c (match_hash, match_equal): new methods. [ruby-core:24748]
+
+ * re.c (reg_match_pos, rb_reg_eqq, rb_reg_s_quote): get rid of use
+ VALUE as int.
Fri Sep 4 20:40:57 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
diff --git a/re.c b/re.c
index a6657b8c4d..a52cc1d36b 100644
--- a/re.c
+++ b/re.c
@@ -2543,6 +2543,55 @@ rb_reg_equal(VALUE re1, VALUE re2)
return Qfalse;
}
+/*
+ * call-seq:
+ * mtch.hash => integer
+ *
+ * Produce a hash based on the target string, regexp and matched
+ * positions of this matchdata.
+ */
+
+static VALUE
+match_hash(VALUE match)
+{
+ const struct re_registers *regs;
+ VALUE h;
+ unsigned long hashval = rb_hash_start(rb_str_hash(RMATCH(match)->str));
+
+ h = rb_reg_hash(RMATCH(match)->regexp);
+ rb_hash_uint(hashval, FIX2LONG(h));
+ regs = RMATCH_REGS(match);
+ hashval = rb_hash_uint(hashval, regs->num_regs);
+ hashval = rb_hash_uint(hashval, rb_memhash(regs->beg, regs->num_regs * sizeof(*regs->beg)));
+ hashval = rb_hash_uint(hashval, rb_memhash(regs->end, regs->num_regs * sizeof(*regs->end)));
+ hashval = rb_hash_end(hashval);
+ return LONG2FIX(hashval);
+}
+
+/*
+ * call-seq:
+ * mtch == mtch2 => true or false
+ *
+ * Equality---Two matchdata are equal if their target strings,
+ * patterns, and matched positions are identical.
+ */
+
+static VALUE
+match_equal(VALUE match1, VALUE match2)
+{
+ const struct re_registers *regs1, *regs2;
+ if (match1 == match2) return Qtrue;
+ if (TYPE(match2) != T_MATCH) return Qfalse;
+ if (!rb_str_equal(RMATCH(match1)->str, RMATCH(match2)->str)) return Qfalse;
+ if (!rb_reg_equal(RMATCH(match1)->regexp, RMATCH(match2)->regexp)) return Qfalse;
+ regs1 = RMATCH_REGS(match1);
+ regs2 = RMATCH_REGS(match2);
+ if (regs1->num_regs != regs2->num_regs) return Qfalse;
+ if (memcmp(regs1->beg, regs2->beg, regs1->num_regs * sizeof(*regs1->beg))) return Qfalse;
+ if (memcmp(regs1->end, regs2->end, regs1->num_regs * sizeof(*regs1->end))) return Qfalse;
+ return Qtrue;
+}
+
static VALUE
reg_operand(VALUE s, int check)
{
diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb
index a2911801bd..cdbe277ba8 100644
--- a/test/ruby/test_regexp.rb
+++ b/test/ruby/test_regexp.rb
@@ -778,4 +778,12 @@ class TestRegexp < Test::Unit::TestCase
assert_nothing_raised { 0x03ffffff.chr("utf-8").size }
assert_nothing_raised { 0x7fffffff.chr("utf-8").size }
end
+
+ def test_matchdata
+ a = "haystack".match(/hay/)
+ b = "haystack".match(/hay/)
+ assert_equal(a, b, '[ruby-core:24748]')
+ h = {a => 42}
+ assert_equal(42, h[b], '[ruby-core:24748]')
+ end
end