From 16a4b46a7bd136bc4e9f5724ec2731ed8e3e1c5a Mon Sep 17 00:00:00 2001 From: ericgpks Date: Thu, 7 Jul 2022 10:43:50 +0900 Subject: [PATCH 01/19] feat: add test for named captures --- test/strscan/test_stringscanner.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/strscan/test_stringscanner.rb b/test/strscan/test_stringscanner.rb index b46b47bedd..41994b8d24 100644 --- a/test/strscan/test_stringscanner.rb +++ b/test/strscan/test_stringscanner.rb @@ -763,6 +763,13 @@ def test_fixed_anchor_false assert_equal(false, StringScanner.new("a", fixed_anchor: nil).fixed_anchor?) assert_equal(false, StringScanner.new("a", fixed_anchor: false).fixed_anchor?) end + + def test_named_captures + s = "foobarbaz" + re = /(?foo)(?bar)(?baz)/ + m = re.match s + assert_equal({"f"=>"foo", "r"=>"bar", "z"=>"baz"}, m.named_captures) + end end class TestStringScannerFixedAnchor < TestStringScanner From a3a7de380a4fc1440b535bda18baac7beeb54b1c Mon Sep 17 00:00:00 2001 From: ericgpks Date: Thu, 7 Jul 2022 11:53:55 +0900 Subject: [PATCH 02/19] fix: change test to be --- test/strscan/test_stringscanner.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/strscan/test_stringscanner.rb b/test/strscan/test_stringscanner.rb index 41994b8d24..0979450496 100644 --- a/test/strscan/test_stringscanner.rb +++ b/test/strscan/test_stringscanner.rb @@ -767,8 +767,9 @@ def test_fixed_anchor_false def test_named_captures s = "foobarbaz" re = /(?foo)(?bar)(?baz)/ - m = re.match s - assert_equal({"f"=>"foo", "r"=>"bar", "z"=>"baz"}, m.named_captures) + scan = StringScanner.new(s) + scan.match? re + assert_equal({"f"=>"foo", "r"=>"bar", "z"=>"baz"}, scan.named_captures) end end From aecf835b92d2a88047dc3bc823ae526b4d696363 Mon Sep 17 00:00:00 2001 From: ericgpks Date: Tue, 12 Jul 2022 09:51:54 +0900 Subject: [PATCH 03/19] feat: add empty method --- ext/strscan/strscan.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/ext/strscan/strscan.c b/ext/strscan/strscan.c index dd811dcfcf..c2e776e564 100644 --- a/ext/strscan/strscan.c +++ b/ext/strscan/strscan.c @@ -1458,6 +1458,17 @@ strscan_fixed_anchor_p(VALUE self) return p->fixed_anchor_p ? Qtrue : Qfalse; } +/* + * call-seq: + * scanner.named_captures -> hash + * + * + */ +static VALUE +strscan_named_captures(VALUE self) +{ +} + /* ======================================================================= Ruby Interface ======================================================================= */ @@ -1652,4 +1663,6 @@ Init_strscan(void) rb_define_method(StringScanner, "inspect", strscan_inspect, 0); rb_define_method(StringScanner, "fixed_anchor?", strscan_fixed_anchor_p, 0); + + rb_define_method(StringScanner, "named_captures", strscan_named_captures, 0); } From f9e9510c8b941598512f037d22c313577a7e142c Mon Sep 17 00:00:00 2001 From: Eriko Sugiyama <40660382+ericgpks@users.noreply.github.com> Date: Thu, 14 Jul 2022 12:41:57 +0900 Subject: [PATCH 04/19] Update ext/strscan/strscan.c return something at first Co-authored-by: Sutou Kouhei --- ext/strscan/strscan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/strscan/strscan.c b/ext/strscan/strscan.c index c2e776e564..391b298c32 100644 --- a/ext/strscan/strscan.c +++ b/ext/strscan/strscan.c @@ -1467,6 +1467,7 @@ strscan_fixed_anchor_p(VALUE self) static VALUE strscan_named_captures(VALUE self) { + return RUBY_Qnil; } /* ======================================================================= From cd5c2c5c4bdbe70b14b23a7de3ec1ff35895c4d4 Mon Sep 17 00:00:00 2001 From: ericgpks Date: Wed, 31 Aug 2022 17:12:43 +0900 Subject: [PATCH 05/19] feat: change to use onig_foreach_name --- ext/strscan/strscan.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ext/strscan/strscan.c b/ext/strscan/strscan.c index 391b298c32..b70ac3ecc6 100644 --- a/ext/strscan/strscan.c +++ b/ext/strscan/strscan.c @@ -1467,7 +1467,15 @@ strscan_fixed_anchor_p(VALUE self) static VALUE strscan_named_captures(VALUE self) { - return RUBY_Qnil; + struct strscanner *p; + VALUE pattern; + GET_SCANNER(self, p); + int i = 0; + int z = 0; + VALUE captures = rb_hash_new(); + onig_foreach_name(RREGEXP(RMATCH(RREGEXP_PTR(pattern))->regexp)->ptr, i, z); + + return captures; } /* ======================================================================= From 1e1bf0f22c14debc3f22d3b51e59f5d751512970 Mon Sep 17 00:00:00 2001 From: ericgpks Date: Tue, 13 Sep 2022 15:25:54 +0900 Subject: [PATCH 06/19] fix: prepare another method to use main and change main logic --- ext/strscan/strscan.c | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/ext/strscan/strscan.c b/ext/strscan/strscan.c index b70ac3ecc6..6f50085ec0 100644 --- a/ext/strscan/strscan.c +++ b/ext/strscan/strscan.c @@ -1458,6 +1458,31 @@ strscan_fixed_anchor_p(VALUE self) return p->fixed_anchor_p ? Qtrue : Qfalse; } +typedef struct { + VALUE self; + VALUE captures; +} named_captures_data; + +static int +named_captures_iter(const OnigUChar *name, + const OnigUChar *name_end, + int back_num, + int *back_refs, + OnigRegex regex, + void *arg) +{ + named_captures_data *data = arg; + + VALUE key = rb_str_new((const char *)name, name_end - name); + VALUE value = RUBY_Qnil; + int i; + for (i = 0; i < back_num; i++) { + value = strscan_aref(data->self, INT2NUM(back_refs[i])); + } + rb_hash_aset(data->captures, key, value); + return 0; +} + /* * call-seq: * scanner.named_captures -> hash @@ -1468,14 +1493,13 @@ static VALUE strscan_named_captures(VALUE self) { struct strscanner *p; - VALUE pattern; GET_SCANNER(self, p); - int i = 0; - int z = 0; - VALUE captures = rb_hash_new(); - onig_foreach_name(RREGEXP(RMATCH(RREGEXP_PTR(pattern))->regexp)->ptr, i, z); + named_captures_data data; + data.self = self; + data.captures = rb_hash_new(); + onig_foreach_name(RREGEXP_PTR(p->regex), named_captures_iter, &data); - return captures; + return data.captures; } /* ======================================================================= From 7380bdadb56e9fdbc0a6a65115067c3365f076ee Mon Sep 17 00:00:00 2001 From: ericgpks Date: Tue, 13 Sep 2022 16:20:37 +0900 Subject: [PATCH 07/19] feat: add document --- ext/strscan/strscan.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ext/strscan/strscan.c b/ext/strscan/strscan.c index 95a0ddd693..74968a8a79 100644 --- a/ext/strscan/strscan.c +++ b/ext/strscan/strscan.c @@ -1487,7 +1487,13 @@ named_captures_iter(const OnigUChar *name, * call-seq: * scanner.named_captures -> hash * + * Returns a hash of string variables matching the regular expression. * + * s = 'foobarbaz' + * re = /(?foo)(?bar)(?baz)/ + * scan = StringScanner.new(s) + * scan.match? re + * scan.named_captures -> {"f"=>"foo", "r"=>"bar", "z"=>"baz"} */ static VALUE strscan_named_captures(VALUE self) From 83d16552192bf196b9862d57c4bf9afb24dff3d1 Mon Sep 17 00:00:00 2001 From: Eriko Sugiyama <40660382+ericgpks@users.noreply.github.com> Date: Wed, 14 Sep 2022 18:25:43 +0900 Subject: [PATCH 08/19] Update ext/strscan/strscan.c fix: change doc style Co-authored-by: Sutou Kouhei --- ext/strscan/strscan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/strscan/strscan.c b/ext/strscan/strscan.c index 74968a8a79..bc6d68fe55 100644 --- a/ext/strscan/strscan.c +++ b/ext/strscan/strscan.c @@ -1493,7 +1493,7 @@ named_captures_iter(const OnigUChar *name, * re = /(?foo)(?bar)(?baz)/ * scan = StringScanner.new(s) * scan.match? re - * scan.named_captures -> {"f"=>"foo", "r"=>"bar", "z"=>"baz"} + * scan.named_captures # -> {"f"=>"foo", "r"=>"bar", "z"=>"baz"} */ static VALUE strscan_named_captures(VALUE self) From 617c3f9842452aee3c51ea17819a803f2cd87562 Mon Sep 17 00:00:00 2001 From: Eriko Sugiyama <40660382+ericgpks@users.noreply.github.com> Date: Wed, 14 Sep 2022 18:27:29 +0900 Subject: [PATCH 09/19] Update test/strscan/test_stringscanner.rb fix: make simplify sample code Co-authored-by: Sutou Kouhei --- test/strscan/test_stringscanner.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/strscan/test_stringscanner.rb b/test/strscan/test_stringscanner.rb index 003ec12a4a..a465e4be85 100644 --- a/test/strscan/test_stringscanner.rb +++ b/test/strscan/test_stringscanner.rb @@ -785,10 +785,8 @@ def test_scan_aref_repeatedly end def test_named_captures - s = "foobarbaz" - re = /(?foo)(?bar)(?baz)/ - scan = StringScanner.new(s) - scan.match? re + scan = StringScanner.new("foobarbaz"/) + scan.match?(/(?foo)(?bar)(?baz)) assert_equal({"f"=>"foo", "r"=>"bar", "z"=>"baz"}, scan.named_captures) end end From 83f042e503d267da46e53c1d5517bbb04dd195b9 Mon Sep 17 00:00:00 2001 From: Eriko Sugiyama <40660382+ericgpks@users.noreply.github.com> Date: Wed, 14 Sep 2022 18:27:57 +0900 Subject: [PATCH 10/19] Update ext/strscan/strscan.c fix: make simple doc sample Co-authored-by: Sutou Kouhei --- ext/strscan/strscan.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ext/strscan/strscan.c b/ext/strscan/strscan.c index bc6d68fe55..9b646ab678 100644 --- a/ext/strscan/strscan.c +++ b/ext/strscan/strscan.c @@ -1489,10 +1489,8 @@ named_captures_iter(const OnigUChar *name, * * Returns a hash of string variables matching the regular expression. * - * s = 'foobarbaz' - * re = /(?foo)(?bar)(?baz)/ - * scan = StringScanner.new(s) - * scan.match? re + * scan = StringScanner.new('foobarbaz') + * scan.match?(/(?foo)(?bar)(?baz)/) * scan.named_captures # -> {"f"=>"foo", "r"=>"bar", "z"=>"baz"} */ static VALUE From aecf8443e0b466a2c73f9815fa9e81b08e7d6720 Mon Sep 17 00:00:00 2001 From: Eriko Sugiyama <40660382+ericgpks@users.noreply.github.com> Date: Wed, 14 Sep 2022 18:28:22 +0900 Subject: [PATCH 11/19] Update test/strscan/test_stringscanner.rb fix: add space for arrow Co-authored-by: Sutou Kouhei --- test/strscan/test_stringscanner.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/strscan/test_stringscanner.rb b/test/strscan/test_stringscanner.rb index a465e4be85..b54b961e74 100644 --- a/test/strscan/test_stringscanner.rb +++ b/test/strscan/test_stringscanner.rb @@ -787,7 +787,7 @@ def test_scan_aref_repeatedly def test_named_captures scan = StringScanner.new("foobarbaz"/) scan.match?(/(?foo)(?bar)(?baz)) - assert_equal({"f"=>"foo", "r"=>"bar", "z"=>"baz"}, scan.named_captures) + assert_equal({"f" => "foo", "r" => "bar", "z" => "baz"}, scan.named_captures) end end From 30fb1b4593c973c03c3edd1d029790fd6a3a2b6f Mon Sep 17 00:00:00 2001 From: ericgpks Date: Wed, 14 Sep 2022 19:15:02 +0900 Subject: [PATCH 12/19] fix regex format in test --- test/strscan/test_stringscanner.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/strscan/test_stringscanner.rb b/test/strscan/test_stringscanner.rb index b54b961e74..23bc73741a 100644 --- a/test/strscan/test_stringscanner.rb +++ b/test/strscan/test_stringscanner.rb @@ -783,10 +783,10 @@ def test_scan_aref_repeatedly assert_equal "t", s[1] assert_equal "ring", s[2] end - + def test_named_captures - scan = StringScanner.new("foobarbaz"/) - scan.match?(/(?foo)(?bar)(?baz)) + scan = StringScanner.new("foobarbaz") + scan.match?(/(?foo)(?bar)(?baz)/) assert_equal({"f" => "foo", "r" => "bar", "z" => "baz"}, scan.named_captures) end end From f63639c85b90fb5433fd2d35ec1ce3f56df859f8 Mon Sep 17 00:00:00 2001 From: ericgpks Date: Wed, 14 Sep 2022 19:20:36 +0900 Subject: [PATCH 13/19] fix: change to use assert to check boolean --- test/strscan/test_stringscanner.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/strscan/test_stringscanner.rb b/test/strscan/test_stringscanner.rb index 23bc73741a..3037df5dfd 100644 --- a/test/strscan/test_stringscanner.rb +++ b/test/strscan/test_stringscanner.rb @@ -786,7 +786,7 @@ def test_scan_aref_repeatedly def test_named_captures scan = StringScanner.new("foobarbaz") - scan.match?(/(?foo)(?bar)(?baz)/) + assert scan.match?(/(?foo)(?bar)(?baz)/) assert_equal({"f" => "foo", "r" => "bar", "z" => "baz"}, scan.named_captures) end end From aa60ea80e99ad33428420dffb35bbec97b732582 Mon Sep 17 00:00:00 2001 From: Eriko Sugiyama <40660382+ericgpks@users.noreply.github.com> Date: Wed, 14 Sep 2022 19:23:38 +0900 Subject: [PATCH 14/19] Update test/strscan/test_stringscanner.rb fix: allow only for CRuby Co-authored-by: Sutou Kouhei --- test/strscan/test_stringscanner.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/test/strscan/test_stringscanner.rb b/test/strscan/test_stringscanner.rb index 3037df5dfd..f47cb828a5 100644 --- a/test/strscan/test_stringscanner.rb +++ b/test/strscan/test_stringscanner.rb @@ -785,6 +785,7 @@ def test_scan_aref_repeatedly end def test_named_captures + omit("not implemented on JRuby and TruffleRuby") if ["jruby", "truffleruby"].include?(RUBY_ENGINE) scan = StringScanner.new("foobarbaz") assert scan.match?(/(?foo)(?bar)(?baz)/) assert_equal({"f" => "foo", "r" => "bar", "z" => "baz"}, scan.named_captures) From a139d4d16efbf1847153bb3148d18e460a5ba67a Mon Sep 17 00:00:00 2001 From: ericgpks Date: Fri, 16 Sep 2022 18:24:26 +0900 Subject: [PATCH 15/19] fix: change test to check length of a string --- test/strscan/test_stringscanner.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/strscan/test_stringscanner.rb b/test/strscan/test_stringscanner.rb index 3037df5dfd..bf1c6e05d0 100644 --- a/test/strscan/test_stringscanner.rb +++ b/test/strscan/test_stringscanner.rb @@ -786,7 +786,8 @@ def test_scan_aref_repeatedly def test_named_captures scan = StringScanner.new("foobarbaz") - assert scan.match?(/(?foo)(?bar)(?baz)/) + re = /(?foo)(?bar)(?baz)/ + assert(scan.match?(re), "9") assert_equal({"f" => "foo", "r" => "bar", "z" => "baz"}, scan.named_captures) end end From 171a940c4d19f4d1d683f6e45bd1d2d4f85ef913 Mon Sep 17 00:00:00 2001 From: ericgpks Date: Sat, 17 Sep 2022 13:19:51 +0900 Subject: [PATCH 16/19] fix: change order to test expected and actual --- test/strscan/test_stringscanner.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/strscan/test_stringscanner.rb b/test/strscan/test_stringscanner.rb index faad9415d2..b85743d27b 100644 --- a/test/strscan/test_stringscanner.rb +++ b/test/strscan/test_stringscanner.rb @@ -788,7 +788,7 @@ def test_named_captures omit("not implemented on JRuby and TruffleRuby") if ["jruby", "truffleruby"].include?(RUBY_ENGINE) scan = StringScanner.new("foobarbaz") re = /(?foo)(?bar)(?baz)/ - assert(scan.match?(re), "9") + assert_equal(scan.rest_size ,scan.match?(re)) assert_equal({"f" => "foo", "r" => "bar", "z" => "baz"}, scan.named_captures) end end From af71c091a9705b289bb086ad0240f8fd41abcca0 Mon Sep 17 00:00:00 2001 From: ericgpks Date: Sat, 17 Sep 2022 13:31:20 +0900 Subject: [PATCH 17/19] fix: change expected value to use literal --- test/strscan/test_stringscanner.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/strscan/test_stringscanner.rb b/test/strscan/test_stringscanner.rb index b85743d27b..c5111582b5 100644 --- a/test/strscan/test_stringscanner.rb +++ b/test/strscan/test_stringscanner.rb @@ -788,7 +788,7 @@ def test_named_captures omit("not implemented on JRuby and TruffleRuby") if ["jruby", "truffleruby"].include?(RUBY_ENGINE) scan = StringScanner.new("foobarbaz") re = /(?foo)(?bar)(?baz)/ - assert_equal(scan.rest_size ,scan.match?(re)) + assert_equal(9 ,scan.match?(re)) assert_equal({"f" => "foo", "r" => "bar", "z" => "baz"}, scan.named_captures) end end From 5b11f738bab904c26d4027de298110dd55842de9 Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Sun, 18 Sep 2022 15:24:10 +0900 Subject: [PATCH 18/19] Fix style --- test/strscan/test_stringscanner.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/strscan/test_stringscanner.rb b/test/strscan/test_stringscanner.rb index c5111582b5..e1502aa804 100644 --- a/test/strscan/test_stringscanner.rb +++ b/test/strscan/test_stringscanner.rb @@ -788,7 +788,7 @@ def test_named_captures omit("not implemented on JRuby and TruffleRuby") if ["jruby", "truffleruby"].include?(RUBY_ENGINE) scan = StringScanner.new("foobarbaz") re = /(?foo)(?bar)(?baz)/ - assert_equal(9 ,scan.match?(re)) + assert_equal(9, scan.match?(re)) assert_equal({"f" => "foo", "r" => "bar", "z" => "baz"}, scan.named_captures) end end From 5def9c2b6ab24d318d22951e52dd563cb2549f8c Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Sun, 18 Sep 2022 15:25:18 +0900 Subject: [PATCH 19/19] Simplify --- test/strscan/test_stringscanner.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/strscan/test_stringscanner.rb b/test/strscan/test_stringscanner.rb index e1502aa804..cd35ebb893 100644 --- a/test/strscan/test_stringscanner.rb +++ b/test/strscan/test_stringscanner.rb @@ -787,8 +787,7 @@ def test_scan_aref_repeatedly def test_named_captures omit("not implemented on JRuby and TruffleRuby") if ["jruby", "truffleruby"].include?(RUBY_ENGINE) scan = StringScanner.new("foobarbaz") - re = /(?foo)(?bar)(?baz)/ - assert_equal(9, scan.match?(re)) + assert_equal(9, scan.match?(/(?foo)(?bar)(?baz)/)) assert_equal({"f" => "foo", "r" => "bar", "z" => "baz"}, scan.named_captures) end end