Skip to content

Commit d2502e0

Browse files
committed
Update strscan to 3.0.9
Patches: * ruby/strscan#67 * ruby/strscan#79 * ruby/strscan#81 * ruby/strscan#84
1 parent 09b6f22 commit d2502e0

File tree

1 file changed

+78
-88
lines changed

1 file changed

+78
-88
lines changed

core/src/main/java/org/jruby/ext/strscan/RubyStringScanner.java

Lines changed: 78 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
import org.jruby.ast.util.ArgsUtil;
5252
import org.jruby.common.IRubyWarnings.ID;
5353
import org.jruby.exceptions.RaiseException;
54-
import org.jruby.runtime.Block;
5554
import org.jruby.runtime.ThreadContext;
5655
import org.jruby.runtime.builtin.IRubyObject;
5756
import org.jruby.util.ByteList;
@@ -62,18 +61,21 @@
6261
import static org.jruby.runtime.Visibility.PRIVATE;
6362

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

7072
private RubyString str;
7173
private int curr = 0;
7274
private int prev = -1;
7375

74-
private Region regs;
75-
private Regex pattern;
76-
private int scannerFlags;
76+
private transient Region regs;
77+
private transient Regex pattern;
78+
private boolean matched;
7779
private boolean fixedAnchor;
7880

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

104106
private void clearMatched() {
105-
scannerFlags &= ~MATCHED_STR_SCN_F;
107+
matched = false;
106108
}
107109

108110
private void setMatched() {
109-
scannerFlags |= MATCHED_STR_SCN_F;
111+
matched = true;
110112
}
111113

112114
private boolean isMatched() {
113-
return (scannerFlags & MATCHED_STR_SCN_F) != 0;
115+
return matched;
114116
}
115117

116118
private void check(ThreadContext context) {
@@ -151,7 +153,7 @@ public IRubyObject initialize_copy(ThreadContext context, IRubyObject other) {
151153
str = otherScanner.str;
152154
curr = otherScanner.curr;
153155
prev = otherScanner.prev;
154-
scannerFlags = otherScanner.scannerFlags;
156+
matched = otherScanner.matched;
155157

156158
regs = otherScanner.regs.clone();
157159
pattern = otherScanner.pattern;
@@ -238,12 +240,13 @@ public IRubyObject charpos(ThreadContext context) {
238240
}
239241

240242
private IRubyObject extractRange(Ruby runtime, int beg, int end) {
241-
int size = str.getByteList().getRealSize();
243+
ByteList byteList = str.getByteList();
244+
int size = byteList.getRealSize();
242245

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

246-
return str.makeSharedString(runtime, beg, end - beg);
249+
return newString(runtime, beg, end - beg);
247250
}
248251

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

257-
return str.makeSharedString(runtime, beg, len);
260+
return newString(runtime, beg, len);
258261
}
259262

260-
final ThreadLocal<Matcher> currentMatcher = new ThreadLocal<>();
261-
final RubyThread.Task<RubyStringScanner, Integer> task = new RubyThread.Task<RubyStringScanner, Integer>() {
262-
@Override
263-
public Integer run(ThreadContext context, RubyStringScanner rubyStringScanner) throws InterruptedException {
264-
ByteList value = str.getByteList();
265-
return currentMatcher.get().matchInterruptible(value.begin() + curr, value.begin() + value.realSize(), Option.NONE);
266-
}
267-
268-
@Override
269-
public void wakeup(RubyThread thread, RubyStringScanner rubyStringScanner) {
270-
thread.getNativeThread().interrupt();
271-
}
272-
};
273-
274263
// MRI: strscan_do_scan
275264
private IRubyObject scan(ThreadContext context, IRubyObject regex, boolean succptr, boolean getstr, boolean headonly) {
276265
final Ruby runtime = context.runtime;
@@ -532,8 +521,9 @@ public IRubyObject peek(ThreadContext context, IRubyObject length) {
532521
}
533522

534523
ByteList value = str.getByteList();
535-
if (curr >= value.getRealSize()) return RubyString.newEmptyString(context.runtime);
536-
if (curr + len > value.getRealSize()) len = value.getRealSize() - curr;
524+
int realSize = value.getRealSize();
525+
if (curr >= realSize) return RubyString.newEmptyString(context.runtime);
526+
if (curr + len > realSize) len = realSize - curr;
537527

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

557-
RubyClass errorClass = runtime.getClass("StringScanner").getClass("Error");
547+
RubyClass errorClass = (RubyClass) runtime.getClassFromPath("StringScanner::Error");
558548
throw RaiseException.from(runtime, errorClass, "unscan failed: previous match had failed");
559549
}
560550

@@ -623,7 +613,7 @@ public IRubyObject matchedsize(ThreadContext context) {
623613
if (runtime.isVerbose()) {
624614
runtime.getWarnings().warning(ID.DEPRECATED_METHOD, "StringScanner#matchedsize is obsolete; use #matched_size instead");
625615
}
626-
return matched_size();
616+
return matched_size(context);
627617
}
628618

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

688678
ByteList value = str.getByteList();
679+
int realSize = value.getRealSize();
689680

690-
if (curr >= value.getRealSize()) {
691-
return RubyString.newEmptyString(runtime);
681+
if (curr >= realSize) {
682+
return RubyString.newEmptyString(runtime, str.getEncoding());
692683
}
693684

694-
return extractRange(runtime, curr, value.getRealSize());
685+
return extractRange(runtime, curr, realSize);
695686
}
696687

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

702693
ByteList value = str.getByteList();
694+
int realSize = value.getRealSize();
703695

704-
if (curr >= value.getRealSize()) return RubyFixnum.zero(runtime);
696+
if (curr >= realSize) return RubyFixnum.zero(runtime);
705697

706-
return RubyFixnum.newFixnum(runtime, value.getRealSize() - curr);
698+
return RubyFixnum.newFixnum(runtime, realSize - curr);
707699
}
708700

