[jruby-joni] 02/09: fix for jruby/jruby#4077
Hideki Yamane
henrich at moszumanska.debian.org
Sun Aug 21 06:26:13 UTC 2016
This is an automated email from the git hooks/post-receive script.
henrich pushed a commit to branch debian/sid
in repository jruby-joni.
commit e0323eea7ae6c403d5d384520081731f9af283f4
Author: Marcin Mielzynski <lopx at gazeta.pl>
Date: Wed Aug 17 02:54:15 2016 +0200
fix for jruby/jruby#4077
---
src/org/joni/Analyser.java | 21 +++--
src/org/joni/Config.java | 2 +
src/org/joni/Lexer.java | 168 ++++++++++++++++++++++----------------
src/org/joni/Parser.java | 18 +++-
src/org/joni/ScanEnvironment.java | 7 +-
src/org/joni/StackMachine.java | 25 +++---
src/org/joni/Token.java | 7 ++
7 files changed, 151 insertions(+), 97 deletions(-)
diff --git a/src/org/joni/Analyser.java b/src/org/joni/Analyser.java
index 6a4e418..ddb0f5c 100644
--- a/src/org/joni/Analyser.java
+++ b/src/org/joni/Analyser.java
@@ -1277,7 +1277,6 @@ final class Analyser extends Parser {
case NodeType.CALL:
CallNode cn = (CallNode)node;
-
if (cn.groupNum != 0) {
int gNum = cn.groupNum;
@@ -1290,15 +1289,19 @@ final class Analyser extends Parser {
setCallAttr(cn);
} else {
if (Config.USE_NAMED_GROUP) {
- NameEntry ne = regex.nameToGroupNumbers(cn.name, cn.nameP, cn.nameEnd);
-
- if (ne == null) {
- newValueException(ERR_UNDEFINED_NAME_REFERENCE, cn.nameP, cn.nameEnd);
- } else if (ne.backNum > 1) {
- newValueException(ERR_MULTIPLEX_DEFINITION_NAME_CALL, cn.nameP, cn.nameEnd);
- } else {
- cn.groupNum = ne.backRef1; // ne.backNum == 1 ? ne.backRef1 : ne.backRefs[0]; // ??? need to check ?
+ if (Config.USE_PERL_SUBEXP_CALL && cn.nameP == cn.nameEnd) {
setCallAttr(cn);
+ } else {
+ NameEntry ne = regex.nameToGroupNumbers(cn.name, cn.nameP, cn.nameEnd);
+
+ if (ne == null) {
+ newValueException(ERR_UNDEFINED_NAME_REFERENCE, cn.nameP, cn.nameEnd);
+ } else if (ne.backNum > 1) {
+ newValueException(ERR_MULTIPLEX_DEFINITION_NAME_CALL, cn.nameP, cn.nameEnd);
+ } else {
+ cn.groupNum = ne.backRef1; // ne.backNum == 1 ? ne.backRef1 : ne.backRefs[0]; // ??? need to check ?
+ setCallAttr(cn);
+ }
}
}
}
diff --git a/src/org/joni/Config.java b/src/org/joni/Config.java
index 3467966..30f3871 100644
--- a/src/org/joni/Config.java
+++ b/src/org/joni/Config.java
@@ -23,9 +23,11 @@ import java.io.PrintStream;
public interface Config extends org.jcodings.Config {
final int CHAR_TABLE_SIZE = 256;
+ final int SCANENV_MEMNODES_SIZE = 8;
final boolean USE_NAMED_GROUP = true;
final boolean USE_SUBEXP_CALL = true;
+ final boolean USE_PERL_SUBEXP_CALL = true;
final boolean USE_BACKREF_WITH_LEVEL = true; /* \k<name+n>, \k<name-n> */
final boolean USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT = true; /* /(?:()|())*\2/ */
diff --git a/src/org/joni/Lexer.java b/src/org/joni/Lexer.java
index c1feb68..812369f 100644
--- a/src/org/joni/Lexer.java
+++ b/src/org/joni/Lexer.java
@@ -851,94 +851,122 @@ class Lexer extends ScannerSupport {
}
}
- private void fetchTokenFor_namedBackref() {
- if (syntax.op2EscKNamedBackref()) {
- if (left()) {
+ private void fetchTokenFor_NamedBackref() {
+ if (Config.USE_NAMED_GROUP) {
+ if (syntax.op2EscKNamedBackref() && left()) {
fetch();
if (c =='<' || c == '\'') {
- int last = p;
- int backNum;
- if (Config.USE_BACKREF_WITH_LEVEL) {
- Ptr rbackNum = new Ptr();
- Ptr rlevel = new Ptr();
- token.setBackrefExistLevel(fetchNameWithLevel(c, rbackNum, rlevel));
- token.setBackrefLevel(rlevel.p);
- backNum = rbackNum.p;
- } else {
- backNum = fetchName(c, true);
- } // USE_BACKREF_AT_LEVEL
- int nameEnd = value; // set by fetchNameWithLevel/fetchName
-
- if (backNum != 0) {
- if (backNum < 0) {
- backNum = backrefRelToAbs(backNum);
- if (backNum <= 0) newValueException(ERR_INVALID_BACKREF);
- }
-
- if (syntax.strictCheckBackref() && (backNum > env.numMem || env.memNodes == null)) {
- newValueException(ERR_INVALID_BACKREF);
- }
- token.type = TokenType.BACKREF;
- token.setBackrefByName(false);
- token.setBackrefNum(1);
- token.setBackrefRef1(backNum);
- } else {
- NameEntry e = env.reg.nameToGroupNumbers(bytes, last, nameEnd);
- if (e == null) newValueException(ERR_UNDEFINED_NAME_REFERENCE, last, nameEnd);
-
- if (syntax.strictCheckBackref()) {
- if (e.backNum == 1) {
- if (e.backRef1 > env.numMem ||
- env.memNodes == null ||
- env.memNodes[e.backRef1] == null) newValueException(ERR_INVALID_BACKREF);
- } else {
- for (int i=0; i<e.backNum; i++) {
- if (e.backRefs[i] > env.numMem ||
- env.memNodes == null ||
- env.memNodes[e.backRefs[i]] == null) newValueException(ERR_INVALID_BACKREF);
- }
- }
- }
-
- token.type = TokenType.BACKREF;
- token.setBackrefByName(true);
-
- if (e.backNum == 1) {
- token.setBackrefNum(1);
- token.setBackrefRef1(e.backRef1);
- } else {
- token.setBackrefNum(e.backNum);
- token.setBackrefRefs(e.backRefs);
- }
- }
+ fetchNamedBackrefToken();
} else {
unfetch();
syntaxWarn(Warnings.INVALID_BACKREFERENCE);
}
- } else {
- syntaxWarn(Warnings.INVALID_BACKREFERENCE);
}
}
}
private void fetchTokenFor_subexpCall() {
- if (syntax.op2EscGSubexpCall()) {
- if (left()) {
+ if (Config.USE_NAMED_GROUP) {
+ if (syntax.op2EscGBraceBackref() && left()) {
+ fetch();
+ if (c == '{') {
+ fetchNamedBackrefToken();
+ } else {
+ unfetch();
+ }
+ }
+ }
+ if (Config.USE_SUBEXP_CALL) {
+ if (syntax.op2EscGSubexpCall() && left()) {
fetch();
if (c == '<' || c == '\'') {
- int last = p;
- int gNum = fetchName(c, true);
- int nameEnd = value;
+ int gNum = -1;
+ boolean rel = false;
+ int cnext = peek();
+ int nameEnd = 0;
+ if (cnext == '0') {
+ inc();
+ if (peekIs(nameEndCodePoint(c))) { /* \g<0>, \g'0' */
+ inc();
+ nameEnd = p;
+ gNum = 0;
+ }
+ } else if (cnext == '+') {
+ inc();
+ rel = true;
+ }
+ int prev = p;
+ if (gNum < 0) {
+ gNum = fetchName(c, true);
+ nameEnd = value;
+ }
token.type = TokenType.CALL;
- token.setCallNameP(last);
+ token.setCallNameP(prev);
token.setCallNameEnd(nameEnd);
token.setCallGNum(gNum);
+ token.setCallRel(rel);
} else {
- unfetch();
syntaxWarn(Warnings.INVALID_SUBEXP_CALL);
+ unfetch();
}
+ }
+ }
+ }
+
+ private void fetchNamedBackrefToken() {
+ int last = p;
+ int backNum;
+ if (Config.USE_BACKREF_WITH_LEVEL) {
+ Ptr rbackNum = new Ptr();
+ Ptr rlevel = new Ptr();
+ token.setBackrefExistLevel(fetchNameWithLevel(c, rbackNum, rlevel));
+ token.setBackrefLevel(rlevel.p);
+ backNum = rbackNum.p;
+ } else {
+ backNum = fetchName(c, true);
+ } // USE_BACKREF_AT_LEVEL
+ int nameEnd = value; // set by fetchNameWithLevel/fetchName
+
+ if (backNum != 0) {
+ if (backNum < 0) {
+ backNum = backrefRelToAbs(backNum);
+ if (backNum <= 0) newValueException(ERR_INVALID_BACKREF);
+ }
+
+ if (syntax.strictCheckBackref() && (backNum > env.numMem || env.memNodes == null)) {
+ newValueException(ERR_INVALID_BACKREF);
+ }
+ token.type = TokenType.BACKREF;
+ token.setBackrefByName(false);
+ token.setBackrefNum(1);
+ token.setBackrefRef1(backNum);
+ } else {
+ NameEntry e = env.reg.nameToGroupNumbers(bytes, last, nameEnd);
+ if (e == null) newValueException(ERR_UNDEFINED_NAME_REFERENCE, last, nameEnd);
+
+ if (syntax.strictCheckBackref()) {
+ if (e.backNum == 1) {
+ if (e.backRef1 > env.numMem ||
+ env.memNodes == null ||
+ env.memNodes[e.backRef1] == null) newValueException(ERR_INVALID_BACKREF);
+ } else {
+ for (int i=0; i<e.backNum; i++) {
+ if (e.backRefs[i] > env.numMem ||
+ env.memNodes == null ||
+ env.memNodes[e.backRefs[i]] == null) newValueException(ERR_INVALID_BACKREF);
+ }
+ }
+ }
+
+ token.type = TokenType.BACKREF;
+ token.setBackrefByName(true);
+
+ if (e.backNum == 1) {
+ token.setBackrefNum(1);
+ token.setBackrefRef1(e.backRef1);
} else {
- syntaxWarn(Warnings.INVALID_SUBEXP_CALL);
+ token.setBackrefNum(e.backNum);
+ token.setBackrefRefs(e.backRefs);
}
}
}
@@ -1110,10 +1138,10 @@ class Lexer extends ScannerSupport {
fetchTokenFor_zero();
break;
case 'k':
- if (Config.USE_NAMED_GROUP) fetchTokenFor_namedBackref();
+ fetchTokenFor_NamedBackref();
break;
case 'g':
- if (Config.USE_SUBEXP_CALL) fetchTokenFor_subexpCall();
+ fetchTokenFor_subexpCall();
break;
case 'Q':
if (syntax.op2EscCapitalQQuote()) token.type = TokenType.QUOTE_OPEN;
diff --git a/src/org/joni/Parser.java b/src/org/joni/Parser.java
index e480afd..81f635c 100644
--- a/src/org/joni/Parser.java
+++ b/src/org/joni/Parser.java
@@ -950,8 +950,8 @@ class Parser extends Lexer {
case CALL:
if (Config.USE_SUBEXP_CALL) {
int gNum = token.getCallGNum();
-
- if (gNum < 0) {
+ if (gNum < 0 || token.getCallRel()) {
+ if (gNum > 0) gNum--;
gNum = backrefRelToAbs(gNum);
if (gNum <= 0) newValueException(ERR_INVALID_BACKREF);
}
@@ -1163,6 +1163,18 @@ class Parser extends Lexer {
private Node parseRegexp() {
fetchToken();
- return parseSubExp(TokenType.EOT);
+ Node top = parseSubExp(TokenType.EOT);
+ if (Config.USE_SUBEXP_CALL) {
+ if (env.numCall > 0) {
+ /* Capture the pattern itself. It is used for (?R), (?0) and \g<0>. */
+ EncloseNode np = new EncloseNode(env.option, false);
+ np.regNum = 0;
+ np.setTarget(top);
+ if (env.memNodes == null) env.memNodes = new Node[Config.SCANENV_MEMNODES_SIZE];
+ env.memNodes[0] = np;
+ top = np;
+ }
+ }
+ return top;
}
}
diff --git a/src/org/joni/ScanEnvironment.java b/src/org/joni/ScanEnvironment.java
index 0dbce24..4c68a04 100644
--- a/src/org/joni/ScanEnvironment.java
+++ b/src/org/joni/ScanEnvironment.java
@@ -27,9 +27,6 @@ import org.joni.exception.ErrorMessages;
import org.joni.exception.InternalException;
public final class ScanEnvironment {
-
- private static final int SCANENV_MEMNODES_SIZE = 8;
-
int option;
final int caseFoldFlag;
final public Encoding enc;
@@ -90,7 +87,7 @@ public final class ScanEnvironment {
public int addMemEntry() {
if (numMem++ == 0) {
- memNodes = new Node[SCANENV_MEMNODES_SIZE];
+ memNodes = new Node[Config.SCANENV_MEMNODES_SIZE];
} else if (numMem >= memNodes.length) {
Node[]tmp = new Node[memNodes.length << 1];
System.arraycopy(memNodes, 0, tmp, 0, memNodes.length);
@@ -111,7 +108,7 @@ public final class ScanEnvironment {
public void pushPrecReadNotNode(Node node) {
numPrecReadNotNodes++;
if (precReadNotNodes == null) {
- precReadNotNodes = new Node[SCANENV_MEMNODES_SIZE];
+ precReadNotNodes = new Node[Config.SCANENV_MEMNODES_SIZE];
} else if (numPrecReadNotNodes >= precReadNotNodes.length) {
Node[]tmp = new Node[precReadNotNodes.length << 1];
System.arraycopy(precReadNotNodes, 0, tmp, 0, precReadNotNodes.length);
diff --git a/src/org/joni/StackMachine.java b/src/org/joni/StackMachine.java
index 07e5e04..d5210ca 100644
--- a/src/org/joni/StackMachine.java
+++ b/src/org/joni/StackMachine.java
@@ -42,15 +42,20 @@ abstract class StackMachine extends Matcher implements StackType {
protected StackMachine(Regex regex, byte[]bytes, int p , int end) {
super(regex, bytes, p, end);
-
- this.stack = regex.requireStack ? fetchStack() : null;
- int n = regex.numRepeat + (regex.numMem << 1);
- this.repeatStk = n > 0 ? new int[n] : null;
-
- memStartStk = regex.numRepeat - 1;
- memEndStk = memStartStk + regex.numMem;
- /* for index start from 1, mem_start_stk[1]..mem_start_stk[num_mem] */
- /* for index start from 1, mem_end_stk[1]..mem_end_stk[num_mem] */
+ stack = regex.requireStack ? fetchStack() : null;
+ final int n;
+ if (Config.USE_SUBEXP_CALL) {
+ n = regex.numRepeat + ((regex.numMem + 1) << 1);
+ memStartStk = regex.numRepeat;
+ memEndStk = memStartStk + regex.numMem + 1;
+ } else {
+ n = regex.numRepeat + (regex.numMem << 1);
+ memStartStk = regex.numRepeat - 1;
+ memEndStk = memStartStk + regex.numMem;
+ /* for index start from 1, mem_start_stk[1]..mem_start_stk[num_mem] */
+ /* for index start from 1, mem_end_stk[1]..mem_end_stk[num_mem] */
+ }
+ repeatStk = n > 0 ? new int[n] : null;
}
private static StackEntry[] allocateStack() {
@@ -86,7 +91,7 @@ abstract class StackMachine extends Matcher implements StackType {
protected final void init() {
if (stack != null) pushEnsured(ALT, regex.codeLength - 1); /* bottom stack */
if (repeatStk != null) {
- for (int i=1; i<=regex.numMem; i++) {
+ for (int i = (Config.USE_SUBEXP_CALL ? 0 : 1); i <= regex.numMem; i++) {
repeatStk[i + memStartStk] = repeatStk[i + memEndStk] = INVALID_INDEX;
}
}
diff --git a/src/org/joni/Token.java b/src/org/joni/Token.java
index 321ad91..c57662e 100644
--- a/src/org/joni/Token.java
+++ b/src/org/joni/Token.java
@@ -156,6 +156,13 @@ final class Token {
INT3 = gnum;
}
+ boolean getCallRel() {
+ return INT4 != 0;
+ }
+ void setCallRel(boolean rel) {
+ INT4 = rel ? 1 : 0;
+ }
+
// prop union member
int getPropCType() {
return INT1;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/jruby-joni.git
More information about the pkg-java-commits
mailing list