Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 19 additions & 10 deletions ext/jruby/org/jruby/ext/strscan/RubyStringScanner.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,15 @@ private void clearMatched() {
matched = false;
}

private void clearNamedCaptures() {
pattern = null;
}

private void clearMatchStatus() {
clearMatched();
clearNamedCaptures();
}

private void setMatched() {
matched = true;
}
Expand Down Expand Up @@ -167,15 +176,15 @@ public IRubyObject initialize_copy(ThreadContext context, IRubyObject other) {
public IRubyObject reset(ThreadContext context) {
check(context);
curr = 0;
clearMatched();
clearMatchStatus();
return this;
}

@JRubyMethod(name = "terminate")
public IRubyObject terminate(ThreadContext context) {
check(context);
curr = str.getByteList().getRealSize();
clearMatched();
clearMatchStatus();
return this;
}

Expand All @@ -198,7 +207,7 @@ public RubyString string() {
public IRubyObject set_string(ThreadContext context, IRubyObject str) {
this.str = RubyString.stringValue(str);
curr = 0;
clearMatched();
clearMatchStatus();
return str;
}

Expand Down Expand Up @@ -265,7 +274,7 @@ private IRubyObject extractBegLen(Ruby runtime, int beg, int len) {
private IRubyObject scan(ThreadContext context, IRubyObject regex, boolean succptr, boolean getstr, boolean headonly) {
final Ruby runtime = context.runtime;
check(context);
clearMatched();
clearMatchStatus();

int restLen = restLen();
if (restLen < 0) {
Expand Down Expand Up @@ -453,7 +462,7 @@ public IRubyObject getch(ThreadContext context) {

public IRubyObject getchCommon(ThreadContext context) {
check(context);
clearMatched();
clearMatchStatus();
ByteList strBL = str.getByteList();
int strSize = strBL.getRealSize();

Expand Down Expand Up @@ -481,7 +490,7 @@ public IRubyObject getchCommon(ThreadContext context) {
@JRubyMethod(name = "get_byte")
public IRubyObject get_byte(ThreadContext context) {
check(context);
clearMatched();
clearMatchStatus();
if (curr >= str.getByteList().getRealSize()) return context.nil;

prev = curr;
Expand All @@ -508,7 +517,7 @@ public IRubyObject getbyte(ThreadContext context) {
public IRubyObject scan_byte(ThreadContext context) {
Ruby runtime = context.runtime;
check(context);
clearMatched();
clearMatchStatus();
ByteList byteList = str.getByteList();
int curr = this.curr;
if (curr >= byteList.getRealSize()) return context.nil;
Expand Down Expand Up @@ -562,7 +571,7 @@ public IRubyObject peep(ThreadContext context, IRubyObject length) {
public IRubyObject scan_base10_integer(ThreadContext context) {
final Ruby runtime = context.runtime;
check(context);
clearMatched();
clearMatchStatus();

strscanMustAsciiCompat(runtime);

Expand Down Expand Up @@ -597,7 +606,7 @@ public IRubyObject scan_base10_integer(ThreadContext context) {
public IRubyObject scan_base16_integer(ThreadContext context) {
final Ruby runtime = context.runtime;
check(context);
clearMatched();
clearMatchStatus();

strscanMustAsciiCompat(runtime);

Expand Down Expand Up @@ -667,7 +676,7 @@ public IRubyObject unscan(ThreadContext context) {
}

curr = prev;
clearMatched();
clearMatchStatus();

return this;
}
Expand Down
10 changes: 7 additions & 3 deletions ext/strscan/strscan.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,13 @@ struct strscanner
};

#define MATCHED_P(s) ((s)->flags & FLAG_MATCHED)
#define MATCHED(s) (s)->flags |= FLAG_MATCHED
#define CLEAR_MATCH_STATUS(s) (s)->flags &= ~FLAG_MATCHED
#define MATCHED(s) ((s)->flags |= FLAG_MATCHED)
#define CLEAR_MATCHED(s) ((s)->flags &= ~FLAG_MATCHED)
#define CLEAR_NAMED_CAPTURES(s) ((s)->regex = Qnil)
#define CLEAR_MATCH_STATUS(s) do {\
CLEAR_MATCHED(s);\
CLEAR_NAMED_CAPTURES(s);\
} while (0)

#define S_PBEG(s) (RSTRING_PTR((s)->str))
#define S_LEN(s) (RSTRING_LEN((s)->str))
Expand Down Expand Up @@ -216,7 +221,6 @@ strscan_s_allocate(VALUE klass)
CLEAR_MATCH_STATUS(p);
onig_region_init(&(p->regs));
p->str = Qnil;
p->regex = Qnil;
return obj;
}

Expand Down
36 changes: 29 additions & 7 deletions test/strscan/test_stringscanner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ def test_peek_byte
def test_scan_byte
omit("not implemented on TruffleRuby") if RUBY_ENGINE == "truffleruby"
s = create_string_scanner('ab')
assert_equal(2, s.match?(/(?<a>ab)/)) # set named_captures
assert_equal(97, s.scan_byte)
assert_equal({}, s.named_captures)
assert_equal(98, s.scan_byte)
assert_nil(s.scan_byte)

Expand Down Expand Up @@ -176,11 +178,13 @@ def test_bol?
end

def test_string
omit("not implemented on TruffleRuby") if RUBY_ENGINE == "truffleruby"
s = create_string_scanner('test string')
assert_equal('test string', s.string)
s.scan(/test/)
s.scan(/(?<t>test)/) # set named_captures
assert_equal('test string', s.string)
s.string = 'a'
assert_equal({}, s.named_captures)
assert_equal('a', s.string)
s.scan(/a/)
s.string = 'b'
Expand Down Expand Up @@ -366,8 +370,11 @@ def test_skip_with_begenning_of_line_anchor_match
end

def test_getch
omit("not implemented on TruffleRuby") if RUBY_ENGINE == "truffleruby"
s = create_string_scanner('abcde')
assert_equal(3, s.match?(/(?<a>abc)/)) # set named_captures
assert_equal('a', s.getch)
assert_equal({}, s.named_captures)
assert_equal('b', s.getch)
assert_equal('c', s.getch)
assert_equal('d', s.getch)
Expand All @@ -385,8 +392,11 @@ def test_getch
end

def test_get_byte
omit("not implemented on TruffleRuby") if RUBY_ENGINE == "truffleruby"
s = create_string_scanner('abcde')
assert_equal(3, s.match?(/(?<a>abc)/)) # set named_captures
assert_equal('a', s.get_byte)
assert_equal({}, s.named_captures)
assert_equal('b', s.get_byte)
assert_equal('c', s.get_byte)
assert_equal('d', s.get_byte)
Expand Down Expand Up @@ -602,18 +612,22 @@ def test_post_match_string
end

def test_terminate
s = create_string_scanner('ssss')
s.getch
omit("not implemented on TruffleRuby") if RUBY_ENGINE == "truffleruby"
s = create_string_scanner('abcd')
s.scan(/(?<a>ab)/) # set named_captures
s.terminate
assert_equal({}, s.named_captures)
assert_equal(true, s.eos?)
s.terminate
assert_equal(true, s.eos?)
end

def test_reset
s = create_string_scanner('ssss')
s.getch
omit("not implemented on TruffleRuby") if RUBY_ENGINE == "truffleruby"
s = create_string_scanner('abcd')
s.scan(/(?<a>ab)/) # set named_captures
s.reset
assert_equal({}, s.named_captures)
assert_equal(0, s.pos)
s.scan(/\w+/)
s.reset
Expand Down Expand Up @@ -848,9 +862,11 @@ def test_peek
end

def test_unscan
omit("not implemented on TruffleRuby") if RUBY_ENGINE == "truffleruby"
s = create_string_scanner('test string')
assert_equal("test", s.scan(/\w+/))
assert_equal(4, s.skip(/(?<t>test)/)) # set named_captures
s.unscan
assert_equal({}, s.named_captures)
assert_equal("te", s.scan(/../))
assert_equal(nil, s.scan(/\d/))
assert_raise(ScanError) { s.unscan }
Expand Down Expand Up @@ -939,18 +955,22 @@ def test_scan_aref_repeatedly
end

def test_named_captures
omit("not implemented on TruffleRuby") if ["truffleruby"].include?(RUBY_ENGINE)
omit("not implemented on TruffleRuby") if RUBY_ENGINE == "truffleruby"
scan = StringScanner.new("foobarbaz")
assert_equal({}, scan.named_captures)
assert_equal(9, scan.match?(/(?<f>foo)(?<r>bar)(?<z>baz)/))
assert_equal({"f" => "foo", "r" => "bar", "z" => "baz"}, scan.named_captures)
assert_equal(9, scan.match?("foobarbaz"))
assert_equal({}, scan.named_captures)
end

def test_scan_integer
omit("scan_integer isn't implemented on TruffleRuby yet") if RUBY_ENGINE == "truffleruby"

s = create_string_scanner('abc')
assert_equal(3, s.match?(/(?<a>abc)/)) # set named_captures
assert_nil(s.scan_integer)
assert_equal({}, s.named_captures)
assert_equal(0, s.pos)
refute_predicate(s, :matched?)

Expand Down Expand Up @@ -1022,7 +1042,9 @@ def test_scan_integer_base_16
assert_predicate(s, :matched?)

s = create_string_scanner('abc')
assert_equal(3, s.match?(/(?<a>abc)/)) # set named_captures
assert_equal(0xabc, s.scan_integer(base: 16))
assert_equal({}, s.named_captures)
assert_equal(3, s.pos)
assert_predicate(s, :matched?)

Expand Down