709701
@JRubyMethod(name = "restsize")
@@ -719,9 +711,15 @@ public RubyFixnum restsize(ThreadContext context) {
719711
@Override
720712
public IRubyObject inspect() {
721713
if (str == null) return inspect("(uninitialized)");
722-
if (curr >= str.getByteList().getRealSize()) return inspect("fin");
723-
if (curr == 0) return inspect(curr + "/" + str.getByteList().getRealSize() + " @ " + inspect2());
724-
return inspect(curr + "/" + str.getByteList().getRealSize() + " " + inspect1() + " @ " + inspect2());
714+
715+
ByteList byteList = str.getByteList();
716+
int realSize = byteList.getRealSize();
717+
718+
if (curr >= realSize) return inspect("fin");
719+
720+
if (curr == 0) return inspect(curr + "/" + realSize + " @ " + inspect2());
721+
722+
return inspect(curr + "/" + realSize + " " + inspect1() + " @ " + inspect2());
725723
}
726724

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

767765
private IRubyObject inspect1() {
768766
final Ruby runtime = getRuntime();
767+
769768
if (curr == 0) return RubyString.newEmptyString(runtime);
769+
770770
if (curr > INSPECT_LENGTH) {
771771
return RubyString.newStringNoCopy(runtime, DOT_BYTES).append(str.substr(runtime, curr - INSPECT_LENGTH, INSPECT_LENGTH)).inspect();
772772
}
773+
773774
return str.substr(runtime, 0, curr).inspect();
774775
}
775776

776777
private IRubyObject inspect2() {
777778
final Ruby runtime = getRuntime();
778-
if (curr >= str.getByteList().getRealSize()) return RubyString.newEmptyString(runtime);
779-
int len = str.getByteList().getRealSize() - curr;
779+
780+
ByteList byteList = str.getByteList();
781+
int realSize = byteList.getRealSize();
782+
783+
if (curr >= realSize) return RubyString.newEmptyString(runtime);
784+
785+
int len = realSize - curr;
786+
780787
if (len > INSPECT_LENGTH) {
781788
return ((RubyString) str.substr(runtime, curr, INSPECT_LENGTH)).cat(DOT_BYTES).inspect();
782789
}
790+
783791
return str.substr(runtime, curr, len).inspect();
784792
}
785793

@@ -792,7 +800,7 @@ public IRubyObject size(ThreadContext context) {
792800
@JRubyMethod(name = "captures")
793801
public IRubyObject captures(ThreadContext context) {
794802
int i, numRegs;
795-
RubyArray newAry;
803+
RubyArray<?> newAry;
796804

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

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

804812
for (i = 1; i < numRegs; i++) {
805-
IRubyObject str = extractRange(runtime,
813+
IRubyObject str;
814+
if (regs.getBeg(i) == -1) {
815+
str = context.nil;
816+
} else {
817+
str = extractRange(runtime,
806818
adjustRegisterPosition(regs.getBeg(i)),
807819
adjustRegisterPosition(regs.getEnd(i)));
820+
}
808821
newAry.push(str);
809822
}
810823

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

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

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

831-
@Deprecated
832-
public IRubyObject initialize(IRubyObject[] args, Block unusedBlock) {
833-
str = args[0].convertToString();
834-
return this;
835-
}
836-
837-
@Deprecated
838-
public IRubyObject initialize_copy(IRubyObject other) {
839-
return initialize_copy(getRuntime().getCurrentContext(), other);
840-
}
844+
@JRubyMethod(name = "values_at")
845+
public IRubyObject values_at(ThreadContext context) {
846+
if (!isMatched()) return context.nil;
841847

842-
@Deprecated
843-
public IRubyObject concat(IRubyObject obj) {
844-
return concat(getRuntime().getCurrentContext(), obj);
848+
return RubyArray.newEmptyArray(context.runtime);
845849
}
846850

847-
@Deprecated
848-
public RubyFixnum pos() {
849-
return pos(getRuntime().getCurrentContext());
850-
}
851+
@JRubyMethod(name = "values_at")
852+
public IRubyObject values_at(ThreadContext context, IRubyObject index) {
853+
if (!isMatched()) return context.nil;
851854

852-
@Deprecated
853-
public IRubyObject set_pos(IRubyObject pos) {
854-
return set_pos(getRuntime().getCurrentContext(), pos);
855+
return RubyArray.newArray(context.runtime, op_aref(context, index));
855856
}
856857

857-
@Deprecated
858-
public IRubyObject getch19(ThreadContext context) {
859-
return getch(context);
860-
}
858+
@JRubyMethod(name = "values_at")
859+
public IRubyObject values_at(ThreadContext context, IRubyObject index1, IRubyObject index2) {
860+
if (!isMatched()) return context.nil;
861861

862-
@Deprecated
863-
public IRubyObject reset() {
864-
return reset(getRuntime().getCurrentContext());
862+
return RubyArray.newArray(context.runtime, op_aref(context, index1), op_aref(context, index2));
865863
}
866864

867-
@Deprecated
868-
public IRubyObject unscan() {
869-
return unscan(getRuntime().getCurrentContext());
870-
}
865+
@JRubyMethod(name = "values_at")
866+
public IRubyObject values_at(ThreadContext context, IRubyObject index1, IRubyObject index2, IRubyObject index3) {
867+
if (!isMatched()) return context.nil;
871868

872-
@Deprecated
873-
public IRubyObject matched_size() {
874-
return matched_size(getRuntime().getCurrentContext());
869+
return RubyArray.newArray(context.runtime, op_aref(context, index1), op_aref(context, index2), op_aref(context, index3));
875870
}
876871

877-
@Deprecated
878-
public IRubyObject bol_p() {
879-
return bol_p(getRuntime().getCurrentContext());
880-
}
872+
// MRI: str_new
873+
private RubyString newString(Ruby runtime, int start, int length) {
874+
ByteList byteList = str.getByteList();
875+
int begin = byteList.begin();
881876

882-
@Deprecated
883-
public RubyFixnum rest_size() {
884-
return rest_size(getRuntime().getCurrentContext());
885-
}
877+
ByteList newByteList = new ByteList(byteList.unsafeBytes(), begin + start, begin + length, byteList.getEncoding(), true);
886878

887-
@Deprecated
888-
public IRubyObject getchCommon(ThreadContext context, boolean is1_9) {
889-
return getchCommon(context);
879+
return RubyString.newString(runtime, newByteList);
890880
}
891881

892882
/**

0 commit comments

Comments
 (0)