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 fbdd0c42d1eec7d958b27ad44640e3d29b1c4b45 Author: Ben Browning <[email protected]> Date: Thu Sep 5 21:00:09 2013 -0400 Add IGNORE_BACKREF_PROC_READ_NOT syntax option Setting this enables the JavaScript behavior of ignoring any backreferences to negative lookahead captures outside of the negative lookahead itself. In otherwords, in a regular expression like "(.*?)a(?!(a+)b\2c)\2(.*)" the second backreference to "\2", outside of the ?! group, is ignored. --- src/org/joni/Parser.java | 47 +++++++++++++++++++++++----- src/org/joni/ScanEnvironment.java | 32 +++++++++++++++++++ src/org/joni/Syntax.java | 4 +++ src/org/joni/ast/EncloseNode.java | 1 + src/org/joni/constants/SyntaxProperties.java | 1 + 5 files changed, 78 insertions(+), 7 deletions(-) diff --git a/src/org/joni/Parser.java b/src/org/joni/Parser.java index f0a049b..4f9764b 100644 --- a/src/org/joni/Parser.java +++ b/src/org/joni/Parser.java @@ -429,6 +429,9 @@ class Parser extends Lexer { break; case '!': /* preceding read */ node = new AnchorNode(AnchorType.PREC_READ_NOT); + if (syntax.ignoreBackrefPrecReadNot()) { + env.pushPrecReadNotNode(node); + } break; case '>': /* (?>...) stop backtrack */ node = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose @@ -579,10 +582,16 @@ class Parser extends Lexer { if (node.getType() == NodeType.ANCHOR) { AnchorNode an = (AnchorNode) node; an.setTarget(target); + if (syntax.ignoreBackrefPrecReadNot() && an.type == AnchorType.PREC_READ_NOT) { + env.popPrecReadNotNode(an); + } } else { EncloseNode en = (EncloseNode)node; en.setTarget(target); if (en.type == EncloseType.MEMORY) { + if (syntax.ignoreBackrefPrecReadNot()) { + en.containingAnchor = env.currentPrecReadNotNode(); + } /* Don't move this to previous of parse_subexp() */ env.setMemNode(en.regNum, node); } @@ -750,13 +759,37 @@ class Parser extends Lexer { break; case BACKREF: - int[]backRefs = token.getBackrefNum() > 1 ? token.getBackrefRefs() : new int[]{token.getBackrefRef1()}; - node = new BackRefNode(token.getBackrefNum(), - backRefs, - token.getBackrefByName(), - token.getBackrefExistLevel(), // #ifdef USE_BACKREF_AT_LEVEL - token.getBackrefLevel(), // ... - env); + if (syntax.ignoreBackrefPrecReadNot() && token.getBackrefNum() == 1 && env.memNodes != null) { + EncloseNode encloseNode = (EncloseNode) env.memNodes[token.getBackrefRef1()]; + boolean shouldIgnore = false; + if (encloseNode != null && encloseNode.containingAnchor != null) { + shouldIgnore = true; + for (Node anchorNode : env.precReadNotNodes) { + if (anchorNode == encloseNode.containingAnchor) { + shouldIgnore = false; + break; + } + } + } + if (shouldIgnore) { + node = StringNode.EMPTY; + } else { + node = new BackRefNode(token.getBackrefNum(), + new int[]{token.getBackrefRef1()}, + token.getBackrefByName(), + token.getBackrefExistLevel(), // #ifdef USE_BACKREF_AT_LEVEL + token.getBackrefLevel(), // ... + env); + } + } else { + int[]backRefs = token.getBackrefNum() > 1 ? token.getBackrefRefs() : new int[]{token.getBackrefRef1()}; + node = new BackRefNode(token.getBackrefNum(), + backRefs, + token.getBackrefByName(), + token.getBackrefExistLevel(), // #ifdef USE_BACKREF_AT_LEVEL + token.getBackrefLevel(), // ... + env); + } break; diff --git a/src/org/joni/ScanEnvironment.java b/src/org/joni/ScanEnvironment.java index 02a1ad7..0dbce24 100644 --- a/src/org/joni/ScanEnvironment.java +++ b/src/org/joni/ScanEnvironment.java @@ -55,6 +55,9 @@ public final class ScanEnvironment { int currMaxRegNum; boolean hasRecursion; + int numPrecReadNotNodes; + Node precReadNotNodes[]; + public ScanEnvironment(Regex regex, Syntax syntax) { this.reg = regex; option = regex.options; @@ -80,6 +83,9 @@ public final class ScanEnvironment { combExpMaxRegNum = 0; currMaxRegNum = 0; hasRecursion = false; + + numPrecReadNotNodes = 0; + precReadNotNodes = null; } public int addMemEntry() { @@ -102,6 +108,32 @@ public final class ScanEnvironment { } } + public void pushPrecReadNotNode(Node node) { + numPrecReadNotNodes++; + if (precReadNotNodes == null) { + precReadNotNodes = new Node[SCANENV_MEMNODES_SIZE]; + } else if (numPrecReadNotNodes >= precReadNotNodes.length) { + Node[]tmp = new Node[precReadNotNodes.length << 1]; + System.arraycopy(precReadNotNodes, 0, tmp, 0, precReadNotNodes.length); + precReadNotNodes = tmp; + } + precReadNotNodes[numPrecReadNotNodes - 1] = node; + } + + public void popPrecReadNotNode(Node node) { + if (precReadNotNodes != null && precReadNotNodes[numPrecReadNotNodes - 1] == node) { + precReadNotNodes[numPrecReadNotNodes - 1] = null; + numPrecReadNotNodes--; + } + } + + public Node currentPrecReadNotNode() { + if (numPrecReadNotNodes > 0) { + return precReadNotNodes[numPrecReadNotNodes - 1]; + } + return null; + } + public int convertBackslashValue(int c) { if (syntax.opEscControlChars()) { switch (c) { diff --git a/src/org/joni/Syntax.java b/src/org/joni/Syntax.java index 774284c..89ead78 100644 --- a/src/org/joni/Syntax.java +++ b/src/org/joni/Syntax.java @@ -326,6 +326,10 @@ public final class Syntax implements SyntaxProperties{ return isBehavior(FIXED_INTERVAL_IS_GREEDY_ONLY); } + public boolean ignoreBackrefPrecReadNot() { + return isBehavior(IGNORE_BACKREF_PREC_READ_NOT); + } + public boolean notNewlineInNegativeCC() { return isBehavior(NOT_NEWLINE_IN_NEGATIVE_CC); diff --git a/src/org/joni/ast/EncloseNode.java b/src/org/joni/ast/EncloseNode.java index 0a07ed1..7c45d14 100644 --- a/src/org/joni/ast/EncloseNode.java +++ b/src/org/joni/ast/EncloseNode.java @@ -34,6 +34,7 @@ public final class EncloseNode extends StateNode implements EncloseType { public int maxLength; // OnigDistance public int charLength; public int optCount; // referenced count in optimize_node_left() + public Node containingAnchor; // // node_new_enclose / onig_node_new_enclose public EncloseNode(int type) { diff --git a/src/org/joni/constants/SyntaxProperties.java b/src/org/joni/constants/SyntaxProperties.java index 78191ec..b31b6cb 100644 --- a/src/org/joni/constants/SyntaxProperties.java +++ b/src/org/joni/constants/SyntaxProperties.java @@ -88,6 +88,7 @@ public interface SyntaxProperties { final int ALLOW_MULTIPLEX_DEFINITION_NAME = (1<<8); /* (?<x>);(?<x>); */ final int FIXED_INTERVAL_IS_GREEDY_ONLY = (1<<9); /* a{n}?=(?:a{n});? */ final int ALLOW_NESTED_REPEAT = (1<<10); /* a{0,}{1}{2} */ + final int IGNORE_BACKREF_PREC_READ_NOT = (1<<11); /* /(?!(a+)b\2c)\2 */ /* syntax (behavior); in char class [...] */ final int NOT_NEWLINE_IN_NEGATIVE_CC = (1<<20); /* [^...] */ -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/jruby-joni.git _______________________________________________ pkg-java-commits mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-java-commits

