Skip to content

Commit

Permalink
Update strscan to 3.0.9
Browse files Browse the repository at this point in the history
  • Loading branch information
headius committed Jan 21, 2024
1 parent 09b6f22 commit d2502e0
Showing 1 changed file with 78 additions and 88 deletions.
166 changes: 78 additions & 88 deletions core/src/main/java/org/jruby/ext/strscan/RubyStringScanner.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
import org.jruby.ast.util.ArgsUtil;
import org.jruby.common.IRubyWarnings.ID;
import org.jruby.exceptions.RaiseException;
import org.jruby.runtime.Block;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
Expand All @@ -62,18 +61,21 @@
import static org.jruby.runtime.Visibility.PRIVATE;

/**
* @author kscott
* JRuby implementation of the strscan library from Ruby.
*
* Original implementation by Kelly Nawrocke. Currently a loose port of the C implementation from CRuby.
*/
@JRubyClass(name = "StringScanner")
public class RubyStringScanner extends RubyObject {
private static final long serialVersionUID = -3722138049229128675L;

private RubyString str;
private int curr = 0;
private int prev = -1;

private Region regs;
private Regex pattern;
private int scannerFlags;
private transient Region regs;
private transient Regex pattern;
private boolean matched;
private boolean fixedAnchor;

private static final int MATCHED_STR_SCN_F = 1 << 11;
Expand Down Expand Up @@ -102,15 +104,15 @@ public static RubyClass createScannerClass(final Ruby runtime) {
}

private void clearMatched() {
scannerFlags &= ~MATCHED_STR_SCN_F;
matched = false;
}

private void setMatched() {
scannerFlags |= MATCHED_STR_SCN_F;
matched = true;
}

private boolean isMatched() {
return (scannerFlags & MATCHED_STR_SCN_F) != 0;
return matched;
}

private void check(ThreadContext context) {
Expand Down Expand Up @@ -151,7 +153,7 @@ public IRubyObject initialize_copy(ThreadContext context, IRubyObject other) {
str = otherScanner.str;
curr = otherScanner.curr;
prev = otherScanner.prev;
scannerFlags = otherScanner.scannerFlags;
matched = otherScanner.matched;

regs = otherScanner.regs.clone();
pattern = otherScanner.pattern;
Expand Down Expand Up @@ -238,12 +240,13 @@ public IRubyObject charpos(ThreadContext context) {
}

private IRubyObject extractRange(Ruby runtime, int beg, int end) {
int size = str.getByteList().getRealSize();
ByteList byteList = str.getByteList();
int size = byteList.getRealSize();

if (beg > size) return runtime.getNil();
if (end > size) end = size;

return str.makeSharedString(runtime, beg, end - beg);
return newString(runtime, beg, end - beg);
}

private IRubyObject extractBegLen(Ruby runtime, int beg, int len) {
Expand All @@ -254,23 +257,9 @@ private IRubyObject extractBegLen(Ruby runtime, int beg, int len) {
if (beg > size) return runtime.getNil();
len = Math.min(len, size - beg);

return str.makeSharedString(runtime, beg, len);
return newString(runtime, beg, len);
}

final ThreadLocal<Matcher> currentMatcher = new ThreadLocal<>();
final RubyThread.Task<RubyStringScanner, Integer> task = new RubyThread.Task<RubyStringScanner, Integer>() {
@Override
public Integer run(ThreadContext context, RubyStringScanner rubyStringScanner) throws InterruptedException {
ByteList value = str.getByteList();
return currentMatcher.get().matchInterruptible(value.begin() + curr, value.begin() + value.realSize(), Option.NONE);
}

@Override
public void wakeup(RubyThread thread, RubyStringScanner rubyStringScanner) {
thread.getNativeThread().interrupt();
}
};

// MRI: strscan_do_scan
private IRubyObject scan(ThreadContext context, IRubyObject regex, boolean succptr, boolean getstr, boolean headonly) {
final Ruby runtime = context.runtime;
Expand Down Expand Up @@ -532,8 +521,9 @@ public IRubyObject peek(ThreadContext context, IRubyObject length) {
}

ByteList value = str.getByteList();
if (curr >= value.getRealSize()) return RubyString.newEmptyString(context.runtime);
if (curr + len > value.getRealSize()) len = value.getRealSize() - curr;
int realSize = value.getRealSize();
if (curr >= realSize) return RubyString.newEmptyString(context.runtime);
if (curr + len > realSize) len = realSize - curr;

return extractBegLen(context.runtime, curr, len);
}
Expand All @@ -554,7 +544,7 @@ public IRubyObject unscan(ThreadContext context) {
if (!isMatched()) {
Ruby runtime = context.runtime;

RubyClass errorClass = runtime.getClass("StringScanner").getClass("Error");
RubyClass errorClass = (RubyClass) runtime.getClassFromPath("StringScanner::Error");
throw RaiseException.from(runtime, errorClass, "unscan failed: previous match had failed");
}

Expand Down Expand Up @@ -623,7 +613,7 @@ public IRubyObject matchedsize(ThreadContext context) {
if (runtime.isVerbose()) {
runtime.getWarnings().warning(ID.DEPRECATED_METHOD, "StringScanner#matchedsize is obsolete; use #matched_size instead");
}
return matched_size();
return matched_size(context);
}

@JRubyMethod(name = "[]")
Expand Down Expand Up @@ -686,12 +676,13 @@ public IRubyObject rest(ThreadContext context) {
Ruby runtime = context.runtime;

ByteList value = str.getByteList();
int realSize = value.getRealSize();

if (curr >= value.getRealSize()) {
return RubyString.newEmptyString(runtime);
if (curr >= realSize) {
return RubyString.newEmptyString(runtime, str.getEncoding());
}

return extractRange(runtime, curr, value.getRealSize());
return extractRange(runtime, curr, realSize);
}

@JRubyMethod(name = "rest_size")
Expand All @@ -700,10 +691,11 @@ public RubyFixnum rest_size(ThreadContext context) {
Ruby runtime = context.runtime;

ByteList value = str.getByteList();
int realSize = value.getRealSize();

if (curr >= value.getRealSize()) return RubyFixnum.zero(runtime);
if (curr >= realSize) return RubyFixnum.zero(runtime);

return RubyFixnum.newFixnum(runtime, value.getRealSize() - curr);
return RubyFixnum.newFixnum(runtime, realSize - curr);
}

@JRubyMethod(name = "restsize")
Expand All @@ -719,9 +711,15 @@ public RubyFixnum restsize(ThreadContext context) {
@Override
public IRubyObject inspect() {
if (str == null) return inspect("(uninitialized)");
if (curr >= str.getByteList().getRealSize()) return inspect("fin");
if (curr == 0) return inspect(curr + "/" + str.getByteList().getRealSize() + " @ " + inspect2());
return inspect(curr + "/" + str.getByteList().getRealSize() + " " + inspect1() + " @ " + inspect2());

ByteList byteList = str.getByteList();
int realSize = byteList.getRealSize();

if (curr >= realSize) return inspect("fin");

if (curr == 0) return inspect(curr + "/" + realSize + " @ " + inspect2());

return inspect(curr + "/" + realSize + " " + inspect1() + " @ " + inspect2());
}

@JRubyMethod(name = "fixed_anchor?")
Expand Down Expand Up @@ -766,20 +764,30 @@ private IRubyObject inspect(String msg) {

private IRubyObject inspect1() {
final Ruby runtime = getRuntime();

if (curr == 0) return RubyString.newEmptyString(runtime);

if (curr > INSPECT_LENGTH) {
return RubyString.newStringNoCopy(runtime, DOT_BYTES).append(str.substr(runtime, curr - INSPECT_LENGTH, INSPECT_LENGTH)).inspect();
}

return str.substr(runtime, 0, curr).inspect();
}

private IRubyObject inspect2() {
final Ruby runtime = getRuntime();
if (curr >= str.getByteList().getRealSize()) return RubyString.newEmptyString(runtime);
int len = str.getByteList().getRealSize() - curr;

ByteList byteList = str.getByteList();
int realSize = byteList.getRealSize();

if (curr >= realSize) return RubyString.newEmptyString(runtime);

int len = realSize - curr;

if (len > INSPECT_LENGTH) {
return ((RubyString) str.substr(runtime, curr, INSPECT_LENGTH)).cat(DOT_BYTES).inspect();
}

return str.substr(runtime, curr, len).inspect();
}

Expand All @@ -792,7 +800,7 @@ public IRubyObject size(ThreadContext context) {
@JRubyMethod(name = "captures")
public IRubyObject captures(ThreadContext context) {
int i, numRegs;
RubyArray newAry;
RubyArray<?> newAry;

if (!isMatched()) return context.nil;

Expand All @@ -802,9 +810,14 @@ public IRubyObject captures(ThreadContext context) {
newAry = RubyArray.newArray(runtime, numRegs);

for (i = 1; i < numRegs; i++) {
IRubyObject str = extractRange(runtime,
IRubyObject str;
if (regs.getBeg(i) == -1) {
str = context.nil;
} else {
str = extractRange(runtime,
adjustRegisterPosition(regs.getBeg(i)),
adjustRegisterPosition(regs.getEnd(i)));
}
newAry.push(str);
}

Expand All @@ -814,7 +827,7 @@ public IRubyObject captures(ThreadContext context) {
@JRubyMethod(name = "values_at", rest = true)
public IRubyObject values_at(ThreadContext context, IRubyObject[] args) {
int i;
RubyArray newAry;
RubyArray<?> newAry;

if (!isMatched()) return context.nil;

Expand All @@ -828,65 +841,42 @@ public IRubyObject values_at(ThreadContext context, IRubyObject[] args) {
return newAry;
}

@Deprecated
public IRubyObject initialize(IRubyObject[] args, Block unusedBlock) {
str = args[0].convertToString();
return this;
}

@Deprecated
public IRubyObject initialize_copy(IRubyObject other) {
return initialize_copy(getRuntime().getCurrentContext(), other);
}
@JRubyMethod(name = "values_at")
public IRubyObject values_at(ThreadContext context) {
if (!isMatched()) return context.nil;

@Deprecated
public IRubyObject concat(IRubyObject obj) {
return concat(getRuntime().getCurrentContext(), obj);
return RubyArray.newEmptyArray(context.runtime);
}

@Deprecated
public RubyFixnum pos() {
return pos(getRuntime().getCurrentContext());
}
@JRubyMethod(name = "values_at")
public IRubyObject values_at(ThreadContext context, IRubyObject index) {
if (!isMatched()) return context.nil;

@Deprecated
public IRubyObject set_pos(IRubyObject pos) {
return set_pos(getRuntime().getCurrentContext(), pos);
return RubyArray.newArray(context.runtime, op_aref(context, index));
}

@Deprecated
public IRubyObject getch19(ThreadContext context) {
return getch(context);
}
@JRubyMethod(name = "values_at")
public IRubyObject values_at(ThreadContext context, IRubyObject index1, IRubyObject index2) {
if (!isMatched()) return context.nil;

@Deprecated
public IRubyObject reset() {
return reset(getRuntime().getCurrentContext());
return RubyArray.newArray(context.runtime, op_aref(context, index1), op_aref(context, index2));
}

@Deprecated
public IRubyObject unscan() {
return unscan(getRuntime().getCurrentContext());
}
@JRubyMethod(name = "values_at")
public IRubyObject values_at(ThreadContext context, IRubyObject index1, IRubyObject index2, IRubyObject index3) {
if (!isMatched()) return context.nil;

@Deprecated
public IRubyObject matched_size() {
return matched_size(getRuntime().getCurrentContext());
return RubyArray.newArray(context.runtime, op_aref(context, index1), op_aref(context, index2), op_aref(context, index3));
}

@Deprecated
public IRubyObject bol_p() {
return bol_p(getRuntime().getCurrentContext());
}
// MRI: str_new
private RubyString newString(Ruby runtime, int start, int length) {
ByteList byteList = str.getByteList();
int begin = byteList.begin();

@Deprecated
public RubyFixnum rest_size() {
return rest_size(getRuntime().getCurrentContext());
}
ByteList newByteList = new ByteList(byteList.unsafeBytes(), begin + start, begin + length, byteList.getEncoding(), true);

@Deprecated
public IRubyObject getchCommon(ThreadContext context, boolean is1_9) {
return getchCommon(context);
return RubyString.newString(runtime, newByteList);
}

/**
Expand Down

0 comments on commit d2502e0

Please sign in to comment.