Skip to content

Commit a7c63d3

Browse files
committed
[GR-18163] Accept string pattern for StringScanner headonly searches.
PullRequest: truffleruby/2880
2 parents c2c992c + 81cd805 commit a7c63d3

File tree

5 files changed

+30
-4
lines changed

5 files changed

+30
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Compatibility:
3434
* Add support for tracing allocations from C functions (#2403, @chrisseaton).
3535
* Implement `rb_str_catf`.
3636
* Search the executable in the passed env `PATH` for subprocesses (#2419).
37+
* Accept a string as the pattern argument to `StringScanner#scan` and `StringScanner#check` (#2423).
3738

3839
Performance:
3940

lib/truffle/strscan.rb

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,11 @@ def peep(len)
309309
end
310310

311311
private def scan_check_args(pattern, headonly)
312-
unless pattern.kind_of? Regexp
312+
case pattern
313+
when String
314+
raise TypeError, "bad pattern argument: #{pattern.inspect}" unless headonly
315+
when Regexp
316+
else
313317
raise TypeError, "bad pattern argument: #{pattern.inspect}"
314318
end
315319
raise ArgumentError, 'uninitialized StringScanner object' unless @string
@@ -321,7 +325,11 @@ def peep(len)
321325
private def scan_internal(pattern, advance_pos, getstr, headonly)
322326
scan_check_args(pattern, headonly)
323327

324-
md = Truffle::RegexpOperations.match_in_region pattern, @string, pos, @string.bytesize, headonly, pos
328+
if Primitive.object_kind_of?(pattern, String)
329+
md = scan_internal_string_pattern(pattern, headonly)
330+
else
331+
md = Truffle::RegexpOperations.match_in_region pattern, @string, pos, @string.bytesize, headonly, pos
332+
end
325333
if md
326334
Primitive.matchdata_fixup_positions(md, pos)
327335
@match = md
@@ -331,6 +339,14 @@ def peep(len)
331339
end
332340
end
333341

342+
private def scan_internal_string_pattern(pattern, headonly)
343+
if @string.byteslice(pos..).start_with?(pattern)
344+
Primitive.matchdata_create_single_group(pattern, @string.dup, 0, pattern.bytesize)
345+
else
346+
nil
347+
end
348+
end
349+
334350
private def scan_internal_set_pos_and_str(advance_pos, getstr, md)
335351
fin = Primitive.match_data_byte_end(md, 0)
336352

spec/ruby/library/stringscanner/check_spec.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,15 @@
1313
@s.check(/is/).should == nil
1414
@s.matched.should == nil
1515
end
16+
17+
ruby_version_is "2.7" do
18+
it "treats String as the pattern itself" do
19+
@s.check("This").should == "This"
20+
@s.matched.should == "This"
21+
@s.pos.should == 0
22+
@s.check(/is/).should == nil
23+
@s.matched.should == nil
24+
end
25+
end
26+
1627
end
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
fails:StringScanner#scan treats String as the pattern itself
21
fails:StringScanner#scan with fixed_anchor: true treats ^ as matching from the beginning of line
32
fails:StringScanner#scan with fixed_anchor: true treats \A as matching from the beginning of string

test/mri/excludes/TestStringScanner.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,3 @@
99
exclude :test_matched, "needs investigation"
1010
exclude :test_post_match, "needs investigation"
1111
exclude :test_pre_match, "needs investigation"
12-
exclude :test_scan_string, "needs investigation"

0 commit comments

Comments
 (0)