[jruby-joni] 160/279: Imported Upstream version 1.1.7+git20120721
Hideki Yamane
henrich at moszumanska.debian.org
Mon Nov 16 11:27:22 UTC 2015
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 1974bf5c7e9fa576bbac00fc88bb6507c1fc3285
Author: Hideki Yamane <henrich at debian.org>
Date: Sun Apr 7 09:12:45 2013 +0900
Imported Upstream version 1.1.7+git20120721
---
.gitignore | 1 +
.travis.yml | 6 +
MANIFEST.MF | 2 +-
pom.xml | 14 +-
src/org/joni/Analyser.java | 982 ++++++-------
src/org/joni/ApplyCaseFold.java | 37 +-
src/org/joni/ApplyCaseFoldArg.java | 24 +-
src/org/joni/ArrayCompiler.java | 358 ++---
src/org/joni/AsmCompiler.java | 26 +-
src/org/joni/AsmCompilerSupport.java | 44 +-
src/org/joni/BitSet.java | 40 +-
src/org/joni/BitStatus.java | 30 +-
src/org/joni/ByteCodeMachine.java | 650 +++++----
src/org/joni/ByteCodePrinter.java | 194 ++-
src/org/joni/CaptureTreeNode.java | 36 +-
src/org/joni/CodeRangeBuffer.java | 146 +-
src/org/joni/Compiler.java | 66 +-
src/org/joni/Config.java | 60 +-
src/org/joni/Lexer.java | 1440 +++++++++-----------
src/org/joni/Matcher.java | 157 ++-
src/org/joni/MatcherFactory.java | 22 +-
src/org/joni/MinMaxLen.java | 82 +-
src/org/joni/NameEntry.java | 40 +-
src/org/joni/NativeMachine.java | 22 +-
src/org/joni/NodeOptInfo.java | 54 +-
src/org/joni/OptAnchorInfo.java | 42 +-
src/org/joni/OptEnvironment.java | 24 +-
src/org/joni/OptExactInfo.java | 107 +-
src/org/joni/OptMapInfo.java | 56 +-
src/org/joni/Option.java | 80 +-
src/org/joni/Parser.java | 492 +++----
src/org/joni/Regex.java | 136 +-
src/org/joni/Region.java | 36 +-
src/org/joni/ScanEnvironment.java | 46 +-
src/org/joni/ScannerSupport.java | 88 +-
src/org/joni/SearchAlgorithm.java | 274 ++--
src/org/joni/StackEntry.java | 44 +-
src/org/joni/StackMachine.java | 146 +-
src/org/joni/Syntax.java | 382 +++---
src/org/joni/Token.java | 24 +-
src/org/joni/UnsetAddrList.java | 34 +-
src/org/joni/WarnCallback.java | 35 +-
src/org/joni/{NativeMachine.java => Warnings.java} | 31 +-
src/org/joni/ast/AnchorNode.java | 44 +-
src/org/joni/ast/AnyCharNode.java | 32 +-
src/org/joni/ast/BackRefNode.java | 54 +-
src/org/joni/ast/CClassNode.java | 221 +--
src/org/joni/ast/CTypeNode.java | 36 +-
src/org/joni/ast/CallNode.java | 46 +-
src/org/joni/ast/ConsAltNode.java | 65 +-
src/org/joni/ast/EncloseNode.java | 76 +-
src/org/joni/ast/Node.java | 73 +-
src/org/joni/ast/QuantifierNode.java | 106 +-
src/org/joni/ast/StateNode.java | 154 +--
src/org/joni/ast/StringNode.java | 98 +-
src/org/joni/bench/AbstractBench.java | 4 +-
src/org/joni/constants/AnchorType.java | 32 +-
src/org/joni/constants/Arguments.java | 26 +-
src/org/joni/constants/AsmConstants.java | 22 +-
src/org/joni/constants/CCSTATE.java | 22 +-
src/org/joni/constants/CCVALTYPE.java | 22 +-
src/org/joni/constants/EncloseType.java | 24 +-
src/org/joni/constants/MetaChar.java | 26 +-
src/org/joni/constants/NodeStatus.java | 22 +-
src/org/joni/constants/NodeType.java | 32 +-
src/org/joni/constants/OPCode.java | 50 +-
src/org/joni/constants/OPSize.java | 29 +-
src/org/joni/constants/Reduce.java | 37 +-
src/org/joni/constants/RegexState.java | 22 +-
src/org/joni/constants/StackPopLevel.java | 22 +-
src/org/joni/constants/StackType.java | 22 +-
src/org/joni/constants/StringType.java | 22 +-
src/org/joni/constants/SyntaxProperties.java | 28 +-
src/org/joni/constants/TargetInfo.java | 22 +-
src/org/joni/constants/TokenType.java | 22 +-
src/org/joni/constants/Traverse.java | 22 +-
src/org/joni/exception/ErrorMessages.java | 30 +-
src/org/joni/exception/InternalException.java | 24 +-
src/org/joni/exception/JOniException.java | 22 +-
src/org/joni/exception/SyntaxException.java | 22 +-
src/org/joni/exception/ValueException.java | 28 +-
test/org/joni/test/Test.java | 88 +-
test/org/joni/test/TestA.java | 60 +-
test/org/joni/test/TestC.java | 54 +-
test/org/joni/test/TestCornerCases.java | 28 +-
test/org/joni/test/TestCrnl.java | 30 +-
test/org/joni/test/TestJoni.java | 40 +-
.../org/joni/test/TestLookBehind.java | 69 +-
test/org/joni/test/TestNSU8.java | 32 +-
test/org/joni/test/TestU.java | 114 +-
test/org/joni/test/TestU8.java | 84 ++
91 files changed, 4588 insertions(+), 4282 deletions(-)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..eb5a316
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+target
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..6768b88
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,6 @@
+language: java
+notifications:
+ # Email notifications are disabled to not annoy anybody.
+ # See http://about.travis-ci.org/docs/user/build-configuration/ to learn more
+ # about configuring notification recipients and more.
+ email: false
diff --git a/MANIFEST.MF b/MANIFEST.MF
index ae40ba2..0dfec5c 100644
--- a/MANIFEST.MF
+++ b/MANIFEST.MF
@@ -1,2 +1,2 @@
Implementation-Title: Joni (java port of Oniguruma)
-Implementation-Version: 1.1.1
+Implementation-Version: 1.1.7
diff --git a/pom.xml b/pom.xml
index 36af172..aca0e9d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
<groupId>org.jruby.joni</groupId>
<artifactId>joni</artifactId>
<packaging>jar</packaging>
- <version>1.1.4</version>
+ <version>1.1.8</version>
<name>Joni</name>
<description>
Java port of Oniguruma: http://www.geocities.jp/kosako3/oniguruma
@@ -18,9 +18,9 @@
</issueManagement>
<scm>
- <connection>scm:svn:http://svn.codehaus.org/jruby</connection>
- <developerConnection>scm:svn:https://svn.codehaus.org/jruby</developerConnection>
- <url>http://svn.codehaus.org/jruby</url>
+ <connection>scm:git:https://github.com/jruby/joni.git</connection>
+ <developerConnection>scm:git:git at github.com:jruby/joni.git</developerConnection>
+ <url>https://github.com/jruby/joni</url>
</scm>
<licenses>
@@ -75,7 +75,7 @@
<dependency>
<groupId>org.jruby.jcodings</groupId>
<artifactId>jcodings</artifactId>
- <version>1.0.4</version>
+ <version>1.0.8</version>
</dependency>
<dependency>
<groupId>junit</groupId>
@@ -84,9 +84,9 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>asm</groupId>
+ <groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
- <version>3.0</version>
+ <version>4.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
diff --git a/src/org/joni/Analyser.java b/src/org/joni/Analyser.java
index cce91ba..d66badf 100644
--- a/src/org/joni/Analyser.java
+++ b/src/org/joni/Analyser.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -35,6 +35,8 @@ import static org.joni.ast.QuantifierNode.isRepeatInfinite;
import java.util.HashSet;
import org.jcodings.CaseFoldCodeItem;
+import org.jcodings.ObjPtr;
+import org.jcodings.Ptr;
import org.jcodings.constants.CharacterType;
import org.joni.ast.AnchorNode;
import org.joni.ast.BackRefNode;
@@ -54,18 +56,18 @@ import org.joni.constants.StackPopLevel;
import org.joni.constants.TargetInfo;
final class Analyser extends Parser {
-
+
protected Analyser(ScanEnvironment env, byte[]bytes, int p, int end) {
super(env, bytes, p, end);
}
-
+
protected final void compile() {
regex.state = RegexState.COMPILING;
-
+
if (Config.DEBUG) {
Config.log.println(regex.encStringToString(bytes, getBegin(), getEnd()));
}
-
+
reset();
regex.numMem = 0;
@@ -73,7 +75,7 @@ final class Analyser extends Parser {
regex.numNullCheck = 0;
//regex.repeatRangeAlloc = 0;
regex.repeatRangeLo = null;
- regex.repeatRangeHi = null;
+ regex.repeatRangeHi = null;
regex.numCombExpCheck = 0;
if (Config.USE_COMBINATION_EXPLOSION_CHECK) regex.numCombExpCheck = 0;
@@ -83,19 +85,19 @@ final class Analyser extends Parser {
if (Config.USE_NAMED_GROUP) {
/* mixed use named group and no-named group */
if (env.numNamed > 0 && syntax.captureOnlyNamedGroup() && !isCaptureGroup(regex.options)) {
- if (env.numNamed != env.numMem) {
+ if (env.numNamed != env.numMem) {
root = disableNoNameGroupCapture(root);
} else {
numberedRefCheck(root);
}
}
} // USE_NAMED_GROUP
-
+
if (Config.USE_NAMED_GROUP) {
if (env.numCall > 0) {
env.unsetAddrList = new UnsetAddrList(env.numCall);
setupSubExpCall(root);
- // r != 0 ???
+ // r != 0 ???
subexpRecursiveCheckTrav(root);
// r < 0 -< err, FOUND_CALLED_NODE = 1
subexpInfRecursiveCheckTrav(root);
@@ -105,28 +107,34 @@ final class Analyser extends Parser {
regex.numCall = 0;
}
} // USE_NAMED_GROUP
-
- setupTree(root, 0);
+
+ if (Config.DEBUG_PARSE_TREE_RAW && Config.DEBUG_PARSE_TREE) {
+ Config.log.println("<RAW TREE>");
+ Config.log.println(root + "\n");
+ }
+
+ root = setupTree(root, 0);
if (Config.DEBUG_PARSE_TREE) {
- root.verifyTree(new HashSet<Node>(),env.reg.warnings);
+ if (Config.DEBUG_PARSE_TREE_RAW) Config.log.println("<TREE>");
+ root.verifyTree(new HashSet<Node>(), env.reg.warnings);
Config.log.println(root + "\n");
}
-
+
regex.captureHistory = env.captureHistory;
regex.btMemStart = env.btMemStart;
regex.btMemEnd = env.btMemEnd;
-
+
if (isFindCondition(regex.options)) {
regex.btMemEnd = bsAll();
} else {
regex.btMemEnd = env.btMemEnd;
regex.btMemEnd |= regex.captureHistory;
}
-
+
if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
- if (env.backrefedMem == 0 || (Config.USE_SUBEXP_CALL && env.numCall == 0)) {
+ if (env.backrefedMem == 0 || (Config.USE_SUBEXP_CALL && env.numCall == 0)) {
setupCombExpCheck(root, 0);
-
+
if (Config.USE_SUBEXP_CALL && env.hasRecursion) {
env.numCombExpCheck = 0;
} else { // USE_SUBEXP_CALL
@@ -139,17 +147,20 @@ final class Analyser extends Parser {
}
}
}
-
+
} // USE_SUBEXP_CALL
regex.numCombExpCheck = env.numCombExpCheck;
} // USE_COMBINATION_EXPLOSION_CHECK
-
+
regex.clearOptimizeInfo();
-
+
if (!Config.DONT_OPTIMIZE) setOptimizedInfoFromTree(root);
env.memNodes = null;
-
+
+ new ArrayCompiler(this).compile();
+ //new AsmCompiler(this).compile();
+
if (regex.numRepeat != 0 || regex.btMemEnd != 0) {
regex.stackPopLevel = StackPopLevel.ALL;
} else {
@@ -160,66 +171,85 @@ final class Analyser extends Parser {
}
}
- new ArrayCompiler(this).compile();
- //new AsmCompiler(this).compile();
-
if (Config.DEBUG_COMPILE) {
if (Config.USE_NAMED_GROUP) Config.log.print(regex.nameTableToString());
Config.log.println("stack used: " + regex.stackNeeded);
+ if (Config.USE_STRING_TEMPLATES) Config.log.print("templates: " + regex.templateNum + "\n");
Config.log.println(new ByteCodePrinter(regex).byteCodeListToString());
+
} // DEBUG_COMPILE
-
+
regex.state = RegexState.NORMAL;
}
-
- private Node noNameDisableMap(Node node, int[]map, int[]counter) {
-
+
+ private void noNameDisableMapFor_cosAlt(Node node, int[]map, Ptr counter) {
+ ConsAltNode can = (ConsAltNode)node;
+ do {
+ can.setCar(noNameDisableMap(can.car, map, counter));
+ } while ((can = can.cdr) != null);
+ }
+
+ private void noNameDisableMapFor_quantifier(Node node, int[]map, Ptr counter) {
+ QuantifierNode qn = (QuantifierNode)node;
+ Node target = qn.target;
+ Node old = target;
+ target = noNameDisableMap(target, map, counter);
+
+ if (target != old) {
+ qn.setTarget(target);
+ if (target.getType() == NodeType.QTFR) qn.reduceNestedQuantifier((QuantifierNode)target);
+ }
+ }
+
+ private Node noNameDisableMapFor_enclose(Node node, int[]map, Ptr counter) {
+ EncloseNode en = (EncloseNode)node;
+ if (en.type == EncloseType.MEMORY) {
+ if (en.isNamedGroup()) {
+ counter.p++;
+ map[en.regNum] = counter.p;
+ en.regNum = counter.p;
+ //en.target = noNameDisableMap(en.target, map, counter);
+ en.setTarget(noNameDisableMap(en.target, map, counter)); // ???
+ } else {
+ node = en.target;
+ en.target = null; // remove first enclose: /(a)(?<b>c)/
+ node = noNameDisableMap(node, map, counter);
+ }
+ } else {
+ //en.target = noNameDisableMap(en.target, map, counter);
+ en.setTarget(noNameDisableMap(en.target, map, counter)); // ???
+ }
+ return node;
+ }
+
+ private void noNameDisableMapFor_anchor(Node node, int[]map, Ptr counter) {
+ AnchorNode an = (AnchorNode)node;
+ switch (an.type) {
+ case AnchorNode.PREC_READ:
+ case AnchorNode.PREC_READ_NOT:
+ case AnchorNode.LOOK_BEHIND:
+ case AnchorNode.LOOK_BEHIND_NOT:
+ an.setTarget(noNameDisableMap(an.target, map, counter));
+ }
+ }
+
+ private Node noNameDisableMap(Node node, int[]map, Ptr counter) {
switch (node.getType()) {
case NodeType.LIST:
case NodeType.ALT:
- ConsAltNode can = (ConsAltNode)node;
- do {
- can.setCar(noNameDisableMap(can.car, map, counter));
- } while ((can = can.cdr) != null);
+ noNameDisableMapFor_cosAlt(node, map, counter);
break;
-
case NodeType.QTFR:
- QuantifierNode qn = (QuantifierNode)node;
- Node target = qn.target;
- Node old = target;
- target = noNameDisableMap(target, map, counter);
-
- if (target != old) {
- qn.setTarget(target);
- if (target.getType() == NodeType.QTFR) qn.reduceNestedQuantifier((QuantifierNode)target);
- }
+ noNameDisableMapFor_quantifier(node, map, counter);
break;
-
case NodeType.ENCLOSE:
- EncloseNode en = (EncloseNode)node;
- if (en.type == EncloseType.MEMORY) {
- if (en.isNamedGroup()) {
- counter[0]++;
- map[en.regNum] = counter[0];
- en.regNum = counter[0];
- //en.target = noNameDisableMap(en.target, map, counter);
- en.setTarget(noNameDisableMap(en.target, map, counter)); // ???
- } else {
- node = en.target;
- en.target = null; // remove first enclose: /(a)(?<b>c)/
- node = noNameDisableMap(node, map, counter);
- }
- } else {
- //en.target = noNameDisableMap(en.target, map, counter);
- en.setTarget(noNameDisableMap(en.target, map, counter)); // ???
- }
+ node = noNameDisableMapFor_enclose(node, map, counter);
break;
-
- default:
+ case NodeType.ANCHOR:
+ noNameDisableMapFor_anchor(node, map, counter);
break;
} // switch
-
- return node;
+ return node;
}
private void renumberByMap(Node node, int[]map) {
@@ -231,26 +261,22 @@ final class Analyser extends Parser {
renumberByMap(can.car, map);
} while ((can = can.cdr) != null);
break;
-
+
case NodeType.QTFR:
renumberByMap(((QuantifierNode)node).target, map);
break;
-
+
case NodeType.ENCLOSE:
renumberByMap(((EncloseNode)node).target, map);
break;
-
+
case NodeType.BREF:
((BackRefNode)node).renumber(map);
break;
-
- default:
- break;
} // switch
}
-
+
protected final void numberedRefCheck(Node node) {
-
switch (node.getType()) {
case NodeType.LIST:
case NodeType.ALT:
@@ -259,58 +285,54 @@ final class Analyser extends Parser {
numberedRefCheck(can.car);
} while ((can = can.cdr) != null);
break;
-
+
case NodeType.QTFR:
numberedRefCheck(((QuantifierNode)node).target);
break;
-
+
case NodeType.ENCLOSE:
numberedRefCheck(((EncloseNode)node).target);
break;
-
+
case NodeType.BREF:
BackRefNode br = (BackRefNode)node;
if (!br.isNameRef()) newValueException(ERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED);
break;
-
- default:
- break;
} // switch
}
-
+
protected final Node disableNoNameGroupCapture(Node root) {
int[]map = new int[env.numMem + 1];
-
+
for (int i=1; i<=env.numMem; i++) map[i] = 0;
-
- int[]counter = new int[]{0}; // !!! this should be passed as the recursion goes right ?, move to plain int
- root = noNameDisableMap(root, map, counter); // ???
+
+ root = noNameDisableMap(root, map, new Ptr(0));
renumberByMap(root, map);
-
+
for (int i=1, pos=1; i<=env.numMem; i++) {
if (map[i] > 0) {
env.memNodes[pos] = env.memNodes[i];
pos++;
}
}
-
+
int loc = env.captureHistory;
env.captureHistory = bsClear();
-
+
for (int i=1; i<=Config.MAX_CAPTURE_HISTORY_GROUP; i++) {
if (bsAt(loc, i)) {
env.captureHistory = bsOnAtSimple(env.captureHistory, map[i]);
}
}
-
+
env.numMem = env.numNamed;
regex.numMem = env.numNamed;
-
+
regex.renumberNameTable(map);
return root;
}
-
+
private void swap(Node a, Node b) {
a.swap(b);
@@ -318,13 +340,13 @@ final class Analyser extends Parser {
root = a;
} else if (root == a) {
root = b;
- }
+ }
}
-
+
// USE_INFINITE_REPEAT_MONOMANIAC_MEM_STATUS_CHECK
private int quantifiersMemoryInfo(Node node) {
int info = 0;
-
+
switch(node.getType()) {
case NodeType.LIST:
case NodeType.ALT:
@@ -334,7 +356,7 @@ final class Analyser extends Parser {
if (v > info) info = v;
} while ((can = can.cdr) != null);
break;
-
+
case NodeType.CALL:
if (Config.USE_SUBEXP_CALL) {
CallNode cn = (CallNode)node;
@@ -343,33 +365,32 @@ final class Analyser extends Parser {
} else {
info = quantifiersMemoryInfo(cn.target);
}
- break;
} // USE_SUBEXP_CALL
break;
-
+
case NodeType.QTFR:
QuantifierNode qn = (QuantifierNode)node;
if (qn.upper != 0) {
info = quantifiersMemoryInfo(qn.target);
}
break;
-
+
case NodeType.ENCLOSE:
EncloseNode en = (EncloseNode)node;
switch (en.type) {
case EncloseType.MEMORY:
return TargetInfo.IS_EMPTY_MEM;
-
+
case EncloseType.OPTION:
case EncloseNode.STOP_BACKTRACK:
info = quantifiersMemoryInfo(en.target);
break;
-
+
default:
break;
} // inner switch
break;
-
+
case NodeType.BREF:
case NodeType.STR:
case NodeType.CTYPE:
@@ -379,28 +400,28 @@ final class Analyser extends Parser {
default:
break;
} // switch
-
+
return info;
}
-
+
private int getMinMatchLength(Node node) {
int min = 0;
-
+
switch (node.getType()) {
case NodeType.BREF:
BackRefNode br = (BackRefNode)node;
if (br.isRecursion()) break;
-
+
if (br.back[0] > env.numMem) newValueException(ERR_INVALID_BACKREF);
min = getMinMatchLength(env.memNodes[br.back[0]]);
-
- for (int i=1; i<br.backNum; i++) {
+
+ for (int i=1; i<br.backNum; i++) {
if (br.back[i] > env.numMem) newValueException(ERR_INVALID_BACKREF);
int tmin = getMinMatchLength(env.memNodes[br.back[i]]);
if (min > tmin) min = tmin;
}
break;
-
+
case NodeType.CALL:
if (Config.USE_SUBEXP_CALL) {
CallNode cn = (CallNode)node;
@@ -410,18 +431,16 @@ final class Analyser extends Parser {
} else {
min = getMinMatchLength(cn.target);
}
- break;
-
} // USE_SUBEXP_CALL
break;
-
+
case NodeType.LIST:
ConsAltNode can = (ConsAltNode)node;
do {
min += getMinMatchLength(can.car);
} while ((can = can.cdr) != null);
break;
-
+
case NodeType.ALT:
ConsAltNode y = (ConsAltNode)node;
do {
@@ -434,20 +453,20 @@ final class Analyser extends Parser {
}
} while ((y = y.cdr) != null);
break;
-
+
case NodeType.STR:
min = ((StringNode)node).length();
break;
-
+
case NodeType.CTYPE:
min = 1;
break;
-
+
case NodeType.CCLASS:
case NodeType.CANY:
min = 1;
break;
-
+
case NodeType.QTFR:
QuantifierNode qn = (QuantifierNode)node;
if (qn.lower > 0) {
@@ -455,7 +474,7 @@ final class Analyser extends Parser {
min = MinMaxLen.distanceMultiply(min, qn.lower);
}
break;
-
+
case NodeType.ENCLOSE:
EncloseNode en = (EncloseNode)node;
switch (en.type) {
@@ -468,28 +487,27 @@ final class Analyser extends Parser {
en.minLength = min;
en.setMinFixed();
}
- break;
} // USE_SUBEXP_CALL
break;
-
+
case EncloseType.OPTION:
case EncloseType.STOP_BACKTRACK:
min = getMinMatchLength(en.target);
break;
} // inner switch
break;
-
+
case NodeType.ANCHOR:
default:
break;
} // switch
-
+
return min;
}
-
+
private int getMaxMatchLength(Node node) {
int max = 0;
-
+
switch (node.getType()) {
case NodeType.LIST:
ConsAltNode ln = (ConsAltNode)node;
@@ -498,7 +516,7 @@ final class Analyser extends Parser {
max = MinMaxLen.distanceAdd(max, tmax);
} while ((ln = ln.cdr) != null);
break;
-
+
case NodeType.ALT:
ConsAltNode an = (ConsAltNode)node;
do {
@@ -506,34 +524,34 @@ final class Analyser extends Parser {
if (max < tmax) max = tmax;
} while ((an = an.cdr) != null);
break;
-
+
case NodeType.STR:
max = ((StringNode)node).length();
break;
-
+
case NodeType.CTYPE:
max = enc.maxLengthDistance();
break;
-
+
case NodeType.CCLASS:
case NodeType.CANY:
max = enc.maxLengthDistance();
break;
-
+
case NodeType.BREF:
BackRefNode br = (BackRefNode)node;
- if (br.isRecursion()) {
+ if (br.isRecursion()) {
max = MinMaxLen.INFINITE_DISTANCE;
break;
}
-
+
for (int i=0; i<br.backNum; i++) {
if (br.back[i] > env.numMem) newValueException(ERR_INVALID_BACKREF);
int tmax = getMaxMatchLength(env.memNodes[br.back[i]]);
if (max < tmax) max = tmax;
}
break;
-
+
case NodeType.CALL:
if (Config.USE_SUBEXP_CALL) {
CallNode cn = (CallNode)node;
@@ -542,24 +560,23 @@ final class Analyser extends Parser {
} else {
max = MinMaxLen.INFINITE_DISTANCE;
}
- break;
} // USE_SUBEXP_CALL
break;
-
+
case NodeType.QTFR:
QuantifierNode qn = (QuantifierNode)node;
if (qn.upper != 0) {
max = getMaxMatchLength(qn.target);
if (max != 0) {
if (!isRepeatInfinite(qn.upper)) {
- max = MinMaxLen.distanceMultiply(max, qn.upper);
+ max = MinMaxLen.distanceMultiply(max, qn.upper);
} else {
max = MinMaxLen.INFINITE_DISTANCE;
}
}
}
break;
-
+
case NodeType.ENCLOSE:
EncloseNode en = (EncloseNode)node;
switch (en.type) {
@@ -572,34 +589,33 @@ final class Analyser extends Parser {
en.maxLength = max;
en.setMaxFixed();
}
- break;
} // USE_SUBEXP_CALL
break;
-
+
case EncloseType.OPTION:
case EncloseType.STOP_BACKTRACK:
max = getMaxMatchLength(en.target);
break;
} // inner switch
break;
-
+
case NodeType.ANCHOR:
default:
break;
} // switch
-
+
return max;
}
-
+
private static final int GET_CHAR_LEN_VARLEN = -1;
private static final int GET_CHAR_LEN_TOP_ALT_VARLEN = -2;
protected final int getCharLengthTree(Node node) {
return getCharLengthTree(node, 0);
}
-
+
private int getCharLengthTree(Node node, int level) {
level++;
-
+
int len = 0;
returnCode = 0;
@@ -611,11 +627,11 @@ final class Analyser extends Parser {
if (returnCode == 0) len = MinMaxLen.distanceAdd(len, tlen);
} while (returnCode == 0 && (ln = ln.cdr) != null);
break;
-
+
case NodeType.ALT:
ConsAltNode an = (ConsAltNode)node;
boolean varLen = false;
-
+
int tlen = getCharLengthTree(an.car, level);
while (returnCode == 0 && (an = an.cdr) != null) {
int tlen2 = getCharLengthTree(an.car, level);
@@ -636,34 +652,33 @@ final class Analyser extends Parser {
}
}
break;
-
+
case NodeType.STR:
StringNode sn = (StringNode)node;
len = sn.length(enc);
break;
-
+
case NodeType.QTFR:
QuantifierNode qn = (QuantifierNode)node;
if (qn.lower == qn.upper) {
tlen = getCharLengthTree(qn.target, level);
- if (returnCode == 0) len = MinMaxLen.distanceMultiply(tlen, qn.lower);
+ if (returnCode == 0) len = MinMaxLen.distanceMultiply(tlen, qn.lower);
} else {
returnCode = GET_CHAR_LEN_VARLEN;
}
break;
-
+
case NodeType.CALL:
if (Config.USE_SUBEXP_CALL) {
CallNode cn = (CallNode)node;
if (!cn.isRecursion()) {
- len = getCharLengthTree(cn.target, level);
+ len = getCharLengthTree(cn.target, level);
} else {
returnCode = GET_CHAR_LEN_VARLEN;
}
- break;
} // USE_SUBEXP_CALL
break;
-
+
case NodeType.CTYPE:
len = 1;
@@ -671,7 +686,7 @@ final class Analyser extends Parser {
case NodeType.CANY:
len = 1;
break;
-
+
case NodeType.ENCLOSE:
EncloseNode en = (EncloseNode)node;
switch(en.type) {
@@ -686,10 +701,9 @@ final class Analyser extends Parser {
en.setCLenFixed();
}
}
- break;
} // USE_SUBEXP_CALL
break;
-
+
case EncloseType.OPTION:
case EncloseType.STOP_BACKTRACK:
len = getCharLengthTree(en.target, level);
@@ -699,20 +713,20 @@ final class Analyser extends Parser {
case NodeType.ANCHOR:
break;
-
+
default:
returnCode = GET_CHAR_LEN_VARLEN;
} // switch
return len;
}
-
+
/* x is not included y ==> 1 : 0 */
private boolean isNotIncluded(Node x, Node y) {
Node tmp;
// !retry:!
- retry:while(true) {
-
+ retry: while(true) {
+
int yType = y.getType();
switch(x.getType()) {
@@ -722,30 +736,30 @@ final class Analyser extends Parser {
CTypeNode cny = (CTypeNode)y;
CTypeNode cnx = (CTypeNode)x;
return cny.ctype == cnx.ctype && cny.not != cnx.not;
-
+
case NodeType.CCLASS:
// !swap:!
tmp = x;
x = y;
y = tmp;
// !goto retry;!
- continue retry;
-
+ continue retry;
+
case NodeType.STR:
// !goto swap;!
tmp = x;
x = y;
y = tmp;
continue retry;
-
+
default:
break;
} // inner switch
break;
-
+
case NodeType.CCLASS:
CClassNode xc = (CClassNode)x;
-
+
switch(yType) {
case NodeType.CTYPE:
switch(((CTypeNode)y).ctype) {
@@ -754,7 +768,7 @@ final class Analyser extends Parser {
if (xc.mbuf == null && !xc.isNot()) {
for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
if (xc.bs.at(i)) {
- if (enc.isSbWord(i)) return false;
+ if (enc.isSbWord(i)) return false;
}
}
return true;
@@ -773,17 +787,17 @@ final class Analyser extends Parser {
return true;
}
// break; not reached
-
+
default:
- break;
+ break;
} // inner switch
break;
-
+
case NodeType.CCLASS:
CClassNode yc = (CClassNode)y;
-
+
for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
- boolean v = xc.bs.at(i);
+ boolean v = xc.bs.at(i);
if ((v && !xc.isNot()) || (!v && xc.isNot())) {
v = yc.bs.at(i);
if ((v && !yc.isNot()) || (!v && yc.isNot())) return false;
@@ -792,7 +806,7 @@ final class Analyser extends Parser {
if ((xc.mbuf == null && !xc.isNot()) || yc.mbuf == null && !yc.isNot()) return true;
return false;
// break; not reached
-
+
case NodeType.STR:
// !goto swap;!
tmp = x;
@@ -802,42 +816,42 @@ final class Analyser extends Parser {
default:
break;
-
+
} // inner switch
break; // case NodeType.CCLASS
-
+
case NodeType.STR:
StringNode xs = (StringNode)x;
if (xs.length() == 0) break;
-
+
switch (yType) {
case NodeType.CTYPE:
CTypeNode cy = ((CTypeNode)y);
switch (cy.ctype) {
case CharacterType.WORD:
if (enc.isMbcWord(xs.bytes, xs.p, xs.end)) {
- return cy.not;
+ return cy.not;
} else {
return !cy.not;
}
-
+
default:
break;
-
+
} // inner switch
break;
-
+
case NodeType.CCLASS:
CClassNode cc = (CClassNode)y;
int code = enc.mbcToCode(xs.bytes, xs.p, xs.p + enc.maxLength());
return !cc.isCodeInCC(enc, code);
-
+
case NodeType.STR:
StringNode ys = (StringNode)y;
int len = xs.length();
if (len > ys.length()) len = ys.length();
if (xs.isAmbig() || ys.isAmbig()) {
- /* tiny version */
+ /* tiny version */
return false;
} else {
for (int i=0, p=ys.p, q=xs.p; i<len; i++, p++, q++) {
@@ -845,52 +859,52 @@ final class Analyser extends Parser {
}
}
break;
-
+
default:
break;
} // inner switch
-
+
break; // case NodeType.STR
-
+
} // switch
-
+
break;
- } // retry:while
+ } // retry: while
return false;
}
-
+
private Node getHeadValueNode(Node node, boolean exact) {
Node n = null;
-
+
switch(node.getType()) {
case NodeType.BREF:
case NodeType.ALT:
case NodeType.CANY:
break;
-
+
case NodeType.CALL:
- break; // if (Config.USE_SUBEXP_CALL)
-
+ break; // if (Config.USE_SUBEXP_CALL)
+
case NodeType.CTYPE:
case NodeType.CCLASS:
if (!exact) n = node;
break;
-
+
case NodeType.LIST:
n = getHeadValueNode(((ConsAltNode)node).car, exact);
break;
-
+
case NodeType.STR:
StringNode sn = (StringNode)node;
if (sn.end <= sn.p) break; // ???
-
+
if (exact && !sn.isRaw() && isIgnoreCase(regex.options)){
// nothing
} else {
n = node;
}
break;
-
+
case NodeType.QTFR:
QuantifierNode qn = (QuantifierNode)node;
if (qn.lower > 0) {
@@ -901,10 +915,10 @@ final class Analyser extends Parser {
}
}
break;
-
+
case NodeType.ENCLOSE:
EncloseNode en = (EncloseNode)node;
-
+
switch (en.type) {
case EncloseType.OPTION:
int options = regex.options;
@@ -912,32 +926,32 @@ final class Analyser extends Parser {
n = getHeadValueNode(en.target, exact);
regex.options = options;
break;
-
+
case EncloseType.MEMORY:
case EncloseType.STOP_BACKTRACK:
n = getHeadValueNode(en.target, exact);
break;
} // inner switch
break;
-
+
case NodeType.ANCHOR:
AnchorNode an = (AnchorNode)node;
if (an.type == AnchorType.PREC_READ) n = getHeadValueNode(an.target, exact);
break;
-
+
default:
break;
} // switch
-
+
return n;
}
-
+
// true: invalid
private boolean checkTypeTree(Node node, int typeMask, int encloseMask, int anchorMask) {
if ((node.getType2Bit() & typeMask) == 0) return true;
boolean invalid = false;
-
+
switch(node.getType()) {
case NodeType.LIST:
case NodeType.ALT:
@@ -946,37 +960,37 @@ final class Analyser extends Parser {
invalid = checkTypeTree(can.car, typeMask, encloseMask, anchorMask);
} while (!invalid && (can = can.cdr) != null);
break;
-
+
case NodeType.QTFR:
invalid = checkTypeTree(((QuantifierNode)node).target, typeMask, encloseMask, anchorMask);
break;
-
+
case NodeType.ENCLOSE:
EncloseNode en = (EncloseNode)node;
if ((en.type & encloseMask) == 0) return true;
invalid = checkTypeTree(en.target, typeMask, encloseMask, anchorMask);
break;
-
+
case NodeType.ANCHOR:
AnchorNode an = (AnchorNode)node;
if ((an.type & anchorMask) == 0) return true;
-
+
if (an.target != null) invalid = checkTypeTree(an.target, typeMask, encloseMask, anchorMask);
break;
-
+
default:
break;
-
+
} // switch
return invalid;
}
-
+
private static final int RECURSION_EXIST = 1;
private static final int RECURSION_INFINITE = 2;
private int subexpInfRecursiveCheck(Node node, boolean head) {
int r = 0;
-
+
switch (node.getType()) {
case NodeType.LIST:
int min;
@@ -991,7 +1005,7 @@ final class Analyser extends Parser {
}
} while ((x = x.cdr) != null);
break;
-
+
case NodeType.ALT:
ConsAltNode can = (ConsAltNode)node;
r = RECURSION_EXIST;
@@ -1001,7 +1015,7 @@ final class Analyser extends Parser {
r &= ret;
} while ((can = can.cdr) != null);
break;
-
+
case NodeType.QTFR:
QuantifierNode qn = (QuantifierNode)node;
r = subexpInfRecursiveCheck(qn.target, head);
@@ -1009,7 +1023,7 @@ final class Analyser extends Parser {
if (qn.lower == 0) r = 0;
}
break;
-
+
case NodeType.ANCHOR:
AnchorNode an = (AnchorNode)node;
switch (an.type) {
@@ -1021,11 +1035,11 @@ final class Analyser extends Parser {
break;
} // inner switch
break;
-
+
case NodeType.CALL:
r = subexpInfRecursiveCheck(((CallNode)node).target, head);
break;
-
+
case NodeType.ENCLOSE:
EncloseNode en = (EncloseNode)node;
if (en.isMark2()) {
@@ -1039,16 +1053,16 @@ final class Analyser extends Parser {
en.clearMark2();
}
break;
-
+
default:
break;
} // switch
return r;
}
-
+
protected final int subexpInfRecursiveCheckTrav(Node node) {
int r = 0;
-
+
switch (node.getType()) {
case NodeType.LIST:
case NodeType.ALT:
@@ -1057,11 +1071,11 @@ final class Analyser extends Parser {
r = subexpInfRecursiveCheckTrav(can.car);
} while (r == 0 && (can = can.cdr) != null);
break;
-
+
case NodeType.QTFR:
r = subexpInfRecursiveCheckTrav(((QuantifierNode)node).target);
break;
-
+
case NodeType.ANCHOR:
AnchorNode an = (AnchorNode)node;
switch (an.type) {
@@ -1073,7 +1087,7 @@ final class Analyser extends Parser {
break;
} // inner switch
break;
-
+
case NodeType.ENCLOSE:
EncloseNode en = (EncloseNode)node;
if (en.isRecursion()) {
@@ -1084,17 +1098,17 @@ final class Analyser extends Parser {
}
r = subexpInfRecursiveCheckTrav(en.target);
break;
-
+
default:
break;
} // switch
-
+
return r;
}
-
+
private int subexpRecursiveCheck(Node node) {
int r = 0;
-
+
switch (node.getType()) {
case NodeType.LIST:
case NodeType.ALT:
@@ -1103,11 +1117,11 @@ final class Analyser extends Parser {
r |= subexpRecursiveCheck(can.car);
} while ((can = can.cdr) != null);
break;
-
+
case NodeType.QTFR:
r = subexpRecursiveCheck(((QuantifierNode)node).target);
break;
-
+
case NodeType.ANCHOR:
AnchorNode an = (AnchorNode)node;
switch (an.type) {
@@ -1119,13 +1133,13 @@ final class Analyser extends Parser {
break;
} // inner switch
break;
-
+
case NodeType.CALL:
CallNode cn = (CallNode)node;
r = subexpRecursiveCheck(cn.target);
- if (r != 0) cn.setRecursion();
+ if (r != 0) cn.setRecursion();
break;
-
+
case NodeType.ENCLOSE:
EncloseNode en = (EncloseNode)node;
if (en.isMark2()) {
@@ -1138,18 +1152,18 @@ final class Analyser extends Parser {
en.clearMark2();
}
break;
-
+
default:
break;
} // switch
-
+
return r;
}
-
+
private static final int FOUND_CALLED_NODE = 1;
protected final int subexpRecursiveCheckTrav(Node node) {
int r = 0;
-
+
switch (node.getType()) {
case NodeType.LIST:
case NodeType.ALT:
@@ -1158,11 +1172,11 @@ final class Analyser extends Parser {
int ret = subexpRecursiveCheckTrav(can.car);
if (ret == FOUND_CALLED_NODE) {
r = FOUND_CALLED_NODE;
- }
+ }
// else if (ret < 0) return ret; ???
} while ((can = can.cdr) != null);
break;
-
+
case NodeType.QTFR:
QuantifierNode qn = (QuantifierNode)node;
r = subexpRecursiveCheckTrav(qn.target);
@@ -1170,7 +1184,7 @@ final class Analyser extends Parser {
if (r == FOUND_CALLED_NODE) qn.isRefered = true;
}
break;
-
+
case NodeType.ANCHOR:
AnchorNode an = (AnchorNode)node;
switch (an.type) {
@@ -1182,7 +1196,7 @@ final class Analyser extends Parser {
break;
} // inner switch
break;
-
+
case NodeType.ENCLOSE:
EncloseNode en = (EncloseNode)node;
if (!en.isRecursion()) {
@@ -1196,16 +1210,25 @@ final class Analyser extends Parser {
r = subexpRecursiveCheckTrav(en.target);
if (en.isCalled()) r |= FOUND_CALLED_NODE;
break;
-
+
default:
break;
} // switch
-
+
return r;
}
-
+
+ private void setCallAttr(CallNode cn) {
+ cn.target = env.memNodes[cn.groupNum]; // no setTarget in call nodes!
+ if (cn.target == null) newValueException(ERR_UNDEFINED_NAME_REFERENCE, cn.nameP, cn.nameEnd);
+
+ ((EncloseNode)cn.target).setCalled();
+ env.btMemStart = BitStatus.bsOnAt(env.btMemStart, cn.groupNum);
+ cn.unsetAddrList = env.unsetAddrList;
+ }
+
protected final void setupSubExpCall(Node node) {
-
+
switch(node.getType()) {
case NodeType.LIST:
ConsAltNode ln = (ConsAltNode)node;
@@ -1213,25 +1236,25 @@ final class Analyser extends Parser {
setupSubExpCall(ln.car);
} while ((ln = ln.cdr) != null);
break;
-
+
case NodeType.ALT:
ConsAltNode can = (ConsAltNode)node;
do {
setupSubExpCall(can.car);
} while ((can = can.cdr) != null);
break;
-
+
case NodeType.QTFR:
setupSubExpCall(((QuantifierNode)node).target);
break;
-
+
case NodeType.ENCLOSE:
setupSubExpCall(((EncloseNode)node).target);
break;
-
+
case NodeType.CALL:
CallNode cn = (CallNode)node;
-
+
if (cn.groupNum != 0) {
int gNum = cn.groupNum;
@@ -1241,36 +1264,23 @@ final class Analyser extends Parser {
}
} // USE_NAMED_GROUP
if (gNum > env.numMem) newValueException(ERR_UNDEFINED_GROUP_REFERENCE, cn.nameP, cn.nameEnd);
-
- // !goto set_call_attr!; // remove duplication ?
- cn.target = env.memNodes[cn.groupNum]; // no setTarget in call nodes!
- if (cn.target == null) newValueException(ERR_UNDEFINED_NAME_REFERENCE, cn.nameP, cn.nameEnd);
-
- ((EncloseNode)cn.target).setCalled();
- env.btMemStart = BitStatus.bsOnAt(env.btMemStart, cn.groupNum);
- cn.unsetAddrList = env.unsetAddrList;
- } else {
+ 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 ?
- // !set_call_attr:!
- cn.target = env.memNodes[cn.groupNum]; // no setTarget in call nodes!
- if (cn.target == null) newValueException(ERR_UNDEFINED_NAME_REFERENCE, cn.nameP, cn.nameEnd);
-
- ((EncloseNode)cn.target).setCalled();
- env.btMemStart = BitStatus.bsOnAt(env.btMemStart, cn.groupNum);
- cn.unsetAddrList = env.unsetAddrList;
+ setCallAttr(cn);
}
}
}
break;
-
+
case NodeType.ANCHOR:
AnchorNode an = (AnchorNode)node;
switch (an.type) {
@@ -1285,21 +1295,19 @@ final class Analyser extends Parser {
} // switch
}
-
+
/* divide different length alternatives in look-behind.
(?<=A|B) ==> (?<=A)|(?<=B)
(?<!A|B) ==> (?<!A)(?<!B)
*/
- private void divideLookBehindAlternatives(Node node) {
+ private Node divideLookBehindAlternatives(Node node) {
AnchorNode an = (AnchorNode)node;
int anchorType = an.type;
-
Node head = an.target;
Node np = ((ConsAltNode)head).car;
-
swap(node, head);
-
+
Node tmp = node;
node = head;
head = tmp;
@@ -1313,18 +1321,19 @@ final class Analyser extends Parser {
insert.setTarget(((ConsAltNode)np).car);
((ConsAltNode)np).setCar(insert);
}
-
+
if (anchorType == AnchorType.LOOK_BEHIND_NOT) {
np = node;
do {
((ConsAltNode)np).toListNode(); /* alt -> list */
- } while ((np = ((ConsAltNode)np).cdr) != null);
+ } while ((np = ((ConsAltNode)np).cdr) != null);
}
+
+ return node;
}
-
- private void setupLookBehind(Node node) {
+
+ private Node setupLookBehind(Node node) {
AnchorNode an = (AnchorNode)node;
-
int len = getCharLengthTree(an.target);
switch(returnCode) {
case 0:
@@ -1335,17 +1344,18 @@ final class Analyser extends Parser {
break;
case GET_CHAR_LEN_TOP_ALT_VARLEN:
if (syntax.differentLengthAltLookBehind()) {
- divideLookBehindAlternatives(node);
+ return divideLookBehindAlternatives(node);
} else {
newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
}
}
+ return node;
}
private void nextSetup(Node node, Node nextNode) {
// retry:
retry: while(true) {
-
+
int type = node.getType();
if (type == NodeType.QTFR) {
QuantifierNode qn = (QuantifierNode)node;
@@ -1368,7 +1378,7 @@ final class Analyser extends Parser {
en.setStopBtSimpleRepeat();
//en.setTarget(qn.target); // optimize it ??
swap(node, en);
-
+
en.setTarget(node);
}
}
@@ -1383,89 +1393,128 @@ final class Analyser extends Parser {
continue retry;
}
}
-
+
break;
} // while
}
-
- private void updateStringNodeCaseFold(Node node) {
- StringNode sn = (StringNode)node;
-
- byte[]sbuf = new byte[sn.length() << 1];
+
+ private void updateStringNodeCaseFoldSingleByte(StringNode sn, byte[]toLower) {
+ int end = sn.end;
+ byte[]bytes = sn.bytes;
int sp = 0;
-
- value = sn.p;
+ int p = sn.p;
+
+ while (p < end) {
+ byte lower = toLower[bytes[p] & 0xff];
+ if (lower != bytes[p]) {
+ byte[]sbuf = new byte[end - sn.p];
+ System.arraycopy(bytes, sn.p, sbuf, 0, sp);
+
+ while (p < end) sbuf[sp++] = toLower[bytes[p++] & 0xff];
+
+ sn.set(sbuf, 0, sp);
+ break;
+ } else {
+ sp++;
+ p++;
+ }
+ }
+ }
+
+ private void updateStringNodeCaseFoldMultiByte(StringNode sn) {
int end = sn.end;
-
+ value = sn.p;
+ int sp = 0;
byte[]buf = new byte[Config.ENC_MBC_CASE_FOLD_MAXLEN];
+
while (value < end) {
- int len = enc.mbcCaseFold(regex.caseFoldFlag, sn.bytes, this, end, buf);
- for (int i=0; i<len; i++) {
- if (sp >= sbuf.length) {
- byte[]tmp = new byte[sbuf.length << 1];
- System.arraycopy(sbuf, 0, tmp, 0, sbuf.length);
- sbuf = tmp;
+ int ovalue = value;
+ int len = enc.mbcCaseFold(regex.caseFoldFlag, bytes, this, end, buf);
+
+ for (int i = 0; i < len; i++) {
+ if (bytes[ovalue + i] != buf[i]) {
+
+ byte[]sbuf = new byte[sn.length() << 1];
+ System.arraycopy(bytes, sn.p, sbuf, 0, ovalue - sn.p);
+ value = ovalue;
+ while (value < end) {
+ len = enc.mbcCaseFold(regex.caseFoldFlag, bytes, this, end, buf);
+ for (i = 0; i < len; i++) {
+ if (sp >= sbuf.length) {
+ byte[]tmp = new byte[sbuf.length << 1];
+ System.arraycopy(sbuf, 0, tmp, 0, sbuf.length);
+ sbuf = tmp;
+ }
+ sbuf[sp++] = buf[i];
+ }
+ }
+ sn.set(sbuf, 0, sp);
+ return;
}
- sbuf[sp++] = buf[i];
+ sp++;
}
}
-
- sn.set(sbuf, 0, sp);
}
-
+
+ private void updateStringNodeCaseFold(Node node) {
+ StringNode sn = (StringNode)node;
+ byte[] toLower = enc.toLowerCaseTable();
+ if (toLower != null) {
+ updateStringNodeCaseFoldSingleByte(sn, toLower);
+ } else {
+ updateStringNodeCaseFoldMultiByte(sn);
+ }
+ }
+
private Node expandCaseFoldMakeRemString(byte[]bytes, int p, int end) {
StringNode node = new StringNode(bytes, p, end);
-
+
updateStringNodeCaseFold(node);
node.setAmbig();
node.setDontGetOptInfo();
return node;
}
-
+
private boolean expandCaseFoldStringAlt(int itemNum, CaseFoldCodeItem[]items,
- byte[]bytes, int p, int slen, int end, Node[]node) {
+ byte[]bytes, int p, int slen, int end, ObjPtr<Node> node) {
boolean varlen = false;
-
for (int i=0; i<itemNum; i++) {
if (items[i].byteLen != slen) {
varlen = true;
break;
}
}
-
- ConsAltNode varANode = null, anode, xnode;
+
+ ConsAltNode varANode = null, altNode, listNode;
if (varlen) {
- node[0] = varANode = newAltNode(null, null);
-
- xnode = newListNode(null, null);
- varANode.setCar(xnode);
-
- anode = newAltNode(null, null);
- xnode.setCar(anode);
+ node.p = varANode = newAltNode(null, null);
+
+ listNode = newListNode(null, null);
+ varANode.setCar(listNode);
+
+ altNode = newAltNode(null, null);
+ listNode.setCar(altNode);
} else {
- node[0] = anode = newAltNode(null, null);
+ node.p = altNode = newAltNode(null, null);
}
-
+
StringNode snode = new StringNode(bytes, p, p + slen);
- anode.setCar(snode);
-
+ altNode.setCar(snode);
+
for (int i=0; i<itemNum; i++) {
snode = new StringNode();
-
- for (int j=0; j<items[i].codeLen; j++) {
- snode.ensure(Config.ENC_CODE_TO_MBC_MAXLEN);
- snode.end += enc.codeToMbc(items[i].code[j], snode.bytes, snode.end);
- }
-
+
+ for (int j = 0; j < items[i].codeLen; j++) snode.catCode(items[i].code[j], enc);
+
ConsAltNode an = newAltNode(null, null);
if (items[i].byteLen != slen) {
int q = p + items[i].byteLen;
if (q < end) {
Node rem = expandCaseFoldMakeRemString(bytes, q, end);
-
- xnode = ConsAltNode.listAdd(null, snode);
- ConsAltNode.listAdd(xnode, rem);
- an.setCar(xnode);
+
+ listNode = ConsAltNode.listAdd(null, snode);
+ ConsAltNode.listAdd(listNode, rem);
+ an.setCar(listNode);
} else {
an.setCar(snode);
}
@@ -1473,18 +1522,18 @@ final class Analyser extends Parser {
varANode = an;
} else {
an.setCar(snode);
- anode.setCdr(an);
- anode = an;
+ altNode.setCdr(an);
+ altNode = an;
}
}
return varlen;
}
-
+
private static final int THRESHOLD_CASE_FOLD_ALT_FOR_EXPANSION = 8;
- private void expandCaseFoldString(Node node) {
+ private Node expandCaseFoldString(Node node) {
StringNode sn = (StringNode)node;
- if (sn.isAmbig() || sn.length() <= 0) return;
+ if (sn.isAmbig() || sn.length() <= 0) return node;
byte[]bytes = sn.bytes;
int p = sn.p;
@@ -1492,94 +1541,91 @@ final class Analyser extends Parser {
int altNum = 1;
ConsAltNode topRoot = null, root = null;
- Node[]prevNode = new Node[]{null};
- StringNode snode = null;
+ ObjPtr<Node> prevNode = new ObjPtr<Node>();
+ StringNode stringNode = null;
while (p < end) {
CaseFoldCodeItem[]items = enc.caseFoldCodesByString(regex.caseFoldFlag, bytes, p, end);
int len = enc.length(bytes, p, end);
if (items.length == 0) {
- if (snode == null) {
- if (root == null && prevNode[0] != null) {
- topRoot = root = ConsAltNode.listAdd(null, prevNode[0]);
- }
-
- prevNode[0] = snode = new StringNode(); // onig_node_new_str(NULL, NULL);
-
- if (root != null) {
- ConsAltNode.listAdd(root, snode);
+ if (stringNode == null) {
+ if (root == null && prevNode.p != null) {
+ topRoot = root = ConsAltNode.listAdd(null, prevNode.p);
}
-
+
+ prevNode.p = stringNode = new StringNode(); // onig_node_new_str(NULL, NULL);
+
+ if (root != null) ConsAltNode.listAdd(root, stringNode);
+
}
-
- snode.cat(bytes, p, p + len);
+
+ stringNode.cat(bytes, p, p + len);
} else {
altNum *= (items.length + 1);
if (altNum > THRESHOLD_CASE_FOLD_ALT_FOR_EXPANSION) break;
-
- if (root == null && prevNode[0] != null) {
- topRoot = root = ConsAltNode.listAdd(null, prevNode[0]);
+
+ if (root == null && prevNode.p != null) {
+ topRoot = root = ConsAltNode.listAdd(null, prevNode.p);
}
-
- boolean r = expandCaseFoldStringAlt(items.length, items, bytes, p, len, end, prevNode);
- if (r) { // if (r == 1)
+
+ if (expandCaseFoldStringAlt(items.length, items, bytes, p, len, end, prevNode)) { // if (r == 1)
if (root == null) {
- topRoot = (ConsAltNode)prevNode[0];
+ topRoot = (ConsAltNode)prevNode.p;
} else {
- ConsAltNode.listAdd(root, prevNode[0]);
+ ConsAltNode.listAdd(root, prevNode.p);
}
-
- root = (ConsAltNode)((ConsAltNode)prevNode[0]).car;
+
+ root = (ConsAltNode)((ConsAltNode)prevNode.p).car;
} else { /* r == 0 */
- if (root != null) {
- ConsAltNode.listAdd(root, prevNode[0]);
- }
+ if (root != null) ConsAltNode.listAdd(root, prevNode.p);
}
- snode = null;
+ stringNode = null;
}
p += len;
}
-
+
if (p < end) {
Node srem = expandCaseFoldMakeRemString(bytes, p, end);
-
- if (prevNode[0] != null && root == null) {
- topRoot = root = ConsAltNode.listAdd(null, prevNode[0]);
+
+ if (prevNode.p != null && root == null) {
+ topRoot = root = ConsAltNode.listAdd(null, prevNode.p);
}
-
+
if (root == null) {
- prevNode[0] = srem;
+ prevNode.p = srem;
} else {
ConsAltNode.listAdd(root, srem);
}
}
/* ending */
- Node xnode = topRoot != null ? topRoot : prevNode[0];
+ Node xnode = topRoot != null ? topRoot : prevNode.p;
+
swap(node, xnode);
+ return xnode;
}
-
+
private static final int CEC_THRES_NUM_BIG_REPEAT = 512;
private static final int CEC_INFINITE_NUM = 0x7fffffff;
private static final int CEC_IN_INFINITE_REPEAT = (1<<0);
private static final int CEC_IN_FINITE_REPEAT = (1<<1);
private static final int CEC_CONT_BIG_REPEAT = (1<<2);
-
+
protected final int setupCombExpCheck(Node node, int state) {
int r = state;
int ret;
-
+
switch (node.getType()) {
case NodeType.LIST:
ConsAltNode ln = (ConsAltNode)node;
-
+
do {
r = setupCombExpCheck(ln.car, r);
//prev = ((ConsAltNode)node).car;
} while (r >= 0 && (ln = ln.cdr) != null);
break;
-
+
case NodeType.ALT:
ConsAltNode an = (ConsAltNode)node;
do {
@@ -1587,18 +1633,18 @@ final class Analyser extends Parser {
r |= ret;
} while (ret >= 0 && (an = an.cdr) != null);
break;
-
+
case NodeType.QTFR:
QuantifierNode qn = (QuantifierNode)node;
int childState = state;
int addState = 0;
int varNum;
-
+
if (!isRepeatInfinite(qn.upper)) {
if (qn.upper > 1) {
/* {0,1}, {1,1} are allowed */
childState |= CEC_IN_FINITE_REPEAT;
-
+
/* check (a*){n,m}, (a+){n,m} => (a*){n,n}, (a+){n,n} */
if (env.backrefedMem == 0) {
if (qn.target.getType() == NodeType.ENCLOSE) {
@@ -1616,7 +1662,7 @@ final class Analyser extends Parser {
}
}
}
-
+
if ((state & CEC_IN_FINITE_REPEAT) != 0) {
qn.combExpCheckNum = -1;
} else {
@@ -1626,9 +1672,9 @@ final class Analyser extends Parser {
} else {
varNum = qn.upper - qn.lower;
}
-
+
if (varNum >= CEC_THRES_NUM_BIG_REPEAT) addState |= CEC_CONT_BIG_REPEAT;
-
+
if (((state & CEC_IN_INFINITE_REPEAT) != 0 && varNum != 0) ||
((state & CEC_CONT_BIG_REPEAT) != 0 && varNum >= CEC_THRES_NUM_BIG_REPEAT)) {
if (qn.combExpCheckNum == 0) {
@@ -1643,7 +1689,7 @@ final class Analyser extends Parser {
r = setupCombExpCheck(qn.target, childState);
r |= addState;
break;
-
+
case NodeType.ENCLOSE:
EncloseNode en = (EncloseNode)node;
switch( en.type) {
@@ -1653,12 +1699,12 @@ final class Analyser extends Parser {
}
r = setupCombExpCheck(en.target, state);
break;
-
+
default:
r = setupCombExpCheck(en.target, state);
} // inner switch
break;
-
+
case NodeType.CALL:
if (Config.USE_SUBEXP_CALL) {
CallNode cn = (CallNode)node;
@@ -1667,15 +1713,14 @@ final class Analyser extends Parser {
} else {
r = setupCombExpCheck(cn.target, state);
}
- break;
} // USE_SUBEXP_CALL
break;
-
+
default:
break;
-
+
} // switch
-
+
return r;
}
@@ -1693,7 +1738,8 @@ final class Analyser extends Parser {
5. find invalid patterns in look-behind.
6. expand repeated string.
*/
- protected final void setupTree(Node node, int state) {
+ protected final Node setupTree(Node node, int state) {
+ restart: while (true) {
switch (node.getType()) {
case NodeType.LIST:
ConsAltNode lin = (ConsAltNode)node;
@@ -1706,30 +1752,30 @@ final class Analyser extends Parser {
prev = lin.car;
} while ((lin = lin.cdr) != null);
break;
-
+
case NodeType.ALT:
ConsAltNode aln = (ConsAltNode)node;
do {
setupTree(aln.car, (state | IN_ALT));
} while ((aln = aln.cdr) != null);
break;
-
+
case NodeType.CCLASS:
break;
case NodeType.STR:
if (isIgnoreCase(regex.options) && !((StringNode)node).isRaw()) {
- expandCaseFoldString(node);
+ node = expandCaseFoldString(node);
}
break;
-
+
case NodeType.CTYPE:
case NodeType.CANY:
break;
-
+
case NodeType.CALL: // if (Config.USE_SUBEXP_CALL) ?
break;
-
+
case NodeType.BREF:
BackRefNode br = (BackRefNode)node;
for (int i=0; i<br.backNum; i++) {
@@ -1744,13 +1790,13 @@ final class Analyser extends Parser {
((EncloseNode)env.memNodes[br.back[i]]).setMemBackrefed();
}
break;
-
+
case NodeType.QTFR:
QuantifierNode qn = (QuantifierNode)node;
Node target = qn.target;
-
+
if ((state & IN_REPEAT) != 0) qn.setInRepeat();
-
+
if (isRepeatInfinite(qn.upper) || qn.lower >= 1) {
int d = getMinMatchLength(target);
if (d == 0) {
@@ -1762,28 +1808,28 @@ final class Analyser extends Parser {
// strange stuff here (turned off)
}
}
-
+
state |= IN_REPEAT;
if (qn.lower != qn.upper) state |= IN_VAR_REPEAT;
-
- setupTree(target, state);
-
+
+ target = setupTree(target, state);
+
/* expand string */
if (target.getType() == NodeType.STR) {
if (!isRepeatInfinite(qn.lower) && qn.lower == qn.upper &&
qn.lower > 1 && qn.lower <= EXPAND_STRING_MAX_LENGTH) {
StringNode sn = (StringNode)target;
int len = sn.length();
-
+
if (len * qn.lower <= EXPAND_STRING_MAX_LENGTH) {
- StringNode str = qn.convertToString();
- // if (str.parent == null) root = str;
+ StringNode str = qn.convertToString(sn.flag);
int n = qn.lower;
- for (int i=0; i<n; i++) {
- str.cat(sn.bytes, sn.p, sn.end);
+ for (int i = 0; i < n; i++) {
+ str.cat(sn.bytes, sn.p, sn.end);
}
+ break; /* break case NT_QTFR: */
}
- break; /* break case NT_QTFR: */
+
}
}
if (Config.USE_OP_PUSH_OR_JUMP_EXACT) {
@@ -1800,7 +1846,7 @@ final class Analyser extends Parser {
}
} // USE_OP_PUSH_OR_JUMP_EXACT
break;
-
+
case NodeType.ENCLOSE:
EncloseNode en = (EncloseNode)node;
switch (en.type) {
@@ -1810,12 +1856,12 @@ final class Analyser extends Parser {
setupTree(en.target, state);
regex.options = options;
break;
-
+
case EncloseType.MEMORY:
if ((state & (IN_ALT | IN_NOT | IN_VAR_REPEAT)) != 0) {
env.btMemStart = bsOnAt(env.btMemStart, en.regNum);
/* SET_ENCLOSE_STATUS(node, NST_MEM_IN_ALT_NOT); */
-
+
}
setupTree(en.target, state);
break;
@@ -1830,56 +1876,47 @@ final class Analyser extends Parser {
}
}
break;
-
+
} // inner switch
break;
-
+
case NodeType.ANCHOR:
AnchorNode an = (AnchorNode)node;
switch (an.type) {
case AnchorType.PREC_READ:
setupTree(an.target, state);
break;
-
+
case AnchorType.PREC_READ_NOT:
setupTree(an.target, (state | IN_NOT));
break;
-
+
case AnchorType.LOOK_BEHIND:
- boolean lbInvalid = checkTypeTree(an.target, NodeType.ALLOWED_IN_LB,
- EncloseType.ALLOWED_IN_LB,
- AnchorType.ALLOWED_IN_LB);
-
- if (lbInvalid) newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
- setupLookBehind(node);
- setupTree(an.target, state);
+ if (checkTypeTree(an.target, NodeType.ALLOWED_IN_LB, EncloseType.ALLOWED_IN_LB, AnchorType.ALLOWED_IN_LB)) newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
+ node = setupLookBehind(node);
+ if (node.getType() != NodeType.ANCHOR) continue restart;
+ setupTree(((AnchorNode)node).target, state);
break;
-
+
case AnchorType.LOOK_BEHIND_NOT:
- boolean lbnInvalid = checkTypeTree(an.target, NodeType.ALLOWED_IN_LB,
- EncloseType.ALLOWED_IN_LB,
- AnchorType.ALLOWED_IN_LB);
-
- if (lbnInvalid) newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
-
- setupLookBehind(node);
- setupTree(an.target, (state | IN_NOT));
+ if (checkTypeTree(an.target, NodeType.ALLOWED_IN_LB, EncloseType.ALLOWED_IN_LB, AnchorType.ALLOWED_IN_LB)) newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
+ node = setupLookBehind(node);
+ if (node.getType() != NodeType.ANCHOR) continue restart;
+ setupTree(((AnchorNode)node).target, (state | IN_NOT));
break;
-
- } // inner switch
- break;
- default:
+ } // inner switch
break;
-
} // switch
+ return node;
+ } // restart: while
}
-
+
private static final int MAX_NODE_OPT_INFO_REF_COUNT = 5;
private void optimizeNodeLeft(Node node, NodeOptInfo opt, OptEnvironment oenv) { // oenv remove, pass mmd
opt.clear();
opt.setBoundNode(oenv.mmd);
-
+
switch (node.getType()) {
case NodeType.LIST: {
OptEnvironment nenv = new OptEnvironment();
@@ -1893,7 +1930,7 @@ final class Analyser extends Parser {
} while ((lin = lin.cdr) != null);
break;
}
-
+
case NodeType.ALT: {
NodeOptInfo nopt = new NodeOptInfo();
ConsAltNode aln = (ConsAltNode)node;
@@ -1910,9 +1947,9 @@ final class Analyser extends Parser {
case NodeType.STR: {
StringNode sn = (StringNode)node;
-
+
int slen = sn.length();
-
+
if (!sn.isAmbig()) {
opt.exb.concatStr(sn.bytes, sn.p, sn.end, sn.isRaw(), enc);
@@ -1929,7 +1966,7 @@ final class Analyser extends Parser {
} else {
opt.exb.concatStr(sn.bytes, sn.p, sn.end, sn.isRaw(), enc);
opt.exb.ignoreCase = true;
-
+
if (slen > 0) {
opt.map.addCharAmb(sn.bytes, sn.p, sn.end, enc, oenv.caseFoldFlag);
}
@@ -1938,13 +1975,13 @@ final class Analyser extends Parser {
}
opt.length.set(slen, max);
}
-
+
if (opt.exb.length == slen) {
opt.exb.reachEnd = true;
}
- break;
+ break;
}
-
+
case NodeType.CCLASS: {
CClassNode cc = (CClassNode)node;
/* no need to check ignore case. (setted in setup_tree()) */
@@ -1961,16 +1998,16 @@ final class Analyser extends Parser {
}
opt.length.set(1, 1);
}
- break;
+ break;
}
-
+
case NodeType.CTYPE: {
int min;
int max = enc.maxLengthDistance();
if (max == 1) {
min = 1;
CTypeNode cn = (CTypeNode)node;
-
+
switch (cn.ctype) {
case CharacterType.WORD:
if (cn.not) {
@@ -1980,7 +2017,7 @@ final class Analyser extends Parser {
}
}
} else {
- for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
+ for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
if (enc.isWord(i)) {
opt.map.addChar((byte)i, enc);
}
@@ -1994,12 +2031,12 @@ final class Analyser extends Parser {
opt.length.set(min, max);
break;
}
-
+
case NodeType.CANY: {
opt.length.set(enc.minLength(), enc.maxLengthDistance());
break;
}
-
+
case NodeType.ANCHOR: {
AnchorNode an = (AnchorNode)node;
switch (an.type) {
@@ -2011,7 +2048,7 @@ final class Analyser extends Parser {
case AnchorType.END_LINE:
opt.anchor.add(an.type);
break;
-
+
case AnchorType.PREC_READ:
NodeOptInfo nopt = new NodeOptInfo();
optimizeNodeLeft(an.target, nopt, oenv);
@@ -2028,24 +2065,24 @@ final class Analyser extends Parser {
case AnchorType.LOOK_BEHIND: /* Sorry, I can't make use of it. */
case AnchorType.LOOK_BEHIND_NOT:
break;
-
+
} // inner switch
break;
}
-
+
case NodeType.BREF: {
BackRefNode br = (BackRefNode)node;
-
+
if (br.isRecursion()) {
opt.length.set(0, MinMaxLen.INFINITE_DISTANCE);
break;
}
-
+
Node[]nodes = oenv.scanEnv.memNodes;
-
+
int min = getMinMatchLength(nodes[br.back[0]]);
int max = getMaxMatchLength(nodes[br.back[0]]);
-
+
for (int i=1; i<br.backNum; i++) {
int tmin = getMinMatchLength(nodes[br.back[i]]);
int tmax = getMaxMatchLength(nodes[br.back[i]]);
@@ -2067,7 +2104,6 @@ final class Analyser extends Parser {
optimizeNodeLeft(cn.target, opt, oenv);
oenv.options = safe;
}
- break;
} // USE_SUBEXP_CALL
break;
}
@@ -2090,7 +2126,7 @@ final class Analyser extends Parser {
if (nopt.exb.length > 0) {
if (nopt.exb.reachEnd) {
int i;
- for (i=1; i<qn.lower && !opt.exb.isFull(); i++) {
+ for (i = 2; i <= qn.lower && !opt.exb.isFull(); i++) {
opt.exb.concat(nopt.exb, enc);
}
if (i < qn.lower) {
@@ -2105,7 +2141,7 @@ final class Analyser extends Parser {
if (qn.lower > 1) {
opt.exm.reachEnd = false;
}
-
+
}
}
int min = MinMaxLen.distanceMultiply(nopt.length.min, qn.lower);
@@ -2128,7 +2164,7 @@ final class Analyser extends Parser {
optimizeNodeLeft(en.target, opt, oenv);
oenv.options = save;
break;
-
+
case EncloseType.MEMORY:
if (Config.USE_SUBEXP_CALL && ++en.optCount > MAX_NODE_OPT_INFO_REF_COUNT) {
int min = 0;
@@ -2139,35 +2175,35 @@ final class Analyser extends Parser {
} else { // USE_SUBEXP_CALL
optimizeNodeLeft(en.target, opt, oenv);
if (opt.anchor.isSet(AnchorType.ANYCHAR_STAR_MASK)) {
- if (bsAt(oenv.scanEnv.backrefedMem, en.regNum)) {
+ if (bsAt(oenv.scanEnv.backrefedMem, en.regNum)) {
opt.anchor.remove(AnchorType.ANYCHAR_STAR_MASK);
}
}
- }
+ }
break;
-
+
case EncloseType.STOP_BACKTRACK:
optimizeNodeLeft(en.target, opt, oenv);
break;
} // inner switch
break;
}
-
+
default:
newInternalException(ERR_PARSER_BUG);
} // switch
}
-
- protected final void setOptimizedInfoFromTree(Node node) {
+
+ protected final void setOptimizedInfoFromTree(Node node) {
NodeOptInfo opt = new NodeOptInfo();
OptEnvironment oenv = new OptEnvironment();
-
+
oenv.enc = regex.enc;
oenv.options = regex.options;
oenv.caseFoldFlag = regex.caseFoldFlag;
oenv.scanEnv = env;
oenv.mmd.clear(); // ??
-
+
optimizeNodeLeft(node, opt, oenv);
regex.anchor = opt.anchor.leftAnchor & (AnchorType.BEGIN_BUF |
@@ -2201,7 +2237,7 @@ final class Analyser extends Parser {
regex.subAnchor |= opt.anchor.leftAnchor & AnchorType.BEGIN_LINE;
if (opt.length.max == 0) regex.subAnchor |= opt.anchor.rightAnchor & AnchorType.END_LINE;
}
-
+
if (Config.DEBUG_COMPILE || Config.DEBUG_MATCH) {
Config.log.println(regex.optimizeInfoToString());
}
diff --git a/src/org/joni/ApplyCaseFold.java b/src/org/joni/ApplyCaseFold.java
index 54a1aa0..7dd84ce 100644
--- a/src/org/joni/ApplyCaseFold.java
+++ b/src/org/joni/ApplyCaseFold.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -35,7 +35,7 @@ final class ApplyCaseFold implements ApplyAllCaseFoldFunction {
Encoding enc = env.enc;
CClassNode cc = arg.cc;
BitSet bs = cc.bs;
-
+
if (length == 1) {
boolean inCC = cc.isCodeInCC(enc, from);
@@ -62,23 +62,18 @@ final class ApplyCaseFold implements ApplyAllCaseFoldFunction {
}
}
} // CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
-
+
} else {
if (cc.isCodeInCC(enc, from) && (!Config.CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS || !cc.isNot())) {
StringNode node = null;
for (int i=0; i<length; i++) {
if (i == 0) {
node = new StringNode();
- node.ensure(Config.ENC_CODE_TO_MBC_MAXLEN);
- node.end += enc.codeToMbc(to[i], node.bytes, node.end);
-
/* char-class expanded multi-char only
compare with string folded at match time. */
node.setAmbig();
- } else {
- node.ensure(Config.ENC_CODE_TO_MBC_MAXLEN);
- node.end += enc.codeToMbc(to[i], node.bytes, node.end);
}
+ node.catCode(to[i], enc);
}
ConsAltNode alt = ConsAltNode.newAltNode(node, null);
@@ -94,6 +89,6 @@ final class ApplyCaseFold implements ApplyAllCaseFoldFunction {
}
}
-
- static final ApplyCaseFold INSTANCE = new ApplyCaseFold();
+
+ static final ApplyCaseFold INSTANCE = new ApplyCaseFold();
}
diff --git a/src/org/joni/ApplyCaseFoldArg.java b/src/org/joni/ApplyCaseFoldArg.java
index 92dd2fb..10b297f 100644
--- a/src/org/joni/ApplyCaseFoldArg.java
+++ b/src/org/joni/ApplyCaseFoldArg.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -27,7 +27,7 @@ public final class ApplyCaseFoldArg {
final CClassNode cc;
ConsAltNode altRoot;
ConsAltNode tail;
-
+
public ApplyCaseFoldArg(ScanEnvironment env, CClassNode cc) {
this.env = env;
this.cc = cc;
diff --git a/src/org/joni/ArrayCompiler.java b/src/org/joni/ArrayCompiler.java
index f23ce58..ac21d0e 100644
--- a/src/org/joni/ArrayCompiler.java
+++ b/src/org/joni/ArrayCompiler.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -44,6 +44,11 @@ import org.joni.constants.OPSize;
import org.joni.constants.TargetInfo;
final class ArrayCompiler extends Compiler {
+ private int[]code;
+ private int codeLength;
+
+ private byte[][]templates;
+ private int templateNum;
ArrayCompiler(Analyser analyser) {
super(analyser);
@@ -51,21 +56,26 @@ final class ArrayCompiler extends Compiler {
@Override
protected final void prepare() {
- regex.code = new int[(analyser.stop - analyser.p) * 2 + 1]; // (+1: empty regex)
- regex.codeLength = 0;
+ int codeSize = Config.USE_STRING_TEMPLATES ? 8 : ((analyser.getEnd() - analyser.getBegin()) * 2 + 2);
+ code = new int[codeSize];
+ codeLength = 0;
}
@Override
protected final void finish() {
addOpcode(OPCode.END);
addOpcode(OPCode.FINISH); // for stack bottom
-
+
+ regex.code = code;
+ regex.codeLength = codeLength;
+ regex.templates = templates;
+ regex.templateNum = templateNum;
+ regex.factory = MatcherFactory.DEFAULT;
+
if (Config.USE_SUBEXP_CALL && analyser.env.unsetAddrList != null) {
analyser.env.unsetAddrList.fix(regex);
analyser.env.unsetAddrList = null;
}
-
- regex.factory = MatcherFactory.DEFAULT;
}
@Override
@@ -80,7 +90,7 @@ final class ArrayCompiler extends Compiler {
}
} while ((aln = aln.cdr) != null);
- int pos = regex.codeLength + len; /* goal position */
+ int pos = codeLength + len; /* goal position */
aln = node;
do {
@@ -90,7 +100,7 @@ final class ArrayCompiler extends Compiler {
}
compileTree(aln.car);
if (aln.cdr != null) {
- len = pos - (regex.codeLength + OPSize.JUMP);
+ len = pos - (codeLength + OPSize.JUMP);
addOpcodeRelAddr(OPCode.JUMP, len);
}
} while ((aln = aln.cdr) != null);
@@ -105,9 +115,13 @@ final class ArrayCompiler extends Compiler {
op == OPCode.EXACTN_IC_SB;
}
+ private boolean opTemplated(int op) {
+ return isNeedStrLenOpExact(op);
+ }
+
private int selectStrOpcode(int mbLength, int strLength, boolean ignoreCase) {
int op;
-
+
if (ignoreCase) {
switch(strLength) {
case 1: op = enc.toLowerCaseTable() != null ? OPCode.EXACT1_IC_SB : OPCode.EXACT1_IC; break;
@@ -135,6 +149,7 @@ final class ArrayCompiler extends Compiler {
break;
case 3:
op = OPCode.EXACTMB3N;
+ break;
default:
op = OPCode.EXACTMBN;
} // switch
@@ -144,15 +159,15 @@ final class ArrayCompiler extends Compiler {
private void compileTreeEmptyCheck(Node node, int emptyInfo) {
int savedNumNullCheck = regex.numNullCheck;
-
+
if (emptyInfo != 0) {
addOpcode(OPCode.NULL_CHECK_START);
addMemNum(regex.numNullCheck); /* NULL CHECK ID */
regex.numNullCheck++;
}
-
+
compileTree(node);
-
+
if (emptyInfo != 0) {
switch(emptyInfo) {
case TargetInfo.IS_EMPTY:
@@ -165,20 +180,23 @@ final class ArrayCompiler extends Compiler {
addOpcode(OPCode.NULL_CHECK_END_MEMST_PUSH);
break;
} // switch
-
+
addMemNum(savedNumNullCheck); /* NULL CHECK ID */
}
}
private int addCompileStringlength(byte[]bytes, int p, int mbLength, int strLength, boolean ignoreCase) {
int op = selectStrOpcode(mbLength, strLength, ignoreCase);
-
int len = OPSize.OPCODE;
+ if (Config.USE_STRING_TEMPLATES && opTemplated(op)) {
+ // string length, template index, template string pointer
+ len += OPSize.LENGTH + OPSize.INDEX + OPSize.INDEX;
+ } else {
+ if (isNeedStrLenOpExact(op)) len += OPSize.LENGTH;
+ len += mbLength * strLength;
+ }
if (op == OPCode.EXACTMBN) len += OPSize.LENGTH;
- if (isNeedStrLenOpExact(op)) len += OPSize.LENGTH;
-
- len += mbLength * strLength;
return len;
}
@@ -186,34 +204,41 @@ final class ArrayCompiler extends Compiler {
protected final void addCompileString(byte[]bytes, int p, int mbLength, int strLength, boolean ignoreCase) {
int op = selectStrOpcode(mbLength, strLength, ignoreCase);
addOpcode(op);
-
+
if (op == OPCode.EXACTMBN) addLength(mbLength);
-
+
if (isNeedStrLenOpExact(op)) {
if (op == OPCode.EXACTN_IC || op == OPCode.EXACTN_IC_SB) {
addLength(mbLength * strLength);
} else {
- addLength(strLength);
+ addLength(strLength);
}
}
- addBytes(bytes, p, mbLength * strLength);
+
+ if (Config.USE_STRING_TEMPLATES && opTemplated(op)) {
+ addInt(templateNum);
+ addInt(p);
+ addTemplate(bytes);
+ } else {
+ addBytes(bytes, p, mbLength * strLength);
+ }
}
private int compileLengthStringNode(Node node) {
StringNode sn = (StringNode)node;
if (sn.length() <= 0) return 0;
boolean ambig = sn.isAmbig();
-
+
int p, prev;
p = prev = sn.p;
int end = sn.end;
byte[]bytes = sn.bytes;
int prevLen = enc.length(bytes, p, end);
p += prevLen;
-
+
int slen = 1;
int rlen = 0;
-
+
while (p < end) {
int len = enc.length(bytes, p, end);
if (len == prevLen) {
@@ -231,9 +256,9 @@ final class ArrayCompiler extends Compiler {
rlen += r;
return rlen;
}
-
+
private int compileLengthStringRawNode(StringNode sn) {
- if (sn.length() <= 0) return 0;
+ if (sn.length() <= 0) return 0;
return addCompileStringlength(sn.bytes, sn.p, 1 /*sb*/, sn.length(), false);
}
@@ -241,7 +266,7 @@ final class ArrayCompiler extends Compiler {
addLength(mbuf.used);
addInts(mbuf.p, mbuf.used);
}
-
+
private int compileLengthCClassNode(CClassNode cc) {
if (cc.isShare()) return OPSize.OPCODE + OPSize.POINTER;
@@ -254,7 +279,7 @@ final class ArrayCompiler extends Compiler {
} else {
len = OPSize.OPCODE + BitSet.BITSET_SIZE;
}
-
+
len += OPSize.LENGTH + cc.mbuf.used;
}
return len;
@@ -267,7 +292,7 @@ final class ArrayCompiler extends Compiler {
addPointer(cc);
return;
}
-
+
if (cc.mbuf == null) {
if (cc.isNot()) {
addOpcode(enc.isSingleByte() ? OPCode.CCLASS_NOT_SB : OPCode.CCLASS_NOT);
@@ -282,7 +307,7 @@ final class ArrayCompiler extends Compiler {
} else {
addOpcode(OPCode.CCLASS_MB);
}
- addMultiByteCClass(cc.mbuf);
+ addMultiByteCClass(cc.mbuf);
} else {
if (cc.isNot()) {
addOpcode(OPCode.CCLASS_MIX_NOT);
@@ -308,17 +333,17 @@ final class ArrayCompiler extends Compiler {
op = enc.isSingleByte() ? OPCode.WORD_SB : OPCode.WORD;
}
break;
-
+
default:
newInternalException(ERR_PARSER_BUG);
- return; // not reached
+ return; // not reached
} // inner switch
addOpcode(op);
}
@Override
protected void compileAnyCharNode() {
- if (isMultiline(regex.options)) {
+ if (isMultiline(regex.options)) {
addOpcode(enc.isSingleByte() ? OPCode.ANYCHAR_ML_SB : OPCode.ANYCHAR_ML);
} else {
addOpcode(enc.isSingleByte() ? OPCode.ANYCHAR_SB : OPCode.ANYCHAR);
@@ -328,7 +353,7 @@ final class ArrayCompiler extends Compiler {
@Override
protected void compileCallNode(CallNode node) {
addOpcode(OPCode.CALL);
- node.unsetAddrList.add(regex.codeLength, node.target);
+ node.unsetAddrList.add(codeLength, node.target);
addAbsAddr(0); /*dummy addr.*/
}
@@ -341,7 +366,7 @@ final class ArrayCompiler extends Compiler {
addLength(br.nestLevel);
// !goto add_bacref_mems;!
addLength(br.backNum);
- for (int i=br.backNum-1; i>=0; i--) addMemNum(br.back[i]);
+ for (int i=br.backNum-1; i>=0; i--) addMemNum(br.back[i]);
return;
} else { // USE_BACKREF_AT_LEVEL
if (br.backNum == 1) {
@@ -370,7 +395,7 @@ final class ArrayCompiler extends Compiler {
}
// !add_bacref_mems:!
addLength(br.backNum);
- for (int i=br.backNum-1; i>=0; i--) addMemNum(br.back[i]);
+ for (int i=br.backNum-1; i>=0; i--) addMemNum(br.back[i]);
}
}
}
@@ -388,45 +413,45 @@ final class ArrayCompiler extends Compiler {
System.arraycopy(regex.repeatRangeHi, 0, tmp, 0, regex.repeatRangeHi.length);
regex.repeatRangeHi = tmp;
}
-
+
regex.repeatRangeLo[id] = lower;
regex.repeatRangeHi[id] = isRepeatInfinite(upper) ? 0x7fffffff : upper;
}
-
+
private void compileRangeRepeatNode(QuantifierNode qn, int targetLen, int emptyInfo) {
int numRepeat = regex.numRepeat;
addOpcode(qn.greedy ? OPCode.REPEAT : OPCode.REPEAT_NG);
addMemNum(numRepeat); /* OP_REPEAT ID */
regex.numRepeat++;
addRelAddr(targetLen + OPSize.REPEAT_INC);
-
+
entryRepeatRange(numRepeat, qn.lower, qn.upper);
-
+
compileTreeEmptyCheck(qn.target, emptyInfo);
-
+
if ((Config.USE_SUBEXP_CALL && regex.numCall > 0) || qn.isInRepeat()) {
addOpcode(qn.greedy ? OPCode.REPEAT_INC_SG : OPCode.REPEAT_INC_NG_SG);
} else {
- addOpcode(qn.greedy ? OPCode.REPEAT_INC : OPCode.REPEAT_INC_NG);
+ addOpcode(qn.greedy ? OPCode.REPEAT_INC : OPCode.REPEAT_INC_NG);
}
-
+
addMemNum(numRepeat); /* OP_REPEAT ID */
}
-
+
private static final int QUANTIFIER_EXPAND_LIMIT_SIZE = 50; // was 50
- private static boolean cknOn(int ckn) {
+ private static boolean cknOn(int ckn) {
return ckn > 0;
}
-
+
private int compileCECLengthQuantifierNode(QuantifierNode qn) {
boolean infinite = isRepeatInfinite(qn.upper);
int emptyInfo = qn.targetEmptyInfo;
-
+
int tlen = compileLengthTree(qn.target);
int ckn = regex.numCombExpCheck > 0 ? qn.combExpCheckNum : 0;
int cklen = cknOn(ckn) ? OPSize.STATE_CHECK_NUM : 0;
-
+
/* anychar repeat */
if (qn.target.getType() == NodeType.CANY) {
if (qn.greedy && infinite) {
@@ -437,14 +462,14 @@ final class ArrayCompiler extends Compiler {
}
}
}
-
+
int modTLen;
if (emptyInfo != 0) {
modTLen = tlen + (OPSize.NULL_CHECK_START + OPSize.NULL_CHECK_END);
} else {
modTLen = tlen;
}
-
+
int len;
if (infinite && qn.lower <= 1) {
if (qn.greedy) {
@@ -482,7 +507,7 @@ final class ArrayCompiler extends Compiler {
len = OPSize.PUSH + cklen + OPSize.JUMP + tlen;
} else {
len = OPSize.REPEAT_INC + modTLen + OPSize.OPCODE + OPSize.RELADDR + OPSize.MEMNUM;
-
+
if (cknOn(ckn)) {
len += OPSize.STATE_CHECK;
}
@@ -494,11 +519,11 @@ final class ArrayCompiler extends Compiler {
protected void compileCECQuantifierNode(QuantifierNode qn) {
boolean infinite = isRepeatInfinite(qn.upper);
int emptyInfo = qn.targetEmptyInfo;
-
+
int tlen = compileLengthTree(qn.target);
-
+
int ckn = regex.numCombExpCheck > 0 ? qn.combExpCheckNum : 0;
-
+
if (qn.isAnyCharStar()) {
compileTreeNTimes(qn.target, qn.lower);
if (qn.nextHeadExact != null && !cknOn(ckn)) {
@@ -533,7 +558,7 @@ final class ArrayCompiler extends Compiler {
return;
}
}
-
+
int modTLen;
if (emptyInfo != 0) {
modTLen = tlen + (OPSize.NULL_CHECK_START + OPSize.NULL_CHECK_END);
@@ -594,7 +619,7 @@ final class ArrayCompiler extends Compiler {
} else {
addOpcodeRelAddr(OPCode.PUSH, OPSize.JUMP);
}
-
+
addOpcodeRelAddr(OPCode.JUMP, tlen);
compileTree(qn.target);
} else {
@@ -609,7 +634,7 @@ final class ArrayCompiler extends Compiler {
private int compileNonCECLengthQuantifierNode(QuantifierNode qn) {
boolean infinite = isRepeatInfinite(qn.upper);
int emptyInfo = qn.targetEmptyInfo;
-
+
int tlen = compileLengthTree(qn.target);
/* anychar repeat */
@@ -622,14 +647,14 @@ final class ArrayCompiler extends Compiler {
}
}
}
-
+
int modTLen = 0;
if (emptyInfo != 0) {
modTLen = tlen + (OPSize.NULL_CHECK_START + OPSize.NULL_CHECK_END);
} else {
modTLen = tlen;
}
-
+
int len;
if (infinite && (qn.lower <= 1 || tlen * qn.lower <= QUANTIFIER_EXPAND_LIMIT_SIZE)) {
if (qn.lower == 1 && tlen > QUANTIFIER_EXPAND_LIMIT_SIZE) {
@@ -637,7 +662,7 @@ final class ArrayCompiler extends Compiler {
} else {
len = tlen * qn.lower;
}
-
+
if (qn.greedy) {
if (qn.headExact != null) {
len += OPSize.PUSH_OR_JUMP_EXACT1 + modTLen + OPSize.JUMP;
@@ -647,13 +672,13 @@ final class ArrayCompiler extends Compiler {
len += OPSize.PUSH + modTLen + OPSize.JUMP;
}
} else {
- len += OPSize.JUMP + modTLen + OPSize.PUSH;
+ len += OPSize.JUMP + modTLen + OPSize.PUSH;
}
-
+
} else if (qn.upper == 0 && qn.isRefered) { /* /(?<n>..){0}/ */
len = OPSize.JUMP + tlen;
} else if (!infinite && qn.greedy &&
- (qn.upper == 1 || (tlen + OPSize.PUSH) * qn.upper <= QUANTIFIER_EXPAND_LIMIT_SIZE )) {
+ (qn.upper == 1 || (tlen + OPSize.PUSH) * qn.upper <= QUANTIFIER_EXPAND_LIMIT_SIZE )) {
len = tlen * qn.lower;
len += (OPSize.PUSH + tlen) * (qn.upper - qn.lower);
} else if (!qn.greedy && qn.upper == 1 && qn.lower == 0) { /* '??' */
@@ -663,14 +688,14 @@ final class ArrayCompiler extends Compiler {
}
return len;
}
-
+
@Override
protected void compileNonCECQuantifierNode(QuantifierNode qn) {
boolean infinite = isRepeatInfinite(qn.upper);
int emptyInfo = qn.targetEmptyInfo;
-
- int tlen = compileLengthTree(qn.target);
-
+
+ int tlen = compileLengthTree(qn.target);
+
if (qn.isAnyCharStar()) {
compileTreeNTimes(qn.target, qn.lower);
if (qn.nextHeadExact != null) {
@@ -691,7 +716,7 @@ final class ArrayCompiler extends Compiler {
return;
}
}
-
+
int modTLen;
if (emptyInfo != 0) {
modTLen = tlen + (OPSize.NULL_CHECK_START + OPSize.NULL_CHECK_END);
@@ -714,7 +739,7 @@ final class ArrayCompiler extends Compiler {
} else {
compileTreeNTimes(qn.target, qn.lower);
}
-
+
if (qn.greedy) {
if (qn.headExact != null) {
addOpcodeRelAddr(OPCode.PUSH_OR_JUMP_EXACT1, modTLen + OPSize.JUMP);
@@ -722,7 +747,7 @@ final class ArrayCompiler extends Compiler {
addBytes(sn.bytes, sn.p, 1);
compileTreeEmptyCheck(qn.target, emptyInfo);
addOpcodeRelAddr(OPCode.JUMP, -(modTLen + OPSize.JUMP + OPSize.PUSH_OR_JUMP_EXACT1));
- } else if (qn.nextHeadExact != null) {
+ } else if (qn.nextHeadExact != null) {
addOpcodeRelAddr(OPCode.PUSH_IF_PEEK_NEXT, modTLen + OPSize.JUMP);
StringNode sn = (StringNode)qn.nextHeadExact;
addBytes(sn.bytes, sn.p, 1);
@@ -741,11 +766,11 @@ final class ArrayCompiler extends Compiler {
} else if (qn.upper == 0 && qn.isRefered) { /* /(?<n>..){0}/ */
addOpcodeRelAddr(OPCode.JUMP, tlen);
compileTree(qn.target);
- } else if (!infinite && qn.greedy &&
+ } else if (!infinite && qn.greedy &&
(qn.upper == 1 || (tlen + OPSize.PUSH) * qn.upper <= QUANTIFIER_EXPAND_LIMIT_SIZE)) {
int n = qn.upper - qn.lower;
compileTreeNTimes(qn.target, qn.lower);
-
+
for (int i=0; i<n; i++) {
addOpcodeRelAddr(OPCode.PUSH, (n - i) * tlen + (n - i - 1) * OPSize.PUSH);
compileTree(qn.target);
@@ -764,7 +789,7 @@ final class ArrayCompiler extends Compiler {
regex.options = node.option;
int tlen = compileLengthTree(node.target);
regex.options = prev;
-
+
if (isDynamic(prev ^ node.option)) {
return OPSize.SET_OPTION_PUSH + OPSize.SET_OPTION + OPSize.FAIL + tlen + OPSize.SET_OPTION;
} else {
@@ -775,17 +800,17 @@ final class ArrayCompiler extends Compiler {
@Override
protected void compileOptionNode(EncloseNode node) {
int prev = regex.options;
-
+
if (isDynamic(prev ^ node.option)) {
addOpcodeOption(OPCode.SET_OPTION_PUSH, node.option);
addOpcodeOption(OPCode.SET_OPTION, prev);
addOpcode(OPCode.FAIL);
}
-
+
regex.options = node.option;
compileTree(node.target);
regex.options = prev;
-
+
if (isDynamic(prev ^ node.option)) {
addOpcodeOption(OPCode.SET_OPTION, prev);
}
@@ -795,14 +820,14 @@ final class ArrayCompiler extends Compiler {
if (node.isOption()) {
return compileLengthOptionNode(node);
}
-
+
int tlen;
if (node.target != null) {
tlen = compileLengthTree(node.target);
} else {
tlen = 0;
}
-
+
int len;
switch (node.type) {
case EncloseType.MEMORY:
@@ -822,17 +847,17 @@ final class ArrayCompiler extends Compiler {
len += tlen + (bsAt(regex.btMemEnd, node.regNum) ? OPSize.MEMORY_END_PUSH : OPSize.MEMORY_END);
}
break;
-
+
case EncloseType.STOP_BACKTRACK:
if (node.isStopBtSimpleRepeat()) {
QuantifierNode qn = (QuantifierNode)node.target;
tlen = compileLengthTree(qn.target);
len = tlen * qn.lower + OPSize.PUSH + tlen + OPSize.POP + OPSize.JUMP;
- } else {
+ } else {
len = OPSize.PUSH_STOP_BT + tlen + OPSize.POP_STOP_BT;
}
break;
-
+
default:
newInternalException(ERR_PARSER_BUG);
return 0; // not reached
@@ -848,7 +873,7 @@ final class ArrayCompiler extends Compiler {
if (Config.USE_SUBEXP_CALL) {
if (node.isCalled()) {
addOpcode(OPCode.CALL);
- node.callAddr = regex.codeLength + OPSize.ABSADDR + OPSize.JUMP;
+ node.callAddr = codeLength + OPSize.ABSADDR + OPSize.JUMP;
node.setAddrFixed();
addAbsAddr(node.callAddr);
len = compileLengthTree(node.target);
@@ -861,16 +886,16 @@ final class ArrayCompiler extends Compiler {
addOpcodeRelAddr(OPCode.JUMP, len);
}
} // USE_SUBEXP_CALL
-
+
if (bsAt(regex.btMemStart, node.regNum)) {
addOpcode(OPCode.MEMORY_START_PUSH);
} else {
addOpcode(OPCode.MEMORY_START);
}
-
+
addMemNum(node.regNum);
compileTree(node.target);
-
+
if (Config.USE_SUBEXP_CALL && node.isCalled()) {
if (bsAt(regex.btMemEnd, node.regNum)) {
addOpcode(node.isRecursion() ? OPCode.MEMORY_END_PUSH_REC : OPCode.MEMORY_END_PUSH);
@@ -888,14 +913,14 @@ final class ArrayCompiler extends Compiler {
addMemNum(node.regNum);
}
break;
-
+
case EncloseType.STOP_BACKTRACK:
if (node.isStopBtSimpleRepeat()) {
QuantifierNode qn = (QuantifierNode)node.target;
-
+
compileTreeNTimes(qn.target, qn.lower);
-
- len = compileLengthTree(qn.target);
+
+ len = compileLengthTree(qn.target);
addOpcodeRelAddr(OPCode.PUSH, len + OPSize.POP + OPSize.JUMP);
compileTree(qn.target);
addOpcode(OPCode.POP);
@@ -906,13 +931,13 @@ final class ArrayCompiler extends Compiler {
addOpcode(OPCode.POP_STOP_BT);
}
break;
-
+
default:
newInternalException(ERR_PARSER_BUG);
break;
} // switch
}
-
+
private int compileLengthAnchorNode(AnchorNode node) {
int tlen;
if (node.target != null) {
@@ -920,25 +945,25 @@ final class ArrayCompiler extends Compiler {
} else {
tlen = 0;
}
-
+
int len;
switch (node.type) {
case AnchorType.PREC_READ:
len = OPSize.PUSH_POS + tlen + OPSize.POP_POS;
break;
-
+
case AnchorType.PREC_READ_NOT:
len = OPSize.PUSH_POS_NOT + tlen + OPSize.FAIL_POS;
break;
-
+
case AnchorType.LOOK_BEHIND:
len = OPSize.LOOK_BEHIND + tlen;
break;
-
+
case AnchorType.LOOK_BEHIND_NOT:
len = OPSize.PUSH_LOOK_BEHIND_NOT + tlen + OPSize.FAIL_LOOK_BEHIND_NOT;
break;
-
+
default:
len = OPSize.OPCODE;
break;
@@ -950,33 +975,33 @@ final class ArrayCompiler extends Compiler {
protected void compileAnchorNode(AnchorNode node) {
int len;
int n;
-
+
switch (node.type) {
case AnchorType.BEGIN_BUF: addOpcode(OPCode.BEGIN_BUF); break;
case AnchorType.END_BUF: addOpcode(OPCode.END_BUF); break;
- case AnchorType.BEGIN_LINE: addOpcode(OPCode.BEGIN_LINE); break;
+ case AnchorType.BEGIN_LINE: addOpcode(OPCode.BEGIN_LINE); break;
case AnchorType.END_LINE: addOpcode(OPCode.END_LINE); break;
case AnchorType.SEMI_END_BUF: addOpcode(OPCode.SEMI_END_BUF); break;
- case AnchorType.BEGIN_POSITION: addOpcode(OPCode.BEGIN_POSITION); break;
+ case AnchorType.BEGIN_POSITION: addOpcode(OPCode.BEGIN_POSITION); break;
- case AnchorType.WORD_BOUND:
+ case AnchorType.WORD_BOUND:
addOpcode(enc.isSingleByte() ? OPCode.WORD_BOUND_SB : OPCode.WORD_BOUND);
break;
-
+
case AnchorType.NOT_WORD_BOUND:
addOpcode(enc.isSingleByte() ? OPCode.NOT_WORD_BOUND_SB : OPCode.NOT_WORD_BOUND);
break;
-
+
case AnchorType.WORD_BEGIN:
if (Config.USE_WORD_BEGIN_END)
addOpcode(enc.isSingleByte() ? OPCode.WORD_BEGIN_SB : OPCode.WORD_BEGIN);
break;
-
+
case AnchorType.WORD_END:
if (Config.USE_WORD_BEGIN_END)
addOpcode(enc.isSingleByte() ? OPCode.WORD_END_SB : OPCode.WORD_END);
- break;
-
+ break;
+
case AnchorType.PREC_READ:
addOpcode(OPCode.PUSH_POS);
compileTree(node.target);
@@ -989,7 +1014,7 @@ final class ArrayCompiler extends Compiler {
compileTree(node.target);
addOpcode(OPCode.FAIL_POS);
break;
-
+
case AnchorType.LOOK_BEHIND:
addOpcode(enc.isSingleByte() ? OPCode.LOOK_BEHIND_SB : OPCode.LOOK_BEHIND);
if (node.charLength < 0) {
@@ -1001,7 +1026,7 @@ final class ArrayCompiler extends Compiler {
addLength(n);
compileTree(node.target);
break;
-
+
case AnchorType.LOOK_BEHIND_NOT:
len = compileLengthTree(node.target);
addOpcodeRelAddr(OPCode.PUSH_LOOK_BEHIND_NOT, len + OPSize.FAIL_LOOK_BEHIND_NOT);
@@ -1015,7 +1040,7 @@ final class ArrayCompiler extends Compiler {
compileTree(node.target);
addOpcode(OPCode.FAIL_LOOK_BEHIND_NOT);
break;
-
+
default:
newInternalException(ERR_PARSER_BUG);
} // switch
@@ -1023,7 +1048,7 @@ final class ArrayCompiler extends Compiler {
private int compileLengthTree(Node node) {
int len = 0;
-
+
switch (node.getType()) {
case NodeType.LIST:
ConsAltNode lin = (ConsAltNode)node;
@@ -1031,7 +1056,7 @@ final class ArrayCompiler extends Compiler {
len += compileLengthTree(lin.car);
} while ((lin = lin.cdr) != null);
break;
-
+
case NodeType.ALT:
ConsAltNode aln = (ConsAltNode)node;
int n = 0;
@@ -1041,7 +1066,7 @@ final class ArrayCompiler extends Compiler {
} while ((aln = aln.cdr) != null);
len += (OPSize.PUSH + OPSize.JUMP) * (n - 1);
break;
-
+
case NodeType.STR:
StringNode sn = (StringNode)node;
if (sn.isRaw()) {
@@ -1050,21 +1075,21 @@ final class ArrayCompiler extends Compiler {
len = compileLengthStringNode(sn);
}
break;
-
+
case NodeType.CCLASS:
len = compileLengthCClassNode((CClassNode)node);
break;
-
+
case NodeType.CTYPE:
case NodeType.CANY:
len = OPSize.OPCODE;
break;
-
+
case NodeType.BREF:
BackRefNode br = (BackRefNode)node;
-
+
if (Config.USE_BACKREF_WITH_LEVEL && br.isNestLevel()) {
- len = OPSize.OPCODE + OPSize.OPTION + OPSize.LENGTH +
+ len = OPSize.OPCODE + OPSize.OPTION + OPSize.LENGTH +
OPSize.LENGTH + (OPSize.MEMNUM * br.backNum);
} else { // USE_BACKREF_AT_LEVEL
if (br.backNum == 1) {
@@ -1075,14 +1100,14 @@ final class ArrayCompiler extends Compiler {
}
}
break;
-
+
case NodeType.CALL:
if (Config.USE_SUBEXP_CALL) {
len = OPSize.CALL;
break;
} // USE_SUBEXP_CALL
break;
-
+
case NodeType.QTFR:
if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
len = compileCECLengthQuantifierNode((QuantifierNode)node);
@@ -1090,74 +1115,74 @@ final class ArrayCompiler extends Compiler {
len = compileNonCECLengthQuantifierNode((QuantifierNode)node);
}
break;
-
+
case NodeType.ENCLOSE:
len = compileLengthEncloseNode((EncloseNode)node);
break;
-
+
case NodeType.ANCHOR:
len = compileLengthAnchorNode((AnchorNode)node);
break;
default:
newInternalException(ERR_PARSER_BUG);
-
+
} //switch
return len;
}
private void ensure(int size) {
- if (size >= regex.code.length) {
- int length = regex.code.length << 1;
+ if (size >= code.length) {
+ int length = code.length << 1;
while (length <= size) length <<= 1;
int[]tmp = new int[length];
- System.arraycopy(regex.code, 0, tmp, 0, regex.code.length);
- regex.code = tmp;
+ System.arraycopy(code, 0, tmp, 0, code.length);
+ code = tmp;
}
}
-
+
private void addInt(int i) {
- if (regex.codeLength >= regex.code.length) {
- int[]tmp = new int[regex.code.length << 1];
- System.arraycopy(regex.code, 0, tmp, 0, regex.code.length);
- regex.code = tmp;
+ if (codeLength >= code.length) {
+ int[]tmp = new int[code.length << 1];
+ System.arraycopy(code, 0, tmp, 0, code.length);
+ code = tmp;
}
- regex.code[regex.codeLength++] = i;
+ code[codeLength++] = i;
}
-
+
void setInt(int i, int offset) {
ensure(offset);
regex.code[offset] = i;
}
-
+
private void addObject(Object o) {
if (regex.operands == null) {
regex.operands = new Object[4];
} else if (regex.operandLength >= regex.operands.length) {
- Object[]tmp = new Object[regex.operands.length << 1];
- System.arraycopy(regex.operands, 0, tmp, 0, regex.operands.length);
- regex.operands = tmp;
+ Object[]tmp = new Object[regex.operands.length << 1];
+ System.arraycopy(regex.operands, 0, tmp, 0, regex.operands.length);
+ regex.operands = tmp;
}
addInt(regex.operandLength);
regex.operands[regex.operandLength++] = o;
}
-
+
private void addBytes(byte[]bytes, int p ,int length) {
- ensure(regex.codeLength + length);
+ ensure(codeLength + length);
int end = p + length;
-
- while (p < end) regex.code[regex.codeLength++] = bytes[p++];
+
+ while (p < end) code[codeLength++] = bytes[p++];
}
-
- private void addInts(int[]ints, int length) {
- ensure(regex.codeLength + length);
- System.arraycopy(ints, 0, regex.code, regex.codeLength, length);
- regex.codeLength += length;
+
+ private void addInts(int[]ints, int length) {
+ ensure(codeLength + length);
+ System.arraycopy(ints, 0, code, codeLength, length);
+ codeLength += length;
}
-
+
private void addOpcode(int opcode) {
addInt(opcode);
-
+
switch(opcode) {
case OPCode.ANYCHAR_STAR:
case OPCode.ANYCHAR_STAR_SB:
@@ -1165,11 +1190,11 @@ final class ArrayCompiler extends Compiler {
case OPCode.ANYCHAR_ML_STAR_SB:
case OPCode.ANYCHAR_STAR_PEEK_NEXT:
case OPCode.ANYCHAR_STAR_PEEK_NEXT_SB:
- case OPCode.ANYCHAR_ML_STAR_PEEK_NEXT:
+ case OPCode.ANYCHAR_ML_STAR_PEEK_NEXT:
case OPCode.ANYCHAR_ML_STAR_PEEK_NEXT_SB:
case OPCode.STATE_CHECK_ANYCHAR_STAR:
case OPCode.STATE_CHECK_ANYCHAR_STAR_SB:
- case OPCode.STATE_CHECK_ANYCHAR_ML_STAR:
+ case OPCode.STATE_CHECK_ANYCHAR_ML_STAR:
case OPCode.MEMORY_START_PUSH:
case OPCode.MEMORY_END_PUSH:
case OPCode.MEMORY_END_PUSH_REC:
@@ -1187,7 +1212,7 @@ final class ArrayCompiler extends Compiler {
case OPCode.REPEAT_INC_SG:
case OPCode.REPEAT_INC_NG:
case OPCode.REPEAT_INC_NG_SG:
- case OPCode.PUSH_POS:
+ case OPCode.PUSH_POS:
case OPCode.PUSH_POS_NOT:
case OPCode.PUSH_STOP_BT:
case OPCode.PUSH_LOOK_BEHIND_NOT:
@@ -1233,5 +1258,16 @@ final class ArrayCompiler extends Compiler {
private void addOpcodeOption(int opcode, int option) {
addOpcode(opcode);
addOption(option);
- }
+ }
+
+ private void addTemplate(byte[]bytes) {
+ if (templateNum == 0) {
+ templates = new byte[2][];
+ } else if (templateNum == templates.length) {
+ byte[][]tmp = new byte[templateNum * 2][];
+ System.arraycopy(templates, 0, tmp, 0, templateNum);
+ templates = tmp;
+ }
+ templates[templateNum++] = bytes;
+ }
}
diff --git a/src/org/joni/AsmCompiler.java b/src/org/joni/AsmCompiler.java
index 433d324..e39dc05 100644
--- a/src/org/joni/AsmCompiler.java
+++ b/src/org/joni/AsmCompiler.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -33,7 +33,7 @@ final class AsmCompiler extends AsmCompilerSupport {
public AsmCompiler(Analyser analyser) {
super(analyser);
}
-
+
@Override
protected void prepare() {
REG_NUM++;
@@ -44,7 +44,7 @@ final class AsmCompiler extends AsmCompilerSupport {
prepareFactory();
prepareFactoryInit();
}
-
+
@Override
protected void finish() {
setupFactoryInit();
diff --git a/src/org/joni/AsmCompilerSupport.java b/src/org/joni/AsmCompilerSupport.java
index 217aa8b..9f98015 100644
--- a/src/org/joni/AsmCompilerSupport.java
+++ b/src/org/joni/AsmCompilerSupport.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -32,7 +32,7 @@ abstract class AsmCompilerSupport extends Compiler implements Opcodes, AsmConsta
protected MethodVisitor factoryInit;// factory constructor
protected String factoryName;
- protected ClassWriter machine; // matcher
+ protected ClassWriter machine; // matcher
protected MethodVisitor machineInit;// matcher constructor
protected MethodVisitor match; // actual matcher implementation (the matchAt method)
protected String machineName;
@@ -40,7 +40,7 @@ abstract class AsmCompilerSupport extends Compiler implements Opcodes, AsmConsta
// we will? try to manage visitMaxs ourselves for efficiency
protected int maxStack = 1;
protected int maxVars = LAST_INDEX;
-
+
// for field generation
protected int bitsets, ranges, templates;
@@ -54,7 +54,7 @@ abstract class AsmCompilerSupport extends Compiler implements Opcodes, AsmConsta
}
};
- private static final DummyClassLoader loader = new DummyClassLoader();
+ private static final DummyClassLoader loader = new DummyClassLoader();
AsmCompilerSupport(Analyser analyser) {
super(analyser);
@@ -97,7 +97,7 @@ abstract class AsmCompilerSupport extends Compiler implements Opcodes, AsmConsta
machine = new ClassWriter(ClassWriter.COMPUTE_MAXS);
machineName = "org/joni/NativeMachine" + REG_NUM;
}
-
+
protected final void prepareMachineInit() {
machine.visit(V1_4, ACC_PUBLIC + ACC_FINAL, machineName, null, "org/joni/NativeMachine", null);
machineInit = machine.visitMethod(ACC_PROTECTED, "<init>", "(Lorg/joni/Regex;[BII)V", null, null);
@@ -108,7 +108,7 @@ abstract class AsmCompilerSupport extends Compiler implements Opcodes, AsmConsta
machineInit.visitVarInsn(ILOAD, 4); // end
machineInit.visitMethodInsn(INVOKESPECIAL, "org/joni/NativeMachine", "<init>", "(Lorg/joni/Regex;[BII)V");
}
-
+
protected final void setupMachineInit() {
if (bitsets + ranges + templates > 0) { // ok, some of these are in use, we'd like to cache the factory
machine.visitField(ACC_PRIVATE + ACC_FINAL, "factory", "L" + factoryName + ";", null, null);
@@ -129,7 +129,7 @@ abstract class AsmCompilerSupport extends Compiler implements Opcodes, AsmConsta
match = machine.visitMethod(ACC_SYNTHETIC, "matchAt", "(III)I", null, null);
move(S, SSTART); // s = sstart
load("bytes", "[B"); //
- astore(BYTES); // byte[]bytes = this.bytes
+ astore(BYTES); // byte[]bytes = this.bytes
}
protected final void setupMachineMatch() {
@@ -232,7 +232,7 @@ abstract class AsmCompilerSupport extends Compiler implements Opcodes, AsmConsta
factory.visitField(ACC_PRIVATE + ACC_FINAL, name, "[I", null, null);
factoryInit.visitVarInsn(ALOAD, THIS); // this;
loadInt(factoryInit, arr.length); // this, length
- factoryInit.visitIntInsn(NEWARRAY, T_INT); // this, arr
+ factoryInit.visitIntInsn(NEWARRAY, T_INT); // this, arr
for (int i=0;i < arr.length; i++) buildArray(i, arr[i], IASTORE);
factoryInit.visitFieldInsn(PUTFIELD, factoryName, name, "[I");
}
@@ -241,13 +241,13 @@ abstract class AsmCompilerSupport extends Compiler implements Opcodes, AsmConsta
factory.visitField(ACC_PRIVATE + ACC_FINAL, name, "[B", null, null);
factoryInit.visitVarInsn(ALOAD, THIS); // this;
loadInt(factoryInit, arr.length); // this, length
- factoryInit.visitIntInsn(NEWARRAY, T_BYTE); // this, arr
+ factoryInit.visitIntInsn(NEWARRAY, T_BYTE); // this, arr
for (int i=p, j=0; i < p + length; i++, j++) buildArray(j, arr[i] & 0xff, BASTORE);
factoryInit.visitFieldInsn(PUTFIELD, factoryName, name, "[B");
}
private void buildArray(int index, int value, int type) {
- factoryInit.visitInsn(DUP); // ... arr, arr
+ factoryInit.visitInsn(DUP); // ... arr, arr
loadInt(factoryInit, index); // ... arr, arr, index
loadInt(factoryInit, value); // ... arr, arr, index, value
factoryInit.visitInsn(type); // ... arr
@@ -255,13 +255,13 @@ abstract class AsmCompilerSupport extends Compiler implements Opcodes, AsmConsta
private void loadInt(MethodVisitor mv, int value) {
if (value >= -1 && value <= 5) {
- mv.visitInsn(value + ICONST_0); // ICONST_0 == 3
+ mv.visitInsn(value + ICONST_0); // ICONST_0 == 3
} else if (value >= 6 && value <= 127 || value >= -128 && value <= -2) {
mv.visitIntInsn(BIPUSH, value);
} else if (value >= 128 && value <= 32767 || value >= -32768 && value <= -129) {
mv.visitIntInsn(SIPUSH, value);
} else {
- mv.visitLdcInsn(new Integer(value));
+ mv.visitLdcInsn(new Integer(value));
}
}
}
diff --git a/src/org/joni/BitSet.java b/src/org/joni/BitSet.java
index 3d9cf99..b58d5eb 100644
--- a/src/org/joni/BitSet.java
+++ b/src/org/joni/BitSet.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -25,7 +25,7 @@ public final class BitSet {
private static final int BITS_IN_ROOM = 4 * BITS_PER_BYTE;
static final int BITSET_SIZE = (SINGLE_BYTE_SIZE / BITS_IN_ROOM);
static final int ROOM_SHIFT = log2(BITS_IN_ROOM);
-
+
final int[] bits = new int[BITSET_SIZE];
private static final int BITS_TO_STRING_WRAP = 4;
@@ -38,23 +38,23 @@ public final class BitSet {
}
return buffer.toString();
}
-
+
public boolean at(int pos) {
return (bits[pos >>> ROOM_SHIFT] & bit(pos)) != 0;
}
public void set(int pos) {
- bits[pos >>> ROOM_SHIFT] |= bit(pos);
+ bits[pos >>> ROOM_SHIFT] |= bit(pos);
}
public void clear(int pos) {
- bits[pos >>> ROOM_SHIFT] &= ~bit(pos);
+ bits[pos >>> ROOM_SHIFT] &= ~bit(pos);
}
public void invert(int pos) {
bits[pos >>> ROOM_SHIFT] ^= bit(pos);
}
-
+
public void clear() {
for (int i=0; i<BITSET_SIZE; i++) bits[i]=0;
}
@@ -69,11 +69,11 @@ public final class BitSet {
public void setRange(int from, int to) {
for (int i=from; i<=to && i < SINGLE_BYTE_SIZE; i++) set(i);
}
-
+
public void setAll() {
for (int i=0; i<BITSET_SIZE; i++) bits[i] = ~0;
}
-
+
public void invert() {
for (int i=0; i<BITSET_SIZE; i++) bits[i] = ~bits[i];
}
@@ -101,11 +101,11 @@ public final class BitSet {
}
return num;
}
-
+
static int bit(int pos){
return 1 << (pos % SINGLE_BYTE_SIZE);
}
-
+
private static int log2(int n){
int log = 0;
while ((n >>>= 1) != 0) log++;
diff --git a/src/org/joni/BitStatus.java b/src/org/joni/BitStatus.java
index 1440170..0c68616 100644
--- a/src/org/joni/BitStatus.java
+++ b/src/org/joni/BitStatus.java
@@ -1,27 +1,27 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
final class BitStatus {
public static final int BIT_STATUS_BITS_NUM = 4 * 8;
-
+
public static int bsClear() {
return 0;
}
@@ -29,9 +29,9 @@ final class BitStatus {
return -1;
}
public static boolean bsAt(int stats, int n) {
- return (n < BIT_STATUS_BITS_NUM ? stats & (1 << n) : (stats & 1)) != 0;
+ return (n < BIT_STATUS_BITS_NUM ? stats & (1 << n) : (stats & 1)) != 0;
}
- public static int bsOnAt(int stats, int n) {
+ public static int bsOnAt(int stats, int n) {
if (n < BIT_STATUS_BITS_NUM) {
stats |= (1 << n);
} else {
@@ -43,7 +43,7 @@ final class BitStatus {
if (n < BIT_STATUS_BITS_NUM) stats |= (1 << n);
return stats;
}
-
+
public static int bsOnOff(int v, int f, boolean negative) {
if (negative) {
v &= ~f;
diff --git a/src/org/joni/ByteCodeMachine.java b/src/org/joni/ByteCodeMachine.java
index 9ca1988..9056166 100644
--- a/src/org/joni/ByteCodeMachine.java
+++ b/src/org/joni/ByteCodeMachine.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -40,7 +40,7 @@ class ByteCodeMachine extends StackMachine {
private int bestLen; // return value
private int s = 0; // current char
- private int range; // right range
+ private int range; // right range
private int sprev;
private int sstart;
private int sbegin;
@@ -58,7 +58,7 @@ class ByteCodeMachine extends StackMachine {
//CaptureTreeNode child;
int k = stkp;
//int k = kp;
-
+
while (k < stk) {
StackEntry e = stack[k];
if (e.type == MEM_START) {
@@ -70,7 +70,7 @@ class ByteCodeMachine extends StackMachine {
node.addChild(child);
stkp = k + 1;
if (makeCaptureHistoryTree(child)) return true;
-
+
k = stkp;
child.end = e.getMemPStr() - str;
}
@@ -93,12 +93,12 @@ class ByteCodeMachine extends StackMachine {
node = region.historyRoot;
node.clear();
}
-
+
// was clear ???
node.group = 0;
node.beg = sstart - str;
node.end = s - str;
-
+
stkp = 0;
makeCaptureHistoryTree(region.historyRoot);
}
@@ -113,11 +113,11 @@ class ByteCodeMachine extends StackMachine {
protected final byte[]cfbuf2() {
return cfbuf2 == null ? cfbuf2 = new byte[Config.ENC_MBC_CASE_FOLD_MAXLEN] : cfbuf2;
}
-
+
private boolean stringCmpIC(int caseFlodFlag, int s1, IntHolder ps2, int mbLen, int textEnd) {
byte[]buf1 = cfbuf();
byte[]buf2 = cfbuf2();
-
+
int s2 = ps2.value;
int end1 = s1 + mbLen;
@@ -128,11 +128,11 @@ class ByteCodeMachine extends StackMachine {
value = s2;
int len2 = enc.mbcCaseFold(caseFlodFlag, bytes, this, textEnd, buf2);
s2 = value;
-
+
if (len1 != len2) return false;
int p1 = 0;
int p2 = 0;
-
+
while (len1-- > 0) {
if (buf1[p1] != buf2[p2]) return false;
p1++; p2++;
@@ -141,16 +141,16 @@ class ByteCodeMachine extends StackMachine {
ps2.value = s2;
return true;
}
-
+
private void debugMatchBegin() {
Config.log.println("match_at: " +
"str: " + str +
", end: " + end +
- ", start: " + this.sstart +
+ ", start: " + this.sstart +
", sprev: " + this.sprev);
Config.log.println("size: " + (end - str) + ", start offset: " + (this.sstart - str));
}
-
+
private void debugMatchLoop() {
if (Config.DEBUG_MATCH) {
Config.log.printf("%4d", (s - str)).print("> \"");
@@ -166,28 +166,28 @@ class ByteCodeMachine extends StackMachine {
StringBuilder sb = new StringBuilder();
new ByteCodePrinter(regex).compiledByteCodeToString(sb, ip);
Config.log.println(sb.toString());
- }
+ }
}
-
+
protected final int matchAt(int range, int sstart, int sprev) {
this.range = range;
this.sstart = sstart;
this.sprev = sprev;
-
+
stk = 0;
ip = 0;
-
+
if (Config.DEBUG_MATCH) debugMatchBegin();
-
+
init();
-
+
bestLen = -1;
s = sstart;
final int[]code = this.code;
while (true) {
if (Config.DEBUG_MATCH) debugMatchLoop();
-
+
sbegin = s;
switch (code[ip++]) {
case OPCode.END: if (opEnd()) return finish(); break;
@@ -215,7 +215,7 @@ class ByteCodeMachine extends StackMachine {
case OPCode.CCLASS_MB_NOT: opCClassMBNot(); break;
case OPCode.CCLASS_MIX_NOT: opCClassMIXNot(); break;
case OPCode.CCLASS_NODE: opCClassNode(); break;
-
+
case OPCode.ANYCHAR: opAnyChar(); break;
case OPCode.ANYCHAR_ML: opAnyCharML(); break;
case OPCode.ANYCHAR_STAR: opAnyCharStar(); break;
@@ -224,28 +224,28 @@ class ByteCodeMachine extends StackMachine {
case OPCode.ANYCHAR_ML_STAR_PEEK_NEXT: opAnyCharMLStarPeekNext(); break;
case OPCode.STATE_CHECK_ANYCHAR_STAR: opStateCheckAnyCharStar(); break;
case OPCode.STATE_CHECK_ANYCHAR_ML_STAR:opStateCheckAnyCharMLStar();break;
-
+
case OPCode.WORD: opWord(); break;
case OPCode.NOT_WORD: opNotWord(); break;
case OPCode.WORD_BOUND: opWordBound(); continue;
case OPCode.NOT_WORD_BOUND: opNotWordBound(); continue;
case OPCode.WORD_BEGIN: opWordBegin(); continue;
case OPCode.WORD_END: opWordEnd(); continue;
-
+
case OPCode.BEGIN_BUF: opBeginBuf(); continue;
case OPCode.END_BUF: opEndBuf(); continue;
case OPCode.BEGIN_LINE: opBeginLine(); continue;
case OPCode.END_LINE: opEndLine(); continue;
case OPCode.SEMI_END_BUF: opSemiEndBuf(); continue;
case OPCode.BEGIN_POSITION: opBeginPosition(); continue;
-
+
case OPCode.MEMORY_START_PUSH: opMemoryStartPush(); continue;
case OPCode.MEMORY_START: opMemoryStart(); continue;
case OPCode.MEMORY_END_PUSH: opMemoryEndPush(); continue;
case OPCode.MEMORY_END: opMemoryEnd(); continue;
case OPCode.MEMORY_END_PUSH_REC: opMemoryEndPushRec(); continue;
case OPCode.MEMORY_END_REC: opMemoryEndRec(); continue;
-
+
case OPCode.BACKREF1: opBackRef1(); continue;
case OPCode.BACKREF2: opBackRef2(); continue;
case OPCode.BACKREFN: opBackRefN(); continue;
@@ -253,50 +253,50 @@ class ByteCodeMachine extends StackMachine {
case OPCode.BACKREF_MULTI: opBackRefMulti(); continue;
case OPCode.BACKREF_MULTI_IC: opBackRefMultiIC(); continue;
case OPCode.BACKREF_WITH_LEVEL: opBackRefAtLevel(); continue;
-
+
case OPCode.NULL_CHECK_START: opNullCheckStart(); continue;
case OPCode.NULL_CHECK_END: opNullCheckEnd(); continue;
case OPCode.NULL_CHECK_END_MEMST: opNullCheckEndMemST(); continue;
case OPCode.NULL_CHECK_END_MEMST_PUSH: opNullCheckEndMemSTPush(); continue;
-
+
case OPCode.JUMP: opJump(); continue;
case OPCode.PUSH: opPush(); continue;
-
+
// CEC
case OPCode.STATE_CHECK_PUSH: opStateCheckPush(); continue;
case OPCode.STATE_CHECK_PUSH_OR_JUMP: opStateCheckPushOrJump(); continue;
case OPCode.STATE_CHECK: opStateCheck(); continue;
-
+
case OPCode.POP: opPop(); continue;
case OPCode.PUSH_OR_JUMP_EXACT1: opPushOrJumpExact1(); continue;
case OPCode.PUSH_IF_PEEK_NEXT: opPushIfPeekNext(); continue;
-
+
case OPCode.REPEAT: opRepeat(); continue;
case OPCode.REPEAT_NG: opRepeatNG(); continue;
case OPCode.REPEAT_INC: opRepeatInc(); continue;
case OPCode.REPEAT_INC_SG: opRepeatIncSG(); continue;
case OPCode.REPEAT_INC_NG: opRepeatIncNG(); continue;
case OPCode.REPEAT_INC_NG_SG: opRepeatIncNGSG(); continue;
-
+
case OPCode.PUSH_POS: opPushPos(); continue;
case OPCode.POP_POS: opPopPos(); continue;
case OPCode.PUSH_POS_NOT: opPushPosNot(); continue;
case OPCode.FAIL_POS: opFailPos(); continue;
case OPCode.PUSH_STOP_BT: opPushStopBT(); continue;
case OPCode.POP_STOP_BT: opPopStopBT(); continue;
-
+
case OPCode.LOOK_BEHIND: opLookBehind(); continue;
case OPCode.PUSH_LOOK_BEHIND_NOT: opPushLookBehindNot(); continue;
case OPCode.FAIL_LOOK_BEHIND_NOT: opFailLookBehindNot(); continue;
-
+
// USE_SUBEXP_CALL
case OPCode.CALL: opCall(); continue;
case OPCode.RETURN: opReturn(); continue;
-
+
// single byte implementations
case OPCode.CCLASS_SB: opCClassSb(); break;
- case OPCode.CCLASS_NOT_SB: opCClassNotSb(); break;
-
+ case OPCode.CCLASS_NOT_SB: opCClassNotSb(); break;
+
case OPCode.ANYCHAR_SB: opAnyCharSb(); break;
case OPCode.ANYCHAR_ML_SB: opAnyCharMLSb(); break;
case OPCode.ANYCHAR_STAR_SB: opAnyCharStarSb(); break;
@@ -305,14 +305,14 @@ class ByteCodeMachine extends StackMachine {
case OPCode.ANYCHAR_ML_STAR_PEEK_NEXT_SB: opAnyCharMLStarPeekNextSb(); break;
case OPCode.STATE_CHECK_ANYCHAR_STAR_SB: opStateCheckAnyCharStarSb(); break;
case OPCode.STATE_CHECK_ANYCHAR_ML_STAR_SB: opStateCheckAnyCharMLStarSb();break;
-
+
case OPCode.WORD_SB: opWordSb(); break;
case OPCode.NOT_WORD_SB: opNotWordSb(); break;
case OPCode.WORD_BOUND_SB: opWordBoundSb(); continue;
case OPCode.NOT_WORD_BOUND_SB: opNotWordBoundSb(); continue;
case OPCode.WORD_BEGIN_SB: opWordBeginSb(); continue;
case OPCode.WORD_END_SB: opWordEndSb(); continue;
-
+
case OPCode.LOOK_BEHIND_SB: opLookBehindSb(); continue;
case OPCode.EXACT1_IC_SB: opExact1ICSb(); break;
@@ -320,19 +320,19 @@ class ByteCodeMachine extends StackMachine {
case OPCode.FINISH:
return finish();
-
+
case OPCode.FAIL: opFail(); continue;
-
+
default:
throw new InternalException(ErrorMessages.ERR_UNDEFINED_BYTECODE);
-
+
} // main switch
} // main while
}
private boolean opEnd() {
int n = s - sstart;
-
+
if (n > bestLen) {
if (Config.USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE) {
if (isFindLongest(regex.options)) {
@@ -345,7 +345,7 @@ class ByteCodeMachine extends StackMachine {
}
}
} // USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
-
+
bestLen = n;
final Region region = msaRegion;
if (region != null) {
@@ -357,25 +357,25 @@ class ByteCodeMachine extends StackMachine {
if (repeatStk[memEndStk + i] != INVALID_INDEX) {
region.beg[i] = bsAt(regex.btMemStart, i) ?
stack[repeatStk[memStartStk + i]].getMemPStr() - str :
- repeatStk[memStartStk + i] - str;
-
-
+ repeatStk[memStartStk + i] - str;
+
+
region.end[i] = bsAt(regex.btMemEnd, i) ?
stack[repeatStk[memEndStk + i]].getMemPStr() :
repeatStk[memEndStk + i] - str;
-
+
} else {
region.beg[i] = region.end[i] = Region.REGION_NOTPOS;
}
-
+
}
-
+
if (Config.USE_CAPTURE_HISTORY) {
if (regex.captureHistory != 0) checkCaptureHistory(region);
}
} else {
msaBegin = sstart - str;
- msaEnd = s - str;
+ msaEnd = s - str;
}
} else {
Region region = msaRegion;
@@ -393,13 +393,13 @@ class ByteCodeMachine extends StackMachine {
} else {
msaBegin = msaEnd = 0;
}
- } // USE_POSIX_REGION_OPTION
+ } // USE_POSIX_REGION_OPTION
}
// end_best_len:
/* default behavior: return first-matching result. */
return endBestLength();
}
-
+
private boolean endBestLength() {
if (isFindCondition(regex.options)) {
if (isFindNotEmpty(regex.options) && s == sstart) {
@@ -416,11 +416,11 @@ class ByteCodeMachine extends StackMachine {
private void opExact1() {
if (s >= range || code[ip] != bytes[s++]) {opFail(); return;}
- //if (s > range) {opFail(); return;}
+ //if (s > range) {opFail(); return;}
ip++;
sprev = sbegin; // break;
}
-
+
private void opExact2() {
if (s + 2 > range) {opFail(); return;}
if (code[ip] != bytes[s]) {opFail(); return;}
@@ -440,7 +440,7 @@ class ByteCodeMachine extends StackMachine {
sprev = s;
ip++; s++;
}
-
+
private void opExact4() {
if (s + 4 > range) {opFail(); return;}
if (code[ip] != bytes[s]) {opFail(); return;}
@@ -453,7 +453,7 @@ class ByteCodeMachine extends StackMachine {
sprev = s;
ip++; s++;
}
-
+
private void opExact5() {
if (s + 5 > range) {opFail(); return;}
if (code[ip] != bytes[s]) {opFail(); return;}
@@ -468,12 +468,20 @@ class ByteCodeMachine extends StackMachine {
sprev = s;
ip++; s++;
}
-
+
private void opExactN() {
- int tlen = code[ip++];
+ int tlen = code[ip++];
if (s + tlen > range) {opFail(); return;}
-
- while (tlen-- > 0) if (code[ip++] != bytes[s++]) {opFail(); return;}
+
+ if (Config.USE_STRING_TEMPLATES) {
+ byte[]bs = regex.templates[code[ip++]];
+ int ps = code[ip++];
+
+ while (tlen-- > 0) if (bs[ps++] != bytes[s++]) {opFail(); return;}
+
+ } else {
+ while (tlen-- > 0) if (code[ip++] != bytes[s++]) {opFail(); return;}
+ }
sprev = s - 1;
}
@@ -485,7 +493,7 @@ class ByteCodeMachine extends StackMachine {
ip++; s++;
sprev = sbegin; // break;
}
-
+
private void opExactMB2N2() {
if (s + 4 > range) {opFail(); return;}
if (code[ip] != bytes[s]) {opFail(); return;}
@@ -498,7 +506,7 @@ class ByteCodeMachine extends StackMachine {
if (code[ip] != bytes[s]) {opFail(); return;}
ip++; s++;
}
-
+
private void opExactMB2N3() {
if (s + 6 > range) {opFail(); return;}
if (code[ip] != bytes[s]) {opFail(); return;}
@@ -515,58 +523,96 @@ class ByteCodeMachine extends StackMachine {
if (code[ip] != bytes[s]) {opFail(); return;}
ip++; s++;
}
-
- private void opExactMB2N() {
+
+ private void opExactMB2N() {
int tlen = code[ip++];
- if (tlen * 2 > range) {opFail(); return;}
-
- while(tlen-- > 0) {
- if (code[ip] != bytes[s]) {opFail(); return;}
- ip++; s++;
- if (code[ip] != bytes[s]) {opFail(); return;}
- ip++; s++;
+ if (s + tlen * 2 > range) {opFail(); return;}
+
+ if (Config.USE_STRING_TEMPLATES) {
+ byte[]bs = regex.templates[code[ip++]];
+ int ps = code[ip++];
+
+ while(tlen-- > 0) {
+ if (bs[ps] != bytes[s]) {opFail(); return;}
+ ps++; s++;
+ if (bs[ps] != bytes[s]) {opFail(); return;}
+ ps++; s++;
+ }
+ } else {
+ while(tlen-- > 0) {
+ if (code[ip] != bytes[s]) {opFail(); return;}
+ ip++; s++;
+ if (code[ip] != bytes[s]) {opFail(); return;}
+ ip++; s++;
+ }
}
sprev = s - 2;
}
-
+
private void opExactMB3N() {
int tlen = code[ip++];
- if (tlen * 3 > range) {opFail(); return;}
-
- while (tlen-- > 0) {
- if (code[ip] != bytes[s]) {opFail(); return;}
- ip++; s++;
- if (code[ip] != bytes[s]) {opFail(); return;}
- ip++; s++;
- if (code[ip] != bytes[s]) {opFail(); return;}
- ip++; s++;
+ if (s + tlen * 3 > range) {opFail(); return;}
+
+ if (Config.USE_STRING_TEMPLATES) {
+ byte[]bs = regex.templates[code[ip++]];
+ int ps = code[ip++];
+
+ while (tlen-- > 0) {
+ if (bs[ps] != bytes[s]) {opFail(); return;}
+ ps++; s++;
+ if (bs[ps] != bytes[s]) {opFail(); return;}
+ ps++; s++;
+ if (bs[ps] != bytes[s]) {opFail(); return;}
+ ps++; s++;
+ }
+ } else {
+ while (tlen-- > 0) {
+ if (code[ip] != bytes[s]) {opFail(); return;}
+ ip++; s++;
+ if (code[ip] != bytes[s]) {opFail(); return;}
+ ip++; s++;
+ if (code[ip] != bytes[s]) {opFail(); return;}
+ ip++; s++;
+ }
}
+
sprev = s - 3;
}
-
+
private void opExactMBN() {
int tlen = code[ip++]; /* mb-len */
int tlen2= code[ip++]; /* string len */
-
+
tlen2 *= tlen;
if (s + tlen2 > range) {opFail(); return;}
-
- while(tlen2-- > 0) {
- if (code[ip] != bytes[s]) {opFail(); return;}
- ip++; s++;
+
+ if (Config.USE_STRING_TEMPLATES) {
+ byte[]bs = regex.templates[code[ip++]];
+ int ps = code[ip++];
+
+ while (tlen2-- > 0) {
+ if (bs[ps] != bytes[s]) {opFail(); return;}
+ ps++; s++;
+ }
+ } else {
+ while (tlen2-- > 0) {
+ if (code[ip] != bytes[s]) {opFail(); return;}
+ ip++; s++;
+ }
}
+
sprev = s - tlen;
}
-
+
private void opExact1IC() {
if (s >= range) {opFail(); return;}
-
+
byte[]lowbuf = cfbuf();
-
+
value = s;
int len = enc.mbcCaseFold(regex.caseFoldFlag, bytes, this, end, lowbuf);
s = value;
-
+
if (s > range) {opFail(); return;}
int q = 0;
@@ -576,7 +622,7 @@ class ByteCodeMachine extends StackMachine {
}
sprev = sbegin; // break;
}
-
+
private void opExact1ICSb() {
if (s >= range || code[ip] != enc.toLowerCaseTable()[bytes[s++] & 0xff]) {opFail(); return;}
ip++;
@@ -585,40 +631,73 @@ class ByteCodeMachine extends StackMachine {
private void opExactNIC() {
int tlen = code[ip++];
- int endp = ip + tlen;
-
byte[]lowbuf = cfbuf();
-
- while (ip < endp) {
- sprev = s;
- if (s >= range) {opFail(); return;}
-
- value = s;
- int len = enc.mbcCaseFold(regex.caseFoldFlag, bytes, this, end, lowbuf);
- s = value;
-
- if (s > range) {opFail(); return;}
- int q = 0;
- while (len-- > 0) {
- if (code[ip] != lowbuf[q]) {opFail(); return;}
- ip++; q++;
+
+ if (Config.USE_STRING_TEMPLATES) {
+ byte[]bs = regex.templates[code[ip++]];
+ int ps = code[ip++];
+ int endp = ps + tlen;
+
+ while (ps < endp) {
+ sprev = s;
+ if (s >= range) {opFail(); return;}
+
+ value = s;
+ int len = enc.mbcCaseFold(regex.caseFoldFlag, bytes, this, end, lowbuf);
+ s = value;
+
+ if (s > range) {opFail(); return;}
+ int q = 0;
+ while (len-- > 0) {
+ if (bs[ps] != lowbuf[q]) {opFail(); return;}
+ ps++; q++;
+ }
+ }
+ } else {
+ int endp = ip + tlen;
+
+ while (ip < endp) {
+ sprev = s;
+ if (s >= range) {opFail(); return;}
+
+ value = s;
+ int len = enc.mbcCaseFold(regex.caseFoldFlag, bytes, this, end, lowbuf);
+ s = value;
+
+ if (s > range) {opFail(); return;}
+ int q = 0;
+ while (len-- > 0) {
+ if (code[ip] != lowbuf[q]) {opFail(); return;}
+ ip++; q++;
+ }
}
}
+
}
-
+
private void opExactNICSb() {
- int tlen = code[ip++];
+ int tlen = code[ip++];
if (s + tlen > range) {opFail(); return;}
- byte[]toLowerTable = enc.toLowerCaseTable();
- while (tlen-- > 0) if (code[ip++] != toLowerTable[bytes[s++] & 0xff]) {opFail(); return;}
+
+ if (Config.USE_STRING_TEMPLATES) {
+ byte[]bs = regex.templates[code[ip++]];
+ int ps = code[ip++];
+ byte[]toLowerTable = enc.toLowerCaseTable();
+
+ while (tlen-- > 0) if (bs[ps++] != toLowerTable[bytes[s++] & 0xff]) {opFail(); return;}
+ } else {
+ byte[]toLowerTable = enc.toLowerCaseTable();
+
+ while (tlen-- > 0) if (code[ip++] != toLowerTable[bytes[s++] & 0xff]) {opFail(); return;}
+ }
sprev = s - 1;
- }
-
+ }
+
private boolean isInBitSet() {
int c = bytes[s] & 0xff;
return ((code[ip + (c >>> BitSet.ROOM_SHIFT)] & (1 << c)) != 0);
}
-
+
private void opCClass() {
if (s >= range || !isInBitSet()) {opFail(); return;}
ip += BitSet.BITSET_SIZE;
@@ -626,16 +705,16 @@ class ByteCodeMachine extends StackMachine {
if (s > end) s = end;
sprev = sbegin; // break;
}
-
+
private void opCClassSb() {
if (s >= range || !isInBitSet()) {opFail(); return;}
ip += BitSet.BITSET_SIZE;
s++;
sprev = sbegin; // break;
- }
-
+ }
+
private boolean isInClassMB() {
- int tlen = code[ip++];
+ int tlen = code[ip++];
if (s >= range) return false;
int mbLen = enc.length(bytes, s, end);
if (s + mbLen > range) return false;
@@ -644,16 +723,16 @@ class ByteCodeMachine extends StackMachine {
int c = enc.mbcToCode(bytes, ss, s);
if (!CodeRange.isInCodeRange(code, ip, c)) return false;
ip += tlen;
- return true;
+ return true;
}
-
+
private void opCClassMB() {
- // beyond string check
+ // beyond string check
if (s >= range || !enc.isMbcHead(bytes, s, end)) {opFail(); return;}
if (!isInClassMB()) {opFail(); return;} // not!!!
sprev = sbegin; // break;
}
-
+
private void opCClassMIX() {
if (s >= range) {opFail(); return;}
if (enc.isMbcHead(bytes, s, end)) {
@@ -668,7 +747,7 @@ class ByteCodeMachine extends StackMachine {
}
sprev = sbegin; // break;
}
-
+
private void opCClassNot() {
if (s >= range || isInBitSet()) {opFail(); return;}
ip += BitSet.BITSET_SIZE;
@@ -676,34 +755,34 @@ class ByteCodeMachine extends StackMachine {
if (s > end) s = end;
sprev = sbegin; // break;
}
-
+
private void opCClassNotSb() {
if (s >= range || isInBitSet()) {opFail(); return;}
ip += BitSet.BITSET_SIZE;
s++;
sprev = sbegin; // break;
- }
-
+ }
+
private boolean isNotInClassMB() {
int tlen = code[ip++];
int mbLen = enc.length(bytes, s, end);
-
+
if (!(s + mbLen <= range)) {
if (s >= range) return false;
s = end;
ip += tlen;
return true;
}
-
+
int ss = s;
s += mbLen;
int c = enc.mbcToCode(bytes, ss, s);
-
+
if (CodeRange.isInCodeRange(code, ip, c)) return false;
ip += tlen;
return true;
- }
-
+ }
+
private void opCClassMBNot() {
if (s >= range) {opFail(); return;}
if (!enc.isMbcHead(bytes, s, end)) {
@@ -716,7 +795,7 @@ class ByteCodeMachine extends StackMachine {
if (!isNotInClassMB()) {opFail(); return;}
sprev = sbegin; // break;
}
-
+
private void opCClassMIXNot() {
if (s >= range) {opFail(); return;}
if (enc.isMbcHead(bytes, s, end)) {
@@ -731,7 +810,7 @@ class ByteCodeMachine extends StackMachine {
}
sprev = sbegin; // break;
}
-
+
private void opCClassNode() {
if (s >= range) {opFail(); return;}
CClassNode cc = (CClassNode)regex.operands[code[ip++]];
@@ -743,7 +822,7 @@ class ByteCodeMachine extends StackMachine {
if (!cc.isCodeInCCLength(mbLen, c)) {opFail(); return;}
sprev = sbegin; // break;
}
-
+
private void opAnyChar() {
if (s >= range) {opFail(); return;}
int n = enc.length(bytes, s, end);
@@ -752,28 +831,28 @@ class ByteCodeMachine extends StackMachine {
s += n;
sprev = sbegin; // break;
}
-
+
private void opAnyCharSb() {
if (s >= range) {opFail(); return;}
if (bytes[s] == Encoding.NEW_LINE) {opFail(); return;}
s++;
sprev = sbegin; // break;
}
-
+
private void opAnyCharML() {
if (s >= range) {opFail(); return;}
int n = enc.length(bytes, s, end);
if (s + n > range) {opFail(); return;}
- s += n;
- sprev = sbegin; // break;
+ s += n;
+ sprev = sbegin; // break;
}
private void opAnyCharMLSb() {
if (s >= range) {opFail(); return;}
s++;
- sprev = sbegin; // break;
+ sprev = sbegin; // break;
}
-
+
private void opAnyCharStar() {
final byte[]bytes = this.bytes;
while (s < range) {
@@ -786,7 +865,7 @@ class ByteCodeMachine extends StackMachine {
}
sprev = sbegin; // break;
}
-
+
private void opAnyCharStarSb() {
final byte[]bytes = this.bytes;
while (s < range) {
@@ -797,7 +876,7 @@ class ByteCodeMachine extends StackMachine {
}
sprev = sbegin; // break;
}
-
+
private void opAnyCharMLStar() {
final byte[]bytes = this.bytes;
while (s < range) {
@@ -818,11 +897,11 @@ class ByteCodeMachine extends StackMachine {
}
sprev = sbegin; // break;
}
-
+
private void opAnyCharStarPeekNext() {
final byte c = (byte)code[ip];
final byte[]bytes = this.bytes;
-
+
while (s < range) {
if (c == bytes[s]) pushAlt(ip + 1, s, sprev);
int n = enc.length(bytes, s, end);
@@ -833,11 +912,11 @@ class ByteCodeMachine extends StackMachine {
ip++;
sprev = sbegin; // break;
}
-
+
private void opAnyCharStarPeekNextSb() {
final byte c = (byte)code[ip];
final byte[]bytes = this.bytes;
-
+
while (s < range) {
byte b = bytes[s];
if (c == b) pushAlt(ip + 1, s, sprev);
@@ -848,11 +927,11 @@ class ByteCodeMachine extends StackMachine {
ip++;
sprev = sbegin; // break;
}
-
+
private void opAnyCharMLStarPeekNext() {
final byte c = (byte)code[ip];
final byte[]bytes = this.bytes;
-
+
while (s < range) {
if (c == bytes[s]) pushAlt(ip + 1, s, sprev);
int n = enc.length(bytes, s, end);
@@ -863,7 +942,7 @@ class ByteCodeMachine extends StackMachine {
ip++;
sprev = sbegin; // break;
}
-
+
private void opAnyCharMLStarPeekNextSb() {
final byte c = (byte)code[ip];
final byte[]bytes = this.bytes;
@@ -876,12 +955,12 @@ class ByteCodeMachine extends StackMachine {
ip++;
sprev = sbegin; // break;
}
-
+
// CEC
private void opStateCheckAnyCharStar() {
int mem = code[ip++];
final byte[]bytes = this.bytes;
-
+
while (s < range) {
if (stateCheckVal(s, mem)) {opFail(); return;}
pushAltWithStateCheck(ip, s, sprev, mem);
@@ -892,11 +971,11 @@ class ByteCodeMachine extends StackMachine {
}
sprev = sbegin; // break;
}
-
+
private void opStateCheckAnyCharStarSb() {
int mem = code[ip++];
final byte[]bytes = this.bytes;
-
+
while (s < range) {
if (stateCheckVal(s, mem)) {opFail(); return;}
pushAltWithStateCheck(ip, s, sprev, mem);
@@ -906,12 +985,12 @@ class ByteCodeMachine extends StackMachine {
}
sprev = sbegin; // break;
}
-
+
// CEC
private void opStateCheckAnyCharMLStar() {
int mem = code[ip++];
-
- final byte[]bytes = this.bytes;
+
+ final byte[]bytes = this.bytes;
while (s < range) {
if (stateCheckVal(s, mem)) {opFail(); return;}
pushAltWithStateCheck(ip, s, sprev, mem);
@@ -922,10 +1001,10 @@ class ByteCodeMachine extends StackMachine {
}
sprev = sbegin; // break;
}
-
+
private void opStateCheckAnyCharMLStarSb() {
int mem = code[ip++];
-
+
while (s < range) {
if (stateCheckVal(s, mem)) {opFail(); return;}
pushAltWithStateCheck(ip, s, sprev, mem);
@@ -934,7 +1013,7 @@ class ByteCodeMachine extends StackMachine {
}
sprev = sbegin; // break;
}
-
+
private void opWord() {
if (s >= range || !enc.isMbcWord(bytes, s, end)) {opFail(); return;}
s += enc.length(bytes, s, end);
@@ -943,22 +1022,22 @@ class ByteCodeMachine extends StackMachine {
private void opWordSb() {
if (s >= range || !enc.isWord(bytes[s] & 0xff)) {opFail(); return;}
- s++;
+ s++;
sprev = sbegin; // break;
}
-
+
private void opNotWord() {
if (s >= range || enc.isMbcWord(bytes, s, end)) {opFail(); return;}
s += enc.length(bytes, s, end);
sprev = sbegin; // break;
}
-
+
private void opNotWordSb() {
if (s >= range || enc.isWord(bytes[s] & 0xff)) {opFail(); return;}
s++;
sprev = sbegin; // break;
}
-
+
private void opWordBound() {
if (s == str) {
if (s >= range || !enc.isMbcWord(bytes, s, end)) {opFail(); return;}
@@ -968,7 +1047,7 @@ class ByteCodeMachine extends StackMachine {
if (enc.isMbcWord(bytes, s, end) == enc.isMbcWord(bytes, sprev, end)) {opFail(); return;}
}
}
-
+
private void opWordBoundSb() {
if (s == str) {
if (s >= range || !enc.isWord(bytes[s] & 0xff)) {opFail(); return;}
@@ -978,7 +1057,7 @@ class ByteCodeMachine extends StackMachine {
if (enc.isWord(bytes[s] & 0xff) == enc.isWord(bytes[sprev] & 0xff)) {opFail(); return;}
}
}
-
+
private void opNotWordBound() {
if (s == str) {
if (s < range && enc.isMbcWord(bytes, s, end)) {opFail(); return;}
@@ -998,7 +1077,7 @@ class ByteCodeMachine extends StackMachine {
if (enc.isWord(bytes[s] & 0xff) != enc.isWord(bytes[sprev] & 0xff)) {opFail(); return;}
}
}
-
+
private void opWordBegin() {
if (s < range && enc.isMbcWord(bytes, s, end)) {
if (s == str || !enc.isMbcWord(bytes, sprev, end)) return;
@@ -1012,7 +1091,7 @@ class ByteCodeMachine extends StackMachine {
}
opFail();
}
-
+
private void opWordEnd() {
if (s != str && enc.isMbcWord(bytes, sprev, end)) {
if (s == end || !enc.isMbcWord(bytes, s, end)) return;
@@ -1026,15 +1105,15 @@ class ByteCodeMachine extends StackMachine {
}
opFail();
}
-
+
private void opBeginBuf() {
if (s != str) opFail();
}
-
+
private void opEndBuf() {
if (s != end) opFail();
}
-
+
private void opBeginLine() {
if (s == str) {
if (isNotBol(msaOptions)) opFail();
@@ -1044,7 +1123,7 @@ class ByteCodeMachine extends StackMachine {
}
opFail();
}
-
+
private void opEndLine() {
if (s == end) {
if (Config.USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE) {
@@ -1061,7 +1140,7 @@ class ByteCodeMachine extends StackMachine {
}
opFail();
}
-
+
private void opSemiEndBuf() {
if (s == end) {
if (Config.USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE) {
@@ -1091,162 +1170,162 @@ class ByteCodeMachine extends StackMachine {
int mem = code[ip++];
pushMemStart(mem, s);
}
-
+
private void opMemoryStart() {
int mem = code[ip++];
repeatStk[memStartStk + mem] = s;
}
-
+
private void opMemoryEndPush() {
int mem = code[ip++];
pushMemEnd(mem, s);
}
-
+
private void opMemoryEnd() {
int mem = code[ip++];
repeatStk[memEndStk + mem] = s;
}
-
+
private void opMemoryEndPushRec() {
int mem = code[ip++];
int stkp = getMemStart(mem); /* should be before push mem-end. */
pushMemEnd(mem, s);
repeatStk[memStartStk + mem] = stkp;
}
-
+
private void opMemoryEndRec() {
int mem = code[ip++];
repeatStk[memEndStk + mem] = s;
int stkp = getMemStart(mem);
-
+
if (BitStatus.bsAt(regex.btMemStart, mem)) {
repeatStk[memStartStk + mem] = stkp;
} else {
repeatStk[memStartStk + mem] = stack[stkp].getMemPStr();
}
-
+
pushMemEndMark(mem);
}
-
+
private boolean backrefInvalid(int mem) {
return repeatStk[memEndStk + mem] == INVALID_INDEX || repeatStk[memStartStk + mem] == INVALID_INDEX;
}
-
+
private int backrefStart(int mem) {
return bsAt(regex.btMemStart, mem) ? stack[repeatStk[memStartStk + mem]].getMemPStr() : repeatStk[memStartStk + mem];
}
-
+
private int backrefEnd(int mem) {
return bsAt(regex.btMemEnd, mem) ? stack[repeatStk[memEndStk + mem]].getMemPStr() : repeatStk[memEndStk + mem];
}
-
+
private void backref(int mem) {
/* if you want to remove following line,
you should check in parse and compile time. (numMem) */
if (mem > regex.numMem || backrefInvalid(mem)) {opFail(); return;}
-
+
int pstart = backrefStart(mem);
int pend = backrefEnd(mem);
-
+
int n = pend - pstart;
if (s + n > range) {opFail(); return;}
sprev = s;
-
+
// STRING_CMP
while(n-- > 0) if (bytes[pstart++] != bytes[s++]) {opFail(); return;}
int len;
-
+
// beyond string check
if (sprev < range) {
while (sprev + (len = enc.length(bytes, sprev, end)) < s) sprev += len;
}
}
-
+
private void opBackRef1() {
backref(1);
}
-
+
private void opBackRef2() {
backref(2);
}
-
+
private void opBackRefN() {
backref(code[ip++]);
}
-
+
private void opBackRefNIC() {
int mem = code[ip++];
- /* if you want to remove following line,
+ /* if you want to remove following line,
you should check in parse and compile time. (numMem) */
if (mem > regex.numMem || backrefInvalid(mem)) {opFail(); return;}
int pstart = backrefStart(mem);
int pend = backrefEnd(mem);
-
+
int n = pend - pstart;
if (s + n > range) {opFail(); return;}
sprev = s;
-
- value = s;
+
+ value = s;
if (!stringCmpIC(regex.caseFoldFlag, pstart, this, n, end)) {opFail(); return;}
s = value;
-
+
int len;
// if (sprev < bytes.length)
while (sprev + (len = enc.length(bytes, sprev, end)) < s) sprev += len;
}
-
+
private void opBackRefMulti() {
int tlen = code[ip++];
-
+
int i;
loop:for (i=0; i<tlen; i++) {
int mem = code[ip++];
if (backrefInvalid(mem)) continue;
-
+
int pstart = backrefStart(mem);
int pend = backrefEnd(mem);
-
+
int n = pend - pstart;
if (s + n > range) {opFail(); return;}
-
+
sprev = s;
int swork = s;
-
+
while (n-- > 0) {
if (bytes[pstart++] != bytes[swork++]) continue loop;
}
-
+
s = swork;
-
+
int len;
// beyond string check
if (sprev < range) {
while (sprev + (len = enc.length(bytes, sprev, end)) < s) sprev += len;
}
-
+
ip += tlen - i - 1; // * SIZE_MEMNUM (1)
break; /* success */
}
if (i == tlen) {opFail(); return;}
}
-
+
private void opBackRefMultiIC() {
int tlen = code[ip++];
-
+
int i;
loop:for (i=0; i<tlen; i++) {
int mem = code[ip++];
if (backrefInvalid(mem)) continue;
-
+
int pstart = backrefStart(mem);
int pend = backrefEnd(mem);
-
+
int n = pend - pstart;
if (s + n > range) {opFail(); return;}
-
+
sprev = s;
value = s;
@@ -1256,13 +1335,13 @@ class ByteCodeMachine extends StackMachine {
int len;
// if (sprev < bytes.length)
while (sprev + (len = enc.length(bytes, sprev, end)) < s) sprev += len;
-
+
ip += tlen - i - 1; // * SIZE_MEMNUM (1)
break; /* success */
}
if (i == tlen) {opFail(); return;}
}
-
+
private boolean memIsInMemp(int mem, int num, int memp) {
for (int i=0; i<num; i++) {
int m = code[memp++];
@@ -1270,9 +1349,9 @@ class ByteCodeMachine extends StackMachine {
}
return false;
}
-
+
// USE_BACKREF_AT_LEVEL // (s) and (end) implicit
- private boolean backrefMatchAtNestedLevel(boolean ignoreCase, int caseFoldFlag,
+ private boolean backrefMatchAtNestedLevel(boolean ignoreCase, int caseFoldFlag,
int nest, int memNum, int memp) {
int pend = -1;
int level = 0;
@@ -1280,7 +1359,7 @@ class ByteCodeMachine extends StackMachine {
while (k >= 0) {
StackEntry e = stack[k];
-
+
if (e.type == CALL_FRAME) {
level--;
} else if (e.type == RETURN) {
@@ -1317,13 +1396,13 @@ class ByteCodeMachine extends StackMachine {
k--;
}
return false;
- }
-
+ }
+
private void opBackRefAtLevel() {
int ic = code[ip++];
int level = code[ip++];
int tlen = code[ip++];
-
+
sprev = s;
if (backrefMatchAtNestedLevel(ic != 0, regex.caseFoldFlag, level, tlen, ip)) { // (s) and (end) implicit
int len;
@@ -1349,7 +1428,7 @@ class ByteCodeMachine extends StackMachine {
int mem = code[ip++];
pushNullCheckStart(mem, s);
}
-
+
private void nullCheckFound() {
// null_check_found:
/* empty loop founded, skip next instruction */
@@ -1366,69 +1445,69 @@ class ByteCodeMachine extends StackMachine {
break;
default:
throw new InternalException(ErrorMessages.ERR_UNEXPECTED_BYTECODE);
- } // switch
+ } // switch
}
-
+
private void opNullCheckEnd() {
int mem = code[ip++];
int isNull = nullCheck(mem, s); /* mem: null check id */
-
+
if (isNull != 0) {
if (Config.DEBUG_MATCH) {
Config.log.println("NULL_CHECK_END: skip id:" + mem + ", s:" + s);
}
-
+
nullCheckFound();
}
}
-
+
// USE_INFINITE_REPEAT_MONOMANIAC_MEM_STATUS_CHECK
private void opNullCheckEndMemST() {
int mem = code[ip++]; /* mem: null check id */
int isNull = nullCheckMemSt(mem, s);
-
+
if (isNull != 0) {
if (Config.DEBUG_MATCH) {
Config.log.println("NULL_CHECK_END_MEMST: skip id:" + mem + ", s:" + s);
}
-
+
if (isNull == -1) {opFail(); return;}
nullCheckFound();
}
}
-
+
// USE_SUBEXP_CALL
private void opNullCheckEndMemSTPush() {
int mem = code[ip++]; /* mem: null check id */
-
+
int isNull;
if (Config.USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT) {
isNull = nullCheckMemStRec(mem, s);
} else {
isNull = nullCheckRec(mem, s);
}
-
+
if (isNull != 0) {
if (Config.DEBUG_MATCH) {
Config.log.println("NULL_CHECK_END_MEMST_PUSH: skip id:" + mem + ", s:" + s);
- }
-
+ }
+
if (isNull == -1) {opFail(); return;}
nullCheckFound();
} else {
pushNullCheckEnd(mem);
}
}
-
+
private void opJump() {
ip += code[ip] + 1;
}
-
+
private void opPush() {
int addr = code[ip++];
pushAlt(ip + addr, s, sprev);
}
-
+
// CEC
private void opStateCheckPush() {
int mem = code[ip++];
@@ -1436,43 +1515,44 @@ class ByteCodeMachine extends StackMachine {
int addr = code[ip++];
pushAltWithStateCheck(ip + addr, s, sprev, mem);
}
-
+
// CEC
private void opStateCheckPushOrJump() {
int mem = code[ip++];
int addr= code[ip++];
-
+
if (stateCheckVal(s, mem)) {
ip += addr;
} else {
pushAltWithStateCheck(ip + addr, s, sprev, mem);
}
}
-
+
// CEC
private void opStateCheck() {
int mem = code[ip++];
if (stateCheckVal(s, mem)) {opFail(); return;}
pushStateCheck(s, mem);
}
-
+
private void opPop() {
popOne();
}
-
+
private void opPushOrJumpExact1() {
int addr = code[ip++];
- if (code[ip] == bytes[s] && s < range) {
+ // beyond string check
+ if (s < range && code[ip] == bytes[s]) {
ip++;
pushAlt(ip + addr, s, sprev);
return;
}
ip += addr + 1;
}
-
+
private void opPushIfPeekNext() {
int addr = code[ip++];
- // beyond string check
+ // beyond string check
if (s < range && code[ip] == bytes[s]) {
ip++;
pushAlt(ip + addr, s, sprev);
@@ -1480,39 +1560,39 @@ class ByteCodeMachine extends StackMachine {
}
ip++;
}
-
+
private void opRepeat() {
int mem = code[ip++]; /* mem: OP_REPEAT ID */
int addr= code[ip++];
-
+
// ensure1();
repeatStk[mem] = stk;
pushRepeat(mem, ip);
-
+
if (regex.repeatRangeLo[mem] == 0) { // lower
pushAlt(ip + addr, s, sprev);
}
}
-
+
private void opRepeatNG() {
int mem = code[ip++]; /* mem: OP_REPEAT ID */
int addr= code[ip++];
-
+
// ensure1();
repeatStk[mem] = stk;
pushRepeat(mem, ip);
-
+
if (regex.repeatRangeLo[mem] == 0) {
pushAlt(ip, s, sprev);
ip += addr;
}
}
-
+
private void repeatInc(int mem, int si) {
StackEntry e = stack[si];
-
+
e.increaseRepeatCount();
-
+
if (e.getRepeatCount() >= regex.repeatRangeHi[mem]) {
/* end of repeat. Nothing to do. */
} else if (e.getRepeatCount() >= regex.repeatRangeLo[mem]) {
@@ -1523,24 +1603,24 @@ class ByteCodeMachine extends StackMachine {
}
pushRepeatInc(si);
}
-
+
private void opRepeatInc() {
- int mem = code[ip++]; /* mem: OP_REPEAT ID */
- int si = repeatStk[mem];
+ int mem = code[ip++]; /* mem: OP_REPEAT ID */
+ int si = repeatStk[mem];
repeatInc(mem, si);
}
-
+
private void opRepeatIncSG() {
int mem = code[ip++]; /* mem: OP_REPEAT ID */
int si = getRepeat(mem);
repeatInc(mem, si);
}
-
+
private void repeatIncNG(int mem, int si) {
StackEntry e = stack[si];
-
+
e.increaseRepeatCount();
-
+
if (e.getRepeatCount() < regex.repeatRangeHi[mem]) {
if (e.getRepeatCount() >= regex.repeatRangeLo[mem]) {
int pcode = e.getRepeatPCode();
@@ -1554,43 +1634,43 @@ class ByteCodeMachine extends StackMachine {
pushRepeatInc(si);
}
}
-
+
private void opRepeatIncNG() {
int mem = code[ip++];
int si = repeatStk[mem];
repeatIncNG(mem, si);
}
-
+
private void opRepeatIncNGSG() {
int mem = code[ip++];
int si = getRepeat(mem);
repeatIncNG(mem, si);
}
-
+
private void opPushPos() {
pushPos(s, sprev);
}
-
+
private void opPopPos() {
StackEntry e = stack[posEnd()];
s = e.getStatePStr();
- sprev= e.getStatePStrPrev();
+ sprev= e.getStatePStrPrev();
}
-
+
private void opPushPosNot() {
int addr = code[ip++];
pushPosNot(ip + addr, s, sprev);
}
-
+
private void opFailPos() {
popTilPosNot();
opFail();
}
-
+
private void opPushStopBT() {
pushStopBT();
}
-
+
private void opPopStopBT() {
stopBtEnd();
}
@@ -1606,9 +1686,9 @@ class ByteCodeMachine extends StackMachine {
int tlen = code[ip++];
s -= tlen;
if (s < str) {opFail(); return;}
- sprev = s == str ? -1 : s - 1;
+ sprev = s == str ? -1 : s - 1;
}
-
+
private void opPushLookBehindNot() {
int addr = code[ip++];
int tlen = code[ip++];
@@ -1629,25 +1709,25 @@ class ByteCodeMachine extends StackMachine {
popTilLookBehindNot();
opFail();
}
-
+
private void opCall() {
int addr = code[ip++];
pushCallFrame(ip);
ip = addr; // absolute address
}
-
+
private void opReturn() {
ip = sreturn();
pushReturn();
}
-
+
private void opFail() {
if (stack == null) {
ip = regex.codeLength - 1;
return;
}
-
+
StackEntry e = pop();
ip = e.getStatePCode();
s = e.getStatePStr();
@@ -1660,7 +1740,7 @@ class ByteCodeMachine extends StackMachine {
}
}
}
-
+
private int finish() {
return bestLen;
}
diff --git a/src/org/joni/ByteCodePrinter.java b/src/org/joni/ByteCodePrinter.java
index 5efb353..77938da 100644
--- a/src/org/joni/ByteCodePrinter.java
+++ b/src/org/joni/ByteCodePrinter.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -27,42 +27,57 @@ import org.joni.constants.OPSize;
import org.joni.exception.InternalException;
class ByteCodePrinter {
- int[]code;
- int codeLength;
-
+ final int[]code;
+ final int codeLength;
+ final byte[][] templates;
+
Object[]operands;
int operantCount;
Encoding enc;
WarnCallback warnings;
-
+
public ByteCodePrinter(Regex regex) {
code = regex.code;
codeLength = regex.codeLength;
operands = regex.operands;
operantCount = regex.operandLength;
- enc = regex.enc;
+
+ templates = regex.templates;
+ enc = regex.enc;
warnings = regex.warnings;
}
-
+
public String byteCodeListToString() {
return compiledByteCodeListToString();
}
-
+
private void pString(StringBuilder sb, int len, int s) {
sb.append(":");
while (len-- > 0) sb.append(new String(new byte[]{(byte)code[s++]}));
}
-
+
+ private void pStringFromTemplate(StringBuilder sb, int len, byte[]tm, int idx) {
+ sb.append(":T:");
+ while (len-- > 0) sb.append(new String(new byte[]{tm[idx++]}));
+ }
+
private void pLenString(StringBuilder sb, int len, int mbLen, int s) {
int x = len * mbLen;
sb.append(":" + len + ":");
while (x-- > 0) sb.append(new String(new byte[]{(byte)code[s++]}));
}
-
+
+ private void pLenStringFromTemplate(StringBuilder sb, int len, int mbLen, byte[]tm, int idx) {
+ int x = len * mbLen;
+ sb.append(":T:" + len + ":");
+ while (x-- > 0) sb.append(new String(new byte[]{(byte)tm[idx++]}));
+ }
+
public int compiledByteCodeToString(StringBuilder sb, int bp) {
int len, n, mem, addr, scn, cod;
BitSet bs;
CClassNode cc;
+ int tm, idx;
sb.append("[" + OPCode.OpCodeNames[code[bp]]);
int argType = OPCode.OpCodeArgTypes[code[bp]];
@@ -77,27 +92,27 @@ class ByteCodePrinter {
sb.append(":(" + code[bp] + ")");
bp += OPSize.RELADDR;
break;
-
+
case Arguments.ABSADDR:
sb.append(":(" + code[bp] + ")");
bp += OPSize.ABSADDR;
break;
-
+
case Arguments.LENGTH:
sb.append(":" + code[bp]);
bp += OPSize.LENGTH;
break;
-
+
case Arguments.MEMNUM:
sb.append(":" + code[bp]);
bp += OPSize.MEMNUM;
break;
-
+
case Arguments.OPTION:
sb.append(":" + code[bp]);
bp += OPSize.OPTION;
break;
-
+
case Arguments.STATE_CHECK:
sb.append(":" + code[bp]);
bp += OPSize.STATE_CHECK;
@@ -108,95 +123,140 @@ class ByteCodePrinter {
case OPCode.EXACT1:
case OPCode.ANYCHAR_STAR_PEEK_NEXT:
case OPCode.ANYCHAR_ML_STAR_PEEK_NEXT:
- case OPCode.ANYCHAR_STAR_PEEK_NEXT_SB:
+ case OPCode.ANYCHAR_STAR_PEEK_NEXT_SB:
case OPCode.ANYCHAR_ML_STAR_PEEK_NEXT_SB:
pString(sb, 1, bp++);
break;
-
+
case OPCode.EXACT2:
pString(sb, 2, bp);
bp += 2;
break;
-
+
case OPCode.EXACT3:
pString(sb, 3, bp);
bp += 3;
break;
-
+
case OPCode.EXACT4:
pString(sb, 4, bp);
bp += 4;
break;
-
+
case OPCode.EXACT5:
- pString(sb, 5, bp);
+ pString(sb, 5, bp);
bp += 5;
break;
-
+
case OPCode.EXACTN:
len = code[bp];
bp += OPSize.LENGTH;
- pLenString(sb, len, 1, bp);
- bp += len;
+ if (Config.USE_STRING_TEMPLATES) {
+ tm = code[bp];
+ bp += OPSize.INDEX;
+ idx = code[bp];
+ bp += OPSize.INDEX;
+ pLenStringFromTemplate(sb, len, 1, templates[tm], idx);
+ } else {
+ pLenString(sb, len, 1, bp);
+ bp += len;
+ }
break;
-
+
case OPCode.EXACTMB2N1:
pString(sb, 2, bp);
bp += 2;
break;
-
+
case OPCode.EXACTMB2N2:
pString(sb, 4, bp);
bp += 4;
break;
-
+
case OPCode.EXACTMB2N3:
pString(sb, 6, bp);
bp += 6;
break;
-
+
case OPCode.EXACTMB2N:
len = code[bp];
bp += OPSize.LENGTH;
- pLenString(sb, len, 2, bp);
- bp += len * 2;
+ if (Config.USE_STRING_TEMPLATES) {
+ tm = code[bp];
+ bp += OPSize.INDEX;
+ idx = code[bp];
+ bp += OPSize.INDEX;
+ pLenStringFromTemplate(sb, len, 2, templates[tm], idx);
+ } else {
+ pLenString(sb, len, 2, bp);
+ bp += len * 2;
+ }
break;
case OPCode.EXACTMB3N:
len = code[bp];
bp += OPSize.LENGTH;
- pLenString(sb, len, 3, bp);
- bp += len * 3;
+ if (Config.USE_STRING_TEMPLATES) {
+ tm = code[bp];
+ bp += OPSize.INDEX;
+ idx = code[bp];
+ bp += OPSize.INDEX;
+ pLenStringFromTemplate(sb, len, 3, templates[tm], idx);
+ } else {
+ pLenString(sb, len, 3, bp);
+ bp += len * 3;
+ }
break;
-
+
case OPCode.EXACTMBN:
int mbLen = code[bp];
bp += OPSize.LENGTH;
len = code[bp];
bp += OPSize.LENGTH;
- sb.append(":" + mbLen + ":" + len + ":");
n = len * mbLen;
- while (n-- > 0) sb.append(new String(new byte[]{(byte)code[bp++]}));
+
+ if (Config.USE_STRING_TEMPLATES) {
+ tm = code[bp];
+ bp += OPSize.INDEX;
+ idx = code[bp];
+ bp += OPSize.INDEX;
+ sb.append(":T:" + mbLen + ":" + len + ":");
+
+ while (n-- > 0) sb.append(new String(new byte[]{templates[tm][idx++]}));
+ } else {
+ sb.append(":" + mbLen + ":" + len + ":");
+
+ while (n-- > 0) sb.append(new String(new byte[]{(byte)code[bp++]}));
+ }
+
break;
-
+
case OPCode.EXACT1_IC:
case OPCode.EXACT1_IC_SB:
final int MAX_CHAR_LENGTH = 6;
byte[]bytes = new byte[MAX_CHAR_LENGTH];
- for (int i = 0; bp + i < code.length && i < MAX_CHAR_LENGTH; i++) bytes[i] = (byte)code[bp + i];
+ for (int i = 0; bp + i < code.length && i < MAX_CHAR_LENGTH; i++) bytes[i] = (byte)code[bp + i];
len = enc.length(bytes, 0, MAX_CHAR_LENGTH);
pString(sb, len, bp);
bp += len;
break;
-
+
case OPCode.EXACTN_IC:
case OPCode.EXACTN_IC_SB:
len = code[bp];
bp += OPSize.LENGTH;
- pLenString(sb, len, 1, bp);
- bp += len;
+ if (Config.USE_STRING_TEMPLATES) {
+ tm = code[bp];
+ bp += OPSize.INDEX;
+ idx = code[bp];
+ bp += OPSize.INDEX;
+ pLenStringFromTemplate(sb, len, 1, templates[tm], idx);
+ } else {
+ pLenString(sb, len, 1, bp);
+ bp += len;
+ }
break;
-
+
case OPCode.CCLASS:
case OPCode.CCLASS_SB:
bs = new BitSet();
@@ -205,7 +265,7 @@ class ByteCodePrinter {
bp += BitSet.BITSET_SIZE;
sb.append(":" + n);
break;
-
+
case OPCode.CCLASS_NOT:
case OPCode.CCLASS_NOT_SB:
bs = new BitSet();
@@ -214,15 +274,15 @@ class ByteCodePrinter {
bp += BitSet.BITSET_SIZE;
sb.append(":" + n);
break;
-
+
case OPCode.CCLASS_MB:
- case OPCode.CCLASS_MB_NOT:
+ case OPCode.CCLASS_MB_NOT:
len = code[bp];
bp += OPSize.LENGTH;
cod = code[bp];
//bp += OPSize.CODE_POINT;
bp += len;
- sb.append(":" + cod + ":" + len);
+ sb.append(":" + cod + ":" + len);
break;
case OPCode.CCLASS_MIX:
@@ -245,13 +305,13 @@ class ByteCodePrinter {
n = cc.bs.numOn();
sb.append(":" + cc + ":" + n);
break;
-
+
case OPCode.BACKREFN_IC:
mem = code[bp];
bp += OPSize.MEMNUM;
sb.append(":" + mem);
break;
-
+
case OPCode.BACKREF_MULTI_IC:
case OPCode.BACKREF_MULTI:
sb.append(" ");
@@ -264,7 +324,7 @@ class ByteCodePrinter {
sb.append(mem);
}
break;
-
+
case OPCode.BACKREF_WITH_LEVEL: {
int option = code[bp];
bp += OPSize.OPTION;
@@ -283,7 +343,7 @@ class ByteCodePrinter {
}
break;
}
-
+
case OPCode.REPEAT:
case OPCode.REPEAT_NG:
mem = code[bp];
@@ -292,7 +352,7 @@ class ByteCodePrinter {
bp += OPSize.RELADDR;
sb.append(":" + mem + ":" + addr);
break;
-
+
case OPCode.PUSH_OR_JUMP_EXACT1:
case OPCode.PUSH_IF_PEEK_NEXT:
addr = code[bp];
@@ -301,14 +361,14 @@ class ByteCodePrinter {
pString(sb, 1, bp);
bp++;
break;
-
+
case OPCode.LOOK_BEHIND:
case OPCode.LOOK_BEHIND_SB:
len = code[bp];
bp += OPSize.LENGTH;
sb.append(":" + len);
break;
-
+
case OPCode.PUSH_LOOK_BEHIND_NOT:
addr = code[bp];
bp += OPSize.RELADDR;
@@ -316,7 +376,7 @@ class ByteCodePrinter {
bp += OPSize.LENGTH;
sb.append(":" + len + ":(" + addr + ")");
break;
-
+
case OPCode.STATE_CHECK_PUSH:
case OPCode.STATE_CHECK_PUSH_OR_JUMP:
scn = code[bp];
@@ -325,7 +385,7 @@ class ByteCodePrinter {
bp += OPSize.RELADDR;
sb.append(":" + scn + ":(" + addr + ")");
break;
-
+
default:
throw new InternalException("undefined code: " + code[--bp]);
}
@@ -342,14 +402,14 @@ class ByteCodePrinter {
private String compiledByteCodeListToString() {
StringBuilder sb = new StringBuilder();
sb.append("code length: " + codeLength + "\n");
-
+
int ncode = 0;
int bp = 0;
int end = codeLength;
-
+
while (bp < end) {
ncode++;
-
+
if (bp > 0) sb.append(ncode % 5 == 0 ? "\n" : " ");
bp = compiledByteCodeToString(sb, bp);
diff --git a/src/org/joni/CaptureTreeNode.java b/src/org/joni/CaptureTreeNode.java
index dd6549c..4cbd31d 100644
--- a/src/org/joni/CaptureTreeNode.java
+++ b/src/org/joni/CaptureTreeNode.java
@@ -1,27 +1,27 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
public class CaptureTreeNode {
-
+
int group;
int beg;
int end;
@@ -34,7 +34,7 @@ public class CaptureTreeNode {
end = Region.REGION_NOTPOS;
group = -1;
}
-
+
static final int HISTORY_TREE_INIT_ALLOC_SIZE = 8;
void addChild(CaptureTreeNode child) {
if (children == null) {
@@ -44,11 +44,11 @@ public class CaptureTreeNode {
System.arraycopy(children, 0, tmp, 0, children.length);
children = tmp;
}
-
+
children[numChildren] = child;
numChildren++;
}
-
+
void clear() {
for (int i=0; i<numChildren; i++) {
children[i] = null; // ???
@@ -57,7 +57,7 @@ public class CaptureTreeNode {
beg = end = Region.REGION_NOTPOS;
group = -1;
}
-
+
CaptureTreeNode cloneTree() {
CaptureTreeNode clone = new CaptureTreeNode();
clone.beg = beg;
@@ -69,6 +69,6 @@ public class CaptureTreeNode {
}
return clone;
}
-
-
+
+
}
diff --git a/src/org/joni/CodeRangeBuffer.java b/src/org/joni/CodeRangeBuffer.java
index 51b77e7..7e7e5e3 100644
--- a/src/org/joni/CodeRangeBuffer.java
+++ b/src/org/joni/CodeRangeBuffer.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -24,51 +24,51 @@ import org.joni.exception.ErrorMessages;
import org.joni.exception.ValueException;
public final class CodeRangeBuffer {
- private static final int INIT_MULTI_BYTE_RANGE_SIZE = 5;
+ private static final int INIT_MULTI_BYTE_RANGE_SIZE = 5;
private static final int ALL_MULTI_BYTE_RANGE = 0x7fffffff;
-
- int[]p;
+
+ int[]p;
int used;
-
+
public CodeRangeBuffer(int[]ranges) {
p = ranges;
used = ranges[0] + 1;
}
-
+
public CodeRangeBuffer() {
p = new int[INIT_MULTI_BYTE_RANGE_SIZE];
writeCodePoint(0, 0);
}
-
+
public int[]getCodeRange() {
return p;
}
-
+
private CodeRangeBuffer(CodeRangeBuffer orig) {
p = new int[orig.p.length];
System.arraycopy(orig.p, 0, p, 0, p.length);
used = orig.used;
}
-
+
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append("CodeRange");
buf.append("\n used: " + used);
buf.append("\n code point: " + p[0]);
buf.append("\n ranges: ");
-
+
for (int i=0; i<p[0]; i++) {
buf.append("[" + rangeNumToString(p[i * 2 + 1]) + ".." + rangeNumToString(p[i * 2 + 2]) + "]");
if (i > 0 && i % 6 == 0) buf.append("\n ");
}
-
+
return buf.toString();
}
-
+
private static String rangeNumToString(int num){
return "0x" + Integer.toString(num, 16);
}
-
+
public void expand(int low) {
int length = p.length;
do { length <<= 1; } while (length < low);
@@ -76,27 +76,27 @@ public final class CodeRangeBuffer {
System.arraycopy(p, 0, tmp, 0, used);
p = tmp;
}
-
+
public void ensureSize(int size) {
int length = p.length;
while (length < size ) { length <<= 1; }
- if (p.length != length) {
+ if (p.length != length) {
int[]tmp = new int[length];
System.arraycopy(p, 0, tmp, 0, used);
- p = tmp;
+ p = tmp;
}
- }
-
+ }
+
private void moveRight(int from, int to, int n) {
if (to + n > p.length) expand(to + n);
System.arraycopy(p, from, p, to, n);
if (to + n > used) used = to + n;
}
-
+
protected void moveLeft(int from, int to, int n) {
System.arraycopy(p, from, p, to, n);
}
-
+
private void moveLeftAndReduce(int from, int to) {
System.arraycopy(p, from, p, to, used - from);
used -= from - to;
@@ -108,11 +108,11 @@ public final class CodeRangeBuffer {
p[pos] = b;
if (used < u) used = u;
}
-
+
public CodeRangeBuffer clone() {
return new CodeRangeBuffer(this);
}
-
+
// ugly part: these methods should be made OO
// add_code_range_to_buf
public static CodeRangeBuffer addCodeRangeToBuff(CodeRangeBuffer pbuf, int from, int to) {
@@ -121,15 +121,15 @@ public final class CodeRangeBuffer {
from = to;
to = n;
}
-
+
if (pbuf == null) pbuf = new CodeRangeBuffer(); // move to CClassNode
-
+
int[]p = pbuf.p;
int n = p[0];
-
+
int low = 0;
int bound = n;
-
+
while (low < bound) {
int x = (low + bound) >>> 1;
if (from > p[x * 2 + 2]) {
@@ -138,10 +138,10 @@ public final class CodeRangeBuffer {
bound = x;
}
}
-
+
int high = low;
bound = n;
-
+
while (high < bound) {
int x = (high + bound) >>> 1;
if (to >= p[x * 2 + 1] - 1) {
@@ -150,38 +150,38 @@ public final class CodeRangeBuffer {
bound = x;
}
}
-
+
int incN = low + 1 - high;
- if (n + incN > Config.MAX_MULTI_BYTE_RANGES_NUM) throw new ValueException(ErrorMessages.ERR_TOO_MANY_MULTI_BYTE_RANGES);
-
+ if (n + incN > Config.MAX_MULTI_BYTE_RANGES_NUM) throw new ValueException(ErrorMessages.ERR_TOO_MANY_MULTI_BYTE_RANGES);
+
if (incN != 1) {
if (from > p[low * 2 + 1]) from = p[low * 2 + 1];
if (to < p[(high - 1) * 2 + 2]) to = p[(high - 1) * 2 + 2];
}
-
+
if (incN != 0 && high < n) {
int fromPos = 1 + high * 2;
int toPos = 1 + (low + 1) * 2;
int size = (n - high) * 2;
-
+
if (incN > 0) {
pbuf.moveRight(fromPos, toPos, size);
} else {
pbuf.moveLeftAndReduce(fromPos, toPos);
}
}
-
+
int pos = 1 + low * 2;
// pbuf.ensureSize(pos + 2);
pbuf.writeCodePoint(pos, from);
pbuf.writeCodePoint(pos + 1, to);
n += incN;
pbuf.writeCodePoint(0, n);
-
+
return pbuf;
}
-
+
// add_code_range, be aware of it returning null!
public static CodeRangeBuffer addCodeRange(CodeRangeBuffer pbuf, ScanEnvironment env, int from, int to) {
if (from >to) {
@@ -198,26 +198,26 @@ public final class CodeRangeBuffer {
protected static CodeRangeBuffer setAllMultiByteRange(Encoding enc, CodeRangeBuffer pbuf) {
return addCodeRangeToBuff(pbuf, enc.mbcodeStartPosition(), ALL_MULTI_BYTE_RANGE);
}
-
+
// ADD_ALL_MULTI_BYTE_RANGE
public static CodeRangeBuffer addAllMultiByteRange(Encoding enc, CodeRangeBuffer pbuf) {
if (!enc.isSingleByte()) return setAllMultiByteRange(enc, pbuf);
return pbuf;
}
-
+
// not_code_range_buf
public static CodeRangeBuffer notCodeRangeBuff(Encoding enc, CodeRangeBuffer bbuf) {
CodeRangeBuffer pbuf = null;
if (bbuf == null) return setAllMultiByteRange(enc, pbuf);
-
+
int[]p = bbuf.p;
int n = p[0];
-
+
if (n <= 0) return setAllMultiByteRange(enc, pbuf);
-
+
int pre = enc.mbcodeStartPosition();
-
+
int from;
int to = 0;
for (int i=0; i<n; i++) {
@@ -229,16 +229,16 @@ public final class CodeRangeBuffer {
if (to == ALL_MULTI_BYTE_RANGE) break;
pre = to + 1;
}
-
+
if (to < ALL_MULTI_BYTE_RANGE) pbuf = addCodeRangeToBuff(pbuf, to + 1, ALL_MULTI_BYTE_RANGE);
return pbuf;
}
-
+
// or_code_range_buf
public static CodeRangeBuffer orCodeRangeBuff(Encoding enc, CodeRangeBuffer bbuf1, boolean not1,
CodeRangeBuffer bbuf2, boolean not2) {
CodeRangeBuffer pbuf = null;
-
+
if (bbuf1 == null && bbuf2 == null) {
if (not1 || not2) {
return setAllMultiByteRange(enc, pbuf);
@@ -251,13 +251,13 @@ public final class CodeRangeBuffer {
boolean tnot;
// swap
tnot = not1; not1 = not2; not2 = tnot;
- tbuf = bbuf1; bbuf1 = bbuf2; bbuf2 = tbuf;
+ tbuf = bbuf1; bbuf1 = bbuf2; bbuf2 = tbuf;
}
-
+
if (bbuf1 == null) {
if (not1) {
return setAllMultiByteRange(enc, pbuf);
- } else {
+ } else {
if (!not2) {
return bbuf2.clone();
} else {
@@ -265,13 +265,13 @@ public final class CodeRangeBuffer {
}
}
}
-
+
if (not1) {
CodeRangeBuffer tbuf;
boolean tnot;
// swap
tnot = not1; not1 = not2; not2 = tnot;
- tbuf = bbuf1; bbuf1 = bbuf2; bbuf2 = tbuf;
+ tbuf = bbuf1; bbuf1 = bbuf2; bbuf2 = tbuf;
}
if (!not2 && !not1) { /* 1 OR 2 */
@@ -279,19 +279,19 @@ public final class CodeRangeBuffer {
} else if (!not1) { /* 1 OR (not 2) */
pbuf = notCodeRangeBuff(enc, bbuf2);
}
-
+
int[]p1 = bbuf1.p;
int n1 = p1[0];
-
+
for (int i=0; i<n1; i++) {
int from = p1[i * 2 + 1];
int to = p1[i * 2 + 2];
pbuf = addCodeRangeToBuff(pbuf, from, to);
}
-
+
return pbuf;
}
-
+
// and_code_range1
public static CodeRangeBuffer andCodeRange1(CodeRangeBuffer pbuf, int from1, int to1, int[]data, int n) {
for (int i=0; i<n; i++) {
@@ -317,35 +317,35 @@ public final class CodeRangeBuffer {
}
if (from1 > to1) break;
}
-
+
if (from1 <= to1) {
pbuf = addCodeRangeToBuff(pbuf, from1, to1);
}
-
+
return pbuf;
}
-
+
// and_code_range_buf
public static CodeRangeBuffer andCodeRangeBuff(CodeRangeBuffer bbuf1, boolean not1,
CodeRangeBuffer bbuf2, boolean not2) {
CodeRangeBuffer pbuf = null;
-
- if (bbuf1 == null) {
+
+ if (bbuf1 == null) {
if (not1 && bbuf2 != null) return bbuf2.clone(); /* not1 != 0 -> not2 == 0 */
- return null;
+ return null;
} else if (bbuf2 == null) {
if (not2) return bbuf1.clone();
return null;
}
-
+
if (not1) {
CodeRangeBuffer tbuf;
boolean tnot;
// swap
tnot = not1; not1 = not2; not2 = tnot;
- tbuf = bbuf1; bbuf1 = bbuf2; bbuf2 = tbuf;
+ tbuf = bbuf1; bbuf1 = bbuf2; bbuf2 = tbuf;
}
-
+
int[]p1 = bbuf1.p;
int n1 = p1[0];
int[]p2 = bbuf2.p;
diff --git a/src/org/joni/Compiler.java b/src/org/joni/Compiler.java
index c9ea261..00059f1 100644
--- a/src/org/joni/Compiler.java
+++ b/src/org/joni/Compiler.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -39,26 +39,26 @@ abstract class Compiler implements ErrorMessages {
protected final Analyser analyser;
protected final Encoding enc;
protected final Regex regex;
-
+
protected Compiler(Analyser analyser) {
this.analyser = analyser;
this.regex = analyser.regex;
this.enc = regex.enc;
}
-
+
final void compile() {
prepare();
compileTree(analyser.root);
finish();
}
-
+
protected abstract void prepare();
protected abstract void finish();
-
+
protected abstract void compileAltNode(ConsAltNode node);
-
+
private void compileStringRawNode(StringNode sn) {
- if (sn.length() <= 0) return;
+ if (sn.length() <= 0) return;
addCompileString(sn.bytes, sn.p, 1 /*sb*/, sn.length(), false);
}
@@ -75,8 +75,8 @@ abstract class Compiler implements ErrorMessages {
int prevLen = enc.length(bytes, p, end);
p += prevLen;
int slen = 1;
-
- while (p < end) {
+
+ while (p < end) {
int len = enc.length(bytes, p, end);
if (len == prevLen) {
slen++;
@@ -88,11 +88,11 @@ abstract class Compiler implements ErrorMessages {
}
p += len;
}
- addCompileString(bytes, prev, prevLen, slen, ambig);
+ addCompileString(bytes, prev, prevLen, slen, ambig);
}
-
+
protected abstract void addCompileString(byte[]bytes, int p, int mbLength, int strLength, boolean ignoreCase);
-
+
protected abstract void compileCClassNode(CClassNode node);
protected abstract void compileCTypeNode(CTypeNode node);
protected abstract void compileAnyCharNode();
@@ -103,7 +103,7 @@ abstract class Compiler implements ErrorMessages {
protected abstract void compileOptionNode(EncloseNode node);
protected abstract void compileEncloseNode(EncloseNode node);
protected abstract void compileAnchorNode(AnchorNode node);
-
+
protected final void compileTree(Node node) {
switch (node.getType()) {
case NodeType.LIST:
@@ -112,11 +112,11 @@ abstract class Compiler implements ErrorMessages {
compileTree(lin.car);
} while ((lin = lin.cdr) != null);
break;
-
+
case NodeType.ALT:
compileAltNode((ConsAltNode)node);
break;
-
+
case NodeType.STR:
StringNode sn = (StringNode)node;
if (sn.isRaw()) {
@@ -125,15 +125,15 @@ abstract class Compiler implements ErrorMessages {
compileStringNode(sn);
}
break;
-
+
case NodeType.CCLASS:
compileCClassNode((CClassNode)node);
break;
-
+
case NodeType.CTYPE:
compileCTypeNode((CTypeNode)node);
break;
-
+
case NodeType.CANY:
compileAnyCharNode();
break;
@@ -141,14 +141,14 @@ abstract class Compiler implements ErrorMessages {
case NodeType.BREF:
compileBackrefNode((BackRefNode)node);
break;
-
+
case NodeType.CALL:
if (Config.USE_SUBEXP_CALL) {
compileCallNode((CallNode)node);
break;
} // USE_SUBEXP_CALL
break;
-
+
case NodeType.QTFR:
if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
compileCECQuantifierNode((QuantifierNode)node);
@@ -156,7 +156,7 @@ abstract class Compiler implements ErrorMessages {
compileNonCECQuantifierNode((QuantifierNode)node);
}
break;
-
+
case NodeType.ENCLOSE:
EncloseNode enode = (EncloseNode)node;
if (enode.isOption()) {
@@ -164,7 +164,7 @@ abstract class Compiler implements ErrorMessages {
} else {
compileEncloseNode(enode);
}
- break;
+ break;
case NodeType.ANCHOR:
compileAnchorNode((AnchorNode)node);
@@ -175,7 +175,7 @@ abstract class Compiler implements ErrorMessages {
newInternalException(ERR_PARSER_BUG);
} // switch
}
-
+
protected final void compileTreeNTimes(Node node, int n) {
for (int i=0; i<n; i++) compileTree(node);
}
diff --git a/src/org/joni/Config.java b/src/org/joni/Config.java
index 07762f0..3467966 100644
--- a/src/org/joni/Config.java
+++ b/src/org/joni/Config.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -23,25 +23,25 @@ import java.io.PrintStream;
public interface Config extends org.jcodings.Config {
final int CHAR_TABLE_SIZE = 256;
-
+
final boolean USE_NAMED_GROUP = true;
final boolean USE_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/ */
final boolean USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE = true; /* /\n$/ =~ "\n" */
final boolean USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR = false;
final boolean CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS = true;
-
+
final boolean USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE = false;
final boolean USE_CAPTURE_HISTORY = false;
final boolean USE_VARIABLE_META_CHARS = true;
final boolean USE_WORD_BEGIN_END = true; /* "\<": word-begin, "\>": word-end */
- final boolean USE_POSIX_API_REGION_OPTION = true; /* needed for POSIX API support */
+ final boolean USE_POSIX_API_REGION_OPTION = true; /* needed for POSIX API support */
final boolean USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE = true;
final boolean USE_COMBINATION_EXPLOSION_CHECK = false;
-
+
final int NREGION = 10;
final int MAX_BACKREF_NUM = 1000;
final int MAX_REPEAT_NUM = 100000;
@@ -53,34 +53,40 @@ public interface Config extends org.jcodings.Config {
// internal config
final boolean USE_PARSE_TREE_NODE_RECYCLE = true;
final boolean USE_OP_PUSH_OR_JUMP_EXACT = true;
- final boolean USE_SHARED_CCLASS_TABLE = false;
- final boolean USE_QTFR_PEEK_NEXT = true;
+ final boolean USE_SHARED_CCLASS_TABLE = false;
+ final boolean USE_QTFR_PEEK_NEXT = true;
final int INIT_MATCH_STACK_SIZE = 64;
final int DEFAULT_MATCH_STACK_LIMIT_SIZE = 0; /* unlimited */
final int NUMBER_OF_POOLED_STACKS = 4;
-
-
+
+
final boolean DONT_OPTIMIZE = false;
-
-
+
+ final boolean USE_STRING_TEMPLATES = true; // use embeded string templates in Regex object as byte arrays instead of compiling them into int bytecode array
+
+
final int MAX_CAPTURE_HISTORY_GROUP = 31;
-
+
final int CHECK_STRING_THRESHOLD_LEN = 7;
final int CHECK_BUFF_MAX_SIZE = 0x4000;
-
-
+
+ final boolean NON_UNICODE_SDW = true;
+
+
final PrintStream log = System.out;
final PrintStream err = System.err;
final boolean DEBUG_ALL = false;
- final boolean DEBUG = DEBUG_ALL;
+
+ final boolean DEBUG = DEBUG_ALL;
final boolean DEBUG_PARSE_TREE = DEBUG_ALL;
+ final boolean DEBUG_PARSE_TREE_RAW = true;
final boolean DEBUG_COMPILE = DEBUG_ALL;
final boolean DEBUG_COMPILE_BYTE_CODE_INFO = DEBUG_ALL;
- final boolean DEBUG_SEARCH = DEBUG_ALL;
+ final boolean DEBUG_SEARCH = DEBUG_ALL;
final boolean DEBUG_MATCH = DEBUG_ALL;
final boolean DEBUG_ASM = true;
final boolean DEBUG_ASM_EXEC = true;
diff --git a/src/org/joni/Lexer.java b/src/org/joni/Lexer.java
index 172132f..bc919ad 100644
--- a/src/org/joni/Lexer.java
+++ b/src/org/joni/Lexer.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -22,6 +22,7 @@ package org.joni;
import static org.joni.Option.isSingleline;
import static org.joni.ast.QuantifierNode.isRepeatInfinite;
+import org.jcodings.Ptr;
import org.jcodings.constants.CharacterType;
import org.jcodings.exception.CharacterPropertyException;
import org.joni.ast.QuantifierNode;
@@ -31,7 +32,7 @@ import org.joni.constants.TokenType;
import org.joni.exception.ErrorMessages;
class Lexer extends ScannerSupport {
- protected final ScanEnvironment env;
+ protected final ScanEnvironment env;
protected final Syntax syntax; // fast access to syntax
protected final Token token = new Token(); // current token
@@ -40,17 +41,17 @@ class Lexer extends ScannerSupport {
this.env = env;
this.syntax = env.syntax;
}
-
+
/**
* @return 0: normal {n,m}, 2: fixed {n}
- * !introduce returnCode here
+ * !introduce returnCode here
*/
private int fetchRangeQuantifier() {
mark();
boolean synAllow = syntax.allowInvalidInterval();
-
+
if (!left()) {
- if (synAllow) {
+ if (synAllow) {
return 1; /* "....{" : OK! */
} else {
newSyntaxException(ERR_END_PATTERN_AT_LEFT_BRACE);
@@ -63,7 +64,7 @@ class Lexer extends ScannerSupport {
newSyntaxException(ERR_END_PATTERN_AT_LEFT_BRACE);
}
}
-
+
int low = scanUnsignedNumber();
if (low < 0) newSyntaxException(ErrorMessages.ERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE);
if (low > Config.MAX_REPEAT_NUM) newSyntaxException(ErrorMessages.ERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE);
@@ -77,18 +78,18 @@ class Lexer extends ScannerSupport {
return invalidRangeQuantifier(synAllow);
}
}
-
+
if (!left()) return invalidRangeQuantifier(synAllow);
-
+
fetch();
int up;
int ret = 0;
if (c == ',') {
- int prev = p; // ??? last
+ int prev = p; // ??? last
up = scanUnsignedNumber();
if (up < 0) newValueException(ERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE);
if (up > Config.MAX_REPEAT_NUM) newValueException(ERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE);
-
+
if (p == prev) {
if (nonLow) return invalidRangeQuantifier(synAllow);
up = QuantifierNode.REPEAT_INFINITE; /* {n,} : {n,infinite} */
@@ -99,28 +100,28 @@ class Lexer extends ScannerSupport {
up = low; /* {n} : exact n times */
ret = 2; /* fixed */
}
-
+
if (!left()) return invalidRangeQuantifier(synAllow);
fetch();
-
+
if (syntax.opEscBraceInterval()) {
if (c != syntax.metaCharTable.esc) return invalidRangeQuantifier(synAllow);
fetch();
}
-
+
if (c != '}') return invalidRangeQuantifier(synAllow);
-
+
if (!isRepeatInfinite(up) && low > up) {
newValueException(ERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE);
}
-
+
token.type = TokenType.INTERVAL;
token.setRepeatLower(low);
token.setRepeatUpper(up);
-
+
return ret; /* 0: normal {n,m}, 2: fixed {n} */
}
-
+
private int invalidRangeQuantifier(boolean synAllow) {
if (synAllow) {
restore();
@@ -130,7 +131,7 @@ class Lexer extends ScannerSupport {
return 0; // not reached
}
}
-
+
/* \M-, \C-, \c, or \... */
private int fetchEscapedValue() {
if (!left()) newSyntaxException(ERR_END_PATTERN_AT_ESCAPE);
@@ -164,20 +165,20 @@ class Lexer extends ScannerSupport {
fetchEscapedValueBackSlash();
}
break;
-
+
case 'c':
if (syntax.opEscCControl()) {
fetchEscapedValueControl();
}
/* fall through */
-
+
default:
fetchEscapedValueBackSlash();
} // switch
-
+
return c; // ???
}
-
+
private void fetchEscapedValueBackSlash() {
c = env.convertBackslashValue(c);
}
@@ -194,7 +195,7 @@ class Lexer extends ScannerSupport {
c &= 0x9f;
}
}
-
+
private int nameEndCodePoint(int start) {
switch(start) {
case '<':
@@ -212,16 +213,16 @@ class Lexer extends ScannerSupport {
\k<num+n>, \k<num-n>
\k<-num+n>, \k<-num-n>
*/
-
+
// value implicit (rnameEnd)
- private boolean fetchNameWithLevel(int startCode, int[]rbackNum, int[]rlevel) {
+ private boolean fetchNameWithLevel(int startCode, Ptr rbackNum, Ptr rlevel) {
int src = p;
boolean existLevel = false;
int isNum = 0;
int sign = 1;
-
+
int endCode = nameEndCodePoint(startCode);
- int pnumHead = p;
+ int pnumHead = p;
int nameEnd = stop;
String err = null;
@@ -232,15 +233,15 @@ class Lexer extends ScannerSupport {
if (c == endCode) newValueException(ERR_EMPTY_GROUP_NAME);
if (enc.isDigit(c)) {
isNum = 1;
- } else if (c == '-') {
+ } else if (c == '-') {
isNum = 2;
sign = -1;
pnumHead = p;
- } else if (!enc.isWord(c)) {
+ } else if (!enc.isWord(c)) {
err = ERR_INVALID_GROUP_NAME;
}
}
-
+
while (left()) {
nameEnd = p;
fetch();
@@ -248,7 +249,7 @@ class Lexer extends ScannerSupport {
if (isNum == 2) err = ERR_INVALID_GROUP_NAME;
break;
}
-
+
if (isNum != 0) {
if (enc.isDigit(c)) {
isNum = 1;
@@ -271,13 +272,13 @@ class Lexer extends ScannerSupport {
unfetch();
int level = scanUnsignedNumber();
if (level < 0) newValueException(ERR_TOO_BIG_NUMBER);
- rlevel[0] = level * flag;
+ rlevel.p = level * flag;
existLevel = true;
-
+
fetch();
isEndCode = c == endCode;
}
-
+
if (!isEndCode) {
err = ERR_INVALID_GROUP_NAME;
nameEnd = stop;
@@ -295,7 +296,7 @@ class Lexer extends ScannerSupport {
} else if (backNum == 0) {
newValueException(ERR_INVALID_GROUP_NAME, src, stop);
}
- rbackNum[0] = backNum * sign;
+ rbackNum.p = backNum * sign;
}
value = nameEnd;
return existLevel;
@@ -304,14 +305,14 @@ class Lexer extends ScannerSupport {
return false; // not reached
}
}
-
+
// USE_NAMED_GROUP
// ref: 0 -> define name (don't allow number name)
// 1 -> reference name (allow number name)
private int fetchNameForNamedGroup(int startCode, boolean ref) {
int src = p;
value = 0;
-
+
int isNum = 0;
int sign = 1;
@@ -332,7 +333,7 @@ class Lexer extends ScannerSupport {
err = ERR_INVALID_GROUP_NAME;
// isNum = 0;
}
- } else if (c == '-') {
+ } else if (c == '-') {
if (ref) {
isNum = 2;
sign = -1;
@@ -342,10 +343,10 @@ class Lexer extends ScannerSupport {
// isNum = 0;
}
} else if (!enc.isWord(c)) {
- err = ERR_INVALID_CHAR_IN_GROUP_NAME;
+ err = ERR_INVALID_CHAR_IN_GROUP_NAME;
}
}
-
+
if (err == null) {
while (left()) {
nameEnd = p;
@@ -354,7 +355,7 @@ class Lexer extends ScannerSupport {
if (isNum == 2) err = ERR_INVALID_GROUP_NAME;
break;
}
-
+
if (isNum != 0) {
if (enc.isDigit(c)) {
isNum = 1;
@@ -372,7 +373,7 @@ class Lexer extends ScannerSupport {
}
}
}
-
+
if (c != endCode) {
err = ERR_INVALID_GROUP_NAME;
nameEnd = stop;
@@ -410,12 +411,12 @@ class Lexer extends ScannerSupport {
private final int fetchNameForNoNamedGroup(int startCode, boolean ref) {
int src = p;
value = 0;
-
+
int isNum = 0;
int sign = 1;
-
+
int endCode = nameEndCodePoint(startCode);
- int pnumHead = p;
+ int pnumHead = p;
int nameEnd = stop;
String err = null;
@@ -424,7 +425,7 @@ class Lexer extends ScannerSupport {
} else {
fetch();
if (c == endCode) newValueException(ERR_EMPTY_GROUP_NAME);
-
+
if (enc.isDigit(c)) {
isNum = 1;
} else if (c == '-') {
@@ -438,17 +439,17 @@ class Lexer extends ScannerSupport {
while(left()) {
nameEnd = p;
-
+
fetch();
if (c == endCode || c == ')') break;
if (!enc.isDigit(c)) err = ERR_INVALID_CHAR_IN_GROUP_NAME;
}
-
- if (err == null && c != endCode) {
+
+ if (err == null && c != endCode) {
err = ERR_INVALID_GROUP_NAME;
nameEnd = stop;
}
-
+
if (err == null) {
mark();
p = pnumHead;
@@ -460,7 +461,7 @@ class Lexer extends ScannerSupport {
newValueException(ERR_INVALID_GROUP_NAME, src, nameEnd);
}
backNum *= sign;
-
+
value = nameEnd;
return backNum;
} else {
@@ -468,7 +469,7 @@ class Lexer extends ScannerSupport {
return 0; // not reached
}
}
-
+
protected final int fetchName(int startCode, boolean ref) {
if (Config.USE_NAMED_GROUP) {
return fetchNameForNamedGroup(startCode, ref);
@@ -476,14 +477,13 @@ class Lexer extends ScannerSupport {
return fetchNameForNoNamedGroup(startCode, ref);
}
}
-
+
private boolean strExistCheckWithEsc(int[]s, int n, int bad) {
int p = this.p;
int to = this.stop;
-
+
boolean inEsc = false;
int i=0;
-
while(p < to) {
if (inEsc) {
inEsc = false;
@@ -508,14 +508,133 @@ class Lexer extends ScannerSupport {
}
}
return false;
- }
-
- private static final int send[] = new int[]{':', ']'};
-
+ }
+
+ private static final int send[] = new int[]{':', ']'};
+
+ private void fetchTokenInCCFor_charType(boolean flag, int type) {
+ token.type = TokenType.CHAR_TYPE;
+ token.setPropCType(type);
+ token.setPropNot(flag);
+ }
+
+ private void fetchTokenInCCFor_p() {
+ int c2 = peek(); // !!! migrate to peekIs
+ if (c2 == '{' && syntax.op2EscPBraceCharProperty()) {
+ inc();
+ token.type = TokenType.CHAR_PROPERTY;
+ token.setPropNot(c == 'P');
+
+ if (syntax.op2EscPBraceCircumflexNot()) {
+ c2 = fetchTo();
+ if (c2 == '^') {
+ token.setPropNot(!token.getPropNot());
+ } else {
+ unfetch();
+ }
+ }
+ } else {
+ syntaxWarn(Warnings.INVALID_UNICODE_PROPERTY, (char)c);
+ }
+ }
+
+ private void fetchTokenInCCFor_x() {
+ if (!left()) return;
+ int last = p;
+
+ if (peekIs('{') && syntax.opEscXBraceHex8()) {
+ inc();
+ int num = scanUnsignedHexadecimalNumber(8);
+ if (num < 0) newValueException(ERR_TOO_BIG_WIDE_CHAR_VALUE);
+ if (left()) {
+ int c2 = peek();
+ if (enc.isXDigit(c2)) newValueException(ERR_TOO_LONG_WIDE_CHAR_VALUE);
+ }
+
+ if (p > last + enc.length(bytes, last, stop) && left() && peekIs('}')) {
+ inc();
+ token.type = TokenType.CODE_POINT;
+ token.base = 16;
+ token.setCode(num);
+ } else {
+ /* can't read nothing or invalid format */
+ p = last;
+ }
+ } else if (syntax.opEscXHex2()) {
+ int num = scanUnsignedHexadecimalNumber(2);
+ if (num < 0) newValueException(ERR_TOO_BIG_NUMBER);
+ if (p == last) { /* can't read nothing. */
+ num = 0; /* but, it's not error */
+ }
+ token.type = TokenType.RAW_BYTE;
+ token.base = 16;
+ token.setC(num);
+ }
+ }
+
+ private void fetchTokenInCCFor_u() {
+ if (!left()) return;
+ int last = p;
+
+ if (syntax.op2EscUHex4()) {
+ int num = scanUnsignedHexadecimalNumber(4);
+ if (num < 0) newValueException(ERR_TOO_BIG_NUMBER);
+ if (p == last) { /* can't read nothing. */
+ num = 0; /* but, it's not error */
+ }
+ token.type = TokenType.CODE_POINT;
+ token.base = 16;
+ token.setCode(num);
+ }
+ }
+
+ private void fetchTokenInCCFor_digit() {
+ if (syntax.opEscOctal3()) {
+ unfetch();
+ int last = p;
+ int num = scanUnsignedOctalNumber(3);
+ if (num < 0) newValueException(ERR_TOO_BIG_NUMBER);
+ if (p == last) { /* can't read nothing. */
+ num = 0; /* but, it's not error */
+ }
+ token.type = TokenType.RAW_BYTE;
+ token.base = 8;
+ token.setC(num);
+ }
+ }
+
+ private void fetchTokenInCCFor_posixBracket() {
+ if (syntax.opPosixBracket() && peekIs(':')) {
+ token.backP = p; /* point at '[' is readed */
+ inc();
+ if (strExistCheckWithEsc(send, send.length, ']')) {
+ token.type = TokenType.POSIX_BRACKET_OPEN;
+ } else {
+ unfetch();
+ // remove duplication, goto cc_in_cc;
+ if (syntax.op2CClassSetOp()) {
+ token.type = TokenType.CC_CC_OPEN;
+ } else {
+ env.ccEscWarn("[");
+ }
+ }
+ } else { // cc_in_cc:
+ if (syntax.op2CClassSetOp()) {
+ token.type = TokenType.CC_CC_OPEN;
+ } else {
+ env.ccEscWarn("[");
+ }
+ }
+ }
+
+ private void fetchTokenInCCFor_and() {
+ if (syntax.op2CClassSetOp() && left() && peekIs('&')) {
+ inc();
+ token.type = TokenType.CC_AND;
+ }
+ }
+
protected final TokenType fetchTokenInCC() {
- int last;
- int c2;
-
if (!left()) {
token.type = TokenType.EOT;
return token.type;
@@ -526,7 +645,7 @@ class Lexer extends ScannerSupport {
token.base = 0;
token.setC(c);
token.escaped = false;
-
+
if (c == ']') {
token.type = TokenType.CC_CLOSE;
} else if (c == '-') {
@@ -539,126 +658,40 @@ class Lexer extends ScannerSupport {
token.setC(c);
switch (c) {
-
case 'w':
- token.type = TokenType.CHAR_TYPE;
- token.setPropCType(CharacterType.WORD);
- token.setPropNot(false);
+ fetchTokenInCCFor_charType(false, Config.NON_UNICODE_SDW ? CharacterType.W : CharacterType.WORD);
break;
-
case 'W':
- token.type = TokenType.CHAR_TYPE;
- token.setPropCType(CharacterType.WORD);
- token.setPropNot(true);
+ fetchTokenInCCFor_charType(true, Config.NON_UNICODE_SDW ? CharacterType.W : CharacterType.WORD);
break;
-
case 'd':
- token.type = TokenType.CHAR_TYPE;
- token.setPropCType(CharacterType.DIGIT);
- token.setPropNot(false);
+ fetchTokenInCCFor_charType(false, Config.NON_UNICODE_SDW ? CharacterType.D : CharacterType.DIGIT);
break;
-
case 'D':
- token.type = TokenType.CHAR_TYPE;
- token.setPropCType(CharacterType.DIGIT);
- token.setPropNot(true);
+ fetchTokenInCCFor_charType(true, Config.NON_UNICODE_SDW ? CharacterType.D : CharacterType.DIGIT);
break;
-
case 's':
- token.type = TokenType.CHAR_TYPE;
- token.setPropCType(CharacterType.SPACE);
- token.setPropNot(false);
+ fetchTokenInCCFor_charType(false, Config.NON_UNICODE_SDW ? CharacterType.S : CharacterType.SPACE);
break;
-
case 'S':
- token.type = TokenType.CHAR_TYPE;
- token.setPropCType(CharacterType.SPACE);
- token.setPropNot(true);
+ fetchTokenInCCFor_charType(true, Config.NON_UNICODE_SDW ? CharacterType.S : CharacterType.SPACE);
break;
-
case 'h':
- if (!syntax.op2EscHXDigit()) break;
- token.type = TokenType.CHAR_TYPE;
- token.setPropCType(CharacterType.XDIGIT);
- token.setPropNot(false);
+ if (syntax.op2EscHXDigit()) fetchTokenInCCFor_charType(false, CharacterType.XDIGIT);
break;
-
case 'H':
- if (!syntax.op2EscHXDigit()) break;
- token.type = TokenType.CHAR_TYPE;
- token.setPropCType(CharacterType.XDIGIT);
- token.setPropNot(true);
+ if (syntax.op2EscHXDigit()) fetchTokenInCCFor_charType(true, CharacterType.XDIGIT);
break;
-
case 'p':
case 'P':
- c2 = peek(); // !!! migrate to peekIs
- if (c2 == '{' && syntax.op2EscPBraceCharProperty()) {
- inc();
- token.type = TokenType.CHAR_PROPERTY;
- token.setPropNot(c == 'P');
-
- if (syntax.op2EscPBraceCircumflexNot()) {
- c2 = fetchTo();
- if (c2 == '^') {
- token.setPropNot(!token.getPropNot());
- } else {
- unfetch();
- }
- }
- }
+ fetchTokenInCCFor_p();
break;
-
case 'x':
- if (!left()) break;
- last = p;
-
- if (peekIs('{') && syntax.opEscXBraceHex8()) {
- inc();
- int num = scanUnsignedHexadecimalNumber(8);
- if (num < 0) newValueException(ERR_TOO_BIG_WIDE_CHAR_VALUE);
- if (left()) {
- c2 = peek();
- if (enc.isXDigit(c2)) newValueException(ERR_TOO_LONG_WIDE_CHAR_VALUE);
- }
-
- if (p > last + enc.length(bytes, last, stop) && left() && peekIs('}')) {
- inc();
- token.type = TokenType.CODE_POINT;
- token.base = 16;
- token.setCode(num);
- } else {
- /* can't read nothing or invalid format */
- p = last;
- }
- } else if (syntax.opEscXHex2()) {
- int num = scanUnsignedHexadecimalNumber(2);
- if (num < 0) newValueException(ERR_TOO_BIG_NUMBER);
- if (p == last) { /* can't read nothing. */
- num = 0; /* but, it's not error */
- }
- token.type = TokenType.RAW_BYTE;
- token.base = 16;
- token.setC(num);
- }
+ fetchTokenInCCFor_x();
break;
-
case 'u':
- if (!left()) break;
- last = p;
-
- if (syntax.op2EscUHex4()) {
- int num = scanUnsignedHexadecimalNumber(4);
- if (num < 0) newValueException(ERR_TOO_BIG_NUMBER);
- if (p == last) { /* can't read nothing. */
- num = 0; /* but, it's not error */
- }
- token.type = TokenType.CODE_POINT;
- token.base = 16;
- token.setCode(num);
- }
+ fetchTokenInCCFor_u();
break;
-
case '0':
case '1':
case '2':
@@ -667,20 +700,9 @@ class Lexer extends ScannerSupport {
case '5':
case '6':
case '7':
- if (syntax.opEscOctal3()) {
- unfetch();
- last = p;
- int num = scanUnsignedOctalNumber(3);
- if (num < 0) newValueException(ERR_TOO_BIG_NUMBER);
- if (p == last) { /* can't read nothing. */
- num = 0; /* but, it's not error */
- }
- token.type = TokenType.RAW_BYTE;
- token.base = 8;
- token.setC(num);
- }
+ fetchTokenInCCFor_digit();
break;
-
+
default:
unfetch();
int num = fetchEscapedValue();
@@ -690,659 +712,513 @@ class Lexer extends ScannerSupport {
}
break;
} // switch
-
+
} else if (c == '[') {
- if (syntax.opPosixBracket() && peekIs(':')) {
- token.backP = p; /* point at '[' is readed */
- inc();
- if (strExistCheckWithEsc(send, send.length, ']')) {
- token.type = TokenType.POSIX_BRACKET_OPEN;
- } else {
- unfetch();
- // remove duplication, goto cc_in_cc;
- if (syntax.op2CClassSetOp()) {
- token.type = TokenType.CC_CC_OPEN;
- } else {
- env.ccEscWarn("[");
- }
- }
- } else { // cc_in_cc:
- if (syntax.op2CClassSetOp()) {
- token.type = TokenType.CC_CC_OPEN;
- } else {
- env.ccEscWarn("[");
- }
- }
+ fetchTokenInCCFor_posixBracket();
} else if (c == '&') {
- if (syntax.op2CClassSetOp() && left() && peekIs('&')) {
- inc();
- token.type = TokenType.CC_AND;
- }
+ fetchTokenInCCFor_and();
}
return token.type;
}
-
+
protected final int backrefRelToAbs(int relNo) {
return env.numMem + 1 + relNo;
}
-
- protected final TokenType fetchToken() {
- int last;
-
- // mark(); // out
-
- start:
- while(true) {
-
- if (!left()) {
- token.type = TokenType.EOT;
- return token.type;
- }
-
- token.type = TokenType.STRING;
- token.base = 0;
- token.backP = p;
- fetch();
-
- if (c == syntax.metaCharTable.esc && !syntax.op2IneffectiveEscape()) { // IS_MC_ESC_CODE(code, syn)
- if (!left()) newSyntaxException(ERR_END_PATTERN_AT_ESCAPE);
-
- token.backP = p;
- fetch();
-
- token.setC(c);
- token.escaped = true;
- switch(c) {
-
- case '*':
- if (!syntax.opEscAsteriskZeroInf()) break;
- token.type = TokenType.OP_REPEAT;
- token.setRepeatLower(0);
- token.setRepeatUpper(QuantifierNode.REPEAT_INFINITE);
- greedyCheck();
- break;
-
- case '+':
- if (!syntax.opEscPlusOneInf()) break;
- token.type = TokenType.OP_REPEAT;
- token.setRepeatLower(1);
- token.setRepeatUpper(QuantifierNode.REPEAT_INFINITE);
- greedyCheck();
- break;
+ private void fetchTokenFor_repeat(int lower, int upper) {
+ token.type = TokenType.OP_REPEAT;
+ token.setRepeatLower(lower);
+ token.setRepeatUpper(upper);
+ greedyCheck();
+ }
- case '?':
- if (!syntax.opEscQMarkZeroOne()) break;
- token.type = TokenType.OP_REPEAT;
- token.setRepeatLower(0);
- token.setRepeatUpper(1);
+ private void fetchTokenFor_openBrace() {
+ switch (fetchRangeQuantifier()) {
+ case 0:
+ greedyCheck();
+ break;
+ case 2:
+ if (syntax.fixedIntervalIsGreedyOnly()) {
+ possessiveCheck();
+ } else {
greedyCheck();
- break;
-
- case '{':
- if (!syntax.opEscBraceInterval()) break;
- switch (fetchRangeQuantifier()) {
- case 0:
- greedyCheck();
- break;
- case 2:
- if (syntax.fixedIntervalIsGreedyOnly()) {
- possessiveCheck();
- } else {
- greedyCheck();
- }
- break;
- default: /* 1 : normal char */
- } // inner switch
- break;
-
- case '|':
- if (!syntax.opEscVBarAlt()) break;
- token.type = TokenType.ALT;
- break;
-
- case '(':
- if (!syntax.opEscLParenSubexp()) break;
- token.type = TokenType.SUBEXP_OPEN;
- break;
+ }
+ break;
+ default: /* 1 : normal char */
+ } // inner switch
+ }
- case ')':
- if (!syntax.opEscLParenSubexp()) break;
- token.type = TokenType.SUBEXP_CLOSE;
- break;
+ private void fetchTokenFor_anchor(int subType) {
+ token.type = TokenType.ANCHOR;
+ token.setAnchor(subType);
+ }
- case 'w':
- if (!syntax.opEscWWord()) break;
- token.type = TokenType.CHAR_TYPE;
- token.setPropCType(CharacterType.WORD);
- token.setPropNot(false);
- break;
+ private void fetchTokenFor_xBrace() {
+ if (!left()) return;
- case 'W':
- if (!syntax.opEscWWord()) break;
- token.type = TokenType.CHAR_TYPE;
- token.setPropCType(CharacterType.WORD);
- token.setPropNot(true);
- break;
+ int last = p;
+ if (peekIs('{') && syntax.opEscXBraceHex8()) {
+ inc();
+ int num = scanUnsignedHexadecimalNumber(8);
+ if (num < 0) newValueException(ERR_TOO_BIG_WIDE_CHAR_VALUE);
+ if (left()) {
+ if (enc.isXDigit(peek())) newValueException(ERR_TOO_LONG_WIDE_CHAR_VALUE);
+ }
- case 'b':
- if (!syntax.opEscBWordBound()) break;
- token.type = TokenType.ANCHOR;
- token.setAnchor(AnchorType.WORD_BOUND);
- break;
+ if (p > last + enc.length(bytes, last, stop) && left() && peekIs('}')) {
+ inc();
+ token.type = TokenType.CODE_POINT;
+ token.setCode(num);
+ } else {
+ /* can't read nothing or invalid format */
+ p = last;
+ }
+ } else if (syntax.opEscXHex2()) {
+ int num = scanUnsignedHexadecimalNumber(2);
+ if (num < 0) newValueException(ERR_TOO_BIG_NUMBER);
+ if (p == last) { /* can't read nothing. */
+ num = 0; /* but, it's not error */
+ }
+ token.type = TokenType.RAW_BYTE;
+ token.base = 16;
+ token.setC(num);
+ }
+ }
- case 'B':
- if (!syntax.opEscBWordBound()) break;
- token.type = TokenType.ANCHOR;
- token.setAnchor(AnchorType.NOT_WORD_BOUND);
- break;
+ private void fetchTokenFor_uHex() {
+ if (!left()) return;
+ int last = p;
- case '<':
- if (Config.USE_WORD_BEGIN_END) {
- if (!syntax.opEscLtGtWordBeginEnd()) break;
- token.type = TokenType.ANCHOR;
- token.setAnchor(AnchorType.WORD_BEGIN);
- break;
- } // USE_WORD_BEGIN_END
- break; // ?
-
- case '>':
- if (Config.USE_WORD_BEGIN_END) {
- if (!syntax.opEscLtGtWordBeginEnd()) break;
- token.type = TokenType.ANCHOR;
- token.setAnchor(AnchorType.WORD_END);
- break;
- } // USE_WORD_BEGIN_END
- break; // ?
+ if (syntax.op2EscUHex4()) {
+ int num = scanUnsignedHexadecimalNumber(4);
+ if (num < 0) newValueException(ERR_TOO_BIG_NUMBER);
+ if (p == last) { /* can't read nothing. */
+ num = 0; /* but, it's not error */
+ }
+ token.type = TokenType.CODE_POINT;
+ token.base = 16;
+ token.setCode(num);
+ }
+ }
- case 's':
- if (!syntax.opEscSWhiteSpace()) break;
- token.type = TokenType.CHAR_TYPE;
- token.setPropCType(CharacterType.SPACE);
- token.setPropNot(false);
- break;
+ private void fetchTokenFor_digit() {
+ unfetch();
+ int last = p;
+ int num = scanUnsignedNumber();
+ if (num < 0 || num > Config.MAX_BACKREF_NUM) { // goto skip_backref
+ } else if (syntax.opDecimalBackref() && (num <= env.numMem || num <= 9)) { /* This spec. from GNU regex */
+ if (syntax.strictCheckBackref()) {
+ if (num > env.numMem || env.memNodes == null || env.memNodes[num] == null) newValueException(ERR_INVALID_BACKREF);
+ }
+ token.type = TokenType.BACKREF;
+ token.setBackrefNum(1);
+ token.setBackrefRef1(num);
+ token.setBackrefByName(false);
+ if (Config.USE_BACKREF_WITH_LEVEL) token.setBackrefExistLevel(false);
+ return;
+ }
- case 'S':
- if (!syntax.opEscSWhiteSpace()) break;
- token.type = TokenType.CHAR_TYPE;
- token.setPropCType(CharacterType.SPACE);
- token.setPropNot(true);
- break;
-
- case 'd':
- if (!syntax.opEscDDigit()) break;
- token.type = TokenType.CHAR_TYPE;
- token.setPropCType(CharacterType.DIGIT);
- token.setPropNot(false);
- break;
-
- case 'D':
- if (!syntax.opEscDDigit()) break;
- token.type = TokenType.CHAR_TYPE;
- token.setPropCType(CharacterType.DIGIT);
- token.setPropNot(true);
- break;
+ if (c == '8' || c == '9') { /* normal char */ // skip_backref:
+ p = last;
+ inc();
+ return;
+ }
+ p = last;
- case 'h':
- if (!syntax.op2EscHXDigit()) break;
- token.type = TokenType.CHAR_TYPE;
- token.setPropCType(CharacterType.XDIGIT);
- token.setPropNot(false);
- break;
+ fetchTokenFor_zero(); /* fall through */
+ }
- case 'H':
- if (!syntax.op2EscHXDigit()) break;
- token.type = TokenType.CHAR_TYPE;
- token.setPropCType(CharacterType.XDIGIT);
- token.setPropNot(true);
- break;
+ private void fetchTokenFor_zero() {
+ if (syntax.opEscOctal3()) {
+ int last = p;
+ int num = scanUnsignedOctalNumber(c == '0' ? 2 : 3);
+ if (num < 0) newValueException(ERR_TOO_BIG_NUMBER);
+ if (p == last) { /* can't read nothing. */
+ num = 0; /* but, it's not error */
+ }
+ token.type = TokenType.RAW_BYTE;
+ token.base = 8;
+ token.setC(num);
+ } else if (c != '0') {
+ inc();
+ }
+ }
- case 'A':
- if (!syntax.opEscAZBufAnchor()) break;
- // begin_buf label
- token.type = TokenType.ANCHOR;
- token.setSubtype(AnchorType.BEGIN_BUF);
- break;
-
- case 'Z':
- if (!syntax.opEscAZBufAnchor()) break;
- token.type = TokenType.ANCHOR;
- token.setSubtype(AnchorType.SEMI_END_BUF);
- break;
-
- case 'z':
- if (!syntax.opEscAZBufAnchor()) break;
- // end_buf label
- token.type = TokenType.ANCHOR;
- token.setSubtype(AnchorType.END_BUF);
- break;
-
- case 'G':
- if (!syntax.opEscCapitalGBeginAnchor()) break;
- token.type = TokenType.ANCHOR;
- token.setSubtype(AnchorType.BEGIN_POSITION);
- break;
-
- case '`':
- if (!syntax.op2EscGnuBufAnchor()) break;
- // goto begin_buf
- token.type = TokenType.ANCHOR;
- token.setSubtype(AnchorType.BEGIN_BUF);
- break;
+ private void fetchTokenFor_namedBackref() {
+ if (syntax.op2EscKNamedBackref()) {
+ if (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
- case '\'':
- if (!syntax.op2EscGnuBufAnchor()) break;
- // goto end_buf
- token.type = TokenType.ANCHOR;
- token.setSubtype(AnchorType.END_BUF);
- break;
+ if (backNum != 0) {
+ if (backNum < 0) {
+ backNum = backrefRelToAbs(backNum);
+ if (backNum <= 0) newValueException(ERR_INVALID_BACKREF);
+ }
- case 'x': // extract to helper for all 'x'
- if (!left()) break;
- last = p;
- if (peekIs('{') && syntax.opEscXBraceHex8()) {
- inc();
- int num = scanUnsignedHexadecimalNumber(8);
- if (num < 0) newValueException(ERR_TOO_BIG_WIDE_CHAR_VALUE);
- if (left()) {
- if (enc.isXDigit(peek())) newValueException(ERR_TOO_LONG_WIDE_CHAR_VALUE);
- }
-
- if (p > last + enc.length(bytes, last, stop) && left() && peekIs('}')) {
- inc();
- token.type = TokenType.CODE_POINT;
- token.setCode(num);
+ 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 {
- /* can't read nothing or invalid format */
- p = last;
- }
- } else if (syntax.opEscXHex2()) {
- int num = scanUnsignedHexadecimalNumber(2);
- if (num < 0) newValueException(ERR_TOO_BIG_NUMBER);
- if (p == last) { /* can't read nothing. */
- num = 0; /* but, it's not error */
- }
- token.type = TokenType.RAW_BYTE;
- token.base = 16;
- token.setC(num);
- }
- break;
-
- case 'u': // extract to helper
- if (!left()) break;
- last = p;
-
- if (syntax.op2EscUHex4()) {
- int num = scanUnsignedHexadecimalNumber(4);
- if (num < 0) newValueException(ERR_TOO_BIG_NUMBER);
- if (p == last) { /* can't read nothing. */
- num = 0; /* but, it's not error */
- }
- token.type = TokenType.CODE_POINT;
- token.base = 16;
- token.setCode(num);
- }
- break;
-
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- unfetch();
- last = p;
- int num = scanUnsignedNumber();
- if (num < 0 || num > Config.MAX_BACKREF_NUM) {
- // goto skip_backref
- } else if (syntax.opDecimalBackref() && (num <= env.numMem || num <= 9)) { /* This spec. from GNU regex */
- if (syntax.strictCheckBackref()) {
- if (num > env.numMem || env.memNodes == null || env.memNodes[num] == null) newValueException(ERR_INVALID_BACKREF);
- }
- token.type = TokenType.BACKREF;
- token.setBackrefNum(1);
- token.setBackrefRef1(num);
- token.setBackrefByName(false);
- if (Config.USE_BACKREF_WITH_LEVEL) token.setBackrefExistLevel(false);
- break;
- }
- // skip_backref:
- if (c == '8' || c == '9') {
- /* normal char */
- p = last;
- inc();
- break;
- }
- p = last;
- /* fall through */
-
- case '0':
- if (syntax.opEscOctal3()) {
- last = p;
- num = scanUnsignedOctalNumber(c == '0' ? 2 : 3);
- if (num < 0) newValueException(ERR_TOO_BIG_NUMBER);
- if (p == last) { /* can't read nothing. */
- num = 0; /* but, it's not error */
- }
- token.type = TokenType.RAW_BYTE;
- token.base = 8;
- token.setC(num);
- } else if (c != '0') {
- inc();
- }
- break;
-
- case 'k':
- if (Config.USE_NAMED_GROUP) {
- if (syntax.op2EscKNamedBackref()) {
- fetch();
- if (c =='<' || c == '\'') {
- last = p;
- int backNum;
- if (Config.USE_BACKREF_WITH_LEVEL) {
- int[]rbackNum = new int[1];
- int[]rlevel = new int[1];
- token.setBackrefExistLevel(fetchNameWithLevel(c, rbackNum, rlevel));
- token.setBackrefLevel(rlevel[0]);
- backNum = rbackNum[0];
- } 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);
- }
- }
- }
+ NameEntry e = env.reg.nameToGroupNumbers(bytes, last, nameEnd);
+ if (e == null) newValueException(ERR_UNDEFINED_NAME_REFERENCE, last, nameEnd);
- 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);
+ 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);
}
}
- } else {
- unfetch();
}
- }
-
- break;
- } // USE_NAMED_GROUP
- break;
-
- case 'g':
- if (Config.USE_SUBEXP_CALL) {
- if (syntax.op2EscGSubexpCall()) {
- fetch();
- if (c == '<' || c == '\'') {
- last = p;
- int gNum = fetchName(c, true);
- int nameEnd = value;
- token.type = TokenType.CALL;
- token.setCallNameP(last);
- token.setCallNameEnd(nameEnd);
- token.setCallGNum(gNum);
+
+ token.type = TokenType.BACKREF;
+ token.setBackrefByName(true);
+
+ if (e.backNum == 1) {
+ token.setBackrefNum(1);
+ token.setBackrefRef1(e.backRef1);
} else {
- unfetch();
+ token.setBackrefNum(e.backNum);
+ token.setBackrefRefs(e.backRefs);
}
}
- break;
- } // USE_SUBEXP_CALL
- break;
-
- case 'Q':
- if (syntax.op2EscCapitalQQuote()) {
- token.type = TokenType.QUOTE_OPEN;
+ } else {
+ unfetch();
+ syntaxWarn(Warnings.INVALID_BACKREFERENCE);
}
- break;
-
- case 'p':
- case 'P':
- if (peekIs('{') && syntax.op2EscPBraceCharProperty()) {
- inc();
- token.type = TokenType.CHAR_PROPERTY;
- token.setPropNot(c == 'P');
-
- if (syntax.op2EscPBraceCircumflexNot()) {
- fetch();
- if (c == '^') {
- token.setPropNot(!token.getPropNot());
- } else {
- unfetch();
- }
- }
+ } else {
+ syntaxWarn(Warnings.INVALID_BACKREFERENCE);
+ }
+ }
+ }
+
+ private void fetchTokenFor_subexpCall() {
+ if (syntax.op2EscGSubexpCall()) {
+ if (left()) {
+ fetch();
+ if (c == '<' || c == '\'') {
+ int last = p;
+ int gNum = fetchName(c, true);
+ int nameEnd = value;
+ token.type = TokenType.CALL;
+ token.setCallNameP(last);
+ token.setCallNameEnd(nameEnd);
+ token.setCallGNum(gNum);
+ } else {
+ unfetch();
+ syntaxWarn(Warnings.INVALID_SUBEXP_CALL);
}
- break;
-
- default:
- unfetch();
- num = fetchEscapedValue();
+ } else {
+ syntaxWarn(Warnings.INVALID_SUBEXP_CALL);
+ }
+ }
+ }
- /* set_raw: */
- if (token.getC() != num) {
- token.type = TokenType.CODE_POINT;
- token.setCode(num);
- } else { /* string */
- p = token.backP + enc.length(bytes, token.backP, stop);
+ private void fetchTokenFor_charProperty() {
+ if (peekIs('{') && syntax.op2EscPBraceCharProperty()) {
+ inc();
+ token.type = TokenType.CHAR_PROPERTY;
+ token.setPropNot(c == 'P');
+
+ if (syntax.op2EscPBraceCircumflexNot()) {
+ fetch();
+ if (c == '^') {
+ token.setPropNot(!token.getPropNot());
+ } else {
+ unfetch();
}
- break;
-
- } // switch (c)
-
+ }
} else {
- token.setC(c);
- token.escaped = false;
-
- // remove code duplication
- if (Config.USE_VARIABLE_META_CHARS) {
- if (c != MetaChar.INEFFECTIVE_META_CHAR && syntax.opVariableMetaCharacters()) {
- if (c == syntax.metaCharTable.anyChar) { // goto any_char
- token.type = TokenType.ANYCHAR;
- break;
- } else if (c == syntax.metaCharTable.anyTime) { // goto anytime
- token.type = TokenType.OP_REPEAT;
- token.setRepeatLower(0);
- token.setRepeatUpper(QuantifierNode.REPEAT_INFINITE);
- greedyCheck();
- break;
- } else if (c == syntax.metaCharTable.zeroOrOneTime) { // goto zero_or_one_time
- token.type = TokenType.OP_REPEAT;
- token.setRepeatLower(0);
- token.setRepeatUpper(1);
- greedyCheck();
- break;
- } else if (c == syntax.metaCharTable.oneOrMoreTime) { // goto one_or_more_time
- token.type = TokenType.OP_REPEAT;
- token.setRepeatLower(1);
- token.setRepeatUpper(QuantifierNode.REPEAT_INFINITE);
- greedyCheck();
- break;
- } else if (c == syntax.metaCharTable.anyCharAnyTime) { // goto one_or_more_time
- token.type = TokenType.ANYCHAR_ANYTIME;
- break;
- // goto out
- }
- }
- } // USE_VARIABLE_META_CHARS
-
- {
+ syntaxWarn(Warnings.INVALID_UNICODE_PROPERTY, (char)c);
+ }
+ }
+
+ private void fetchTokenFor_metaChars() {
+ if (c == syntax.metaCharTable.anyChar) {
+ token.type = TokenType.ANYCHAR;
+ } else if (c == syntax.metaCharTable.anyTime) {
+ fetchTokenFor_repeat(0, QuantifierNode.REPEAT_INFINITE);
+ } else if (c == syntax.metaCharTable.zeroOrOneTime) {
+ fetchTokenFor_repeat(0, 1);
+ } else if (c == syntax.metaCharTable.oneOrMoreTime) {
+ fetchTokenFor_repeat(1, QuantifierNode.REPEAT_INFINITE);
+ } else if (c == syntax.metaCharTable.anyCharAnyTime) {
+ token.type = TokenType.ANYCHAR_ANYTIME;
+ // goto out
+ }
+ }
+
+ protected final TokenType fetchToken() {
+ // mark(); // out
+ start:
+ while(true) {
+ if (!left()) {
+ token.type = TokenType.EOT;
+ return token.type;
+ }
+
+ token.type = TokenType.STRING;
+ token.base = 0;
+ token.backP = p;
+
+ fetch();
+
+ if (c == syntax.metaCharTable.esc && !syntax.op2IneffectiveEscape()) { // IS_MC_ESC_CODE(code, syn)
+ if (!left()) newSyntaxException(ERR_END_PATTERN_AT_ESCAPE);
+
+ token.backP = p;
+ fetch();
+
+ token.setC(c);
+ token.escaped = true;
switch(c) {
-
- case '.':
- if (!syntax.opDotAnyChar()) break;
- // any_char:
- token.type = TokenType.ANYCHAR;
- break;
-
+
case '*':
- if (!syntax.opAsteriskZeroInf()) break;
- // anytime:
- token.type = TokenType.OP_REPEAT;
- token.setRepeatLower(0);
- token.setRepeatUpper(QuantifierNode.REPEAT_INFINITE);
- greedyCheck();
+ if (syntax.opEscAsteriskZeroInf()) fetchTokenFor_repeat(0, QuantifierNode.REPEAT_INFINITE);
break;
-
case '+':
- if (!syntax.opPlusOneInf()) break;
- // one_or_more_time:
- token.type = TokenType.OP_REPEAT;
- token.setRepeatLower(1);
- token.setRepeatUpper(QuantifierNode.REPEAT_INFINITE);
- greedyCheck();
+ if (syntax.opEscPlusOneInf()) fetchTokenFor_repeat(1, QuantifierNode.REPEAT_INFINITE);
break;
-
- case '?':
- if (!syntax.opQMarkZeroOne()) break;
- // zero_or_one_time:
- token.type = TokenType.OP_REPEAT;
- token.setRepeatLower(0);
- token.setRepeatUpper(1);
- greedyCheck();
+ case '?':
+ if (syntax.opEscQMarkZeroOne()) fetchTokenFor_repeat(0, 1);
break;
-
case '{':
- if (!syntax.opBraceInterval()) break;
- switch(fetchRangeQuantifier()) {
- case 0:
- greedyCheck();
- break;
- case 2:
- if (syntax.fixedIntervalIsGreedyOnly()) {
- possessiveCheck();
- } else {
- greedyCheck();
- }
- break;
- default: /* 1 : normal char */
- } // inner switch
+ if (syntax.opEscBraceInterval()) fetchTokenFor_openBrace();
break;
-
case '|':
- if (!syntax.opVBarAlt()) break;
- token.type = TokenType.ALT;
+ if (syntax.opEscVBarAlt()) token.type = TokenType.ALT;
break;
-
case '(':
- if (peekIs('?') && syntax.op2QMarkGroupEffect()) {
- inc();
- if (peekIs('#')) {
- fetch();
- while (true) {
- if (!left()) newSyntaxException(ERR_END_PATTERN_IN_GROUP);
- fetch();
- if (c == syntax.metaCharTable.esc) {
- if (left()) fetch();
- } else {
- if (c == ')') break;
- }
- }
- continue start; // goto start
- }
- unfetch();
- }
-
- if (!syntax.opLParenSubexp()) break;
- token.type = TokenType.SUBEXP_OPEN;
+ if (syntax.opEscLParenSubexp()) token.type = TokenType.SUBEXP_OPEN;
break;
-
case ')':
- if (!syntax.opLParenSubexp()) break;
- token.type = TokenType.SUBEXP_CLOSE;
+ if (syntax.opEscLParenSubexp()) token.type = TokenType.SUBEXP_CLOSE;
break;
-
- case '^':
- if (!syntax.opLineAnchor()) break;
- token.type = TokenType.ANCHOR;
- token.setSubtype(isSingleline(env.option) ? AnchorType.BEGIN_BUF : AnchorType.BEGIN_LINE);
+ case 'w':
+ if (syntax.opEscWWord()) fetchTokenInCCFor_charType(false, Config.NON_UNICODE_SDW ? CharacterType.W : CharacterType.WORD);
break;
-
- case '$':
- if (!syntax.opLineAnchor()) break;
- token.type = TokenType.ANCHOR;
- token.setSubtype(isSingleline(env.option) ? AnchorType.SEMI_END_BUF : AnchorType.END_LINE);
+ case 'W':
+ if (syntax.opEscWWord()) fetchTokenInCCFor_charType(true, Config.NON_UNICODE_SDW ? CharacterType.W : CharacterType.WORD);
break;
-
- case '[':
- if (!syntax.opBracketCC()) break;
- token.type = TokenType.CC_CC_OPEN;
+ case 'b':
+ if (syntax.opEscBWordBound()) fetchTokenFor_anchor(AnchorType.WORD_BOUND);
break;
-
- case ']':
- //if (*src > env->pattern) /* /].../ is allowed. */
- //CLOSE_BRACKET_WITHOUT_ESC_WARN(env, (UChar* )"]");
+ case 'B':
+ if (syntax.opEscBWordBound()) fetchTokenFor_anchor(AnchorType.NOT_WORD_BOUND);
break;
-
- case '#':
- if (Option.isExtend(env.option)) {
- while (left()) {
- fetch();
- if (enc.isNewLine(c)) break;
- }
- continue start; // goto start
-
- }
+ case '<':
+ if (Config.USE_WORD_BEGIN_END && syntax.opEscLtGtWordBeginEnd()) fetchTokenFor_anchor(AnchorType.WORD_BEGIN);
+ break;
+ case '>':
+ if (Config.USE_WORD_BEGIN_END && syntax.opEscLtGtWordBeginEnd()) fetchTokenFor_anchor(AnchorType.WORD_END);
+ break;
+ case 's':
+ if (syntax.opEscSWhiteSpace()) fetchTokenInCCFor_charType(false, Config.NON_UNICODE_SDW ? CharacterType.S : CharacterType.SPACE);
+ break;
+ case 'S':
+ if (syntax.opEscSWhiteSpace()) fetchTokenInCCFor_charType(true, Config.NON_UNICODE_SDW ? CharacterType.S : CharacterType.SPACE);
+ break;
+ case 'd':
+ if (syntax.opEscDDigit()) fetchTokenInCCFor_charType(false, Config.NON_UNICODE_SDW ? CharacterType.D : CharacterType.DIGIT);
+ break;
+ case 'D':
+ if (syntax.opEscDDigit()) fetchTokenInCCFor_charType(true, Config.NON_UNICODE_SDW ? CharacterType.D : CharacterType.DIGIT);
+ break;
+ case 'h':
+ if (syntax.op2EscHXDigit()) fetchTokenInCCFor_charType(false, CharacterType.XDIGIT);
+ break;
+ case 'H':
+ if (syntax.op2EscHXDigit()) fetchTokenInCCFor_charType(true, CharacterType.XDIGIT);
+ break;
+ case 'A':
+ if (syntax.opEscAZBufAnchor()) fetchTokenFor_anchor(AnchorType.BEGIN_BUF);
+ break;
+ case 'Z':
+ if (syntax.opEscAZBufAnchor()) fetchTokenFor_anchor(AnchorType.SEMI_END_BUF);
+ break;
+ case 'z':
+ if (syntax.opEscAZBufAnchor()) fetchTokenFor_anchor(AnchorType.END_BUF);
+ break;
+ case 'G':
+ if (syntax.opEscCapitalGBeginAnchor()) fetchTokenFor_anchor(AnchorType.BEGIN_POSITION);
break;
-
- case ' ':
- case '\t':
- case '\n':
- case '\r':
- case '\f':
- if (Option.isExtend(env.option)) {
- continue start; // goto start
+ case '`':
+ if (syntax.op2EscGnuBufAnchor()) fetchTokenFor_anchor(AnchorType.BEGIN_BUF);
+ break;
+ case '\'':
+ if (syntax.op2EscGnuBufAnchor()) fetchTokenFor_anchor(AnchorType.END_BUF);
+ break;
+ case 'x':
+ fetchTokenFor_xBrace();
+ break;
+ case 'u':
+ fetchTokenFor_uHex();
+ break;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ fetchTokenFor_digit();
+ break;
+ case '0':
+ fetchTokenFor_zero();
+ break;
+ case 'k':
+ if (Config.USE_NAMED_GROUP) fetchTokenFor_namedBackref();
+ break;
+ case 'g':
+ if (Config.USE_SUBEXP_CALL) fetchTokenFor_subexpCall();
+ break;
+ case 'Q':
+ if (syntax.op2EscCapitalQQuote()) token.type = TokenType.QUOTE_OPEN;
+ break;
+ case 'p':
+ case 'P':
+ fetchTokenFor_charProperty();
+ break;
+
+ default:
+ unfetch();
+ int num = fetchEscapedValue();
+
+ /* set_raw: */
+ if (token.getC() != num) {
+ token.type = TokenType.CODE_POINT;
+ token.setCode(num);
+ } else { /* string */
+ p = token.backP + enc.length(bytes, token.backP, stop);
}
break;
-
- default: // string
+
+ } // switch (c)
+
+ } else {
+ token.setC(c);
+ token.escaped = false;
+
+ if (Config.USE_VARIABLE_META_CHARS && (c != MetaChar.INEFFECTIVE_META_CHAR && syntax.opVariableMetaCharacters())) {
+ fetchTokenFor_metaChars();
break;
-
- } // switch
+ }
+
+ {
+ switch(c) {
+ case '.':
+ if (syntax.opDotAnyChar()) token.type = TokenType.ANYCHAR;
+ break;
+ case '*':
+ if (syntax.opAsteriskZeroInf()) fetchTokenFor_repeat(0, QuantifierNode.REPEAT_INFINITE);
+ break;
+ case '+':
+ if (syntax.opPlusOneInf()) fetchTokenFor_repeat(1, QuantifierNode.REPEAT_INFINITE);
+ break;
+ case '?':
+ if (syntax.opQMarkZeroOne()) fetchTokenFor_repeat(0, 1);
+ break;
+ case '{':
+ if (syntax.opBraceInterval()) fetchTokenFor_openBrace();
+ break;
+ case '|':
+ if (syntax.opVBarAlt()) token.type = TokenType.ALT;
+ break;
+
+ case '(':
+ if (peekIs('?') && syntax.op2QMarkGroupEffect()) {
+ inc();
+ if (peekIs('#')) {
+ fetch();
+ while (true) {
+ if (!left()) newSyntaxException(ERR_END_PATTERN_IN_GROUP);
+ fetch();
+ if (c == syntax.metaCharTable.esc) {
+ if (left()) fetch();
+ } else {
+ if (c == ')') break;
+ }
+ }
+ continue start; // goto start
+ }
+ unfetch();
+ }
+
+ if (syntax.opLParenSubexp()) token.type = TokenType.SUBEXP_OPEN;
+ break;
+ case ')':
+ if (syntax.opLParenSubexp()) token.type = TokenType.SUBEXP_CLOSE;
+ break;
+ case '^':
+ if (syntax.opLineAnchor()) fetchTokenFor_anchor(isSingleline(env.option) ? AnchorType.BEGIN_BUF : AnchorType.BEGIN_LINE);
+ break;
+ case '$':
+ if (syntax.opLineAnchor()) fetchTokenFor_anchor(isSingleline(env.option) ? AnchorType.SEMI_END_BUF : AnchorType.END_LINE);
+ break;
+ case '[':
+ if (syntax.opBracketCC()) token.type = TokenType.CC_CC_OPEN;
+ break;
+ case ']':
+ //if (*src > env->pattern) /* /].../ is allowed. */
+ //CLOSE_BRACKET_WITHOUT_ESC_WARN(env, (UChar* )"]");
+ break;
+ case '#':
+ if (Option.isExtend(env.option)) {
+ while (left()) {
+ fetch();
+ if (enc.isNewLine(c)) break;
+ }
+ continue start; // goto start
+ }
+ break;
+
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ case '\f':
+ if (Option.isExtend(env.option)) continue start; // goto start
+ break;
+
+ default: // string
+ break;
+
+ } // switch
+ }
}
- }
-
- break;
+
+ break;
} // while
- return token.type;
+ return token.type;
}
-
+
private void greedyCheck() {
if (left() && peekIs('?') && syntax.opQMarkNonGreedy()) {
-
+
fetch();
token.setRepeatGreedy(false);
@@ -1351,14 +1227,14 @@ class Lexer extends ScannerSupport {
possessiveCheck();
}
}
-
+
private void possessiveCheck() {
- if (left() && peekIs('+') &&
+ if (left() && peekIs('+') &&
(syntax.op2PlusPossessiveRepeat() && token.type != TokenType.INTERVAL ||
syntax.op2PlusPossessiveInterval() && token.type == TokenType.INTERVAL)) {
-
+
fetch();
-
+
token.setRepeatGreedy(true);
token.setRepeatPossessive(true);
} else {
@@ -1382,4 +1258,14 @@ class Lexer extends ScannerSupport {
newInternalException(ERR_PARSER_BUG);
return 0; // not reached
}
+
+ protected final void syntaxWarn(String message, char c) {
+ syntaxWarn(message.replace("<%n>", Character.toString(c)));
+ }
+
+ protected final void syntaxWarn(String message) {
+ if (Config.USE_WARN) {
+ env.reg.warnings.warn(message + ": /" + new String(bytes, getBegin(), getEnd()) + "/");
+ }
+ }
}
diff --git a/src/org/joni/Matcher.java b/src/org/joni/Matcher.java
index 1f0a1dd..4fa923d 100644
--- a/src/org/joni/Matcher.java
+++ b/src/org/joni/Matcher.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
@@ -59,7 +59,7 @@ public abstract class Matcher extends IntHolder {
}
// main matching method
- protected abstract int matchAt(int range, int sstart, int sprev);
+ protected abstract int matchAt(int range, int sstart, int sprev);
protected abstract void stateCheckBuffInit(int strLength, int offset, int stateNum);
protected abstract void stateCheckBuffClear();
@@ -67,15 +67,15 @@ public abstract class Matcher extends IntHolder {
public final Region getRegion() {
return msaRegion;
}
-
+
public final Region getEagerRegion() {
return msaRegion != null ? msaRegion : new Region(msaBegin, msaEnd);
}
-
+
public final int getBegin() {
return msaBegin;
}
-
+
public final int getEnd() {
return msaEnd;
}
@@ -84,25 +84,25 @@ public abstract class Matcher extends IntHolder {
msaOptions = option;
msaStart = start;
if (Config.USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE) msaBestLen = -1;
- }
+ }
public final int match(int at, int range, int option) {
msaInit(option, at);
-
+
if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
int offset = at = str;
stateCheckBuffInit(end - str, offset, regex.numCombExpCheck); // move it to construction?
} // USE_COMBINATION_EXPLOSION_CHECK
-
+
int prev = enc.prevCharHead(bytes, str, at, end);
-
+
if (Config.USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE) {
return matchAt(end /*range*/, at, prev);
} else {
return matchAt(range /*range*/, at, prev);
}
}
-
+
int low, high; // these are the return values
private boolean forwardSearchRange(byte[]bytes, int str, int end, int s, int range, IntHolder lowPrev) {
int pprev = -1;
@@ -114,20 +114,20 @@ public abstract class Matcher extends IntHolder {
", end: " + end +
", s: " + s +
", range: " + range);
- }
-
+ }
+
if (regex.dMin > 0) {
if (enc.isSingleByte()) {
p += regex.dMin;
} else {
int q = p + regex.dMin;
- while (p < q) p += enc.length(bytes, p, end);
+ while (p < q && p < end) p += enc.length(bytes, p, end);
}
}
retry:while (true) {
p = regex.searchAlgorithm.search(regex, bytes, p, end, range);
-
+
if (p != -1 && p < range) {
if (p - regex.dMin < s) {
// retry_gate:
@@ -135,7 +135,7 @@ public abstract class Matcher extends IntHolder {
p += enc.length(bytes, p, end);
continue retry;
}
-
+
if (regex.subAnchor != 0) {
switch (regex.subAnchor) {
case AnchorType.BEGIN_LINE:
@@ -149,7 +149,7 @@ public abstract class Matcher extends IntHolder {
}
}
break;
-
+
case AnchorType.END_LINE:
if (p == end) {
if (!Config.USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE) {
@@ -199,30 +199,30 @@ public abstract class Matcher extends IntHolder {
}
/* no needs to adjust *high, *high is used as range check only */
high = p - regex.dMin;
-
+
if (Config.DEBUG_SEARCH) {
Config.log.println("forward_search_range success: "+
"low: " + (low - str) +
", high: " + (high - str) +
", dmin: " + regex.dMin +
", dmax: " + regex.dMax);
- }
-
+ }
+
return true; /* success */
}
return false; /* fail */
- } //while
+ } //while
}
-
+
// low, high
private boolean backwardSearchRange(byte[]bytes, int str, int end, int s, int range, int adjrange) {
range += regex.dMin;
int p = s;
-
+
retry:while (true) {
p = regex.searchAlgorithm.searchBackward(regex, bytes, range, adjrange, end, p, s, range);
-
+
if (p != -1) {
if (regex.subAnchor != 0) {
switch (regex.subAnchor) {
@@ -235,7 +235,7 @@ public abstract class Matcher extends IntHolder {
}
}
break;
-
+
case AnchorType.END_LINE:
if (p == end) {
if (!Config.USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE) {
@@ -254,28 +254,28 @@ public abstract class Matcher extends IntHolder {
break;
} // switch
}
-
+
/* no needs to adjust *high, *high is used as range check only */
if (regex.dMax != MinMaxLen.INFINITE_DISTANCE) {
low = p - regex.dMax;
high = p - regex.dMin;
high = enc.rightAdjustCharHead(bytes, adjrange, high, end);
}
-
+
if (Config.DEBUG_SEARCH) {
Config.log.println("backward_search_range: "+
"low: " + (low - str) +
", high: " + (high - str));
- }
-
+ }
+
return true;
}
-
+
if (Config.DEBUG_SEARCH) Config.log.println("backward_search_range: fail.");
return false;
} // while
}
-
+
// MATCH_AND_RETURN_CHECK
private boolean matchCheck(int upperRange, int s, int prev) {
if (Config.USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE) {
@@ -297,30 +297,30 @@ public abstract class Matcher extends IntHolder {
} else {
//range = upperRange;
if (matchAt(end, s, prev) != -1) return true;
- }
+ }
}
return false;
}
-
+
public final int search(int start, int range, int option) {
int s, prev;
int origStart = start;
int origRange = range;
-
+
if (Config.DEBUG_SEARCH) {
Config.log.println("onig_search (entry point): "+
- "str: " + str +
- ", end: " + (end - str) +
- ", start: " + (start - str) +
+ "str: " + str +
+ ", end: " + (end - str) +
+ ", start: " + (start - str) +
", range " + (range - str));
}
-
+
if (start > end || start < str) return -1;
-
+
/* anchor optimize: resume search range */
if (regex.anchor != 0 && str < end) {
int minSemiEnd, maxSemiEnd;
-
+
if ((regex.anchor & AnchorType.BEGIN_POSITION) != 0) {
/* search start-position only */
// !begin_position:!
@@ -334,7 +334,7 @@ public abstract class Matcher extends IntHolder {
if (range > start) {
if (start != str) return -1; // mismatch_no_msa;
range = str + 1;
- } else {
+ } else {
if (range <= str) {
start = str;
range = str;
@@ -359,12 +359,12 @@ public abstract class Matcher extends IntHolder {
}
if (minSemiEnd > str && start <= minSemiEnd) {
// !goto end_buf;!
- if (endBuf(start, range, minSemiEnd, maxSemiEnd)) return -1; // mismatch_no_msa;
+ if (endBuf(start, range, minSemiEnd, maxSemiEnd)) return -1; // mismatch_no_msa;
}
} else {
minSemiEnd = end;
// !goto end_buf;!
- if (endBuf(start, range, minSemiEnd, maxSemiEnd)) return -1; // mismatch_no_msa;
+ if (endBuf(start, range, minSemiEnd, maxSemiEnd)) return -1; // mismatch_no_msa;
}
} else if ((regex.anchor & AnchorType.ANYCHAR_STAR_ML) != 0) {
// goto !begin_position;!
@@ -372,15 +372,15 @@ public abstract class Matcher extends IntHolder {
range = start + 1;
} else {
range = start;
- }
+ }
}
-
+
} else if (str == end) { /* empty string */
// empty address ?
if (Config.DEBUG_SEARCH) {
Config.log.println("onig_search: empty string.");
}
-
+
if (regex.thresholdLength == 0) {
s = start = str;
prev = -1;
@@ -393,11 +393,11 @@ public abstract class Matcher extends IntHolder {
}
return -1; // goto mismatch_no_msa;
}
-
+
if (Config.DEBUG_SEARCH) {
Config.log.println("onig_search(apply anchor): " +
"end: " + (end - str) +
- ", start " + (start - str) +
+ ", start " + (start - str) +
", range " + (range - str));
}
@@ -406,7 +406,7 @@ public abstract class Matcher extends IntHolder {
int offset = Math.min(start, range) - str;
stateCheckBuffInit(end - str, offset, regex.numCombExpCheck);
}
-
+
s = start;
if (range > start) { /* forward search */
if (s > str) {
@@ -414,7 +414,7 @@ public abstract class Matcher extends IntHolder {
} else {
prev = 0; // -1
}
-
+
if (regex.searchAlgorithm != SearchAlgorithm.NONE) {
int schRange = range;
if (regex.dMax != 0) {
@@ -426,7 +426,7 @@ public abstract class Matcher extends IntHolder {
}
}
if ((end - start) < regex.thresholdLength) return mismatch();
-
+
if (regex.dMax != MinMaxLen.INFINITE_DISTANCE) {
do {
if (!forwardSearchRange(bytes, str, end, s, schRange, this)) return mismatch(); // low, high, lowPrev
@@ -441,43 +441,38 @@ public abstract class Matcher extends IntHolder {
}
} while (s < range);
return mismatch();
-
+
} else { /* check only. */
if (!forwardSearchRange(bytes, str, end, s, schRange, null)) return mismatch();
-
+
if ((regex.anchor & AnchorType.ANYCHAR_STAR) != 0) {
do {
if (matchCheck(origRange, s, prev)) return match(s);
prev = s;
s += enc.length(bytes, s, end);
-
- while (!enc.isNewLine(bytes, prev, end) && s < range) {
- prev = s;
- s += enc.length(bytes, s, end);
- }
} while (s < range);
return mismatch();
}
-
+
}
}
-
+
do {
if (matchCheck(origRange, s, prev)) return match(s);
prev = s;
s += enc.length(bytes, s, end);
} while (s < range);
-
+
if (s == range) { /* because empty match with /$/. */
if (matchCheck(origRange, s, prev)) return match(s);
}
} else { /* backward search */
- if (Config.USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE) {
+ if (Config.USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE) {
if (origStart < end) {
- origStart += enc.length(bytes, origStart, end); // /* is upper range */
+ origStart += enc.length(bytes, origStart, end); // /* is upper range */
}
}
-
+
if (regex.searchAlgorithm != SearchAlgorithm.NONE) {
int adjrange;
if (range < end) {
@@ -500,7 +495,7 @@ public abstract class Matcher extends IntHolder {
return mismatch();
} else { /* check only. */
if ((end - range) < regex.thresholdLength) return mismatch();
-
+
int schStart = s;
if (regex.dMax != 0) {
if (regex.dMax == MinMaxLen.INFINITE_DISTANCE) {
@@ -517,20 +512,20 @@ public abstract class Matcher extends IntHolder {
if (!backwardSearchRange(bytes, str, end, schStart, range, adjrange)) return mismatch();
}
}
-
+
do {
prev = enc.prevCharHead(bytes, str, s, end);
if (matchCheck(origStart, s, prev)) return match(s);
s = prev;
} while (s >= range);
-
+
}
return mismatch();
}
-
+
private boolean endBuf(int start, int range, int minSemiEnd, int maxSemiEnd) {
if ((maxSemiEnd - str) < regex.anchorDmin) return true; // mismatch_no_msa;
-
+
if (range > start) {
if ((minSemiEnd - start) > regex.anchorDmax) {
start = minSemiEnd - regex.anchorDmax;
@@ -548,7 +543,7 @@ public abstract class Matcher extends IntHolder {
if ((minSemiEnd - range) > regex.anchorDmax) {
range = minSemiEnd - regex.anchorDmax;
}
- if ((maxSemiEnd - start) < regex.anchorDmin) {
+ if ((maxSemiEnd - start) < regex.anchorDmin) {
start = maxSemiEnd - regex.anchorDmin;
start = enc.leftAdjustCharHead(bytes, str, start, end);
}
@@ -556,11 +551,11 @@ public abstract class Matcher extends IntHolder {
}
return false;
}
-
+
private int match(int s) {
return s - str; // sstart ???
}
-
+
private int mismatch() {
if (Config.USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE) {
if (msaBestLen >= 0) {
diff --git a/src/org/joni/MatcherFactory.java b/src/org/joni/MatcherFactory.java
index 729eeb0..09d6083 100644
--- a/src/org/joni/MatcherFactory.java
+++ b/src/org/joni/MatcherFactory.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
diff --git a/src/org/joni/MinMaxLen.java b/src/org/joni/MinMaxLen.java
index dca90e6..072d5f3 100644
--- a/src/org/joni/MinMaxLen.java
+++ b/src/org/joni/MinMaxLen.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -25,40 +25,40 @@ final class MinMaxLen {
MinMaxLen() {
}
-
+
MinMaxLen(int min, int max) {
this.min = min;
this.max = max;
}
-
- /* 1000 / (min-max-dist + 1) */
- private static final short distValues[] = {
- 1000, 500, 333, 250, 200, 167, 143, 125, 111, 100,
- 91, 83, 77, 71, 67, 63, 59, 56, 53, 50,
- 48, 45, 43, 42, 40, 38, 37, 36, 34, 33,
- 32, 31, 30, 29, 29, 28, 27, 26, 26, 25,
- 24, 24, 23, 23, 22, 22, 21, 21, 20, 20,
- 20, 19, 19, 19, 18, 18, 18, 17, 17, 17,
- 16, 16, 16, 16, 15, 15, 15, 15, 14, 14,
- 14, 14, 14, 14, 13, 13, 13, 13, 13, 13,
- 12, 12, 12, 12, 12, 12, 11, 11, 11, 11,
+
+ /* 1000 / (min-max-dist + 1) */
+ private static final short distValues[] = {
+ 1000, 500, 333, 250, 200, 167, 143, 125, 111, 100,
+ 91, 83, 77, 71, 67, 63, 59, 56, 53, 50,
+ 48, 45, 43, 42, 40, 38, 37, 36, 34, 33,
+ 32, 31, 30, 29, 29, 28, 27, 26, 26, 25,
+ 24, 24, 23, 23, 22, 22, 21, 21, 20, 20,
+ 20, 19, 19, 19, 18, 18, 18, 17, 17, 17,
+ 16, 16, 16, 16, 15, 15, 15, 15, 14, 14,
+ 14, 14, 14, 14, 13, 13, 13, 13, 13, 13,
+ 12, 12, 12, 12, 12, 12, 11, 11, 11, 11,
11, 11, 11, 11, 11, 10, 10, 10, 10, 10
};
-
+
int distanceValue() {
if (max == INFINITE_DISTANCE) return 0;
int d = max - min;
/* return dist_vals[d] * 16 / (mm->min + 12); */
- return d < distValues.length ? distValues[d] : 1;
+ return d < distValues.length ? distValues[d] : 1;
}
-
+
int compareDistanceValue(MinMaxLen other, int v1, int v2) {
if (v2 <= 0) return -1;
if (v1 <= 0) return 1;
-
+
v1 *= distanceValue();
v2 *= other.distanceValue();
-
+
if (v2 > v1) return 1;
if (v2 < v1) return -1;
@@ -68,38 +68,38 @@ final class MinMaxLen {
}
boolean equal(MinMaxLen other) {
- return min == other.min && max == other.max;
+ return min == other.min && max == other.max;
}
void set(int min, int max) {
this.min = min;
this.max = max;
}
-
+
void clear() {
min = max = 0;
}
-
- void copy(MinMaxLen other) {
+
+ void copy(MinMaxLen other) {
min = other.min;
max = other.max;
}
-
+
void add(MinMaxLen other) {
min = distanceAdd(min, other.min);
max = distanceAdd(max, other.max);
}
-
+
void addLength(int len) {
min = distanceAdd(min, len);
- max = distanceAdd(max, len);
+ max = distanceAdd(max, len);
}
void altMerge(MinMaxLen other) {
if (min > other.min) min = other.min;
- if (max < other.max) max = other.max;
+ if (max < other.max) max = other.max;
}
-
+
static final int INFINITE_DISTANCE = 0x7FFFFFFF;
static int distanceAdd(int d1, int d2) {
if (d1 == INFINITE_DISTANCE || d2 == INFINITE_DISTANCE) {
@@ -118,7 +118,7 @@ final class MinMaxLen {
return INFINITE_DISTANCE;
}
}
-
+
static String distanceRangeToString(int a, int b) {
String s = "";
if (a == INFINITE_DISTANCE) {
@@ -128,12 +128,12 @@ final class MinMaxLen {
}
s += "-";
-
+
if (b == INFINITE_DISTANCE) {
s += "inf";
} else {
s += "(" + b + ")";
}
- return s;
+ return s;
}
}
diff --git a/src/org/joni/NameEntry.java b/src/org/joni/NameEntry.java
index 794cf1b..55c34b3 100644
--- a/src/org/joni/NameEntry.java
+++ b/src/org/joni/NameEntry.java
@@ -1,35 +1,35 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
public final class NameEntry {
static final int INIT_NAME_BACKREFS_ALLOC_NUM = 8;
-
+
public final byte[]name;
public final int nameP;
public final int nameEnd;
-
+
int backNum;
int backRef1;
int backRefs[];
-
+
public NameEntry(byte[]bytes, int p, int end) {
name = bytes;
nameP = p;
@@ -52,18 +52,18 @@ public final class NameEntry {
private void alloc() {
backRefs = new int[INIT_NAME_BACKREFS_ALLOC_NUM];
}
-
+
private void ensureSize() {
if (backNum > backRefs.length) {
- int[]tmp = new int[backRefs.length << 1];
+ int[]tmp = new int[backRefs.length << 1];
System.arraycopy(backRefs, 0, tmp, 0, backRefs.length);
backRefs = tmp;
}
}
-
+
public void addBackref(int backRef) {
backNum++;
-
+
switch (backNum) {
case 1:
backRef1 = backRef;
@@ -78,7 +78,7 @@ public final class NameEntry {
backRefs[backNum - 1] = backRef;
}
}
-
+
public String toString() {
StringBuilder buff = new StringBuilder(new String(name, nameP, nameEnd - nameP) + " ");
if (backNum == 0) {
@@ -91,7 +91,7 @@ public final class NameEntry {
buff.append(backRefs[i]);
}
}
- return buff.toString();
+ return buff.toString();
}
}
diff --git a/src/org/joni/NativeMachine.java b/src/org/joni/NativeMachine.java
index 6fc5dbb..3c37ad3 100644
--- a/src/org/joni/NativeMachine.java
+++ b/src/org/joni/NativeMachine.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
diff --git a/src/org/joni/NodeOptInfo.java b/src/org/joni/NodeOptInfo.java
index 20bc0bc..1943666 100644
--- a/src/org/joni/NodeOptInfo.java
+++ b/src/org/joni/NodeOptInfo.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -28,13 +28,13 @@ public final class NodeOptInfo {
final OptExactInfo exm = new OptExactInfo(); /* middle */
final OptExactInfo expr = new OptExactInfo(); /* prec read (?=...) */
final OptMapInfo map = new OptMapInfo(); /* boundary */
-
+
public void setBoundNode(MinMaxLen mmd) {
exb.mmd.copy(mmd);
expr.mmd.copy(mmd);
map.mmd.copy(mmd);
- }
-
+ }
+
public void clear() {
length.clear();
anchor.clear();
@@ -43,7 +43,7 @@ public final class NodeOptInfo {
expr.clear();
map.clear();
}
-
+
public void copy(NodeOptInfo other) {
length.copy(other.length);
anchor.copy(other.anchor);
@@ -52,40 +52,40 @@ public final class NodeOptInfo {
expr.copy(other.expr);
map.copy(other.map);
}
-
+
public void concatLeftNode(NodeOptInfo other, Encoding enc) {
OptAnchorInfo tanchor = new OptAnchorInfo(); // remove it somehow ?
tanchor.concat(anchor, other.anchor, length.max, other.length.max);
anchor.copy(tanchor);
-
+
if (other.exb.length > 0 && length.max == 0) {
tanchor.concat(anchor, other.exb.anchor, length.max, other.length.max);
other.exb.anchor.copy(tanchor);
}
-
+
if (other.map.value > 0 && length.max == 0) {
if (other.map.mmd.max == 0) {
other.map.anchor.leftAnchor |= anchor.leftAnchor;
}
}
-
+
boolean exbReach = exb.reachEnd;
boolean exmReach = exm.reachEnd;
-
+
if (other.length.max != 0) {
exb.reachEnd = exm.reachEnd = false;
}
-
+
if (other.exb.length > 0) {
if (exbReach) {
exb.concat(other.exb, enc);
other.exb.clear();
- } else if (exmReach) {
- exm.concat(other.exb, enc);
- other.exb.clear();
+ } else if (exmReach) {
+ exm.concat(other.exb, enc);
+ other.exb.clear();
}
}
-
+
exm.select(other.exb, enc);
exm.select(other.exm, enc);
@@ -108,7 +108,7 @@ public final class NodeOptInfo {
map.select(other.map);
length.add(other.length);
}
-
+
public void altMerge(NodeOptInfo other, OptEnvironment env) {
anchor.altMerge(other.anchor);
exb.altMerge(other.exb, env);
@@ -123,5 +123,5 @@ public final class NodeOptInfo {
expr.mmd.copy(mmd);
map.mmd.copy(mmd);
}
-
+
}
diff --git a/src/org/joni/OptAnchorInfo.java b/src/org/joni/OptAnchorInfo.java
index 9084728..202ba81 100644
--- a/src/org/joni/OptAnchorInfo.java
+++ b/src/org/joni/OptAnchorInfo.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -24,16 +24,16 @@ import org.joni.constants.AnchorType;
final class OptAnchorInfo implements AnchorType {
int leftAnchor;
int rightAnchor;
-
+
void clear() {
leftAnchor = rightAnchor = 0;
}
-
+
void copy(OptAnchorInfo other) {
leftAnchor = other.leftAnchor;
rightAnchor = other.rightAnchor;
}
-
+
void concat(OptAnchorInfo left, OptAnchorInfo right, int leftLength, int rightLength) {
leftAnchor = left.leftAnchor;
if (leftLength == 0) leftAnchor |= right.leftAnchor;
@@ -41,12 +41,12 @@ final class OptAnchorInfo implements AnchorType {
rightAnchor = right.rightAnchor;
if (rightLength == 0) rightAnchor |= left.rightAnchor;
}
-
+
boolean isSet(int anchor) {
if ((leftAnchor & anchor) != 0) return true;
- return (rightAnchor & anchor) != 0;
+ return (rightAnchor & anchor) != 0;
}
-
+
void add(int anchor) {
if (isLeftAnchor(anchor)) {
leftAnchor |= anchor;
@@ -54,7 +54,7 @@ final class OptAnchorInfo implements AnchorType {
rightAnchor |= anchor;
}
}
-
+
void remove(int anchor) {
if (isLeftAnchor(anchor)) {
leftAnchor &= ~anchor;
@@ -62,18 +62,18 @@ final class OptAnchorInfo implements AnchorType {
rightAnchor &= ~anchor;
}
}
-
+
void altMerge(OptAnchorInfo other) {
leftAnchor &= other.leftAnchor;
rightAnchor &= other.rightAnchor;
}
-
+
static boolean isLeftAnchor(int anchor) { // make a mask for it ?
return !(anchor == END_BUF || anchor == SEMI_END_BUF ||
anchor == END_LINE || anchor == PREC_READ ||
anchor == PREC_READ_NOT);
}
-
+
static String anchorToString(int anchor) {
StringBuffer s = new StringBuffer("[");
diff --git a/src/org/joni/OptEnvironment.java b/src/org/joni/OptEnvironment.java
index 4b59c31..bc62750 100644
--- a/src/org/joni/OptEnvironment.java
+++ b/src/org/joni/OptEnvironment.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -28,7 +28,7 @@ final class OptEnvironment {
int options;
int caseFoldFlag;
ScanEnvironment scanEnv;
-
+
void copy(OptEnvironment other) {
mmd.copy(other.mmd);
enc = other.enc;
diff --git a/src/org/joni/OptExactInfo.java b/src/org/joni/OptExactInfo.java
index 45d94fc..ef9fb78 100644
--- a/src/org/joni/OptExactInfo.java
+++ b/src/org/joni/OptExactInfo.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -23,55 +23,54 @@ import org.jcodings.Encoding;
final class OptExactInfo {
static final int OPT_EXACT_MAXLEN = 24;
-
+
final MinMaxLen mmd = new MinMaxLen();
final OptAnchorInfo anchor = new OptAnchorInfo();
-
+
boolean reachEnd;
boolean ignoreCase;
+
+ final byte bytes[] = new byte[OPT_EXACT_MAXLEN];
int length;
- final byte s[] = new byte[OPT_EXACT_MAXLEN];
-
boolean isFull() {
- return length >= OPT_EXACT_MAXLEN;
+ return length >= OPT_EXACT_MAXLEN;
}
-
+
void clear() {
mmd.clear();
anchor.clear();
-
+
reachEnd = false;
ignoreCase = false;
length = 0;
- s[0] = 0; // ???
}
-
+
void copy(OptExactInfo other) {
mmd.copy(other.mmd);
anchor.copy(other.anchor);
reachEnd = other.reachEnd;
ignoreCase = other.ignoreCase;
length = other.length;
-
- System.arraycopy(other.s, 0, s, 0, OPT_EXACT_MAXLEN);
+
+ System.arraycopy(other.bytes, 0, bytes, 0, OPT_EXACT_MAXLEN);
}
-
+
void concat(OptExactInfo other, Encoding enc) {
if (!ignoreCase && other.ignoreCase) {
if (length >= other.length) return; /* avoid */
- ignoreCase = true;
+ ignoreCase = true;
}
-
+
int p = 0; // add->s;
int end = p + other.length;
-
+
int i;
for (i=length; p < end;) {
- int len = enc.length(other.s, p, end);
+ int len = enc.length(other.bytes, p, end);
if (i + len > OPT_EXACT_MAXLEN) break;
for (int j=0; j<len && p < end; j++) {
- s[i++] = other.s[p++]; // arraycopy or even don't copy anything ??
+ bytes[i++] = other.bytes[p++]; // arraycopy or even don't copy anything ??
}
}
@@ -83,18 +82,18 @@ final class OptExactInfo {
if (!other.reachEnd) tmp.rightAnchor = 0;
anchor.copy(tmp);
}
-
+
// ?? raw is not used here
- void concatStr(byte[]bytes, int p, int end, boolean raw, Encoding enc) {
+ void concatStr(byte[]lbytes, int p, int end, boolean raw, Encoding enc) {
int i;
for (i = length; p < end && i < OPT_EXACT_MAXLEN;) {
- int len = enc.length(bytes, p, end);
+ int len = enc.length(lbytes, p, end);
if (i + len > OPT_EXACT_MAXLEN) break;
for (int j=0; j<len && p < end; j++) {
- s[i++] = bytes[p++];
+ bytes[i++] = lbytes[p++];
}
}
-
+
length = i;
}
@@ -103,41 +102,41 @@ final class OptExactInfo {
clear();
return;
}
-
+
if (!mmd.equal(other.mmd)) {
clear();
return;
}
-
+
int i;
for (i=0; i<length && i<other.length;) {
- if (s[i] != other.s[i]) break;
- int len = env.enc.length(s, i, length);
+ if (bytes[i] != other.bytes[i]) break;
+ int len = env.enc.length(bytes, i, length);
int j;
for (j=1; j<len; j++) {
- if (s[i+j] != other.s[i+j]) break;
+ if (bytes[i+j] != other.bytes[i+j]) break;
}
-
+
if (j < len) break;
i += len;
}
-
+
if (!other.reachEnd || i<other.length || i<length) reachEnd = false;
-
+
length = i;
ignoreCase |= other.ignoreCase;
-
+
anchor.altMerge(other.anchor);
-
+
if (!reachEnd) anchor.rightAnchor = 0;
}
-
-
+
+
void select(OptExactInfo alt, Encoding enc) {
int v1 = length;
int v2 = alt.length;
-
+
if (v2 == 0) {
return;
} else if (v1 == 0) {
@@ -145,27 +144,27 @@ final class OptExactInfo {
return;
} else if (v1 <= 2 && v2 <= 2) {
/* ByteValTable[x] is big value --> low price */
- v2 = OptMapInfo.positionValue(enc, s[0] & 0xff);
- v1 = OptMapInfo.positionValue(enc, alt.s[0] & 0xff);
-
+ v2 = OptMapInfo.positionValue(enc, bytes[0] & 0xff);
+ v1 = OptMapInfo.positionValue(enc, alt.bytes[0] & 0xff);
+
if (length > 1) v1 += 5;
if (alt.length > 1) v2 += 5;
}
-
+
if (!ignoreCase) v1 *= 2;
if (!alt.ignoreCase) v2 *= 2;
-
+
if (mmd.compareDistanceValue(alt.mmd, v1, v2) > 0) copy(alt);
}
-
+
// comp_opt_exact_or_map_info
private static final int COMP_EM_BASE = 20;
int compare(OptMapInfo m) {
if (m.value <= 0) return -1;
-
+
int ve = COMP_EM_BASE * length * (ignoreCase ? 1 : 2);
int vm = COMP_EM_BASE * 5 * 2 / m.value;
-
+
return mmd.compareDistanceValue(m.mmd, ve, vm);
}
}
diff --git a/src/org/joni/OptMapInfo.java b/src/org/joni/OptMapInfo.java
index 2763b53..9d3574b 100644
--- a/src/org/joni/OptMapInfo.java
+++ b/src/org/joni/OptMapInfo.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -23,20 +23,20 @@ import org.jcodings.CaseFoldCodeItem;
import org.jcodings.Encoding;
final class OptMapInfo {
-
+
final MinMaxLen mmd = new MinMaxLen(); /* info position */
final OptAnchorInfo anchor = new OptAnchorInfo();
-
+
int value; /* weighted value */
final byte map[] = new byte[Config.CHAR_TABLE_SIZE];
-
+
void clear() {
mmd.clear();
anchor.clear();
value = 0;
for (int i=0; i<map.length; i++) map[i] = 0;
}
-
+
void copy(OptMapInfo other) {
mmd.copy(other.mmd);
anchor.copy(other.anchor);
@@ -44,7 +44,7 @@ final class OptMapInfo {
//for(int i=0; i<map.length; i++) map[i] = other.map[i];
System.arraycopy(other.map, 0, map, 0, other.map.length);
}
-
+
void addChar(byte c, Encoding enc) {
int c_ = c & 0xff;
if (map[c_] == 0) {
@@ -52,10 +52,10 @@ final class OptMapInfo {
value += positionValue(enc, c_);
}
}
-
+
void addCharAmb(byte[]bytes, int p, int end, Encoding enc, int caseFoldFlag) {
addChar(bytes[p], enc);
-
+
caseFoldFlag &= ~Config.INTERNAL_ENC_CASE_FOLD_MULTI_CHAR;
CaseFoldCodeItem[]items = enc.caseFoldCodesByString(caseFoldFlag, bytes, p, end);
@@ -74,13 +74,13 @@ final class OptMapInfo {
copy(alt);
return;
}
-
+
int v1 = z / value;
int v2 = z /alt.value;
-
+
if (mmd.compareDistanceValue(alt.mmd, v1, v2) > 0) copy(alt);
}
-
+
// alt_merge_opt_map_info
void altMerge(OptMapInfo other, Encoding enc) {
/* if (! is_equal_mml(&to->mmd, &add->mmd)) return ; */
@@ -89,19 +89,19 @@ final class OptMapInfo {
clear();
return;
}
-
+
mmd.altMerge(other.mmd);
-
+
int val = 0;
for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) {
if (other.map[i] != 0) map[i] = 1;
if (map[i] != 0) val += positionValue(enc, i);
}
-
+
value = val;
anchor.altMerge(other.anchor);
}
-
+
static final short ByteValTable[] = {
5, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10, 1, 1, 10, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -112,9 +112,9 @@ final class OptMapInfo {
5, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 1
};
-
+
// map_position_value
- static int positionValue(Encoding enc, int i) {
+ static int positionValue(Encoding enc, int i) {
if (i < ByteValTable.length) {
if (i == 0 && enc.minLength() > 1) {
return 20;
@@ -125,5 +125,5 @@ final class OptMapInfo {
return 4; /* Take it easy. */
}
}
-
+
}
diff --git a/src/org/joni/Option.java b/src/org/joni/Option.java
index adee24f..13fbba3 100644
--- a/src/org/joni/Option.java
+++ b/src/org/joni/Option.java
@@ -1,42 +1,42 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
public class Option {
-
+
/* options */
public static final int NONE = 0;
- public static final int IGNORECASE = (1<<0);
+ public static final int IGNORECASE = (1<<0);
public static final int EXTEND = (1<<1);
public static final int MULTILINE = (1<<2);
- public static final int SINGLELINE = (1<<3);
- public static final int FIND_LONGEST = (1<<4);
+ public static final int SINGLELINE = (1<<3);
+ public static final int FIND_LONGEST = (1<<4);
public static final int FIND_NOT_EMPTY = (1<<5);
public static final int NEGATE_SINGLELINE = (1<<6);
public static final int DONT_CAPTURE_GROUP = (1<<7);
public static final int CAPTURE_GROUP = (1<<8);
-
+
/* options (search time) */
public static final int NOTBOL = (1<<9);
public static final int NOTEOL = (1<<10);
- public static final int POSIX_REGION = (1<<11);
+ public static final int POSIX_REGION = (1<<11);
public static final int MAXBIT = (1<<12); /* limit */
public static final int DEFAULT = NONE;
@@ -52,67 +52,67 @@ public class Option {
if (isNegateSingleline(option)) options += "NEGATE_SINGLELINE ";
if (isDontCaptureGroup(option)) options += "DONT_CAPTURE_GROUP ";
if (isCaptureGroup(option)) options += "CAPTURE_GROUP ";
-
+
if (isNotBol(option)) options += "NOTBOL ";
if (isNotEol(option)) options += "NOTEOL ";
- if (isPosixRegion(option)) options += "POSIX_REGION ";
-
+ if (isPosixRegion(option)) options += "POSIX_REGION ";
+
return options;
- }
-
+ }
+
public static boolean isIgnoreCase(int option) {
return (option & IGNORECASE) != 0;
}
-
+
public static boolean isExtend(int option) {
return (option & EXTEND) != 0;
- }
+ }
public static boolean isSingleline(int option) {
return (option & SINGLELINE) != 0;
- }
+ }
public static boolean isMultiline(int option) {
return (option & MULTILINE) != 0;
- }
+ }
public static boolean isFindLongest(int option) {
return (option & FIND_LONGEST) != 0;
- }
+ }
public static boolean isFindNotEmpty(int option) {
return (option & FIND_NOT_EMPTY) != 0;
- }
+ }
public static boolean isFindCondition(int option) {
return (option & (FIND_LONGEST | FIND_NOT_EMPTY)) != 0;
- }
-
+ }
+
public static boolean isNegateSingleline(int option) {
return (option & NEGATE_SINGLELINE) != 0;
}
-
+
public static boolean isDontCaptureGroup(int option) {
return (option & DONT_CAPTURE_GROUP) != 0;
- }
-
+ }
+
public static boolean isCaptureGroup(int option) {
return (option & CAPTURE_GROUP) != 0;
- }
-
+ }
+
public static boolean isNotBol(int option) {
return (option & NOTBOL) != 0;
- }
+ }
public static boolean isNotEol(int option) {
return (option & NOTEOL) != 0;
}
-
+
public static boolean isPosixRegion(int option) {
return (option & POSIX_REGION) != 0;
- }
-
- /* OP_SET_OPTION is required for these options. ??? */
+ }
+
+ /* OP_SET_OPTION is required for these options. ??? */
// public static boolean isDynamic(int option) {
// return (option & (MULTILINE | IGNORECASE)) != 0;
// }
diff --git a/src/org/joni/Parser.java b/src/org/joni/Parser.java
index a787d16..3d56e9e 100644
--- a/src/org/joni/Parser.java
+++ b/src/org/joni/Parser.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -24,6 +24,7 @@ import static org.joni.BitStatus.bsOnOff;
import static org.joni.Option.isDontCaptureGroup;
import static org.joni.Option.isIgnoreCase;
+import org.jcodings.Ptr;
import org.jcodings.constants.CharacterType;
import org.jcodings.constants.PosixBracket;
import org.joni.ast.AnchorNode;
@@ -49,28 +50,28 @@ class Parser extends Lexer {
protected final Regex regex;
protected Node root;
-
+
protected int returnCode; // return code used by parser methods (they itself return parsed nodes)
- // this approach will not affect recursive calls
-
+ // this approach will not affect recursive calls
+
protected Parser(ScanEnvironment env, byte[]bytes, int p, int end) {
super(env, bytes, p, end);
regex = env.reg;
}
-
+
// onig_parse_make_tree
protected final Node parse() {
root = parseRegexp();
regex.numMem = env.numMem;
return root;
}
-
+
private static final int POSIX_BRACKET_NAME_MIN_LEN = 4;
private static final int POSIX_BRACKET_CHECK_LIMIT_LENGTH = 20;
private static final byte BRACKET_END[] = ":]".getBytes();
private boolean parsePosixBracket(CClassNode cc) {
mark();
-
+
boolean not;
if (peekIs('^')) {
inc();
@@ -94,17 +95,17 @@ class Parser extends Lexer {
return false;
}
}
-
+
}
// not_posix_bracket:
c = 0;
int i= 0;
- while(left() && ((c=peek()) != ':') && c != ']') {
+ while (left() && ((c=peek()) != ':') && c != ']') {
inc();
if (++i > POSIX_BRACKET_CHECK_LIMIT_LENGTH) break;
}
-
+
if (c == ':' && left()) {
inc();
if (left()) {
@@ -115,7 +116,7 @@ class Parser extends Lexer {
restore();
return true; /* 1: is not POSIX bracket, but no error. */
}
-
+
private CClassNode parseCharProperty() {
int ctype = fetchCharPropertyToCType();
CClassNode n = new CClassNode();
@@ -123,76 +124,82 @@ class Parser extends Lexer {
if (token.getPropNot()) n.setNot();
return n;
}
-
+
private boolean codeExistCheck(int code, boolean ignoreEscaped) {
mark();
-
+
boolean inEsc = false;
- while(left()) {
- if (ignoreEscaped && inEsc) {
+ while (left()) {
+ if (ignoreEscaped && inEsc) {
inEsc = false;
} else {
fetch();
if (c == code) {
restore();
- return true;
+ return true;
}
if (c == syntax.metaCharTable.esc) inEsc = true;
}
}
-
+
restore();
return false;
}
-
+
private CClassNode parseCharClass() {
fetchTokenInCC();
- boolean neg;
+ final boolean neg;
if (token.type == TokenType.CHAR && token.getC() == '^' && !token.escaped) {
neg = true;
fetchTokenInCC();
} else {
neg = false;
}
-
+
if (token.type == TokenType.CC_CLOSE) {
if (!codeExistCheck(']', true)) newSyntaxException(ERR_EMPTY_CHAR_CLASS);
env.ccEscWarn("]");
token.type = TokenType.CHAR; /* allow []...] */
}
-
+
CClassNode cc = new CClassNode();
CClassNode prevCC = null;
CClassNode workCC = null;
CCStateArg arg = new CCStateArg();
-
+
boolean andStart = false;
arg.state = CCSTATE.START;
- while(token.type != TokenType.CC_CLOSE) {
+ while (token.type != TokenType.CC_CLOSE) {
boolean fetched = false;
-
+
switch (token.type) {
-
+
case CHAR:
- int len = enc.codeToMbcLength(token.getC());
- if (len > 1) {
+ final int len;
+ if (Config.VANILLA) {
+ len = enc.codeToMbcLength(token.getC());
+ if (len > 1) {
arg.inType = CCVALTYPE.CODE_POINT;
} else {
- // !sb_char:!
- arg.inType = CCVALTYPE.SB;
+ arg.inType = CCVALTYPE.SB; // sb_char:
}
- arg.v = token.getC();
- arg.vIsRaw = false;
- // !goto val_entry2;!
- valEntry2(cc, arg);
+ } else {
+ if (token.getCode() >= BitSet.SINGLE_BYTE_SIZE || (len = enc.codeToMbcLength(token.getC())) > 1) {
+ arg.inType = CCVALTYPE.CODE_POINT;
+ } else {
+ arg.inType = CCVALTYPE.SB; // sb_char:
+ }
+ }
+ arg.v = token.getC();
+ arg.vIsRaw = false;
+ parseCharClassValEntry2(cc, arg); // goto val_entry2
break;
case RAW_BYTE:
- /* tok->base != 0 : octal or hexadec. */
- if (!enc.isSingleByte() && token.base != 0) {
+ if (!enc.isSingleByte() && token.base != 0) { /* tok->base != 0 : octal or hexadec. */
byte[]buf = new byte[Config.ENC_MBC_CASE_FOLD_MAXLEN];
int psave = p;
int base = token.base;
@@ -207,9 +214,9 @@ class Parser extends Lexer {
buf[i] = (byte)token.getC();
}
if (i < enc.minLength()) newValueException(ERR_TOO_SHORT_MULTI_BYTE_STRING);
-
+
len = enc.length(buf, 0, i);
- if (i < len) {
+ if (i < len) {
newValueException(ERR_TOO_SHORT_MULTI_BYTE_STRING);
} else if (i > len) { /* fetch back */
p = psave;
@@ -218,120 +225,99 @@ class Parser extends Lexer {
}
if (i == 1) {
arg.v = buf[0] & 0xff;
- // !goto raw_single!
- arg.inType = CCVALTYPE.SB;
+ arg.inType = CCVALTYPE.SB; // goto raw_single
} else {
arg.v = enc.mbcToCode(buf, 0, buf.length);
arg.inType = CCVALTYPE.CODE_POINT;
}
} else {
arg.v = token.getC();
- // !raw_single:!
- arg.inType = CCVALTYPE.SB;
+ arg.inType = CCVALTYPE.SB; // raw_single:
}
arg.vIsRaw = true;
- // !goto val_entry2;!
- valEntry2(cc, arg);
+ parseCharClassValEntry2(cc, arg); // goto val_entry2
break;
-
+
case CODE_POINT:
arg.v = token.getCode();
arg.vIsRaw = true;
- // !val_entry:!
- // !val_entry2:!
- valEntry(cc, arg);
+ parseCharClassValEntry(cc, arg); // val_entry:, val_entry2
break;
-
+
case POSIX_BRACKET_OPEN:
if (parsePosixBracket(cc)) { /* true: is not POSIX bracket */
env.ccEscWarn("[");
p = token.backP;
arg.v = token.getC();
arg.vIsRaw = false;
- // !goto val_entry;!
- valEntry(cc, arg);
+ parseCharClassValEntry(cc, arg); // goto val_entry
break;
}
- // !goto next_class;!
- cc.nextStateClass(arg, env);
+ cc.nextStateClass(arg, env); // goto next_class
break;
-
+
case CHAR_TYPE:
cc.addCType(token.getPropCType(), token.getPropNot(), env, this);
- // !next_class:!
- cc.nextStateClass(arg, env);
+ cc.nextStateClass(arg, env); // next_class:
break;
-
+
case CHAR_PROPERTY:
int ctype = fetchCharPropertyToCType();
cc.addCType(ctype, token.getPropNot(), env, this);
- // !goto next_class;!
- cc.nextStateClass(arg, env);
+ cc.nextStateClass(arg, env); // goto next_class
break;
-
+
case CC_RANGE:
if (arg.state == CCSTATE.VALUE) {
fetchTokenInCC();
fetched = true;
if (token.type == TokenType.CC_CLOSE) { /* allow [x-] */
- // !range_end_val:!
- // !goto val_entry;!
- rangeEndVal(cc, arg);
+ parseCharClassRangeEndVal(cc, arg); // range_end_val:, goto val_entry;
break;
} else if (token.type == TokenType.CC_AND) {
env.ccEscWarn("-");
- // goto !range_end_val;!
- rangeEndVal(cc, arg);
+ parseCharClassRangeEndVal(cc, arg); // goto range_end_val
break;
}
arg.state = CCSTATE.RANGE;
} else if (arg.state == CCSTATE.START) {
- /* [-xa] is allowed */
- arg.v = token.getC();
+ arg.v = token.getC(); /* [-xa] is allowed */
arg.vIsRaw = false;
fetchTokenInCC();
fetched = true;
- /* [--x] or [a&&-x] is warned. */
- if (token.type == TokenType.CC_RANGE || andStart) env.ccEscWarn("-");
- // !goto val_entry;!
- valEntry(cc, arg);
+ if (token.type == TokenType.CC_RANGE || andStart) env.ccEscWarn("-"); /* [--x] or [a&&-x] is warned. */
+ parseCharClassValEntry(cc, arg); // goto val_entry
break;
} else if (arg.state == CCSTATE.RANGE) {
env.ccEscWarn("-");
- /* [!--x] is allowed */
- // !goto sb_char;!
- sbChar(cc, arg);
+ parseCharClassSbChar(cc, arg); // goto sb_char /* [!--x] is allowed */
break;
} else { /* CCS_COMPLETE */
fetchTokenInCC();
fetched = true;
if (token.type == TokenType.CC_CLOSE) { /* allow [a-b-] */
- // goto !range_end_val!
- rangeEndVal(cc, arg);
+ parseCharClassRangeEndVal(cc, arg); // goto range_end_val
break;
} else if (token.type == TokenType.CC_AND) {
env.ccEscWarn("-");
- // goto !range_end_val;!
- rangeEndVal(cc, arg);
+ parseCharClassRangeEndVal(cc, arg); // goto range_end_val
break;
}
-
+
if (syntax.allowDoubleRangeOpInCC()) {
env.ccEscWarn("-");
- /* [0-9-a] is allowed as [0-9\-a] */
- // !goto sb_char!
- sbChar(cc, arg);
+ parseCharClassSbChar(cc, arg); // goto sb_char /* [0-9-a] is allowed as [0-9\-a] */
break;
}
newSyntaxException(ERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS);
}
break;
-
+
case CC_CC_OPEN: /* [ */
CClassNode acc = parseCharClass();
cc.or(acc, enc);
break;
-
+
case CC_AND: /* && */
if (arg.state == CCSTATE.VALUE) {
arg.v = 0; // ??? safe v ?
@@ -348,37 +334,37 @@ class Parser extends Lexer {
if (workCC == null) workCC = new CClassNode();
cc = workCC;
}
- // initialize_cclass(cc); // clear it ??
- break;
-
+ cc.clear();
+ break;
+
case EOT:
newSyntaxException(ERR_PREMATURE_END_OF_CHAR_CLASS);
-
- default:
- newInternalException(ERR_PARSER_BUG);
+
+ default:
+ newInternalException(ERR_PARSER_BUG);
} // switch
-
+
if (!fetched) fetchTokenInCC();
-
+
} // while
-
+
if (arg.state == CCSTATE.VALUE) {
arg.v = 0; // ??? safe v ?
arg.vIsRaw = false;
cc.nextStateValue(arg, env);
}
-
+
if (prevCC != null) {
prevCC.and(cc, enc);
cc = prevCC;
}
-
+
if (neg) {
cc.setNot();
} else {
cc.clearNot();
}
-
+
if (cc.isNot() && syntax.notNewlineInNegativeCC()) {
if (!cc.isEmpty()) {
final int NEW_LINE = 0x0a;
@@ -391,81 +377,71 @@ class Parser extends Lexer {
}
}
}
-
+
return cc;
}
-
- private void valEntry2(CClassNode cc, CCStateArg arg) {
- cc.nextStateValue(arg, env);
- }
-
- private void valEntry(CClassNode cc, CCStateArg arg) {
- int len = enc.codeToMbcLength(arg.v);
- arg.inType = len == 1 ? CCVALTYPE.SB : CCVALTYPE.CODE_POINT;
- // !val_entry2:!
- valEntry2(cc, arg);
- }
-
- private void sbChar(CClassNode cc, CCStateArg arg) {
+
+ private void parseCharClassSbChar(CClassNode cc, CCStateArg arg) {
arg.inType = CCVALTYPE.SB;
arg.v = token.getC();
arg.vIsRaw = false;
- // !goto val_entry2;!
- valEntry2(cc, arg);
+ parseCharClassValEntry2(cc, arg); // goto val_entry2
}
- private void rangeEndVal(CClassNode cc, CCStateArg arg) {
+ private void parseCharClassRangeEndVal(CClassNode cc, CCStateArg arg) {
arg.v = '-';
arg.vIsRaw = false;
- // !goto val_entry;!
- valEntry(cc, arg);
+ parseCharClassValEntry(cc, arg); // goto val_entry
+ }
+
+ private void parseCharClassValEntry(CClassNode cc, CCStateArg arg) {
+ int len = enc.codeToMbcLength(arg.v);
+ arg.inType = len == 1 ? CCVALTYPE.SB : CCVALTYPE.CODE_POINT;
+ parseCharClassValEntry2(cc, arg); // val_entry2:
+ }
+
+ private void parseCharClassValEntry2(CClassNode cc, CCStateArg arg) {
+ cc.nextStateValue(arg, env);
}
-
+
private Node parseEnclose(TokenType term) {
Node node = null;
-
+
if (!left()) newSyntaxException(ERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS);
-
+
int option = env.option;
-
- if (peekIs('?') && syntax.op2QMarkGroupEffect()) {
+
+ if (peekIs('?') && syntax.op2QMarkGroupEffect()) {
inc();
if (!left()) newSyntaxException(ERR_END_PATTERN_IN_GROUP);
-
+
boolean listCapture = false;
-
+
fetch();
switch(c) {
case ':': /* (?:...) grouping only */
- // !group:!
- fetchToken();
+ fetchToken(); // group:
node = parseSubExp(term);
returnCode = 1; /* group */
return node;
-
case '=':
node = new AnchorNode(AnchorType.PREC_READ);
break;
-
case '!': /* preceding read */
node = new AnchorNode(AnchorType.PREC_READ_NOT);
break;
-
case '>': /* (?>...) stop backtrack */
node = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose
break;
-
case '\'':
if (Config.USE_NAMED_GROUP) {
if (syntax.op2QMarkLtNamedGroup()) {
- // !goto named_group1!;
- listCapture = false;
- node = namedGroup2(listCapture);
+ listCapture = false; // goto named_group1
+ node = parseEncloseNamedGroup2(listCapture);
break;
} else {
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
}
- break;
} // USE_NAMED_GROUP
break;
case '<': /* look behind (?<=...), (?<!...) */
@@ -479,32 +455,27 @@ class Parser extends Lexer {
if (syntax.op2QMarkLtNamedGroup()) {
unfetch();
c = '<';
-
- // !named_group1:!
- listCapture = false;
- // !named_group2:!
- node = namedGroup2(listCapture);
+
+ listCapture = false; // named_group1:
+ node = parseEncloseNamedGroup2(listCapture); // named_group2:
break;
} else {
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
}
-
+
} else { // USE_NAMED_GROUP
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
} // USE_NAMED_GROUP
}
break;
-
case '@':
- if (syntax.op2AtMarkCaptureHistory()) {
+ if (syntax.op2AtMarkCaptureHistory()) {
if (Config.USE_NAMED_GROUP) {
- if (syntax.op2QMarkLtNamedGroup()) {
+ if (syntax.op2QMarkLtNamedGroup()) {
fetch();
if (c == '<' || c == '\'') {
listCapture = true;
- // /* (?@<name>...) */
- // goto !named_group2;!
- node = namedGroup2(listCapture);
+ node = parseEncloseNamedGroup2(listCapture); // goto named_group2 /* (?@<name>...) */
}
unfetch();
}
@@ -518,7 +489,7 @@ class Parser extends Lexer {
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
}
break;
-
+
// case 'p': #ifdef USE_POSIXLINE_OPTION
case '-':
case 'i':
@@ -526,24 +497,20 @@ class Parser extends Lexer {
case 's':
case 'x':
boolean neg = false;
- while(true) {
+ while (true) {
switch(c) {
case ':':
case ')':
break;
-
case '-':
neg = true;
break;
-
case 'x':
option = bsOnOff(option, Option.EXTEND, neg);
break;
-
case 'i':
option = bsOnOff(option, Option.IGNORECASE, neg);
break;
-
case 's':
if (syntax.op2OptionPerl()) {
option = bsOnOff(option, Option.MULTILINE, neg);
@@ -551,7 +518,6 @@ class Parser extends Lexer {
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
}
break;
-
case 'm':
if (syntax.op2OptionPerl()) {
option = bsOnOff(option, Option.SINGLELINE, !neg);
@@ -561,15 +527,14 @@ class Parser extends Lexer {
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
}
break;
-
// case 'p': #ifdef USE_POSIXLINE_OPTION // not defined
// option = bsOnOff(option, Option.MULTILINE|Option.SINGLELINE, neg);
// break;
-
+
default:
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
} // switch
-
+
if (c == ')') {
EncloseNode en = new EncloseNode(option, 0); // node_new_option
node = en;
@@ -590,15 +555,14 @@ class Parser extends Lexer {
if (!left()) newSyntaxException(ERR_END_PATTERN_IN_GROUP);
fetch();
} // while
-
+
default:
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
} // switch
-
+
} else {
if (isDontCaptureGroup(env.option)) {
- // !goto group;!
- fetchToken();
+ fetchToken(); // goto group
node = parseSubExp(term);
returnCode = 1; /* group */
return node;
@@ -608,7 +572,7 @@ class Parser extends Lexer {
en.regNum = num;
node = en;
}
-
+
fetchToken();
Node target = parseSubExp(term);
@@ -626,32 +590,31 @@ class Parser extends Lexer {
returnCode = 0;
return node; // ??
}
-
- private Node namedGroup2(boolean listCapture) {
+
+ private Node parseEncloseNamedGroup2(boolean listCapture) {
int nm = p;
int num = fetchName(c, false);
int nameEnd = value;
num = env.addMemEntry();
if (listCapture && num >= BitStatus.BIT_STATUS_BITS_NUM) newValueException(ERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY);
-
+
regex.nameAdd(bytes, nm, nameEnd, num, syntax);
EncloseNode en = new EncloseNode(env.option, true); // node_new_enclose_memory
en.regNum = num;
Node node = en;
-
+
if (listCapture) env.captureHistory = bsOnAtSimple(env.captureHistory, num);
env.numNamed++;
return node;
}
-
- private int nextChar; // hidden var
- private int findStrPosition(int[]s, int n, int from, int to) {
+
+ private int findStrPosition(int[]s, int n, int from, int to, Ptr nextChar) {
int x;
int q;
int p = from;
int i = 0;
- while(p < to) {
+ while (p < to) {
x = enc.mbcToCode(bytes, p, to);
q = p + enc.length(bytes, p, to);
if (x == s[0]) {
@@ -661,7 +624,7 @@ class Parser extends Lexer {
q += enc.length(bytes, q, to);
}
if (i >= n) {
- if (bytes[nextChar] != 0) nextChar = q; // we may need zero term semantics...
+ if (bytes[nextChar.p] != 0) nextChar.p = q; // we may need zero term semantics...
return p;
}
}
@@ -669,22 +632,18 @@ class Parser extends Lexer {
}
return -1;
}
-
+
private Node parseExp(TokenType term) {
- if (token.type == term) {
- //!goto end_of_token;!
- return new StringNode();
- }
-
+ if (token.type == term) return StringNode.EMPTY; // goto end_of_token
+
Node node = null;
boolean group = false;
switch(token.type) {
case ALT:
case EOT:
- // !end_of_token:!
- return new StringNode(); // node_new_empty
-
+ return StringNode.EMPTY; // end_of_token:, node_new_empty
+
case SUBEXP_OPEN:
node = parseEnclose(TokenType.SUBEXP_CLOSE);
if (returnCode == 1) {
@@ -697,53 +656,55 @@ class Parser extends Lexer {
Node target = parseSubExp(term);
env.option = prev;
en.setTarget(target);
- return node;
+ return node;
}
break;
-
case SUBEXP_CLOSE:
if (!syntax.allowUnmatchedCloseSubexp()) newSyntaxException(ERR_UNMATCHED_CLOSE_PARENTHESIS);
-
if (token.escaped) {
- // !goto tk_raw_byte;!
- return parseExpTkRawByte(group);
+ return parseExpTkRawByte(group); // goto tk_raw_byte
} else {
- // !goto tk_byte;!
- return parseExpTkByte(group);
+ return parseExpTkByte(group); // goto tk_byte
}
-
case STRING:
- // !tk_byte:!
- return parseExpTkByte(group);
-
+ return parseExpTkByte(group); // tk_byte:
+
case RAW_BYTE:
- // !tk_raw_byte:!
- return parseExpTkRawByte(group);
-
+ return parseExpTkRawByte(group); // tk_raw_byte:
case CODE_POINT:
byte[]buf = new byte[Config.ENC_CODE_TO_MBC_MAXLEN];
int num = enc.codeToMbc(token.getCode(), buf, 0);
- // #ifdef NUMBERED_CHAR_IS_NOT_CASE_AMBIG ... // setRaw() #else
+ // #ifdef NUMBERED_CHAR_IS_NOT_CASE_AMBIG ... // setRaw() #else
node = new StringNode(buf, 0, num);
break;
-
+
case QUOTE_OPEN:
int[]endOp = new int[]{syntax.metaCharTable.esc, 'E'};
int qstart = p;
- int qend = findStrPosition(endOp, endOp.length, qstart, stop); // will set nextChar!!!
- if (qend == -1) {
- nextChar = qend = stop;
- }
+ Ptr nextChar = new Ptr();
+ int qend = findStrPosition(endOp, endOp.length, qstart, stop, nextChar);
+ if (qend == -1) nextChar.p = qend = stop;
node = new StringNode(bytes, qstart, qend);
- p = nextChar;
+ p = nextChar.p;
break;
case CHAR_TYPE:
switch(token.getPropCType()) {
+ case CharacterType.D:
+ case CharacterType.S:
+ case CharacterType.W:
+ if (Config.NON_UNICODE_SDW) {
+ CClassNode cc = new CClassNode();
+ cc.addCType(token.getPropCType(), false, env, this);
+ if (token.getPropNot()) cc.setNot();
+ node = cc;
+ }
+ break;
+
case CharacterType.WORD:
node = new CTypeNode(token.getPropCType(), token.getPropNot());
break;
-
+
case CharacterType.SPACE:
case CharacterType.DIGIT:
case CharacterType.XDIGIT:
@@ -753,41 +714,41 @@ class Parser extends Lexer {
if (token.getPropNot()) ccn.setNot();
node = ccn;
break;
-
+
default:
newInternalException(ERR_PARSER_BUG);
-
+
} // inner switch
break;
-
+
case CHAR_PROPERTY:
node = parseCharProperty();
break;
-
+
case CC_CC_OPEN:
CClassNode cc = parseCharClass();
node = cc;
if (isIgnoreCase(env.option)) {
ApplyCaseFoldArg arg = new ApplyCaseFoldArg(env, cc);
enc.applyAllCaseFold(env.caseFoldFlag, ApplyCaseFold.INSTANCE, arg);
-
+
if (arg.altRoot != null) {
node = ConsAltNode.newAltNode(node, arg.altRoot);
}
}
break;
-
+
case ANYCHAR:
node = new AnyCharNode();
break;
-
+
case ANYCHAR_ANYTIME:
node = new AnyCharNode();
QuantifierNode qn = new QuantifierNode(0, QuantifierNode.REPEAT_INFINITE, false);
qn.setTarget(node);
node = qn;
break;
-
+
case BACKREF:
int[]backRefs = token.getBackrefNum() > 1 ? token.getBackrefRefs() : new int[]{token.getBackrefRef1()};
node = new BackRefNode(token.getBackrefNum(),
@@ -796,9 +757,9 @@ class Parser extends Lexer {
token.getBackrefExistLevel(), // #ifdef USE_BACKREF_AT_LEVEL
token.getBackrefLevel(), // ...
env);
-
+
break;
-
+
case CALL:
if (Config.USE_SUBEXP_CALL) {
int gNum = token.getCallGNum();
@@ -809,109 +770,101 @@ class Parser extends Lexer {
}
node = new CallNode(bytes, token.getCallNameP(), token.getCallNameEnd(), gNum);
env.numCall++;
- break;
} // USE_SUBEXP_CALL
break;
case ANCHOR:
node = new AnchorNode(token.getAnchor()); // possible bug in oniguruma
break;
-
+
case OP_REPEAT:
case INTERVAL:
if (syntax.contextIndepRepeatOps()) {
if (syntax.contextInvalidRepeatOps()) {
newSyntaxException(ERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED);
} else {
- node = new StringNode(); // node_new_empty
+ node = StringNode.EMPTY; // node_new_empty
}
} else {
- // !goto tk_byte;!
- return parseExpTkByte(group);
+ return parseExpTkByte(group); // goto tk_byte
}
break;
-
+
default:
newInternalException(ERR_PARSER_BUG);
} //switch
-
+
//targetp = node;
-
- // !re_entry:!
- fetchToken();
-
- // !repeat:!
- return parseExpRepeat(node, group);
+
+ fetchToken(); // re_entry:
+
+ return parseExpRepeat(node, group); // repeat:
}
-
+
private Node parseExpTkByte(boolean group) {
- // !tk_byte:!
- StringNode node = new StringNode(bytes, token.backP, p);
+ StringNode node = new StringNode(bytes, token.backP, p); // tk_byte:
while (true) {
fetchToken();
if (token.type != TokenType.STRING) break;
-
+
if (token.backP == node.end) {
node.end = p; // non escaped character, remain shared, just increase shared range
} else {
- node.cat(bytes, token.backP, p); // non continuous string stream, need to COW
+ node.cat(bytes, token.backP, p); // non continuous string stream, need to COW
}
- }
- // !string_end:!
+ }
// targetp = node;
- // !goto repeat;!
- return parseExpRepeat(node, group);
+ return parseExpRepeat(node, group); // string_end:, goto repeat
}
-
+
private Node parseExpTkRawByte(boolean group) {
- // !tk_raw_byte:!
+ // tk_raw_byte:
// important: we don't use 0xff mask here neither in the compiler
// (in the template string) so we won't have to mask target
- // strings when comparing against them in the matcher
+ // strings when comparing against them in the matcher
StringNode node = new StringNode((byte)token.getC());
node.setRaw();
- int len = 1;
+ int len = 1;
while (true) {
- if (len >= enc.minLength()) {
- if (len == enc.length(node.bytes, node.p, node.end)) {
+ if (len >= enc.minLength()) {
+ if (len == enc.length(node.bytes, node.p, node.end)) {
fetchToken();
node.clearRaw();
// !goto string_end;!
return parseExpRepeat(node, group);
}
}
-
+
fetchToken();
if (token.type != TokenType.RAW_BYTE) {
/* Don't use this, it is wrong for little endian encodings. */
// USE_PAD_TO_SHORT_BYTE_CHAR ...
-
+
newValueException(ERR_TOO_SHORT_MULTI_BYTE_STRING);
}
// important: we don't use 0xff mask here neither in the compiler
// (in the template string) so we won't have to mask target
- // strings when comparing against them in the matcher
+ // strings when comparing against them in the matcher
node.cat((byte)token.getC());
len++;
} // while
}
-
+
private Node parseExpRepeat(Node target, boolean group) {
- // !repeat:!
- while (token.type == TokenType.OP_REPEAT || token.type == TokenType.INTERVAL) {
+ while (token.type == TokenType.OP_REPEAT || token.type == TokenType.INTERVAL) { // repeat:
if (target.isInvalidQuantifier()) newSyntaxException(ERR_TARGET_OF_REPEAT_OPERATOR_INVALID);
QuantifierNode qtfr = new QuantifierNode(token.getRepeatLower(),
token.getRepeatUpper(),
token.type == TokenType.INTERVAL);
-
+
qtfr.greedy = token.getRepeatGreedy();
int ret = qtfr.setQuantifier(target, group, env, bytes, getBegin(), getEnd());
Node qn = qtfr;
-
+
if (token.getRepeatPossessive()) {
EncloseNode en = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose
en.setTarget(qn);
@@ -923,29 +876,27 @@ class Parser extends Lexer {
} else if (ret == 2) { /* split case: /abc+/ */
target = ConsAltNode.newListNode(target, null);
ConsAltNode tmp = ((ConsAltNode)target).setCdr(ConsAltNode.newListNode(qn, null));
-
+
fetchToken();
return parseExpRepeatForCar(target, tmp, group);
}
- // !goto re_entry;!
- fetchToken();
+ fetchToken(); // goto re_entry
}
return target;
}
private Node parseExpRepeatForCar(Node top, ConsAltNode target, boolean group) {
- // !repeat:!
- while (token.type == TokenType.OP_REPEAT || token.type == TokenType.INTERVAL) {
+ while (token.type == TokenType.OP_REPEAT || token.type == TokenType.INTERVAL) { // repeat:
if (target.car.isInvalidQuantifier()) newSyntaxException(ERR_TARGET_OF_REPEAT_OPERATOR_INVALID);
QuantifierNode qtfr = new QuantifierNode(token.getRepeatLower(),
token.getRepeatUpper(),
token.type == TokenType.INTERVAL);
-
+
qtfr.greedy = token.getRepeatGreedy();
int ret = qtfr.setQuantifier(target.car, group, env, bytes, getBegin(), getEnd());
Node qn = qtfr;
-
+
if (token.getRepeatPossessive()) {
EncloseNode en = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose
en.setTarget(qn);
@@ -957,11 +908,10 @@ class Parser extends Lexer {
} else if (ret == 2) { /* split case: /abc+/ */
assert false;
}
- // !goto re_entry;!
- fetchToken();
+ fetchToken(); // goto re_entry
}
return top;
- }
+ }
private Node parseBranch(TokenType term) {
Node node = parseExp(term);
@@ -971,13 +921,13 @@ class Parser extends Lexer {
} else {
ConsAltNode top = ConsAltNode.newListNode(node, null);
ConsAltNode t = top;
-
+
while (token.type != TokenType.EOT && token.type != term && token.type != TokenType.ALT) {
node = parseExp(term);
if (node.getType() == NodeType.LIST) {
t.setCdr((ConsAltNode)node);
while (((ConsAltNode)node).cdr != null ) node = ((ConsAltNode)node).cdr;
-
+
t = ((ConsAltNode)node);
} else {
t.setCdr(ConsAltNode.newListNode(node, null));
@@ -987,7 +937,7 @@ class Parser extends Lexer {
return top;
}
}
-
+
/* term_tok: TK_EOT or TK_SUBEXP_CLOSE */
private Node parseSubExp(TokenType term) {
Node node = parseBranch(term);
@@ -1000,11 +950,11 @@ class Parser extends Lexer {
while (token.type == TokenType.ALT) {
fetchToken();
node = parseBranch(term);
-
+
t.setCdr(ConsAltNode.newAltNode(node, null));
t = t.cdr;
}
-
+
if (token.type != term) parseSubExpError(term);
return top;
} else {
@@ -1012,7 +962,7 @@ class Parser extends Lexer {
return null; //not reached
}
}
-
+
private void parseSubExpError(TokenType term) {
if (term == TokenType.SUBEXP_CLOSE) {
newSyntaxException(ERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS);
@@ -1020,7 +970,7 @@ class Parser extends Lexer {
newInternalException(ERR_PARSER_BUG);
}
}
-
+
private Node parseRegexp() {
fetchToken();
return parseSubExp(TokenType.EOT);
diff --git a/src/org/joni/Regex.java b/src/org/joni/Regex.java
index d6308de..03adf2b 100644
--- a/src/org/joni/Regex.java
+++ b/src/org/joni/Regex.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -27,6 +27,9 @@ import java.util.IllegalFormatConversionException;
import java.util.Iterator;
import org.jcodings.Encoding;
+import org.jcodings.EncodingDB;
+import org.jcodings.specific.ASCIIEncoding;
+import org.jcodings.specific.UTF8Encoding;
import org.jcodings.util.BytesHash;
import org.joni.constants.AnchorType;
import org.joni.constants.RegexState;
@@ -35,7 +38,7 @@ import org.joni.exception.InternalException;
import org.joni.exception.ValueException;
public final class Regex implements RegexState {
-
+
int[] code; /* compiled pattern */
int codeLength;
boolean stackNeeded;
@@ -66,9 +69,9 @@ public final class Regex implements RegexState {
Object userObject;
//final Syntax syntax;
final int caseFoldFlag;
-
+
BytesHash<NameEntry> nameTable; // named entries
-
+
/* optimization info (string search, char-map and anchors) */
SearchAlgorithm searchAlgorithm; /* optimize flag */
int thresholdLength; /* search str-length for apply optimize */
@@ -76,21 +79,52 @@ public final class Regex implements RegexState {
int anchorDmin; /* (SEMI_)END_BUF anchor distance */
int anchorDmax; /* (SEMI_)END_BUF anchor distance */
int subAnchor; /* start-anchor for exact or map */
-
+
byte[]exact;
int exactP;
int exactEnd;
-
+
byte[]map; /* used as BM skip or char-map */
int[]intMap; /* BM skip for exact_len > 255 */
int[]intMapBackward; /* BM skip for backward search */
int dMin; /* min-distance of exact or map */
int dMax; /* max-distance of exact or map */
+ byte[][]templates;
+ int templateNum;
+
+ public Regex(CharSequence cs) {
+ this(cs.toString());
+ }
+
+ public Regex(CharSequence cs, Encoding enc) {
+ this(cs.toString(), enc);
+ }
+
+ public Regex(String str) {
+ this(str.getBytes(), 0, str.length(), 0, UTF8Encoding.INSTANCE);
+ }
+
+ public Regex(String str, Encoding enc) {
+ this(str.getBytes(), 0, str.length(), 0, enc);
+ }
+
+ public Regex(byte[] bytes) {
+ this(bytes, 0, bytes.length, 0, ASCIIEncoding.INSTANCE);
+ }
+
+ public Regex(byte[] bytes, int p, int end) {
+ this(bytes, p, end, 0, ASCIIEncoding.INSTANCE);
+ }
+
+ public Regex(byte[] bytes, int p, int end, int option) {
+ this(bytes, p, end, option, ASCIIEncoding.INSTANCE);
+ }
+
public Regex(byte[]bytes, int p, int end, int option, Encoding enc) {
this(bytes, p, end, option, enc, Syntax.RUBY, WarnCallback.DEFAULT);
}
-
+
// onig_new
public Regex(byte[]bytes, int p, int end, int option, Encoding enc, Syntax syntax) {
this(bytes, p, end, option, Config.ENC_CASE_FOLD_DEFAULT, enc, syntax, WarnCallback.DEFAULT);
@@ -99,7 +133,7 @@ public final class Regex implements RegexState {
public Regex(byte[]bytes, int p, int end, int option, Encoding enc, WarnCallback warnings) {
this(bytes, p, end, option, enc, Syntax.RUBY, warnings);
}
-
+
// onig_new
public Regex(byte[]bytes, int p, int end, int option, Encoding enc, Syntax syntax, WarnCallback warnings) {
this(bytes, p, end, option, Config.ENC_CASE_FOLD_DEFAULT, enc, syntax, warnings);
@@ -107,19 +141,19 @@ public final class Regex implements RegexState {
// onig_alloc_init
public Regex(byte[]bytes, int p, int end, int option, int caseFoldFlag, Encoding enc, Syntax syntax, WarnCallback warnings) {
-
+
if ((option & (Option.DONT_CAPTURE_GROUP | Option.CAPTURE_GROUP)) ==
(Option.DONT_CAPTURE_GROUP | Option.CAPTURE_GROUP)) {
throw new ValueException(ErrorMessages.ERR_INVALID_COMBINATION_OF_OPTIONS);
}
-
+
if ((option & Option.NEGATE_SINGLELINE) != 0) {
option |= syntax.options;
option &= ~Option.SINGLELINE;
} else {
option |= syntax.options;
}
-
+
this.enc = enc;
this.options = option;
this.caseFoldFlag = caseFoldFlag;
@@ -129,19 +163,19 @@ public final class Regex implements RegexState {
this.warnings = null;
}
-
+
public Matcher matcher(byte[]bytes) {
return matcher(bytes, 0, bytes.length);
}
-
+
public Matcher matcher(byte[]bytes, int p, int end) {
return factory.create(this, bytes, p, end);
}
-
+
public int numberOfCaptures() {
return numMem;
}
-
+
public int numberOfCaptureHistories() {
if (Config.USE_CAPTURE_HISTORY) {
int n = 0;
@@ -153,10 +187,10 @@ public final class Regex implements RegexState {
return 0;
}
}
-
+
String nameTableToString() {
StringBuilder sb = new StringBuilder();
-
+
if (nameTable != null) {
sb.append("name table\n");
for (NameEntry ne : nameTable) {
@@ -166,7 +200,7 @@ public final class Regex implements RegexState {
}
return sb.toString();
}
-
+
NameEntry nameFind(byte[]name, int nameP, int nameEnd) {
if (nameTable != null) return nameTable.get(name, nameP, nameEnd);
return null;
@@ -184,7 +218,7 @@ public final class Regex implements RegexState {
}
}
}
- }
+ }
public int numberOfNames() {
return nameTable == null ? 0 : nameTable.size();
@@ -199,7 +233,7 @@ public final class Regex implements RegexState {
} else {
e = nameFind(name, nameP, nameEnd);
}
-
+
if (e == null) {
// dup the name here as oni does ?, what for ? (it has to manage it, we don't)
e = new NameEntry(name, nameP, nameEnd);
@@ -230,7 +264,7 @@ public final class Regex implements RegexState {
for (int i = e.backNum - 1; i >= 0; i--) {
if (region.beg[e.backRefs[i]] != Region.REGION_NOTPOS) return e.backRefs[i];
}
- }
+ }
return e.backRefs[e.backNum - 1];
}
}
@@ -241,7 +275,7 @@ public final class Regex implements RegexState {
public boolean noNameGroupIsActive(Syntax syntax) {
if (isDontCaptureGroup(options)) return false;
-
+
if (Config.USE_NAMED_GROUP) {
if (numberOfNames() > 0 && syntax.captureOnlyNamedGroup() && !isCaptureGroup(options)) return false;
}
@@ -263,7 +297,7 @@ public final class Regex implements RegexState {
for (int i=0; i<len-1; i++) map[bytes[p + i] & 0xff] = (byte)(len - 1 -i); // oxff ??
} else {
if (intMap == null) intMap = new int[Config.CHAR_TABLE_SIZE];
-
+
for (int i=0; i<len-1; i++) intMap[bytes[p + i] & 0xff] = len - 1 - i; // oxff ??
}
}
@@ -272,7 +306,7 @@ public final class Regex implements RegexState {
if (e.length == 0) return;
// shall we copy that ?
- exact = e.s;
+ exact = e.bytes;
exactP = 0;
exactEnd = e.length;
@@ -281,44 +315,39 @@ public final class Regex implements RegexState {
searchAlgorithm = enc.toLowerCaseTable() != null ? SearchAlgorithm.SLOW_IC_SB : new SearchAlgorithm.SLOW_IC(this);
} else {
boolean allowReverse = enc.isReverseMatchAllowed(exact, exactP, exactEnd);
-
+
if (e.length >= 3 || (e.length >= 2 && allowReverse)) {
setupBMSkipMap();
if (allowReverse) {
searchAlgorithm = SearchAlgorithm.BM;
} else {
- searchAlgorithm = SearchAlgorithm.BM_NOT_REV;
+ searchAlgorithm = SearchAlgorithm.BM_NOT_REV;
}
} else {
searchAlgorithm = enc.isSingleByte() ? SearchAlgorithm.SLOW_SB : SearchAlgorithm.SLOW;
}
}
-
+
dMin = e.mmd.min;
dMax = e.mmd.max;
-
+
if (dMin != MinMaxLen.INFINITE_DISTANCE) {
thresholdLength = dMin + (exactEnd - exactP);
}
}
void setOptimizeMapInfo(OptMapInfo m) {
- /*
- for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) {
- map[i] = m.map[i]; // do we really have to copy that ???
- }
- */
map = m.map;
-
+
searchAlgorithm = enc.isSingleByte() ? SearchAlgorithm.MAP_SB : SearchAlgorithm.MAP;
dMin = m.mmd.min;
dMax = m.mmd.max;
-
+
if (dMin != MinMaxLen.INFINITE_DISTANCE) {
thresholdLength = dMin + 1;
}
}
-
+
void setSubAnchor(OptAnchorInfo anc) {
subAnchor |= anc.leftAnchor & AnchorType.BEGIN_LINE;
subAnchor |= anc.rightAnchor & AnchorType.END_LINE;
@@ -330,14 +359,14 @@ public final class Regex implements RegexState {
anchorDmax = 0;
anchorDmin = 0;
subAnchor = 0;
-
+
exact = null;
exactP = exactEnd = 0;
}
-
+
public String encStringToString(byte[]bytes, int p, int end) {
StringBuilder sb = new StringBuilder("\nPATTERN: /");
-
+
if (enc.minLength() > 1) {
int p_ = p;
while (p_ < end) {
@@ -361,12 +390,12 @@ public final class Regex implements RegexState {
}
return sb.append("/").toString();
}
-
+
public String optimizeInfoToString() {
String s = "";
s += "optimize: " + searchAlgorithm.getName() + "\n";
s += " anchor: " + OptAnchorInfo.anchorToString(anchor);
-
+
if ((anchor & AnchorType.END_BUF_MASK) != 0) {
s += MinMaxLen.distanceRangeToString(anchorDmin, anchorDmax);
}
@@ -381,11 +410,11 @@ public final class Regex implements RegexState {
s += "threshold length: " + thresholdLength + "\n";
if (exact != null) {
- s += "exact: [" + new String(exact, exactP, exactEnd - exactP) + "]: length: " + (exactEnd - exactP) + "\n";
+ s += "exact: [" + new String(exact, exactP, exactEnd - exactP) + "]: length: " + (exactEnd - exactP) + "\n";
} else if (searchAlgorithm == SearchAlgorithm.MAP || searchAlgorithm == SearchAlgorithm.MAP_SB) {
int n=0;
for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) if (map[i] != 0) n++;
-
+
s += "map: n = " + n + "\n";
if (n > 0) {
int c=0;
@@ -401,6 +430,7 @@ public final class Regex implements RegexState {
s += "]\n";
}
}
+
return s;
}
diff --git a/src/org/joni/Region.java b/src/org/joni/Region.java
index 08b90f9..cb54315 100644
--- a/src/org/joni/Region.java
+++ b/src/org/joni/Region.java
@@ -1,44 +1,44 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
public final class Region {
static final int REGION_NOTPOS = -1;
-
+
public final int numRegs;
public final int[]beg;
public final int[]end;
public CaptureTreeNode historyRoot;
-
+
public Region(int num) {
this.numRegs = num;
this.beg = new int[num];
this.end = new int[num];
}
-
+
public Region(int begin, int end) {
this.numRegs = 1;
this.beg = new int[]{begin};
this.end = new int[]{end};
}
-
+
public Region clone() {
Region region = new Region(numRegs);
System.arraycopy(beg, 0, region.beg, 0, beg.length);
@@ -46,18 +46,18 @@ public final class Region {
if (historyRoot != null) region.historyRoot = historyRoot.cloneTree();
return region;
}
-
+
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Region: \n");
for (int i=0; i<beg.length; i++) sb.append(" " + i + ": (" + beg[i] + "-" + end[i] + ")");
return sb.toString();
}
-
+
CaptureTreeNode getCaptureTree() {
return historyRoot;
}
-
+
void clear() {
for (int i=0; i<beg.length; i++) {
beg[i] = end[i] = REGION_NOTPOS;
diff --git a/src/org/joni/ScanEnvironment.java b/src/org/joni/ScanEnvironment.java
index 95dd90a..02a1ad7 100644
--- a/src/org/joni/ScanEnvironment.java
+++ b/src/org/joni/ScanEnvironment.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -27,9 +27,9 @@ 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;
@@ -38,23 +38,23 @@ public final class ScanEnvironment {
int btMemStart;
int btMemEnd;
int backrefedMem;
-
+
final public Regex reg;
-
+
int numCall;
UnsetAddrList unsetAddrList; // USE_SUBEXP_CALL
public int numMem;
int numNamed; // USE_NAMED_GROUP
-
+
public Node memNodes[];
-
+
// USE_COMBINATION_EXPLOSION_CHECK
int numCombExpCheck;
int combExpMaxRegNum;
int currMaxRegNum;
boolean hasRecursion;
-
+
public ScanEnvironment(Regex regex, Syntax syntax) {
this.reg = regex;
option = regex.options;
@@ -81,7 +81,7 @@ public final class ScanEnvironment {
currMaxRegNum = 0;
hasRecursion = false;
}
-
+
public int addMemEntry() {
if (numMem++ == 0) {
memNodes = new Node[SCANENV_MEMNODES_SIZE];
@@ -93,7 +93,7 @@ public final class ScanEnvironment {
return numMem;
}
-
+
public void setMemNode(int num, Node node) {
if (numMem >= num) {
memNodes[num] = node;
@@ -101,7 +101,7 @@ public final class ScanEnvironment {
throw new InternalException(ErrorMessages.ERR_PARSER_BUG);
}
}
-
+
public int convertBackslashValue(int c) {
if (syntax.opEscControlChars()) {
switch (c) {
@@ -121,7 +121,7 @@ public final class ScanEnvironment {
}
return c;
}
-
+
void ccEscWarn(String s) {
if (Config.USE_WARN) {
if (syntax.warnCCOpNotEscaped() && syntax.backSlashEscapeInCC()) {
@@ -129,7 +129,7 @@ public final class ScanEnvironment {
}
}
}
-
+
void closeBracketWithoutEscapeWarn(String s) {
if (Config.USE_WARN) {
if (syntax.warnCCOpNotEscaped()) {
diff --git a/src/org/joni/ScannerSupport.java b/src/org/joni/ScannerSupport.java
index 370d338..8598fc6 100644
--- a/src/org/joni/ScannerSupport.java
+++ b/src/org/joni/ScannerSupport.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -28,7 +28,7 @@ import org.joni.exception.ValueException;
abstract class ScannerSupport extends IntHolder implements ErrorMessages {
protected final Encoding enc; // fast access to encoding
-
+
protected final byte[]bytes; // pattern
protected int p; // current scanner position
protected int stop; // pattern end (mutable)
@@ -38,28 +38,29 @@ abstract class ScannerSupport extends IntHolder implements ErrorMessages {
private final int begin; // pattern begin position for reset() support
private final int end; // pattern end position for reset() support
protected int _p; // used by mark()/restore() to mark positions
-
+
protected ScannerSupport(Encoding enc, byte[]bytes, int p, int end) {
this.enc = enc;
-
+
this.bytes = bytes;
this.begin = p;
this.end = end;
-
+
reset();
}
-
+
protected int getBegin() {
return begin;
}
-
+
protected int getEnd() {
return end;
}
-
+
private final int INT_SIGN_BIT = 1 << 31;
-
+
protected final int scanUnsignedNumber() {
+ int last = c;
int num = 0; // long ???
while(left()) {
fetch();
@@ -68,14 +69,16 @@ abstract class ScannerSupport extends IntHolder implements ErrorMessages {
num = num * 10 + Encoding.digitVal(c);
if (((onum ^ num) & INT_SIGN_BIT) != 0) return -1;
} else {
- unfetch();
+ unfetch();
break;
}
- }
- return num;
+ }
+ c = last;
+ return num;
}
-
+
protected final int scanUnsignedHexadecimalNumber(int maxLength) {
+ int last = c;
int num = 0;
while(left() && maxLength-- != 0) {
fetch();
@@ -89,15 +92,17 @@ abstract class ScannerSupport extends IntHolder implements ErrorMessages {
break;
}
}
+ c = last;
return num;
}
-
+
protected final int scanUnsignedOctalNumber(int maxLength) {
+ int last = c;
int num = 0;
while(left() && maxLength-- != 0) {
fetch();
- if (enc.isDigit(c) && c < '8') {
- int onum = num;
+ if (enc.isDigit(c) && c < '8') {
+ int onum = num;
int val = Encoding.odigitVal(c);
num = (num << 3) + val;
if (((onum ^ num) & INT_SIGN_BIT) != 0) return -1;
@@ -106,56 +111,57 @@ abstract class ScannerSupport extends IntHolder implements ErrorMessages {
break;
}
}
- return num;
+ c = last;
+ return num;
}
-
+
protected final void reset() {
p = begin;
stop = end;
}
-
+
protected final void mark() {
_p = p;
}
-
+
protected final void restore() {
p = _p;
}
-
+
protected final void inc() {
lastFetched = p;
p += enc.length(bytes, p, stop);
}
-
+
protected final void fetch() {
c = enc.mbcToCode(bytes, p, stop);
lastFetched = p;
p += enc.length(bytes, p, stop);
}
-
+
protected int fetchTo() {
int to = enc.mbcToCode(bytes, p, stop);
lastFetched = p;
p += enc.length(bytes, p, stop);
return to;
}
-
+
protected final void unfetch() {
p = lastFetched;
}
-
+
protected final int peek() {
- return p < stop ? enc.mbcToCode(bytes, p, stop) : 0;
+ return p < stop ? enc.mbcToCode(bytes, p, stop) : 0;
}
-
+
protected final boolean peekIs(int c) {
return peek() == c;
}
-
+
protected final boolean left() {
return p < stop;
}
-
+
protected void newSyntaxException(String message) {
throw new SyntaxException(message);
}
@@ -163,7 +169,7 @@ abstract class ScannerSupport extends IntHolder implements ErrorMessages {
protected void newValueException(String message) {
throw new ValueException(message);
}
-
+
protected void newValueException(String message, String str) {
throw new ValueException(message, str);
}
@@ -175,5 +181,5 @@ abstract class ScannerSupport extends IntHolder implements ErrorMessages {
protected void newInternalException(String message) {
throw new InternalException(message);
}
-
+
}
diff --git a/src/org/joni/SearchAlgorithm.java b/src/org/joni/SearchAlgorithm.java
index 36bf877..6d63c2f 100644
--- a/src/org/joni/SearchAlgorithm.java
+++ b/src/org/joni/SearchAlgorithm.java
@@ -1,3 +1,22 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
package org.joni;
import org.jcodings.Encoding;
@@ -8,44 +27,44 @@ public abstract class SearchAlgorithm {
public abstract String getName();
public abstract int search(Regex regex, byte[]text, int textP, int textEnd, int textRange);
public abstract int searchBackward(Regex regex, byte[]text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_);
-
+
public static final SearchAlgorithm NONE = new SearchAlgorithm() {
public final String getName() {
return "NONE";
}
-
+
public final int search(Regex regex, byte[]text, int textP, int textEnd, int textRange) {
return textP;
}
-
+
public final int searchBackward(Regex regex, byte[]text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
return textP;
}
-
+
};
-
+
public static final SearchAlgorithm SLOW = new SearchAlgorithm() {
-
+
public final String getName() {
return "EXACT";
}
-
+
public final int search(Regex regex, byte[]text, int textP, int textEnd, int textRange) {
Encoding enc = regex.enc;
byte[]target = regex.exact;
int targetP = regex.exactP;
int targetEnd = regex.exactEnd;
-
-
+
+
int end = textEnd;
end -= targetEnd - targetP - 1;
-
+
if (end > textRange) end = textRange;
-
+
int s = textP;
-
+
while (s < end) {
if (text[s] == target[targetP]) {
int p = s + 1;
@@ -54,30 +73,30 @@ public abstract class SearchAlgorithm {
if (target[t] != text[p++]) break;
t++;
}
-
+
if (t == targetEnd) return s;
}
s += enc.length(text, s, textEnd);
}
-
- return -1;
+
+ return -1;
}
-
+
public final int searchBackward(Regex regex, byte[]text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
Encoding enc = regex.enc;
byte[]target = regex.exact;
int targetP = regex.exactP;
- int targetEnd = regex.exactEnd;
-
+ int targetEnd = regex.exactEnd;
+
int s = textEnd;
s -= targetEnd - targetP;
-
+
if (s > textStart) {
s = textStart;
} else {
s = enc.leftAdjustCharHead(text, adjustText, s, textEnd);
}
-
+
while (s >= textP) {
if (text[s] == target[targetP]) {
int p = s + 1;
@@ -90,28 +109,28 @@ public abstract class SearchAlgorithm {
}
s = enc.prevCharHead(text, adjustText, s, textEnd);
}
- return -1;
+ return -1;
}
};
public static final SearchAlgorithm SLOW_SB = new SearchAlgorithm() {
-
+
public final String getName() {
return "EXACT_SB";
}
-
+
public final int search(Regex regex, byte[]text, int textP, int textEnd, int textRange) {
byte[]target = regex.exact;
int targetP = regex.exactP;
int targetEnd = regex.exactEnd;
-
+
int end = textEnd;
end -= targetEnd - targetP - 1;
-
+
if (end > textRange) end = textRange;
-
+
int s = textP;
-
+
while (s < end) {
if (text[s] == target[targetP]) {
int p = s + 1;
@@ -120,25 +139,25 @@ public abstract class SearchAlgorithm {
if (target[t] != text[p++]) break;
t++;
}
-
+
if (t == targetEnd) return s;
}
s++;
}
-
- return -1;
+
+ return -1;
}
-
+
public final int searchBackward(Regex regex, byte[]text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
byte[]target = regex.exact;
int targetP = regex.exactP;
- int targetEnd = regex.exactEnd;
-
+ int targetEnd = regex.exactEnd;
+
int s = textEnd;
s -= targetEnd - targetP;
-
+
if (s > textStart) s = textStart;
-
+
while (s >= textP) {
if (text[s] == target[targetP]) {
int p = s + 1;
@@ -152,11 +171,11 @@ public abstract class SearchAlgorithm {
//s = s <= adjustText ? -1 : s - 1;
s--;
}
- return -1;
+ return -1;
}
};
-
-
+
+
public static final class SLOW_IC extends SearchAlgorithm {
private final byte[]buf = new byte[Config.ENC_MBC_CASE_FOLD_MAXLEN];
private final IntHolder holder = new IntHolder();
@@ -167,50 +186,50 @@ public abstract class SearchAlgorithm {
this.caseFoldFlag = regex.caseFoldFlag;
this.enc = regex.enc;
}
-
+
public final String getName() {
return "EXACT_IC";
- }
-
+ }
+
public final int search(Regex regex, byte[]text, int textP, int textEnd, int textRange) {
byte[]target = regex.exact;
int targetP = regex.exactP;
int targetEnd = regex.exactEnd;
-
+
int end = textEnd;
end -= targetEnd - targetP - 1;
-
+
if (end > textRange) end = textRange;
int s = textP;
-
+
while (s < end) {
if (lowerCaseMatch(target, targetP, targetEnd, text, s, textEnd)) return s;
s += enc.length(text, s, textEnd);
}
return -1;
}
-
+
public final int searchBackward(Regex regex, byte[]text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
byte[]target = regex.exact;
int targetP = regex.exactP;
int targetEnd = regex.exactEnd;
-
+
int s = textEnd;
s -= targetEnd - targetP;
-
+
if (s > textStart) {
s = textStart;
} else {
s = enc.leftAdjustCharHead(text, adjustText, s, textEnd);
}
-
+
while (s >= textP) {
if (lowerCaseMatch(target, targetP, targetEnd, text, s, textEnd)) return s;
s = enc.prevCharHead(text, adjustText, s, textEnd);
}
- return -1;
+ return -1;
}
-
+
private boolean lowerCaseMatch(byte[]t, int tP, int tEnd,
byte[]bytes, int p, int end) {
@@ -222,7 +241,7 @@ public abstract class SearchAlgorithm {
} else {
int q = 0;
while (lowlen > 0) {
- if (t[tP++] != buf[q++]) return false;
+ if (t[tP++] != buf[q++]) return false;
lowlen--;
}
}
@@ -235,20 +254,20 @@ public abstract class SearchAlgorithm {
public final String getName() {
return "EXACT_IC_SB";
- }
-
- public final int search(Regex regex, byte[]text, int textP, int textEnd, int textRange) {
+ }
+
+ public final int search(Regex regex, byte[]text, int textP, int textEnd, int textRange) {
final byte[]toLowerTable = regex.enc.toLowerCaseTable();
byte[]target = regex.exact;
int targetP = regex.exactP;
int targetEnd = regex.exactEnd;
-
+
int end = textEnd;
end -= targetEnd - targetP - 1;
-
+
if (end > textRange) end = textRange;
int s = textP;
-
+
while (s < end) {
if (target[targetP] == toLowerTable[text[s] & 0xff]) {
int p = s + 1;
@@ -257,25 +276,25 @@ public abstract class SearchAlgorithm {
if (target[t] != toLowerTable[text[p++] & 0xff]) break;
t++;
}
-
+
if (t == targetEnd) return s;
}
- s++;
+ s++;
}
return -1;
}
-
+
public final int searchBackward(Regex regex, byte[]text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
final byte[]toLowerTable = regex.enc.toLowerCaseTable();
byte[]target = regex.exact;
int targetP = regex.exactP;
int targetEnd = regex.exactEnd;
-
+
int s = textEnd;
s -= targetEnd - targetP;
-
+
if (s > textStart) s = textStart;
-
+
while (s >= textP) {
if (target[targetP] == toLowerTable[text[s] & 0xff]) {
int p = s + 1;
@@ -289,76 +308,80 @@ public abstract class SearchAlgorithm {
//s = s <= adjustText ? -1 : s - 1;
s--;
}
- return -1;
+ return -1;
}
- };
-
+ };
+
public static final SearchAlgorithm BM = new SearchAlgorithm() {
-
+
public final String getName() {
return "EXACT_BM";
- }
-
+ }
+
public final int search(Regex regex, byte[]text, int textP, int textEnd, int textRange) {
byte[]target = regex.exact;
int targetP = regex.exactP;
- int targetEnd = regex.exactEnd;
-
+ int targetEnd = regex.exactEnd;
+
int end = textRange + (targetEnd - targetP) - 1;
if (end > textEnd) end = textEnd;
-
+
int tail = targetEnd - 1;
int s = textP + (targetEnd - targetP) - 1;
-
+
if (regex.intMap == null) {
while (s < end) {
int p = s;
int t = tail;
- while (t >= targetP && text[p] == target[t]) {
+
+ while (text[p] == target[t]) {
+ if (t == targetP) return p;
p--; t--;
}
- if (t < targetP) return p + 1;
+
s += regex.map[text[s] & 0xff];
}
} else { /* see int_map[] */
while (s < end) {
int p = s;
int t = tail;
- while (t >= targetP && text[p] == target[t]) {
+
+ while (text[p] == target[t]) {
+ if (t == targetP) return p;
p--; t--;
}
- if (t < targetP) return p + 1;
+
s += regex.intMap[text[s] & 0xff];
}
}
- return -1;
+ return -1;
}
-
+
private static final int BM_BACKWARD_SEARCH_LENGTH_THRESHOLD = 100;
-
+
public final int searchBackward(Regex regex, byte[]text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
Encoding enc = regex.enc;
byte[]target = regex.exact;
int targetP = regex.exactP;
int targetEnd = regex.exactEnd;
-
+
if (regex.intMapBackward == null) {
if (s_ - range_ < BM_BACKWARD_SEARCH_LENGTH_THRESHOLD) {
// goto exact_method;
return SLOW.searchBackward(regex, text, textP, adjustText, textEnd, textStart, s_, range_);
}
- setBmBackwardSkip(regex, target, targetP, targetEnd);
+ setBmBackwardSkip(regex, target, targetP, targetEnd);
}
-
+
int s = textEnd - (targetEnd - targetP);
-
+
if (textStart < s) {
s = textStart;
} else {
s = enc.leftAdjustCharHead(text, adjustText, s, textEnd);
}
-
+
while (s >= textP) {
int p = s;
int t = targetP;
@@ -366,14 +389,14 @@ public abstract class SearchAlgorithm {
p++; t++;
}
if (t == targetEnd) return s;
-
+
s -= regex.intMapBackward[text[s] & 0xff];
s = enc.leftAdjustCharHead(text, adjustText, s, textEnd);
}
- return -1;
+ return -1;
}
-
-
+
+
private void setBmBackwardSkip(Regex regex, byte[]bytes, int p, int end) {
int[] skip;
if (regex.intMapBackward == null) {
@@ -382,52 +405,51 @@ public abstract class SearchAlgorithm {
} else {
skip = regex.intMapBackward;
}
-
+
int len = end - p;
-
+
for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) skip[i] = len;
for (int i=len-1; i>0; i--) skip[bytes[i] & 0xff] = i;
- }
+ }
};
-
+
public static final SearchAlgorithm BM_NOT_REV = new SearchAlgorithm() {
-
+
public final String getName() {
return "EXACT_BM_NOT_REV";
- }
-
+ }
+
public final int search(Regex regex, byte[]text, int textP, int textEnd, int textRange) {
Encoding enc = regex.enc;
byte[]target = regex.exact;
int targetP = regex.exactP;
- int targetEnd = regex.exactEnd;
-
+ int targetEnd = regex.exactEnd;
+
int tail = targetEnd - 1;
int tlen1 = tail - targetP;
int end = textRange;
-
+
if (Config.DEBUG_SEARCH) {
Config.log.println("bm_search_notrev: "+
"text: " + textP +
", text_end: " + textEnd +
", text_range: " + textRange);
}
-
+
if (end + tlen1 > textEnd) end = textEnd - tlen1;
-
+
int s = textP;
-
+
if (regex.intMap == null) {
while (s < end) {
int p, se;
p = se = s + tlen1;
int t = tail;
- while (t >= targetP && text[p] == target[t]) {
+ while (text[p] == target[t]) {
+ if (t == targetP) return s;
p--; t--;
}
-
- if (t < targetP) return s;
-
+
int skip = regex.map[text[se] & 0xff];
t = s;
do {
@@ -439,35 +461,35 @@ public abstract class SearchAlgorithm {
int p, se;
p = se = s + tlen1;
int t = tail;
- while (t >= targetP && text[p] == target[t]) {
+
+ while (text[p] == target[t]) {
+ if (t == targetP) return s;
p--; t--;
}
-
- if (t < targetP) return s;
-
+
int skip = regex.intMap[text[se] & 0xff];
t = s;
do {
s += enc.length(text, s, textEnd);
} while ((s - t) < skip && s < end);
-
+
}
}
- return -1;
+ return -1;
}
-
+
public final int searchBackward(Regex regex, byte[]text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
return BM.searchBackward(regex, text, textP, adjustText, textEnd, textStart, s_, range_);
}
};
-
-
+
+
public static final SearchAlgorithm MAP = new SearchAlgorithm() {
public final String getName() {
return "MAP";
- }
-
+ }
+
// TODO: check 1.9 inconsistent calls to map_search
public final int search(Regex regex, byte[]text, int textP, int textEnd, int textRange) {
Encoding enc = regex.enc;
@@ -480,13 +502,13 @@ public abstract class SearchAlgorithm {
}
return -1;
}
-
+
public final int searchBackward(Regex regex, byte[]text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
Encoding enc = regex.enc;
byte[]map = regex.map;
int s = textStart;
- if (s >= textEnd) s = textEnd - 1; // multibyte safe ?
+ if (s >= textEnd) s = textEnd - 1; // multibyte safe ?
while (s >= textP) {
if (map[text[s] & 0xff] != 0) return s;
s = enc.prevCharHead(text, adjustText, s, textEnd);
@@ -499,30 +521,30 @@ public abstract class SearchAlgorithm {
public final String getName() {
return "MAP_SB";
- }
-
+ }
+
public final int search(Regex regex, byte[]text, int textP, int textEnd, int textRange) {
byte[]map = regex.map;
int s = textP;
-
+
while (s < textRange) {
if (map[text[s] & 0xff] != 0) return s;
s++;
}
return -1;
}
-
+
public final int searchBackward(Regex regex, byte[]text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
byte[]map = regex.map;
int s = textStart;
- if (s >= textEnd) s = textEnd - 1;
+ if (s >= textEnd) s = textEnd - 1;
while (s >= textP) {
if (map[text[s] & 0xff] != 0) return s;
s--;
}
return -1;
}
- };
-
+ };
+
}
diff --git a/src/org/joni/StackEntry.java b/src/org/joni/StackEntry.java
index 001c98d..81b1785 100644
--- a/src/org/joni/StackEntry.java
+++ b/src/org/joni/StackEntry.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -22,7 +22,7 @@ package org.joni;
final class StackEntry {
int type;
private int E1, E2, E3, E4;
-
+
// first union member
/* byte code position */
void setStatePCode(int pcode) {
@@ -52,7 +52,7 @@ final class StackEntry {
int getStateCheck() {
return E4;
}
-
+
// second union member
/* for OP_REPEAT_INC, OP_REPEAT_INC_NG */
void setRepeatCount(int count) {
@@ -63,7 +63,7 @@ final class StackEntry {
}
void decreaseRepeatCount() {
E1--;
- }
+ }
void increaseRepeatCount() {
E1++;
}
@@ -81,7 +81,7 @@ final class StackEntry {
int getRepeatNum() {
return E3;
}
-
+
// third union member
/* index of stack */ /*int repeat_inc struct*/
void setSi(int si) {
@@ -90,7 +90,7 @@ final class StackEntry {
int getSi() {
return E1;
}
-
+
// fourth union member
/* memory num */
void setMemNum(int num) {
@@ -106,7 +106,7 @@ final class StackEntry {
int getMemPStr() {
return E2;
}
-
+
/* Following information is set, if this stack type is MEM-START */
/* prev. info (for backtrack "(...)*" ) */
void setMemStart(int start) {
@@ -122,7 +122,7 @@ final class StackEntry {
int getMemEnd() {
return E4;
}
-
+
// fifth union member
/* null check id */
void setNullCheckNum(int num) {
@@ -137,8 +137,8 @@ final class StackEntry {
}
int getNullCheckPStr() {
return E2;
- }
-
+ }
+
// sixth union member
/* byte code position */
void setCallFrameRetAddr(int addr) {
@@ -158,7 +158,7 @@ final class StackEntry {
void setCallFramePStr(int pstr) {
E3 = pstr;
}
- int getCallFramePStr() {
- return E3;
+ int getCallFramePStr() {
+ return E3;
}
}
diff --git a/src/org/joni/StackMachine.java b/src/org/joni/StackMachine.java
index 7fe60a7..a5e51a4 100644
--- a/src/org/joni/StackMachine.java
+++ b/src/org/joni/StackMachine.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -29,7 +29,7 @@ import org.joni.constants.StackType;
abstract class StackMachine extends Matcher implements StackType {
protected static final int INVALID_INDEX = -1;
-
+
protected StackEntry[]stack;
protected int stk; // stkEnd
@@ -38,7 +38,7 @@ abstract class StackMachine extends Matcher implements StackType {
// CEC
protected byte[] stateCheckBuff; // move to int[] ?
- int stateCheckBuffSize;
+ int stateCheckBuffSize;
protected StackMachine(Regex regex, byte[]bytes, int p , int end) {
super(regex, bytes, p, end);
@@ -46,7 +46,7 @@ abstract class StackMachine extends Matcher implements StackType {
this.stack = regex.stackNeeded ? 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] */
@@ -58,13 +58,13 @@ abstract class StackMachine extends Matcher implements StackType {
stack[0] = new StackEntry();
return stack;
}
-
+
private void doubleStack() {
StackEntry[] newStack = new StackEntry[stack.length << 1];
System.arraycopy(stack, 0, newStack, 0, stack.length);
stack = newStack;
- }
-
+ }
+
static final ThreadLocal<WeakReference<StackEntry[]>> stacks
= new ThreadLocal<WeakReference<StackEntry[]>>() {
@Override
@@ -86,7 +86,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=1; i<=regex.numMem; i++) {
repeatStk[i + memStartStk] = repeatStk[i + memEndStk] = INVALID_INDEX;
}
}
@@ -98,7 +98,7 @@ abstract class StackMachine extends Matcher implements StackType {
if (e == null) stack[stk] = e = new StackEntry();
return e;
}
-
+
protected final void pushType(int type) {
ensure1().type = type;
stk++;
@@ -124,7 +124,7 @@ abstract class StackMachine extends Matcher implements StackType {
private void stateCheckMark() {
StackEntry e = stack[stk];
int x = stateCheckPos(e.getStatePStr(), e.getStateCheck());
- stateCheckBuff[x / 8] |= (1 << (x % 8));
+ stateCheckBuff[x / 8] |= (1 << (x % 8));
}
// STATE_CHECK_BUFF_INIT
@@ -133,16 +133,16 @@ abstract class StackMachine extends Matcher implements StackType {
if (stateNum > 0 && strLength >= Config.CHECK_STRING_THRESHOLD_LEN) {
int size = ((strLength + 1) * stateNum + 7) >>> 3;
offset = (offset * stateNum) >>> 3;
-
+
if (size > 0 && offset < size && size < Config.CHECK_BUFF_MAX_SIZE) {
if (size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) {
- stateCheckBuff = new byte[size];
+ stateCheckBuff = new byte[size];
} else {
// same impl, reduce...
stateCheckBuff = new byte[size];
}
Arrays.fill(stateCheckBuff, offset, (size - offset), (byte)0);
- stateCheckBuffSize = size;
+ stateCheckBuffSize = size;
} else {
stateCheckBuff = null; // reduce
stateCheckBuffSize = 0;
@@ -175,17 +175,17 @@ abstract class StackMachine extends Matcher implements StackType {
if (Config.USE_COMBINATION_EXPLOSION_CHECK) e.setStateCheck(0);
stk++;
}
-
+
protected final void pushAltWithStateCheck(int pat, int s, int sprev, int snum) {
StackEntry e = ensure1();
e.type = ALT;
e.setStatePCode(pat);
e.setStatePStr(s);
- e.setStatePStrPrev(sprev);
- if (Config.USE_COMBINATION_EXPLOSION_CHECK) e.setStateCheck(stateCheckBuff != null ? snum : 0);
+ e.setStatePStrPrev(sprev);
+ if (Config.USE_COMBINATION_EXPLOSION_CHECK) e.setStateCheck(stateCheckBuff != null ? snum : 0);
stk++;
}
-
+
protected final void pushStateCheck(int s, int snum) {
if (stateCheckBuff != null) {
StackEntry e = ensure1();
@@ -193,30 +193,30 @@ abstract class StackMachine extends Matcher implements StackType {
e.setStatePStr(s);
e.setStateCheck(snum);
stk++;
- }
+ }
}
protected final void pushAlt(int pat, int s, int prev) {
push(ALT, pat, s, prev);
}
-
+
protected final void pushPos(int s, int prev) {
push(POS, -1 /*NULL_UCHARP*/, s, prev);
}
-
+
protected final void pushPosNot(int pat, int s, int prev) {
push(POS_NOT, pat, s, prev);
}
-
- protected final void pushStopBT() {
+
+ protected final void pushStopBT() {
pushType(STOP_BT);
}
-
+
protected final void pushLookBehindNot(int pat, int s, int sprev) {
push(LOOK_BEHIND_NOT, pat, s, sprev);
}
-
- protected final void pushRepeat(int id, int pat) {
+
+ protected final void pushRepeat(int id, int pat) {
StackEntry e = ensure1();
e.type = REPEAT;
e.setRepeatNum(id);
@@ -224,14 +224,14 @@ abstract class StackMachine extends Matcher implements StackType {
e.setRepeatCount(0);
stk++;
}
-
+
protected final void pushRepeatInc(int sindex) {
StackEntry e = ensure1();
e.type = REPEAT_INC;
e.setSi(sindex);
stk++;
}
-
+
protected final void pushMemStart(int mnum, int s) {
StackEntry e = ensure1();
e.type = MEM_START;
@@ -239,7 +239,7 @@ abstract class StackMachine extends Matcher implements StackType {
e.setMemPstr(s);
e.setMemStart(repeatStk[memStartStk + mnum]);
e.setMemEnd(repeatStk[memEndStk + mnum]);
- repeatStk[memStartStk + mnum] = stk;
+ repeatStk[memStartStk + mnum] = stk;
repeatStk[memEndStk + mnum] = INVALID_INDEX;
stk++;
}
@@ -247,25 +247,25 @@ abstract class StackMachine extends Matcher implements StackType {
protected final void pushMemEnd(int mnum, int s) {
StackEntry e = ensure1();
e.type = MEM_END;
- e.setMemNum(mnum);
+ e.setMemNum(mnum);
e.setMemPstr(s);
e.setMemStart(repeatStk[memStartStk + mnum]);
e.setMemEnd(repeatStk[memEndStk + mnum]);
repeatStk[memEndStk + mnum] = stk;
stk++;
- }
-
+ }
+
protected final void pushMemEndMark(int mnum) {
StackEntry e = ensure1();
e.type = MEM_END_MARK;
e.setMemNum(mnum);
stk++;
}
-
+
protected final int getMemStart(int mnum) {
int level = 0;
int stkp = stk;
-
+
while (stkp > 0) {
stkp--;
StackEntry e = stack[stkp];
@@ -278,7 +278,7 @@ abstract class StackMachine extends Matcher implements StackType {
}
return stkp;
}
-
+
protected final void pushNullCheckStart(int cnum, int s) {
StackEntry e = ensure1();
e.type = NULL_CHECK_START;
@@ -286,30 +286,30 @@ abstract class StackMachine extends Matcher implements StackType {
e.setNullCheckPStr(s);
stk++;
}
-
+
protected final void pushNullCheckEnd(int cnum) {
StackEntry e = ensure1();
e.type = NULL_CHECK_END;
e.setNullCheckNum(cnum);
stk++;
}
-
+
protected final void pushCallFrame(int pat) {
StackEntry e = ensure1();
e.type = CALL_FRAME;
e.setCallFrameRetAddr(pat);
stk++;
}
-
+
protected final void pushReturn() {
StackEntry e = ensure1();
e.type = RETURN;
stk++;
}
-
+
// stack debug routines here
// ...
-
+
protected final void popOne() {
stk--;
}
@@ -328,7 +328,7 @@ abstract class StackMachine extends Matcher implements StackType {
private StackEntry popFree() {
while (true) {
StackEntry e = stack[--stk];
-
+
if ((e.type & MASK_POP_USED) != 0) {
return e;
} else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
@@ -340,8 +340,8 @@ abstract class StackMachine extends Matcher implements StackType {
private StackEntry popMemStart() {
while (true) {
StackEntry e = stack[--stk];
-
- if ((e.type & MASK_POP_USED) != 0) {
+
+ if ((e.type & MASK_POP_USED) != 0) {
return e;
} else if (e.type == MEM_START) {
repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
@@ -367,9 +367,9 @@ abstract class StackMachine extends Matcher implements StackType {
stack[e.getSi()].decreaseRepeatCount();
} else if (e.type == MEM_END) {
repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
- repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
- } else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
- if (e.type == STATE_CHECK_MARK) stateCheckMark();
+ repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
+ } else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
+ if (e.type == STATE_CHECK_MARK) stateCheckMark();
}
}
}
@@ -378,7 +378,7 @@ abstract class StackMachine extends Matcher implements StackType {
while (true) {
stk--;
StackEntry e = stack[stk];
-
+
if (e.type == POS_NOT) {
break;
} else if (e.type == MEM_START) {
@@ -396,12 +396,12 @@ abstract class StackMachine extends Matcher implements StackType {
}
}
}
-
+
protected final void popTilLookBehindNot() {
while (true) {
stk--;
StackEntry e = stack[stk];
-
+
if (e.type == LOOK_BEHIND_NOT) {
break;
} else if (e.type == MEM_START) {
@@ -419,7 +419,7 @@ abstract class StackMachine extends Matcher implements StackType {
}
}
}
-
+
protected final int posEnd() {
int k = stk;
while (true) {
@@ -429,12 +429,12 @@ abstract class StackMachine extends Matcher implements StackType {
e.type = VOID;
} else if (e.type == POS) {
e.type = VOID;
- break;
+ break;
}
}
return k;
}
-
+
protected final void stopBtEnd() {
int k = stk;
while (true) {
@@ -449,14 +449,14 @@ abstract class StackMachine extends Matcher implements StackType {
}
}
}
-
+
// int for consistency with other null check routines
protected final int nullCheck(int id, int s) {
int k = stk;
while (true) {
k--;
StackEntry e = stack[k];
-
+
if (e.type == NULL_CHECK_START) {
if (e.getNullCheckNum() == id) {
return e.getNullCheckPStr() == s ? 1 : 0;
@@ -464,14 +464,14 @@ abstract class StackMachine extends Matcher implements StackType {
}
}
}
-
+
protected final int nullCheckRec(int id, int s) {
int level = 0;
int k = stk;
while (true) {
k--;
StackEntry e = stack[k];
-
+
if (e.type == NULL_CHECK_START) {
if (e.getNullCheckNum() == id) {
if (level == 0) {
@@ -485,14 +485,14 @@ abstract class StackMachine extends Matcher implements StackType {
}
}
}
-
+
protected final int nullCheckMemSt(int id, int s) {
int k = stk;
int isNull;
while (true) {
k--;
StackEntry e = stack[k];
-
+
if (e.type == NULL_CHECK_START) {
if (e.getNullCheckNum() == id) {
if (e.getNullCheckPStr() != s) {
@@ -529,7 +529,7 @@ abstract class StackMachine extends Matcher implements StackType {
}
return isNull;
}
-
+
protected final int nullCheckMemStRec(int id, int s) {
int level = 0;
int k = stk;
@@ -580,14 +580,14 @@ abstract class StackMachine extends Matcher implements StackType {
}
return isNull;
}
-
+
protected final int getRepeat(int id) {
int level = 0;
int k = stk;
while (true) {
k--;
StackEntry e = stack[k];
-
+
if (e.type == REPEAT) {
if (level == 0) {
if (e.getRepeatNum() == id) return k;
@@ -599,15 +599,15 @@ abstract class StackMachine extends Matcher implements StackType {
}
}
}
-
+
protected final int sreturn() {
int level = 0;
int k = stk;
while (true) {
k--;
StackEntry e = stack[k];
-
- if (e.type == CALL_FRAME) {
+
+ if (e.type == CALL_FRAME) {
if (level == 0) {
return e.getCallFrameRetAddr();
} else {
diff --git a/src/org/joni/Syntax.java b/src/org/joni/Syntax.java
index b89abe9..74662a8 100644
--- a/src/org/joni/Syntax.java
+++ b/src/org/joni/Syntax.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -24,7 +24,7 @@ import static org.joni.constants.MetaChar.INEFFECTIVE_META_CHAR;
import org.joni.constants.SyntaxProperties;
public final class Syntax implements SyntaxProperties{
- private final int op;
+ private final int op;
private final int op2;
private final int behavior;
public final int options;
@@ -39,273 +39,273 @@ public final class Syntax implements SyntaxProperties{
}
public static class MetaCharTable {
- public final int esc;
+ public final int esc;
public final int anyChar;
public final int anyTime;
public final int zeroOrOneTime;
public final int oneOrMoreTime;
public final int anyCharAnyTime;
-
- public MetaCharTable(int esc, int anyChar, int anyTime,
+
+ public MetaCharTable(int esc, int anyChar, int anyTime,
int zeroOrOneTime, int oneOrMoreTime, int anyCharAnyTime) {
this.esc = esc;
this.anyChar = anyChar;
this.anyTime = anyTime;
this.zeroOrOneTime = zeroOrOneTime;
- this.oneOrMoreTime = oneOrMoreTime;
+ this.oneOrMoreTime = oneOrMoreTime;
this.anyCharAnyTime = anyCharAnyTime;
}
}
-
+
/**
* OP
- *
+ *
*/
protected boolean isOp(int opm) {
return (op & opm) != 0;
}
-
- public boolean opVariableMetaCharacters() {
+
+ public boolean opVariableMetaCharacters() {
return isOp(OP_VARIABLE_META_CHARACTERS);
}
-
- public boolean opDotAnyChar() {
+
+ public boolean opDotAnyChar() {
return isOp(OP_DOT_ANYCHAR);
}
- public boolean opAsteriskZeroInf() {
+ public boolean opAsteriskZeroInf() {
return isOp(OP_ASTERISK_ZERO_INF);
}
-
- public boolean opEscAsteriskZeroInf() {
+
+ public boolean opEscAsteriskZeroInf() {
return isOp(OP_ESC_ASTERISK_ZERO_INF);
}
- public boolean opPlusOneInf() {
+ public boolean opPlusOneInf() {
return isOp(OP_PLUS_ONE_INF);
}
-
- public boolean opEscPlusOneInf() {
+
+ public boolean opEscPlusOneInf() {
return isOp(OP_ESC_PLUS_ONE_INF);
}
- public boolean opQMarkZeroOne() {
+ public boolean opQMarkZeroOne() {
return isOp(OP_QMARK_ZERO_ONE);
}
-
- public boolean opEscQMarkZeroOne() {
+
+ public boolean opEscQMarkZeroOne() {
return isOp(OP_ESC_QMARK_ZERO_ONE);
}
-
- public boolean opBraceInterval() {
+
+ public boolean opBraceInterval() {
return isOp(OP_BRACE_INTERVAL);
}
-
- public boolean opEscBraceInterval() {
+
+ public boolean opEscBraceInterval() {
return isOp(OP_ESC_BRACE_INTERVAL);
}
- public boolean opVBarAlt() {
+ public boolean opVBarAlt() {
return isOp(OP_VBAR_ALT);
}
- public boolean opEscVBarAlt() {
+ public boolean opEscVBarAlt() {
return isOp(OP_ESC_VBAR_ALT);
}
-
- public boolean opLParenSubexp() {
+
+ public boolean opLParenSubexp() {
return isOp(OP_LPAREN_SUBEXP);
}
- public boolean opEscLParenSubexp() {
+ public boolean opEscLParenSubexp() {
return isOp(OP_ESC_LPAREN_SUBEXP);
}
-
- public boolean opEscAZBufAnchor() {
+
+ public boolean opEscAZBufAnchor() {
return isOp(OP_ESC_AZ_BUF_ANCHOR);
}
- public boolean opEscCapitalGBeginAnchor() {
+ public boolean opEscCapitalGBeginAnchor() {
return isOp(OP_ESC_CAPITAL_G_BEGIN_ANCHOR);
}
-
- public boolean opDecimalBackref() {
+
+ public boolean opDecimalBackref() {
return isOp(OP_DECIMAL_BACKREF);
}
- public boolean opBracketCC() {
+ public boolean opBracketCC() {
return isOp(OP_BRACKET_CC);
}
-
- public boolean opEscWWord() {
+
+ public boolean opEscWWord() {
return isOp(OP_ESC_W_WORD);
}
- public boolean opEscLtGtWordBeginEnd() {
+ public boolean opEscLtGtWordBeginEnd() {
return isOp(OP_ESC_LTGT_WORD_BEGIN_END);
}
public boolean opEscBWordBound() {
return isOp(OP_ESC_B_WORD_BOUND);
}
-
+
public boolean opEscSWhiteSpace() {
return isOp(OP_ESC_S_WHITE_SPACE);
}
-
- public boolean opEscDDigit() {
+
+ public boolean opEscDDigit() {
return isOp(OP_ESC_D_DIGIT);
}
- public boolean opLineAnchor() {
+ public boolean opLineAnchor() {
return isOp(OP_LINE_ANCHOR);
}
-
- public boolean opPosixBracket() {
+
+ public boolean opPosixBracket() {
return isOp(OP_POSIX_BRACKET);
}
-
- public boolean opQMarkNonGreedy() {
+
+ public boolean opQMarkNonGreedy() {
return isOp(OP_QMARK_NON_GREEDY);
}
-
- public boolean opEscControlChars() {
+
+ public boolean opEscControlChars() {
return isOp(OP_ESC_CONTROL_CHARS);
}
-
- public boolean opEscCControl() {
+
+ public boolean opEscCControl() {
return isOp(OP_ESC_C_CONTROL);
}
- public boolean opEscOctal3() {
+ public boolean opEscOctal3() {
return isOp(OP_ESC_OCTAL3);
}
-
- public boolean opEscXHex2() {
+
+ public boolean opEscXHex2() {
return isOp(OP_ESC_X_HEX2);
}
-
- public boolean opEscXBraceHex8() {
+
+ public boolean opEscXBraceHex8() {
return isOp(OP_ESC_X_BRACE_HEX8);
}
-
+
/**
* OP
- *
+ *
*/
protected boolean isOp2(int opm) {
return (op2 & opm) != 0;
}
-
- public boolean op2EscCapitalQQuote() {
+
+ public boolean op2EscCapitalQQuote() {
return isOp2(OP2_ESC_CAPITAL_Q_QUOTE);
- }
-
- public boolean op2QMarkGroupEffect() {
+ }
+
+ public boolean op2QMarkGroupEffect() {
return isOp2(OP2_QMARK_GROUP_EFFECT);
- }
+ }
- public boolean op2OptionPerl() {
+ public boolean op2OptionPerl() {
return isOp2(OP2_OPTION_PERL);
- }
+ }
- public boolean op2OptionRuby() {
+ public boolean op2OptionRuby() {
return isOp2(OP2_OPTION_RUBY);
- }
-
- public boolean op2PlusPossessiveRepeat() {
+ }
+
+ public boolean op2PlusPossessiveRepeat() {
return isOp2(OP2_PLUS_POSSESSIVE_REPEAT);
- }
+ }
- public boolean op2PlusPossessiveInterval() {
+ public boolean op2PlusPossessiveInterval() {
return isOp2(OP2_PLUS_POSSESSIVE_INTERVAL);
- }
-
- public boolean op2CClassSetOp() {
+ }
+
+ public boolean op2CClassSetOp() {
return isOp2(OP2_CCLASS_SET_OP);
- }
+ }
- public boolean op2QMarkLtNamedGroup() {
+ public boolean op2QMarkLtNamedGroup() {
return isOp2(OP2_QMARK_LT_NAMED_GROUP);
- }
+ }
- public boolean op2EscKNamedBackref() {
+ public boolean op2EscKNamedBackref() {
return isOp2(OP2_ESC_K_NAMED_BACKREF);
- }
-
- public boolean op2EscGSubexpCall() {
+ }
+
+ public boolean op2EscGSubexpCall() {
return isOp2(OP2_ESC_G_SUBEXP_CALL);
- }
+ }
- public boolean op2AtMarkCaptureHistory() {
+ public boolean op2AtMarkCaptureHistory() {
return isOp2(OP2_ATMARK_CAPTURE_HISTORY);
- }
-
- public boolean op2EscCapitalCBarControl() {
+ }
+
+ public boolean op2EscCapitalCBarControl() {
return isOp2(OP2_ESC_CAPITAL_C_BAR_CONTROL);
- }
+ }
- public boolean op2EscCapitalMBarMeta() {
+ public boolean op2EscCapitalMBarMeta() {
return isOp2(OP2_ESC_CAPITAL_M_BAR_META);
- }
-
- public boolean op2EscVVtab() {
+ }
+
+ public boolean op2EscVVtab() {
return isOp2(OP2_ESC_V_VTAB);
}
-
- public boolean op2EscUHex4() {
+
+ public boolean op2EscUHex4() {
return isOp2(OP2_ESC_U_HEX4);
- }
-
- public boolean op2EscGnuBufAnchor() {
+ }
+
+ public boolean op2EscGnuBufAnchor() {
return isOp2(OP2_ESC_GNU_BUF_ANCHOR);
- }
-
- public boolean op2EscPBraceCharProperty() {
+ }
+
+ public boolean op2EscPBraceCharProperty() {
return isOp2(OP2_ESC_P_BRACE_CHAR_PROPERTY);
- }
+ }
- public boolean op2EscPBraceCircumflexNot() {
+ public boolean op2EscPBraceCircumflexNot() {
return isOp2(OP2_ESC_P_BRACE_CIRCUMFLEX_NOT);
- }
+ }
- public boolean op2EscHXDigit() {
+ public boolean op2EscHXDigit() {
return isOp2(OP2_ESC_H_XDIGIT);
- }
-
- public boolean op2IneffectiveEscape() {
+ }
+
+ public boolean op2IneffectiveEscape() {
return isOp2(OP2_INEFFECTIVE_ESCAPE);
- }
-
+ }
+
/**
* BEHAVIOR
- *
+ *
*/
protected boolean isBehavior(int bvm) {
return (behavior & bvm) != 0;
}
-
+
public boolean contextIndepRepeatOps() {
- return isBehavior(CONTEXT_INDEP_REPEAT_OPS);
+ return isBehavior(CONTEXT_INDEP_REPEAT_OPS);
}
-
+
public boolean contextInvalidRepeatOps() {
- return isBehavior(CONTEXT_INVALID_REPEAT_OPS);
+ return isBehavior(CONTEXT_INVALID_REPEAT_OPS);
}
-
+
public boolean allowUnmatchedCloseSubexp() {
- return isBehavior(ALLOW_UNMATCHED_CLOSE_SUBEXP);
+ return isBehavior(ALLOW_UNMATCHED_CLOSE_SUBEXP);
}
-
+
public boolean allowInvalidInterval() {
- return isBehavior(ALLOW_INVALID_INTERVAL);
+ return isBehavior(ALLOW_INVALID_INTERVAL);
}
public boolean allowIntervalLowAbbrev() {
- return isBehavior(ALLOW_INTERVAL_LOW_ABBREV);
+ return isBehavior(ALLOW_INTERVAL_LOW_ABBREV);
}
-
+
public boolean strictCheckBackref() {
return isBehavior(STRICT_CHECK_BACKREF);
}
@@ -313,7 +313,7 @@ public final class Syntax implements SyntaxProperties{
public boolean differentLengthAltLookBehind() {
return isBehavior(DIFFERENT_LEN_ALT_LOOK_BEHIND);
}
-
+
public boolean captureOnlyNamedGroup() {
return isBehavior(CAPTURE_ONLY_NAMED_GROUP);
}
@@ -325,8 +325,8 @@ public final class Syntax implements SyntaxProperties{
public boolean fixedIntervalIsGreedyOnly() {
return isBehavior(FIXED_INTERVAL_IS_GREEDY_ONLY);
}
-
-
+
+
public boolean notNewlineInNegativeCC() {
return isBehavior(NOT_NEWLINE_IN_NEGATIVE_CC);
}
@@ -334,30 +334,30 @@ public final class Syntax implements SyntaxProperties{
public boolean backSlashEscapeInCC() {
return isBehavior(BACKSLASH_ESCAPE_IN_CC);
}
-
+
public boolean allowEmptyRangeInCC() {
return isBehavior(ALLOW_EMPTY_RANGE_IN_CC);
}
-
+
public boolean allowDoubleRangeOpInCC() {
return isBehavior(ALLOW_DOUBLE_RANGE_OP_IN_CC);
}
-
+
public boolean warnCCOpNotEscaped() {
return isBehavior(WARN_CC_OP_NOT_ESCAPED);
}
-
+
public boolean warnReduntantNestedRepeat() {
return isBehavior(WARN_REDUNDANT_NESTED_REPEAT);
}
-
+
public static final Syntax RUBY = new Syntax(
(( GNU_REGEX_OP | OP_QMARK_NON_GREEDY |
OP_ESC_OCTAL3 | OP_ESC_X_HEX2 |
OP_ESC_X_BRACE_HEX8 | OP_ESC_CONTROL_CHARS |
OP_ESC_C_CONTROL )
& ~OP_ESC_LTGT_WORD_BEGIN_END ),
-
+
( OP2_QMARK_GROUP_EFFECT |
OP2_OPTION_RUBY |
OP2_QMARK_LT_NAMED_GROUP | OP2_ESC_K_NAMED_BACKREF |
@@ -368,8 +368,8 @@ public final class Syntax implements SyntaxProperties{
OP2_CCLASS_SET_OP | OP2_ESC_CAPITAL_C_BAR_CONTROL |
OP2_ESC_CAPITAL_M_BAR_META | OP2_ESC_V_VTAB |
OP2_ESC_H_XDIGIT ),
-
- ( GNU_REGEX_BV |
+
+ ( GNU_REGEX_BV |
ALLOW_INTERVAL_LOW_ABBREV |
DIFFERENT_LEN_ALT_LOOK_BEHIND |
CAPTURE_ONLY_NAMED_GROUP |
@@ -377,9 +377,9 @@ public final class Syntax implements SyntaxProperties{
FIXED_INTERVAL_IS_GREEDY_ONLY |
WARN_CC_OP_NOT_ESCAPED |
WARN_REDUNDANT_NESTED_REPEAT ),
-
+
Option.NONE,
-
+
new MetaCharTable(
'\\', /* esc */
INEFFECTIVE_META_CHAR, /* anychar '.' */
@@ -389,14 +389,14 @@ public final class Syntax implements SyntaxProperties{
INEFFECTIVE_META_CHAR /* anychar anytime */
)
);
-
+
public static final Syntax DEFAULT = RUBY;
-
+
public static final Syntax ASIS = new Syntax(
0,
OP2_INEFFECTIVE_ESCAPE,
-
+
0,
Option.NONE,
@@ -410,17 +410,17 @@ public final class Syntax implements SyntaxProperties{
INEFFECTIVE_META_CHAR /* anychar anytime */
)
);
-
+
public static final Syntax PosixBasic = new Syntax(
(POSIX_COMMON_OP | OP_ESC_LPAREN_SUBEXP |
OP_ESC_BRACE_INTERVAL ),
-
+
0,
-
+
0,
-
+
( Option.SINGLELINE | Option.MULTILINE ),
-
+
new MetaCharTable(
'\\', /* esc */
INEFFECTIVE_META_CHAR, /* anychar '.' */
@@ -428,23 +428,23 @@ public final class Syntax implements SyntaxProperties{
INEFFECTIVE_META_CHAR, /* zero or one time '?' */
INEFFECTIVE_META_CHAR, /* one or more time '+' */
INEFFECTIVE_META_CHAR /* anychar anytime */
- )
+ )
);
-
+
public static final Syntax PosixExtended = new Syntax(
( POSIX_COMMON_OP | OP_LPAREN_SUBEXP |
OP_BRACE_INTERVAL |
OP_PLUS_ONE_INF | OP_QMARK_ZERO_ONE |OP_VBAR_ALT ),
-
+
0,
-
- ( CONTEXT_INDEP_ANCHORS |
- CONTEXT_INDEP_REPEAT_OPS | CONTEXT_INVALID_REPEAT_OPS |
+
+ ( CONTEXT_INDEP_ANCHORS |
+ CONTEXT_INDEP_REPEAT_OPS | CONTEXT_INVALID_REPEAT_OPS |
ALLOW_UNMATCHED_CLOSE_SUBEXP |
ALLOW_DOUBLE_RANGE_OP_IN_CC ),
-
- ( Option.SINGLELINE | Option.MULTILINE ),
-
+
+ ( Option.SINGLELINE | Option.MULTILINE ),
+
new MetaCharTable(
'\\', /* esc */
INEFFECTIVE_META_CHAR, /* anychar '.' */
@@ -452,9 +452,9 @@ public final class Syntax implements SyntaxProperties{
INEFFECTIVE_META_CHAR, /* zero or one time '?' */
INEFFECTIVE_META_CHAR, /* one or more time '+' */
INEFFECTIVE_META_CHAR /* anychar anytime */
- )
+ )
);
-
+
public static final Syntax Emacs = new Syntax(
( OP_DOT_ANYCHAR | OP_BRACKET_CC |
OP_ESC_BRACE_INTERVAL |
@@ -462,13 +462,13 @@ public final class Syntax implements SyntaxProperties{
OP_ASTERISK_ZERO_INF | OP_PLUS_ONE_INF |
OP_QMARK_ZERO_ONE | OP_DECIMAL_BACKREF |
OP_LINE_ANCHOR | OP_ESC_CONTROL_CHARS ),
-
+
OP2_ESC_GNU_BUF_ANCHOR,
-
+
ALLOW_EMPTY_RANGE_IN_CC,
Option.NONE,
-
+
new MetaCharTable(
'\\', /* esc */
INEFFECTIVE_META_CHAR, /* anychar '.' */
@@ -476,9 +476,9 @@ public final class Syntax implements SyntaxProperties{
INEFFECTIVE_META_CHAR, /* zero or one time '?' */
INEFFECTIVE_META_CHAR, /* one or more time '+' */
INEFFECTIVE_META_CHAR /* anychar anytime */
- )
+ )
);
-
+
public static final Syntax Grep = new Syntax(
( OP_DOT_ANYCHAR | OP_BRACKET_CC | OP_POSIX_BRACKET |
OP_ESC_BRACE_INTERVAL | OP_ESC_LPAREN_SUBEXP |
@@ -487,13 +487,13 @@ public final class Syntax implements SyntaxProperties{
OP_ESC_QMARK_ZERO_ONE | OP_LINE_ANCHOR |
OP_ESC_W_WORD | OP_ESC_B_WORD_BOUND |
OP_ESC_LTGT_WORD_BEGIN_END | OP_DECIMAL_BACKREF ),
-
+
0,
-
+
( ALLOW_EMPTY_RANGE_IN_CC | NOT_NEWLINE_IN_NEGATIVE_CC ),
Option.NONE,
-
+
new MetaCharTable(
'\\', /* esc */
INEFFECTIVE_META_CHAR, /* anychar '.' */
@@ -501,14 +501,14 @@ public final class Syntax implements SyntaxProperties{
INEFFECTIVE_META_CHAR, /* zero or one time '?' */
INEFFECTIVE_META_CHAR, /* one or more time '+' */
INEFFECTIVE_META_CHAR /* anychar anytime */
- )
+ )
);
-
+
public static final Syntax GnuRegex = new Syntax(
GNU_REGEX_OP,
0,
GNU_REGEX_BV,
-
+
Option.NONE,
new MetaCharTable(
@@ -520,23 +520,23 @@ public final class Syntax implements SyntaxProperties{
INEFFECTIVE_META_CHAR /* anychar anytime */
)
);
-
+
public static final Syntax Java = new Syntax(
(( GNU_REGEX_OP | OP_QMARK_NON_GREEDY |
OP_ESC_CONTROL_CHARS | OP_ESC_C_CONTROL |
OP_ESC_OCTAL3 | OP_ESC_X_HEX2 )
& ~OP_ESC_LTGT_WORD_BEGIN_END ),
-
+
( OP2_ESC_CAPITAL_Q_QUOTE | OP2_QMARK_GROUP_EFFECT |
OP2_OPTION_PERL | OP2_PLUS_POSSESSIVE_REPEAT |
OP2_PLUS_POSSESSIVE_INTERVAL | OP2_CCLASS_SET_OP |
OP2_ESC_V_VTAB | OP2_ESC_U_HEX4 |
OP2_ESC_P_BRACE_CHAR_PROPERTY ),
-
+
( GNU_REGEX_BV | DIFFERENT_LEN_ALT_LOOK_BEHIND ),
-
+
Option.SINGLELINE,
-
+
new MetaCharTable(
'\\', /* esc */
INEFFECTIVE_META_CHAR, /* anychar '.' */
@@ -544,9 +544,9 @@ public final class Syntax implements SyntaxProperties{
INEFFECTIVE_META_CHAR, /* zero or one time '?' */
INEFFECTIVE_META_CHAR, /* one or more time '+' */
INEFFECTIVE_META_CHAR /* anychar anytime */
- )
+ )
);
-
+
public static final Syntax Perl = new Syntax(
(( GNU_REGEX_OP | OP_QMARK_NON_GREEDY |
OP_ESC_OCTAL3 | OP_ESC_X_HEX2 |
@@ -558,11 +558,11 @@ public final class Syntax implements SyntaxProperties{
OP2_QMARK_GROUP_EFFECT | OP2_OPTION_PERL |
OP2_ESC_P_BRACE_CHAR_PROPERTY |
OP2_ESC_P_BRACE_CIRCUMFLEX_NOT ),
-
+
GNU_REGEX_BV,
-
+
Option.SINGLELINE,
-
+
new MetaCharTable(
'\\', /* esc */
INEFFECTIVE_META_CHAR, /* anychar '.' */
@@ -570,16 +570,16 @@ public final class Syntax implements SyntaxProperties{
INEFFECTIVE_META_CHAR, /* zero or one time '?' */
INEFFECTIVE_META_CHAR, /* one or more time '+' */
INEFFECTIVE_META_CHAR /* anychar anytime */
- )
+ )
);
-
+
public static final Syntax PerlNG = new Syntax(
(( GNU_REGEX_OP | OP_QMARK_NON_GREEDY |
OP_ESC_OCTAL3 | OP_ESC_X_HEX2 |
OP_ESC_X_BRACE_HEX8 | OP_ESC_CONTROL_CHARS |
OP_ESC_C_CONTROL )
& ~OP_ESC_LTGT_WORD_BEGIN_END ),
-
+
( OP2_ESC_CAPITAL_Q_QUOTE |
OP2_QMARK_GROUP_EFFECT | OP2_OPTION_PERL |
OP2_ESC_P_BRACE_CHAR_PROPERTY |
@@ -587,20 +587,20 @@ public final class Syntax implements SyntaxProperties{
OP2_QMARK_LT_NAMED_GROUP |
OP2_ESC_K_NAMED_BACKREF |
OP2_ESC_G_SUBEXP_CALL ),
-
+
( GNU_REGEX_BV |
CAPTURE_ONLY_NAMED_GROUP |
ALLOW_MULTIPLEX_DEFINITION_NAME ),
-
+
Option.SINGLELINE,
-
+
new MetaCharTable(
- '\\', /* esc */
+ '\\', /* esc */
INEFFECTIVE_META_CHAR, /* anychar '.' */
INEFFECTIVE_META_CHAR, /* anytime '*' */
INEFFECTIVE_META_CHAR, /* zero or one time '?' */
INEFFECTIVE_META_CHAR, /* one or more time '+' */
INEFFECTIVE_META_CHAR /* anychar anytime */
- )
+ )
);
}
diff --git a/src/org/joni/Token.java b/src/org/joni/Token.java
index 16e2b1a..8ad7330 100644
--- a/src/org/joni/Token.java
+++ b/src/org/joni/Token.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -153,7 +153,7 @@ final class Token {
}
void setCallGNum(int gnum) {
INT3 = gnum;
- }
+ }
// prop union member
int getPropCType() {
diff --git a/src/org/joni/UnsetAddrList.java b/src/org/joni/UnsetAddrList.java
index 8787972..34e472d 100644
--- a/src/org/joni/UnsetAddrList.java
+++ b/src/org/joni/UnsetAddrList.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -28,14 +28,14 @@ public final class UnsetAddrList {
int num;
Node[]targets;
int[]offsets;
-
+
public UnsetAddrList(int size) {
targets = new Node[size];
offsets = new int[size];
}
-
+
public void add(int offset, Node node) {
- if (num >= offsets.length) {
+ if (num >= offsets.length) {
Node []ttmp = new Node[targets.length << 1];
System.arraycopy(targets, 0, ttmp, 0, num);
targets = ttmp;
@@ -45,10 +45,10 @@ public final class UnsetAddrList {
}
targets[num] = node;
offsets[num] = offset;
-
+
num++;
}
-
+
public void fix(Regex regex) {
for (int i=0; i<num; i++) {
EncloseNode en = (EncloseNode)targets[i];
@@ -56,7 +56,7 @@ public final class UnsetAddrList {
regex.code[offsets[i]] = en.callAddr; // is this safe ?
}
}
-
+
public String toString() {
StringBuilder value = new StringBuilder();
if (num > 0) {
diff --git a/src/org/joni/WarnCallback.java b/src/org/joni/WarnCallback.java
index 351146b..b5f2a27 100644
--- a/src/org/joni/WarnCallback.java
+++ b/src/org/joni/WarnCallback.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
@@ -23,10 +23,11 @@ package org.joni;
* @author <a href="mailto:ola.bini at gmail.com">Ola Bini</a>
*/
public interface WarnCallback {
- WarnCallback DEFAULT = new WarnCallback(){
- public void warn(String message) {
- System.err.println(message);
- }
- };
+ WarnCallback DEFAULT = new WarnCallback() {
+ public void warn(String message) {
+ System.err.println(message);
+ }
+ };
+
void warn(String message);
-}// WarnCallback
+}
diff --git a/src/org/joni/NativeMachine.java b/src/org/joni/Warnings.java
similarity index 69%
copy from src/org/joni/NativeMachine.java
copy to src/org/joni/Warnings.java
index 6fc5dbb..80e1519 100644
--- a/src/org/joni/NativeMachine.java
+++ b/src/org/joni/Warnings.java
@@ -1,27 +1,26 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni;
-public abstract class NativeMachine extends Matcher {
-
- protected NativeMachine(Regex regex, byte[]bytes, int p, int end) {
- super(regex, bytes, p, end);
- }
+public interface Warnings {
+ final String INVALID_BACKREFERENCE = "invalid back reference";
+ final String INVALID_SUBEXP_CALL = "invalid subexp call";
+ final String INVALID_UNICODE_PROPERTY = "invalid Unicode Property \\<%n>";
}
diff --git a/src/org/joni/ast/AnchorNode.java b/src/org/joni/ast/AnchorNode.java
index cccbc49..988d994 100644
--- a/src/org/joni/ast/AnchorNode.java
+++ b/src/org/joni/ast/AnchorNode.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.ast;
@@ -30,32 +30,32 @@ public final class AnchorNode extends Node implements AnchorType {
this.type = type;
charLength = -1;
}
-
+
@Override
public int getType() {
return ANCHOR;
}
-
+
@Override
protected void setChild(Node newChild) {
target = newChild;
}
-
+
@Override
protected Node getChild() {
return target;
- }
-
+ }
+
public void setTarget(Node tgt) {
target = tgt;
- tgt.parent = this;
+ tgt.parent = this;
}
-
+
@Override
public String getName() {
return "Anchor";
}
-
+
@Override
public String toString(int level) {
StringBuilder value = new StringBuilder();
@@ -63,7 +63,7 @@ public final class AnchorNode extends Node implements AnchorType {
value.append("\n target: " + pad(target, level + 1));
return value.toString();
}
-
+
public String typeToString() {
StringBuilder type = new StringBuilder();
if (isType(BEGIN_BUF)) type.append("BEGIN_BUF ");
@@ -82,11 +82,11 @@ public final class AnchorNode extends Node implements AnchorType {
if (isType(LOOK_BEHIND_NOT)) type.append("LOOK_BEHIND_NOT ");
if (isType(ANYCHAR_STAR)) type.append("ANYCHAR_STAR ");
if (isType(ANYCHAR_STAR_ML)) type.append("ANYCHAR_STAR_ML ");
- return type.toString();
+ return type.toString();
}
private boolean isType(int type) {
- return (this.type & type) != 0;
+ return (this.type & type) != 0;
}
}
diff --git a/src/org/joni/ast/AnyCharNode.java b/src/org/joni/ast/AnyCharNode.java
index d349d8c..5b4f9b6 100644
--- a/src/org/joni/ast/AnyCharNode.java
+++ b/src/org/joni/ast/AnyCharNode.java
@@ -1,40 +1,40 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.ast;
public final class AnyCharNode extends Node {
public AnyCharNode(){}
-
+
@Override
public int getType() {
return CANY;
}
-
+
@Override
public String getName() {
return "Any Char";
- }
-
+ }
+
@Override
public String toString(int level) {
String value = "";
return value;
- }
+ }
}
diff --git a/src/org/joni/ast/BackRefNode.java b/src/org/joni/ast/BackRefNode.java
index 040fb81..603cbe7 100644
--- a/src/org/joni/ast/BackRefNode.java
+++ b/src/org/joni/ast/BackRefNode.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.ast;
@@ -24,49 +24,49 @@ import org.joni.exception.ErrorMessages;
import org.joni.exception.ValueException;
public final class BackRefNode extends StateNode {
- //private static int NODE_BACKREFS_SIZE = 6;
-
+ //private static int NODE_BACKREFS_SIZE = 6;
+
//int state;
public int backNum;
public int back[];
-
+
public int nestLevel;
-
+
public BackRefNode(int backNum, int[]backRefs, boolean byName, ScanEnvironment env) {
this.backNum = backNum;
if (byName) setNameRef();
-
+
for (int i=0; i<backNum; i++) {
if (backRefs[i] <= env.numMem && env.memNodes[backRefs[i]] == null) {
setRecursion(); /* /...(\1).../ */
break;
}
}
-
+
back = new int[backNum];
System.arraycopy(backRefs, 0, back, 0, backNum); // shall we really dup it ???
}
-
+
// #ifdef USE_BACKREF_AT_LEVEL
public BackRefNode(int backNum, int[]backRefs, boolean byName, boolean existLevel, int nestLevel, ScanEnvironment env) {
this(backNum, backRefs, byName, env);
-
+
if (existLevel) {
//state |= NST_NEST_LEVEL;
setNestLevel();
this.nestLevel = nestLevel;
}
}
-
+
@Override
public int getType() {
return BREF;
- }
-
+ }
+
@Override
public String getName() {
return "Back Ref";
- }
+ }
@Override
public String toString(int level) {
@@ -78,12 +78,12 @@ public final class BackRefNode extends StateNode {
value.append("\n nextLevel: " + nestLevel);
return value.toString();
}
-
+
public void renumber(int[]map) {
if (!isNameRef()) throw new ValueException(ErrorMessages.ERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED);
-
+
int oldNum = backNum;
-
+
int pos = 0;
for (int i=0; i<oldNum; i++) {
int n = map[back[i]];
@@ -94,5 +94,5 @@ public final class BackRefNode extends StateNode {
}
backNum = pos;
}
-
+
}
diff --git a/src/org/joni/ast/CClassNode.java b/src/org/joni/ast/CClassNode.java
index 40c7c90..7927023 100644
--- a/src/org/joni/ast/CClassNode.java
+++ b/src/org/joni/ast/CClassNode.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.ast;
@@ -24,6 +24,7 @@ import org.jcodings.Encoding;
import org.jcodings.IntHolder;
import org.jcodings.constants.CharacterType;
import org.jcodings.exception.EncodingException;
+import org.jcodings.specific.ASCIIEncoding;
import org.joni.BitSet;
import org.joni.CodeRangeBuffer;
import org.joni.Config;
@@ -38,29 +39,35 @@ import org.joni.exception.ValueException;
public final class CClassNode extends Node {
private static final int FLAG_NCCLASS_NOT = 1<<0;
private static final int FLAG_NCCLASS_SHARE = 1<<1;
-
+
int flags;
public final BitSet bs = new BitSet(); // conditional creation ?
public CodeRangeBuffer mbuf; /* multi-byte info or NULL */
-
+
private int ctype; // for hashing purposes
- private Encoding enc; // ...
+ private Encoding enc; // ...
// node_new_cclass
public CClassNode() {}
-
+
public CClassNode(int ctype, Encoding enc, boolean not, int sbOut, int[]ranges) {
this(not, sbOut, ranges);
this.ctype = ctype;
this.enc = enc;
}
-
+
+ public void clear() {
+ bs.clear();
+ flags = 0;
+ mbuf = null;
+ }
+
// node_new_cclass_by_codepoint_range, only used by shared Char Classes
public CClassNode(boolean not, int sbOut, int[]ranges) {
if (not) setNot();
// bs.clear();
-
+
if (sbOut > 0 && ranges != null) {
int n = ranges[0];
for (int i=0; i<n; i++) {
@@ -71,30 +78,30 @@ public final class CClassNode extends Node {
setupBuffer(ranges);
return;
}
- bs.set(j);
+ bs.set(j);
}
}
}
setupBuffer(ranges);
}
-
+
@Override
public int getType() {
- return CCLASS;
+ return CCLASS;
}
-
+
@Override
public String getName() {
return "Character Class";
}
-
+
@Override
public boolean equals(Object other) {
if (!(other instanceof CClassNode)) return false;
CClassNode cc = (CClassNode)other;
return ctype == cc.ctype && isNot() == cc.isNot() && enc == cc.enc;
}
-
+
@Override
public int hashCode() {
if (Config.USE_SHARED_CCLASS_TABLE) {
@@ -107,51 +114,51 @@ public final class CClassNode extends Node {
return super.hashCode();
}
}
-
+
@Override
public String toString(int level) {
StringBuilder value = new StringBuilder();
value.append("\n flags: " + flagsToString());
value.append("\n bs: " + pad(bs, level + 1));
value.append("\n mbuf: " + pad(mbuf, level + 1));
-
+
return value.toString();
- }
-
+ }
+
public String flagsToString() {
StringBuilder flags = new StringBuilder();
if (isNot()) flags.append("NOT ");
if (isShare()) flags.append("SHARE ");
return flags.toString();
}
-
- private void setupBuffer(int[]ranges) {
+
+ private void setupBuffer(int[]ranges) {
if (ranges != null) {
if (ranges[0] == 0) return;
mbuf = new CodeRangeBuffer(ranges);
}
}
-
+
public boolean isEmpty() {
return mbuf == null && bs.isEmpty();
}
-
+
public void addCodeRangeToBuf(int from, int to) {
mbuf = CodeRangeBuffer.addCodeRangeToBuff(mbuf, from, to);
}
-
+
public void addCodeRange(ScanEnvironment env, int from, int to) {
mbuf = CodeRangeBuffer.addCodeRange(mbuf, env, from, to);
}
-
+
public void addAllMultiByteRange(Encoding enc) {
mbuf = CodeRangeBuffer.addAllMultiByteRange(enc, mbuf);
}
-
+
public void clearNotFlag(Encoding enc) {
if (isNot()) {
bs.invert();
-
+
if (!enc.isSingleByte()) {
mbuf = CodeRangeBuffer.notCodeRangeBuff(enc, mbuf);
}
@@ -173,41 +180,41 @@ public final class CClassNode extends Node {
bsr1.invertTo(bs1);
bsr1 = bs1;
}
-
+
if (not2) {
BitSet bs2 = new BitSet();
bsr2.invertTo(bs2);
bsr2 = bs2;
}
-
+
bsr1.and(bsr2);
-
+
if (bsr1 != bs) {
bs.copy(bsr1);
bsr1 = bs;
}
-
+
if (not1) {
bs.invert();
}
-
+
CodeRangeBuffer pbuf = null;
-
+
if (!enc.isSingleByte()) {
- if (not1 && not2) {
+ if (not1 && not2) {
pbuf = CodeRangeBuffer.orCodeRangeBuff(enc, buf1, false, buf2, false);
} else {
pbuf = CodeRangeBuffer.andCodeRangeBuff(buf1, not1, buf2, not2);
-
+
if (not1) {
pbuf = CodeRangeBuffer.notCodeRangeBuff(enc, pbuf);
}
}
mbuf = pbuf;
}
-
+
}
-
+
// or_cclass
public void or(CClassNode other, Encoding enc) {
boolean not1 = isNot();
@@ -216,30 +223,30 @@ public final class CClassNode extends Node {
boolean not2 = other.isNot();
BitSet bsr2 = other.bs;
CodeRangeBuffer buf2 = other.mbuf;
-
+
if (not1) {
BitSet bs1 = new BitSet();
bsr1.invertTo(bs1);
bsr1 = bs1;
}
-
+
if (not2) {
BitSet bs2 = new BitSet();
bsr2.invertTo(bs2);
bsr2 = bs2;
}
-
+
bsr1.or(bsr2);
-
+
if (bsr1 != bs) {
bs.copy(bsr1);
bsr1 = bs;
}
-
+
if (not1) {
bs.invert();
}
-
+
if (!enc.isSingleByte()) {
CodeRangeBuffer pbuf = null;
if (not1 && not2) {
@@ -247,13 +254,13 @@ public final class CClassNode extends Node {
} else {
pbuf = CodeRangeBuffer.orCodeRangeBuff(enc, buf1, not1, buf2, not2);
if (not1) {
- pbuf = CodeRangeBuffer.notCodeRangeBuff(enc, pbuf);
+ pbuf = CodeRangeBuffer.notCodeRangeBuff(enc, pbuf);
}
}
mbuf = pbuf;
}
}
-
+
// add_ctype_to_cc_by_range // Encoding out!
public void addCTypeByRange(int ctype, boolean not, Encoding enc, int sbOut, int mbr[]) {
int n = mbr[0];
@@ -262,14 +269,21 @@ public final class CClassNode extends Node {
for (int i=0; i<n; i++) {
for (int j=mbr[i * 2 + 1]; j<=mbr[i * 2 + 2]; j++) {
if (j >= sbOut) {
- if (j == mbr[i * 2 + 2]) {
- i++;
- } else if (j > mbr[i * 2 + 1]) {
- addCodeRangeToBuf(j, mbr[i * 2 + 2]);
- i++;
+ if (Config.VANILLA) {
+ if (j == mbr[i * 2 + 2]) {
+ i++;
+ } else if (j > mbr[i * 2 + 1]) {
+ addCodeRangeToBuf(j, mbr[i * 2 + 2]);
+ i++;
+ }
+ } else {
+ if (j >= mbr[i * 2 + 1]) {
+ addCodeRangeToBuf(j, mbr[i * 2 + 2]);
+ i++;
+ }
}
// !goto sb_end!, remove duplication!
- for (; i<n; i++) {
+ for (; i<n; i++) {
addCodeRangeToBuf(mbr[2 * i + 1], mbr[2 * i + 2]);
}
return;
@@ -278,13 +292,13 @@ public final class CClassNode extends Node {
}
}
// !sb_end:!
- for (int i=0; i<n; i++) {
+ for (int i=0; i<n; i++) {
addCodeRangeToBuf(mbr[2 * i + 1], mbr[2 * i + 2]);
}
-
+
} else {
int prev = 0;
-
+
for (int i=0; i<n; i++) {
for (int j=prev; j < mbr[2 * i + 1]; j++) {
if (j >= sbOut) {
@@ -305,7 +319,7 @@ public final class CClassNode extends Node {
for (int j=prev; j<sbOut; j++) {
bs.set(j);
}
-
+
// !sb_end2:!
prev = sbOut;
for (int i=0; i<n; i++) {
@@ -315,12 +329,33 @@ public final class CClassNode extends Node {
if (prev < 0x7fffffff/*!!!*/) addCodeRangeToBuf(prev, 0x7fffffff);
}
}
-
+
public void addCType(int ctype, boolean not, ScanEnvironment env, IntHolder sbOut) {
Encoding enc = env.enc;
- int[]ranges = enc.ctypeCodeRange(ctype, sbOut);
+ if (Config.NON_UNICODE_SDW) {
+ switch(ctype) {
+ case CharacterType.D:
+ case CharacterType.S:
+ case CharacterType.W:
+ ctype ^= CharacterType.SPECIAL_MASK;
+ if (not) {
+ for (int c = 0; c < BitSet.SINGLE_BYTE_SIZE; c++) {
+ if (!ASCIIEncoding.INSTANCE.isCodeCType(c, ctype)) bs.set(c);
+ //if ((AsciiTables.AsciiCtypeTable[c] & (1 << ctype)) == 0) bs.set(c);
+ }
+ addAllMultiByteRange(enc);
+ } else {
+ for (int c = 0; c < BitSet.SINGLE_BYTE_SIZE; c++) {
+ if (ASCIIEncoding.INSTANCE.isCodeCType(c, ctype)) bs.set(c);
+ //if ((AsciiTables.AsciiCtypeTable[c] & (1 << ctype)) != 0) bs.set(c);
+ }
+ }
+ return;
+ }
+ }
+ int[]ranges = enc.ctypeCodeRange(ctype, sbOut);
if (ranges != null) {
addCTypeByRange(ctype, not, enc, sbOut.value, ranges);
return;
@@ -349,7 +384,7 @@ public final class CClassNode extends Node {
}
}
break;
-
+
case CharacterType.GRAPH:
case CharacterType.PRINT:
if (not) {
@@ -363,7 +398,7 @@ public final class CClassNode extends Node {
addAllMultiByteRange(enc);
}
break;
-
+
case CharacterType.WORD:
if (!not) {
for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
@@ -375,17 +410,17 @@ public final class CClassNode extends Node {
for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
try {
if (enc.codeToMbcLength(c) > 0 && /* check invalid code point */
- !enc.isWord(c)) bs.set(c);
+ !enc.isWord(c)) bs.set(c);
} catch (EncodingException ve) {};
}
}
break;
-
+
default:
throw new InternalException(ErrorMessages.ERR_PARSER_BUG);
} // switch
}
-
+
public static final class CCStateArg {
public int v;
public int vs;
@@ -395,12 +430,12 @@ public final class CClassNode extends Node {
public CCVALTYPE type;
public CCSTATE state;
}
-
+
public void nextStateClass(CCStateArg arg, ScanEnvironment env) {
if (arg.state == CCSTATE.RANGE) throw new SyntaxException(ErrorMessages.ERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE);
-
+
if (arg.state == CCSTATE.VALUE && arg.type != CCVALTYPE.CLASS) {
- if (arg.type == CCVALTYPE.SB) {
+ if (arg.type == CCVALTYPE.SB) {
bs.set(arg.vs);
} else if (arg.type == CCVALTYPE.CODE_POINT) {
addCodeRange(env, arg.vs, arg.vs);
@@ -409,24 +444,24 @@ public final class CClassNode extends Node {
arg.state = CCSTATE.VALUE;
arg.type = CCVALTYPE.CLASS;
}
-
+
public void nextStateValue(CCStateArg arg, ScanEnvironment env) {
switch(arg.state) {
case VALUE:
if (arg.type == CCVALTYPE.SB) {
if (arg.vs > 0xff) throw new ValueException(ErrorMessages.ERR_INVALID_CODE_POINT_VALUE);
- bs.set(arg.vs);
+ bs.set(arg.vs);
} else if (arg.type == CCVALTYPE.CODE_POINT) {
addCodeRange(env, arg.vs, arg.vs);
}
break;
-
+
case RANGE:
if (arg.inType == arg.type) {
if (arg.inType == CCVALTYPE.SB) {
if (arg.vs > 0xff || arg.v > 0xff) throw new ValueException(ErrorMessages.ERR_INVALID_CODE_POINT_VALUE);
-
+
if (arg.vs > arg.v) {
if (env.syntax.allowEmptyRangeInCC()) {
// goto ccs_range_end
@@ -448,7 +483,7 @@ public final class CClassNode extends Node {
break;
} else {
throw new ValueException(ErrorMessages.ERR_EMPTY_RANGE_IN_CHAR_CLASS);
- }
+ }
}
bs.setRange(arg.vs, arg.v < 0xff ? arg.v : 0xff);
addCodeRange(env, arg.vs, arg.v);
@@ -456,26 +491,26 @@ public final class CClassNode extends Node {
// ccs_range_end:
arg.state = CCSTATE.COMPLETE;
break;
-
+
case COMPLETE:
case START:
arg.state = CCSTATE.VALUE;
break;
-
+
default:
break;
} // switch
-
+
arg.vsIsRaw = arg.vIsRaw;
arg.vs = arg.v;
arg.type = arg.inType;
}
-
+
// onig_is_code_in_cc_len
public boolean isCodeInCCLength(int encLength, int code) {
boolean found;
-
+
if (encLength > 1 || code >= BitSet.SINGLE_BYTE_SIZE) {
if (mbuf == null) {
found = false;
@@ -485,7 +520,7 @@ public final class CClassNode extends Node {
} else {
found = bs.at(code);
}
-
+
if (isNot()) {
return !found;
} else {
@@ -493,7 +528,7 @@ public final class CClassNode extends Node {
}
}
- // onig_is_code_in_cc
+ // onig_is_code_in_cc
public boolean isCodeInCC(Encoding enc, int code) {
int len;
if (enc.minLength() > 1) {
@@ -501,31 +536,31 @@ public final class CClassNode extends Node {
} else {
len = enc.codeToMbcLength(code);
}
- return isCodeInCCLength(len, code);
+ return isCodeInCCLength(len, code);
}
-
+
public void setNot() {
flags |= FLAG_NCCLASS_NOT;
}
-
+
public void clearNot() {
flags &= ~FLAG_NCCLASS_NOT;
}
-
+
public boolean isNot() {
return (flags & FLAG_NCCLASS_NOT) != 0;
}
-
+
public void setShare() {
flags |= FLAG_NCCLASS_SHARE;
}
-
+
public void clearShare() {
flags &= ~FLAG_NCCLASS_SHARE;
}
-
+
public boolean isShare() {
return (flags & FLAG_NCCLASS_SHARE) != 0;
}
-
+
}
diff --git a/src/org/joni/ast/CTypeNode.java b/src/org/joni/ast/CTypeNode.java
index 093216a..017ce54 100644
--- a/src/org/joni/ast/CTypeNode.java
+++ b/src/org/joni/ast/CTypeNode.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.ast;
@@ -22,29 +22,29 @@ package org.joni.ast;
public final class CTypeNode extends Node {
public int ctype;
public boolean not;
-
+
public CTypeNode(int type, boolean not) {
this.ctype= type;
this.not = not;
}
-
+
@Override
public int getType() {
return CTYPE;
}
-
+
@Override
public String getName() {
return "Character Type";
- }
-
+ }
+
@Override
public String toString(int level) {
StringBuilder value = new StringBuilder();
value.append("\n ctype: " + ctype);
value.append("\n not: " + not);
-
+
return value.toString();
}
-
+
}
diff --git a/src/org/joni/ast/CallNode.java b/src/org/joni/ast/CallNode.java
index 8261f75..a361544 100644
--- a/src/org/joni/ast/CallNode.java
+++ b/src/org/joni/ast/CallNode.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.ast;
@@ -32,24 +32,24 @@ public final class CallNode extends StateNode {
public int groupNum;
public Node target; // is it an EncloseNode always ?
public UnsetAddrList unsetAddrList;
-
+
public CallNode(byte[]name, int nameP, int nameEnd, int gnum) {
this.name = name;
this.nameP = nameP;
this.nameEnd = nameEnd;
this.groupNum = gnum; /* call by number if gnum != 0 */
}
-
+
@Override
public int getType() {
return CALL;
}
-
+
@Override
protected void setChild(Node newChild) {
target = newChild;
}
-
+
@Override
protected Node getChild() {
return target;
@@ -57,21 +57,21 @@ public final class CallNode extends StateNode {
public void setTarget(Node tgt) {
target = tgt;
- tgt.parent = this;
- }
+ tgt.parent = this;
+ }
@Override
public String getName() {
return "Call";
}
-
+
@Override
public void verifyTree(Set<Node> set, WarnCallback warnings) {
if (target == null || target.parent == this)
warnings.warn(this.getAddressName() + " doesn't point to a target or the target has been stolen");
// do not recurse here
- }
-
+ }
+
@Override
public String toString(int level) {
StringBuilder value = new StringBuilder(super.toString(level));
@@ -79,8 +79,8 @@ public final class CallNode extends StateNode {
value.append("\n groupNum: " + groupNum);
value.append("\n target: " + pad(target.getAddressName(), level + 1));
value.append("\n unsetAddrList: " + pad(unsetAddrList, level + 1));
-
+
return value.toString();
- }
-
+ }
+
}
diff --git a/src/org/joni/ast/ConsAltNode.java b/src/org/joni/ast/ConsAltNode.java
index 3d7f784..7d456fe 100644
--- a/src/org/joni/ast/ConsAltNode.java
+++ b/src/org/joni/ast/ConsAltNode.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.ast;
@@ -30,27 +30,27 @@ public final class ConsAltNode extends Node {
public Node car;
public ConsAltNode cdr;
private int type; // List or Alt
-
+
private ConsAltNode(Node car, ConsAltNode cdr, int type) {
this.car = car;
if (car != null) car.parent = this;
this.cdr = cdr;
if (cdr != null) cdr.parent = this;
-
+
this.type = type;
}
-
+
public static ConsAltNode newAltNode(Node left, ConsAltNode right) {
return new ConsAltNode(left, right, ALT);
}
-
+
public static ConsAltNode newListNode(Node left, ConsAltNode right) {
return new ConsAltNode(left, right, LIST);
}
-
+
public static ConsAltNode listAdd(ConsAltNode list, Node x) {
ConsAltNode n = newListNode(x, null);
-
+
if (list != null) {
while (list.cdr != null) {
list = list.cdr;
@@ -59,25 +59,25 @@ public final class ConsAltNode extends Node {
}
return n;
}
-
+
public void toListNode() {
type = LIST;
}
-
+
public void toAltNode() {
type = ALT;
}
-
+
@Override
- public int getType() {
+ public int getType() {
return type;
}
-
+
@Override
protected void setChild(Node newChild) {
car = newChild;
- }
-
+ }
+
@Override
protected Node getChild() {
return car;
@@ -95,10 +95,9 @@ public final class ConsAltNode extends Node {
withCan.cdr = tmp;
}
}
-
super.swap(with);
- }
-
+ }
+
@Override
public void verifyTree(Set<Node> set, WarnCallback warnings) {
if (!set.contains(this)) {
@@ -123,13 +122,13 @@ public final class ConsAltNode extends Node {
ca.parent = this;
return car;
}
-
+
public ConsAltNode setCdr(ConsAltNode cd) {
cdr = cd;
cd.parent = this;
return cdr;
}
-
+
@Override
public String getName() {
switch (type) {
@@ -145,10 +144,10 @@ public final class ConsAltNode extends Node {
@Override
public String toString(int level) {
StringBuilder value = new StringBuilder();
- value.append("\n left: " + pad(car, level + 1));
- value.append("\n right: " + (cdr == null ? "NULL" : cdr.toString()));
-
+ value.append("\n car: " + pad(car, level + 1));
+ value.append("\n cdr: " + (cdr == null ? "NULL" : cdr.toString()));
+
return value.toString();
- }
+ }
}
diff --git a/src/org/joni/ast/EncloseNode.java b/src/org/joni/ast/EncloseNode.java
index 02b2391..0a07ed1 100644
--- a/src/org/joni/ast/EncloseNode.java
+++ b/src/org/joni/ast/EncloseNode.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.ast;
@@ -24,7 +24,7 @@ import org.joni.Option;
import org.joni.constants.EncloseType;
public final class EncloseNode extends StateNode implements EncloseType {
-
+
public int type; // enclose type
public int regNum;
public int option;
@@ -34,20 +34,20 @@ public final class EncloseNode extends StateNode implements EncloseType {
public int maxLength; // OnigDistance
public int charLength;
public int optCount; // referenced count in optimize_node_left()
-
+
// node_new_enclose / onig_node_new_enclose
public EncloseNode(int type) {
this.type = type;
callAddr = -1;
}
-
+
// node_new_enclose_memory
public EncloseNode(int option, boolean isNamed) {
this(MEMORY);
if (isNamed) setNamedGroup();
if (Config.USE_SUBEXP_CALL) this.option = option;
}
-
+
// node_new_option
public EncloseNode(int option, int _) {
this(OPTION);
@@ -58,12 +58,12 @@ public final class EncloseNode extends StateNode implements EncloseType {
public int getType() {
return ENCLOSE;
}
-
+
@Override
protected void setChild(Node newChild) {
target = newChild;
}
-
+
@Override
protected Node getChild() {
return target;
@@ -71,14 +71,14 @@ public final class EncloseNode extends StateNode implements EncloseType {
public void setTarget(Node tgt) {
target = tgt;
- tgt.parent = this;
- }
-
+ tgt.parent = this;
+ }
+
@Override
public String getName() {
return "Enclose";
- }
-
+ }
+
@Override
public String toString(int level) {
StringBuilder value = new StringBuilder(super.toString(level));
@@ -91,61 +91,61 @@ public final class EncloseNode extends StateNode implements EncloseType {
value.append("\n maxLength: " + maxLength);
value.append("\n charLength: " + charLength);
value.append("\n optCount: " + optCount);
-
+
return value.toString();
}
-
+
public String typeToString() {
StringBuilder types = new StringBuilder();
if (isStopBacktrack()) types.append("STOP_BACKTRACK ");
if (isMemory()) types.append("MEMORY ");
if (isOption()) types.append("OPTION ");
-
+
return types.toString();
}
-
+
public void setEncloseStatus(int flag) {
state |= flag;
}
-
+
public void clearEncloseStatus(int flag) {
state &= ~flag;
}
-
+
public void clearMemory() {
type &= ~MEMORY;
}
-
+
public void setMemory() {
type |= MEMORY;
}
-
+
public boolean isMemory() {
return (type & MEMORY) != 0;
}
-
+
public void clearOption() {
type &= ~OPTION;
}
-
+
public void setOption() {
type |= OPTION;
}
-
+
public boolean isOption() {
return (type & OPTION) != 0;
}
-
+
public void clearStopBacktrack() {
type &= ~STOP_BACKTRACK;
}
-
+
public void setStopBacktrack() {
type |= STOP_BACKTRACK;
}
-
+
public boolean isStopBacktrack() {
return (type & STOP_BACKTRACK) != 0;
- }
-
+ }
+
}
diff --git a/src/org/joni/ast/Node.java b/src/org/joni/ast/Node.java
index eef7790..5a75221 100644
--- a/src/org/joni/ast/Node.java
+++ b/src/org/joni/ast/Node.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.ast;
@@ -27,13 +27,13 @@ import org.joni.constants.NodeType;
public abstract class Node implements NodeType {
public Node parent;
-
+
public abstract int getType();
public final int getType2Bit() {
- return 1 << getType();
- }
-
+ return 1 << getType();
+ }
+
protected void setChild(Node tgt){} // default definition
protected Node getChild(){return null;}; // default definition
@@ -42,20 +42,20 @@ public abstract class Node implements NodeType {
//if (getChild() != null) getChild().parent = with;
//if (with.getChild() != null) with.getChild().parent = this;
-
+
//tmp = getChild();
//setChild(with.getChild());
//with.setChild(tmp);
-
+
if (parent != null) parent.setChild(with);
-
+
if (with.parent != null) with.parent.setChild(this);
tmp = parent;
parent = with.parent;
with.parent = tmp;
}
-
+
// overridden by ConsAltNode and CallNode
public void verifyTree(Set<Node> set, WarnCallback warnings) {
if (!set.contains(this) && getChild() != null) {
@@ -65,31 +65,30 @@ public abstract class Node implements NodeType {
}
getChild().verifyTree(set, warnings);
}
- }
-
+ }
+
public abstract String getName();
protected abstract String toString(int level);
-
+
public String getAddressName() {
return getName() + ":0x" + Integer.toHexString(System.identityHashCode(this));
}
-
+
public final String toString() {
StringBuilder s = new StringBuilder();
- s.append("<" + getAddressName() + ">");
- s.append("\n parent: " + (parent == null ? "NULL" : parent.getAddressName()));
+ s.append("<" + getAddressName() + " (" + (parent == null ? "NULL" : parent.getAddressName()) + ")>");
return s + toString(0);
}
-
+
protected static String pad(Object value, int level) {
if (value == null) return "NULL";
-
+
StringBuilder pad = new StringBuilder(" ");
for (int i=0; i<level; i++) pad.append(pad);
-
+
return value.toString().replace("\n", "\n" + pad);
}
-
+
public final boolean isInvalidQuantifier() {
if (!Config.VANILLA) return false;
@@ -99,37 +98,37 @@ public abstract class Node implements NodeType {
case ANCHOR:
return true;
-
+
case ENCLOSE:
/* allow enclosed elements */
/* return is_invalid_quantifier_target(NENCLOSE(node)->target); */
break;
-
+
case LIST:
node = (ConsAltNode)this;
do {
if (!node.car.isInvalidQuantifier()) return false;
} while ((node = node.cdr) != null);
return false;
-
+
case ALT:
node = (ConsAltNode)this;
do {
if (node.car.isInvalidQuantifier()) return true;
} while ((node = node.cdr) != null);
break;
-
+
default:
break;
}
-
+
return false;
}
-
+
public final boolean isAllowedInLookBehind() {
- return (getType2Bit() & ALLOWED_IN_LB) != 0;
+ return (getType2Bit() & ALLOWED_IN_LB) != 0;
}
-
+
public final boolean isSimple() {
return (getType2Bit() & SIMPLE) != 0;
}
diff --git a/src/org/joni/ast/QuantifierNode.java b/src/org/joni/ast/QuantifierNode.java
index 280f9bf..8ec53cb 100644
--- a/src/org/joni/ast/QuantifierNode.java
+++ b/src/org/joni/ast/QuantifierNode.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.ast;
@@ -30,52 +30,52 @@ public final class QuantifierNode extends StateNode {
public int lower;
public int upper;
public boolean greedy;
-
+
public int targetEmptyInfo;
-
+
public Node headExact;
public Node nextHeadExact;
public boolean isRefered; /* include called node. don't eliminate even if {0} */
-
+
// USE_COMBINATION_EXPLOSION_CHECK
- public int combExpCheckNum; /* 1,2,3...: check, 0: no check */
-
+ public int combExpCheckNum; /* 1,2,3...: check, 0: no check */
+
public QuantifierNode(int lower, int upper, boolean byNumber) {
this.lower = lower;
this.upper = upper;
greedy = true;
targetEmptyInfo = TargetInfo.ISNOT_EMPTY;
-
- if (byNumber) setByNumber();
+
+ if (byNumber) setByNumber();
}
@Override
public int getType() {
return QTFR;
}
-
+
@Override
protected void setChild(Node newChild) {
target = newChild;
}
-
+
@Override
protected Node getChild() {
return target;
}
-
+
public void setTarget(Node tgt) {
target = tgt;
- tgt.parent = this;
+ tgt.parent = this;
}
-
- public StringNode convertToString() {
+
+ public StringNode convertToString(int flag) {
StringNode sn = new StringNode();
- sn.flag = ((StringNode)target).flag;
+ sn.flag = flag;
sn.swap(this);
return sn;
}
-
+
@Override
public String getName() {
return "Quantifier";
@@ -93,14 +93,14 @@ public final class QuantifierNode extends StateNode {
value.append("\n nextHeadExact: " + pad(nextHeadExact, level + 1));
value.append("\n isRefered: " + isRefered);
value.append("\n combExpCheckNum: " + combExpCheckNum);
-
+
return value.toString();
}
-
+
public boolean isAnyCharStar() {
return greedy && isRepeatInfinite(upper) && target.getType() == CANY;
}
-
+
/* ?:0, *:1, +:2, ??:3, *?:4, +?:5 */
protected int popularNum() {
if (greedy) {
@@ -120,7 +120,7 @@ public final class QuantifierNode extends StateNode {
}
return -1;
}
-
+
protected void set(QuantifierNode other) {
setTarget(other.target);
other.target = null;
@@ -128,7 +128,7 @@ public final class QuantifierNode extends StateNode {
upper = other.upper;
greedy = other.greedy;
targetEmptyInfo = other.targetEmptyInfo;
-
+
//setHeadExact(other.headExact);
//setNextHeadExact(other.nextHeadExact);
headExact = other.headExact;
@@ -136,41 +136,41 @@ public final class QuantifierNode extends StateNode {
isRefered = other.isRefered;
combExpCheckNum = other.combExpCheckNum;
}
-
+
public void reduceNestedQuantifier(QuantifierNode other) {
int pnum = popularNum();
int cnum = other.popularNum();
-
+
if (pnum < 0 || cnum < 0) return;
-
+
switch(Reduce.REDUCE_TABLE[cnum][pnum]) {
case DEL:
- // no need to set the parent here...
+ // no need to set the parent here...
// swap ?
set(other); // *pnode = *cnode; ???
break;
-
+
case A:
setTarget(other.target);
lower = 0;
upper = REPEAT_INFINITE;
greedy = true;
break;
-
+
case AQ:
setTarget(other.target);
lower = 0;
upper = REPEAT_INFINITE;
greedy = false;
break;
-
+
case QQ:
setTarget(other.target);
lower = 0;
upper = 1;
greedy = false;
break;
-
+
case P_QQ:
setTarget(other);
lower = 0;
@@ -180,7 +180,7 @@ public final class QuantifierNode extends StateNode {
other.upper = REPEAT_INFINITE;
other.greedy = true;
return;
-
+
case PQ_Q:
setTarget(other);
lower = 0;
@@ -190,7 +190,7 @@ public final class QuantifierNode extends StateNode {
other.upper = REPEAT_INFINITE;
other.greedy = false;
return;
-
+
case ASIS:
setTarget(other);
return;
@@ -198,12 +198,12 @@ public final class QuantifierNode extends StateNode {
// ??? remove the parent from target ???
other.target = null; // remove target from reduced quantifier
}
-
+
public int setQuantifier(Node tgt, boolean group, ScanEnvironment env, byte[]bytes, int p, int end) {
if (lower == 1 && upper == 1) return 1;
-
+
switch(tgt.getType()) {
-
+
case STR:
if (!group) {
StringNode sn = (StringNode)tgt;
@@ -216,25 +216,25 @@ public final class QuantifierNode extends StateNode {
}
}
break;
-
+
case QTFR:
/* check redundant double repeat. */
/* verbose warn (?:.?)? etc... but not warn (.?)? etc... */
QuantifierNode qnt = (QuantifierNode)tgt;
int nestQNum = popularNum();
int targetQNum = qnt.popularNum();
-
+
if (Config.USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR) {
if (!isByNumber() && !qnt.isByNumber() && env.syntax.warnReduntantNestedRepeat()) {
switch(Reduce.REDUCE_TABLE[targetQNum][nestQNum]) {
case ASIS:
break;
-
+
case DEL:
- env.reg.warnings.warn(new String(bytes, p, end) +
+ env.reg.warnings.warn(new String(bytes, p, end) +
" redundant nested repeat operator");
break;
-
+
default:
env.reg.warnings.warn(new String(bytes, p, end) +
" nested repeat operator " + Reduce.PopularQStr[targetQNum] +
@@ -243,7 +243,7 @@ public final class QuantifierNode extends StateNode {
}
}
} // USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR
-
+
if (targetQNum >= 0) {
if (nestQNum >= 0) {
reduceNestedQuantifier(qnt);
@@ -255,11 +255,11 @@ public final class QuantifierNode extends StateNode {
}
}
}
-
+
default:
break;
}
-
+
setTarget(tgt);
return 0;
}
@@ -268,5 +268,5 @@ public final class QuantifierNode extends StateNode {
public static boolean isRepeatInfinite(int n) {
return n == REPEAT_INFINITE;
}
-
+
}
diff --git a/src/org/joni/ast/StateNode.java b/src/org/joni/ast/StateNode.java
index 117d3df..299b319 100644
--- a/src/org/joni/ast/StateNode.java
+++ b/src/org/joni/ast/StateNode.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.ast;
@@ -28,7 +28,7 @@ public abstract class StateNode extends Node implements NodeStatus {
public String toString(int level) {
return "\n state: " + stateToString();
}
-
+
public String stateToString() {
StringBuilder states = new StringBuilder();
if (isMinFixed()) states.append("MIN_FIXED ");
@@ -48,185 +48,185 @@ public abstract class StateNode extends Node implements NodeStatus {
return states.toString();
}
-
+
public boolean isMinFixed() {
return (state & NST_MIN_FIXED) != 0;
}
-
+
public void setMinFixed() {
state |= NST_MIN_FIXED;
}
-
+
public void clearMinFixed() {
state &= ~NST_MIN_FIXED;
}
-
+
public boolean isMaxFixed() {
return (state & NST_MAX_FIXED) != 0;
}
-
+
public void setMaxFixed() {
state |= NST_MAX_FIXED;
}
-
+
public void clearMaxFixed() {
- state &= ~NST_MAX_FIXED;
+ state &= ~NST_MAX_FIXED;
}
-
+
public boolean isCLenFixed() {
return (state & NST_CLEN_FIXED) != 0;
}
-
+
public void setCLenFixed() {
state |= NST_CLEN_FIXED;
}
-
+
public void clearCLenFixed() {
- state &= ~NST_CLEN_FIXED;
+ state &= ~NST_CLEN_FIXED;
}
-
+
public boolean isMark1() {
return (state & NST_MARK1) != 0;
}
-
+
public void setMark1() {
state |= NST_MARK1;
}
-
+
public void clearMark1() {
- state &= ~NST_MARK1;
+ state &= ~NST_MARK1;
}
-
+
public boolean isMark2() {
return (state & NST_MARK2) != 0;
}
-
+
public void setMark2() {
state |= NST_MARK2;
}
-
+
public void clearMark2() {
- state &= ~NST_MARK2;
+ state &= ~NST_MARK2;
}
-
+
public boolean isMemBackrefed() {
return (state & NST_MEM_BACKREFED) != 0;
}
-
+
public void setMemBackrefed() {
state |= NST_MEM_BACKREFED;
}
-
+
public void clearMemBackrefed() {
- state &= ~NST_MEM_BACKREFED;
+ state &= ~NST_MEM_BACKREFED;
}
-
+
public boolean isStopBtSimpleRepeat() {
return (state & NST_STOP_BT_SIMPLE_REPEAT) != 0;
}
-
+
public void setStopBtSimpleRepeat() {
state |= NST_STOP_BT_SIMPLE_REPEAT;
}
-
+
public void clearStopBtSimpleRepeat() {
- state &= ~NST_STOP_BT_SIMPLE_REPEAT;
+ state &= ~NST_STOP_BT_SIMPLE_REPEAT;
}
public boolean isRecursion() {
return (state & NST_RECURSION) != 0;
}
-
+
public void setRecursion() {
state |= NST_RECURSION;
}
-
+
public void clearRecursion() {
- state &= ~NST_RECURSION;
+ state &= ~NST_RECURSION;
}
-
+
public boolean isCalled() {
return (state & NST_CALLED) != 0;
}
-
+
public void setCalled() {
state |= NST_CALLED;
}
-
- public void clearCAlled() {
- state &= ~NST_CALLED;
+
+ public void clearCAlled() {
+ state &= ~NST_CALLED;
}
-
+
public boolean isAddrFixed() {
return (state & NST_ADDR_FIXED) != 0;
}
-
+
public void setAddrFixed() {
state |= NST_ADDR_FIXED;
}
-
- public void clearAddrFixed() {
- state &= ~NST_ADDR_FIXED;
+
+ public void clearAddrFixed() {
+ state &= ~NST_ADDR_FIXED;
}
-
+
public boolean isNamedGroup() {
return (state & NST_NAMED_GROUP) != 0;
}
-
+
public void setNamedGroup() {
state |= NST_NAMED_GROUP;
}
-
- public void clearNamedGroup() {
- state &= ~NST_NAMED_GROUP;
+
+ public void clearNamedGroup() {
+ state &= ~NST_NAMED_GROUP;
}
public boolean isNameRef() {
return (state & NST_NAME_REF) != 0;
}
-
+
public void setNameRef() {
state |= NST_NAME_REF;
}
-
- public void clearNameRef() {
- state &= ~NST_NAME_REF;
+
+ public void clearNameRef() {
+ state &= ~NST_NAME_REF;
}
-
+
public boolean isInRepeat() {
return (state & NST_IN_REPEAT) != 0;
}
-
+
public void setInRepeat() {
state |= NST_IN_REPEAT;
}
-
- public void clearInRepeat() {
- state &= ~NST_IN_REPEAT;
+
+ public void clearInRepeat() {
+ state &= ~NST_IN_REPEAT;
}
-
+
public boolean isNestLevel() {
return (state & NST_NEST_LEVEL) != 0;
}
-
+
public void setNestLevel() {
state |= NST_NEST_LEVEL;
}
-
- public void clearNestLevel() {
- state &= ~NST_NEST_LEVEL;
+
+ public void clearNestLevel() {
+ state &= ~NST_NEST_LEVEL;
}
-
+
public boolean isByNumber() {
return (state & NST_BY_NUMBER) != 0;
}
-
+
public void setByNumber() {
state |= NST_BY_NUMBER;
}
-
- public void clearByNumber() {
- state &= ~NST_BY_NUMBER;
+
+ public void clearByNumber() {
+ state &= ~NST_BY_NUMBER;
}
-
+
}
diff --git a/src/org/joni/ast/StringNode.java b/src/org/joni/ast/StringNode.java
index bf8217e..15ed04c 100644
--- a/src/org/joni/ast/StringNode.java
+++ b/src/org/joni/ast/StringNode.java
@@ -1,38 +1,40 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.ast;
import org.jcodings.Encoding;
+import org.joni.Config;
import org.joni.constants.StringType;
public final class StringNode extends Node implements StringType {
-
+
private static final int NODE_STR_MARGIN = 16;
private static final int NODE_STR_BUF_SIZE = 24;
-
+ public static final StringNode EMPTY = new StringNode(null, Integer.MAX_VALUE, Integer.MAX_VALUE);
+
public byte[]bytes;
public int p;
public int end;
-
- int flag;
-
+
+ public int flag;
+
public StringNode() {
this.bytes = new byte[NODE_STR_BUF_SIZE];
}
@@ -43,7 +45,7 @@ public final class StringNode extends Node implements StringType {
this.end = end;
setShared();
}
-
+
public StringNode(byte c) {
this();
bytes[end++] = c;
@@ -60,12 +62,12 @@ public final class StringNode extends Node implements StringType {
bytes = tmp;
}
}
-
+
/* COW and/or ensure there is ahead bytes available in node's buffer
*/
private void modifyEnsure(int ahead) {
- int len = (end - p) + ahead;
if (isShared()) {
+ int len = (end - p) + ahead;
byte[]tmp = new byte[len + NODE_STR_MARGIN];
System.arraycopy(bytes, p, tmp, 0, end - p);
bytes = tmp;
@@ -73,46 +75,43 @@ public final class StringNode extends Node implements StringType {
p = 0;
clearShared();
} else {
- if (len >= bytes.length) {
- byte[]tmp = new byte[len + NODE_STR_MARGIN];
- System.arraycopy(bytes, p, tmp, 0, end - p);
- bytes = tmp;
- }
+ ensure(ahead);
}
}
-
+
@Override
public int getType() {
return STR;
}
-
+
@Override
public String getName() {
return "String";
- }
-
+ }
+
@Override
public String toString(int level) {
StringBuilder value = new StringBuilder();
- value.append("\n bytes: ");
+ value.append("\n bytes: '");
for (int i=p; i<end; i++) {
if ((bytes[i] & 0xff) >= 0x20 && (bytes[i] & 0xff) < 0x7f) {
value.append((char)bytes[i]);
} else {
- value.append(String.format(" 0x%02x", bytes[i]));
+ value.append(String.format("[0x%02x]", bytes[i]));
}
}
+ value.append("'");
return value.toString();
}
public int length() {
return end - p;
}
-
+
public int length(Encoding enc) {
return enc.strLength(bytes, p, end);
}
-
+
public StringNode splitLastChar(Encoding enc) {
StringNode n = null;
@@ -126,7 +125,7 @@ public final class StringNode extends Node implements StringType {
}
return n;
}
-
+
public boolean canBeSplit(Encoding enc) {
if (end > p) {
return enc.length(bytes, p, end) < (end - p);
@@ -140,19 +139,24 @@ public final class StringNode extends Node implements StringType {
this.end = end;
setShared();
}
-
+
public void cat(byte[]cat, int catP, int catEnd) {
int len = catEnd - catP;
modifyEnsure(len);
System.arraycopy(cat, catP, bytes, end, len);
end += len;
}
-
+
public void cat(byte c) {
modifyEnsure(1);
bytes[end++] = c;
}
-
+
+ public void catCode(int code, Encoding enc) {
+ ensure(Config.ENC_CODE_TO_MBC_MAXLEN);
+ end += enc.codeToMbc(code, bytes, end);
+ }
+
public void clear() {
if (bytes.length > NODE_STR_BUF_SIZE) bytes = new byte[NODE_STR_BUF_SIZE];
flag = 0;
@@ -162,47 +166,47 @@ public final class StringNode extends Node implements StringType {
public void setRaw() {
flag |= NSTR_RAW;
}
-
+
public void clearRaw() {
flag &= ~NSTR_RAW;
}
-
+
public boolean isRaw() {
return (flag & NSTR_RAW) != 0;
}
-
+
public void setAmbig() {
flag |= NSTR_AMBIG;
}
-
+
public void clearAmbig() {
flag &= ~NSTR_AMBIG;
}
-
+
public boolean isAmbig() {
return (flag & NSTR_AMBIG) != 0;
}
-
+
public void setDontGetOptInfo() {
flag |= NSTR_DONT_GET_OPT_INFO;
}
-
+
public void clearDontGetOptInfo() {
flag &= ~NSTR_DONT_GET_OPT_INFO;
}
-
+
public boolean isDontGetOptInfo() {
return (flag & NSTR_DONT_GET_OPT_INFO) != 0;
}
-
+
public void setShared() {
flag |= NSTR_SHARED;
}
-
+
public void clearShared() {
flag &= ~NSTR_SHARED;
}
-
+
public boolean isShared() {
return (flag & NSTR_SHARED) != 0;
}
diff --git a/src/org/joni/bench/AbstractBench.java b/src/org/joni/bench/AbstractBench.java
index 5e058f9..7abcb51 100644
--- a/src/org/joni/bench/AbstractBench.java
+++ b/src/org/joni/bench/AbstractBench.java
@@ -9,7 +9,7 @@ public abstract class AbstractBench {
protected void bench(String _reg, String _str, int warmup, int times) throws Exception {
byte[] reg = _reg.getBytes();
byte[] str = _str.getBytes();
-
+
Regex p = new Regex(reg,0,reg.length,Option.DEFAULT,ASCIIEncoding.INSTANCE,Syntax.DEFAULT);
System.err.println("::: /" + _reg + "/ =~ \"" + _str + "\", " + warmup + " * " + times + " times");
@@ -27,7 +27,7 @@ public abstract class AbstractBench {
protected void benchBestOf(String _reg, String _str, int warmup, int times) throws Exception {
byte[] reg = _reg.getBytes();
byte[] str = _str.getBytes();
-
+
Regex p = new Regex(reg,0,reg.length,Option.DEFAULT,ASCIIEncoding.INSTANCE,Syntax.DEFAULT);
System.err.println("::: /" + _reg + "/ =~ \"" + _str + "\", " + warmup + " * " + times + " times");
diff --git a/src/org/joni/constants/AnchorType.java b/src/org/joni/constants/AnchorType.java
index 144dd1d..5d7336d 100644
--- a/src/org/joni/constants/AnchorType.java
+++ b/src/org/joni/constants/AnchorType.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
@@ -38,21 +38,21 @@ public interface AnchorType {
final int ANYCHAR_STAR = (1<<14); /* ".*" optimize info */
final int ANYCHAR_STAR_ML = (1<<15); /* ".*" optimize info (multi-line) */
-
+
final int ANYCHAR_STAR_MASK = (ANYCHAR_STAR | ANYCHAR_STAR_ML);
final int END_BUF_MASK = (END_BUF | SEMI_END_BUF);
-
+
final int ALLOWED_IN_LB = ( LOOK_BEHIND |
BEGIN_LINE |
END_LINE |
BEGIN_BUF |
BEGIN_POSITION );
-
+
final int ALLOWED_IN_LB_NOT = ( LOOK_BEHIND |
LOOK_BEHIND_NOT |
BEGIN_LINE |
END_LINE |
BEGIN_BUF |
- BEGIN_POSITION );
-
+ BEGIN_POSITION );
+
}
diff --git a/src/org/joni/constants/Arguments.java b/src/org/joni/constants/Arguments.java
index 1aacfdd..6098239 100644
--- a/src/org/joni/constants/Arguments.java
+++ b/src/org/joni/constants/Arguments.java
@@ -1,27 +1,27 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
public interface Arguments {
- final int SPECIAL = -1;
- final int NON = 0;
+ final int SPECIAL = -1;
+ final int NON = 0;
final int RELADDR = 1;
final int ABSADDR = 2;
final int LENGTH = 3;
diff --git a/src/org/joni/constants/AsmConstants.java b/src/org/joni/constants/AsmConstants.java
index 6329780..2e28958 100644
--- a/src/org/joni/constants/AsmConstants.java
+++ b/src/org/joni/constants/AsmConstants.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
diff --git a/src/org/joni/constants/CCSTATE.java b/src/org/joni/constants/CCSTATE.java
index 23baa87..669b821 100644
--- a/src/org/joni/constants/CCSTATE.java
+++ b/src/org/joni/constants/CCSTATE.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
diff --git a/src/org/joni/constants/CCVALTYPE.java b/src/org/joni/constants/CCVALTYPE.java
index b531e30..b2bcb30 100644
--- a/src/org/joni/constants/CCVALTYPE.java
+++ b/src/org/joni/constants/CCVALTYPE.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
diff --git a/src/org/joni/constants/EncloseType.java b/src/org/joni/constants/EncloseType.java
index 553b5dc..125af0c 100644
--- a/src/org/joni/constants/EncloseType.java
+++ b/src/org/joni/constants/EncloseType.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
@@ -23,7 +23,7 @@ public interface EncloseType {
final int MEMORY = 1<<0;
final int OPTION = 1<<1;
final int STOP_BACKTRACK = 1<<2;
-
+
final int ALLOWED_IN_LB = MEMORY;
final int ALLOWED_IN_LB_NOT = 0;
}
diff --git a/src/org/joni/constants/MetaChar.java b/src/org/joni/constants/MetaChar.java
index 3589aff..37f94a7 100644
--- a/src/org/joni/constants/MetaChar.java
+++ b/src/org/joni/constants/MetaChar.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
@@ -23,9 +23,9 @@ public interface MetaChar {
final int ESCAPE = 0;
final int ANYCHAR = 1;
final int ANYTIME = 2;
- final int ZERO_OR_ONE_TIME = 3;
+ final int ZERO_OR_ONE_TIME = 3;
final int ONE_OR_MORE_TIME = 4;
final int ANYCHAR_ANYTIME = 5;
-
+
final int INEFFECTIVE_META_CHAR = 0;
}
diff --git a/src/org/joni/constants/NodeStatus.java b/src/org/joni/constants/NodeStatus.java
index 901d47d..e7a4754 100644
--- a/src/org/joni/constants/NodeStatus.java
+++ b/src/org/joni/constants/NodeStatus.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
diff --git a/src/org/joni/constants/NodeType.java b/src/org/joni/constants/NodeType.java
index dccece2..4e37d67 100644
--- a/src/org/joni/constants/NodeType.java
+++ b/src/org/joni/constants/NodeType.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
@@ -32,7 +32,7 @@ public interface NodeType {
final int LIST = 8;
final int ALT = 9;
final int CALL = 10;
-
+
final int BIT_STR = 1 << STR;
final int BIT_CCLASS = 1 << CCLASS;
final int BIT_CTYPE = 1 << CTYPE;
@@ -44,9 +44,9 @@ public interface NodeType {
final int BIT_LIST = 1 << LIST;
final int BIT_ALT = 1 << ALT;
final int BIT_CALL = 1 << CALL;
-
+
/* allowed node types in look-behind */
- final int ALLOWED_IN_LB = ( BIT_LIST |
+ final int ALLOWED_IN_LB = ( BIT_LIST |
BIT_ALT |
BIT_STR |
BIT_CCLASS |
@@ -56,11 +56,11 @@ public interface NodeType {
BIT_ENCLOSE |
BIT_QTFR |
BIT_CALL );
-
+
final int SIMPLE = ( BIT_STR |
BIT_CCLASS |
BIT_CTYPE |
BIT_CANY |
BIT_BREF);
-
+
}
diff --git a/src/org/joni/constants/OPCode.java b/src/org/joni/constants/OPCode.java
index 8e06f88..05d1f8b 100644
--- a/src/org/joni/constants/OPCode.java
+++ b/src/org/joni/constants/OPCode.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
@@ -43,7 +43,7 @@ public interface OPCode {
final int CCLASS = 16;
final int CCLASS_MB = 17;
- final int CCLASS_MIX = 18;
+ final int CCLASS_MIX = 18;
final int CCLASS_NOT = 19;
final int CCLASS_MB_NOT = 20;
final int CCLASS_MIX_NOT = 21;
@@ -91,14 +91,14 @@ public interface OPCode {
final int POP = 57;
final int PUSH_OR_JUMP_EXACT1 = 58; /* if match exact then push, else jump. */
final int PUSH_IF_PEEK_NEXT = 59; /* if match exact then push, else none. */
-
+
final int REPEAT = 60; /* {n,m} */
final int REPEAT_NG = 61; /* {n,m}? (non greedy) */
final int REPEAT_INC = 62;
final int REPEAT_INC_NG = 63; /* non greedy */
final int REPEAT_INC_SG = 64; /* search and get in stack */
final int REPEAT_INC_NG_SG = 65; /* search and get in stack (non greedy) */
-
+
final int NULL_CHECK_START = 66; /* null loop checker start */
final int NULL_CHECK_END = 67; /* null loop checker end */
final int NULL_CHECK_END_MEMST = 68; /* null loop checker end (with capture status) */
@@ -126,7 +126,7 @@ public interface OPCode {
/* no need: IS_DYNAMIC_OPTION() == 0 */
final int SET_OPTION_PUSH = 86; /* set option and push recover option */
final int SET_OPTION = 87; /* set option */
-
+
// single byte versions
final int ANYCHAR_SB = 88; /* "." */
final int ANYCHAR_ML_SB = 89; /* "." multi-line */
@@ -145,12 +145,12 @@ public interface OPCode {
final int NOT_WORD_BOUND_SB = 101;
final int WORD_BEGIN_SB = 102;
final int WORD_END_SB = 103;
-
+
final int LOOK_BEHIND_SB = 104;
-
+
final int EXACT1_IC_SB = 105; /* single byte, N = 1, ignore case */
final int EXACTN_IC_SB = 106; /* single byte, ignore case */
-
+
public final String OpCodeNames[] = Config.DEBUG_COMPILE ? new String[] {
"finish", /*OP_FINISH*/
@@ -241,7 +241,7 @@ public interface OPCode {
"state-check-anychar-ml*", /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
"set-option-push", /*OP_SET_OPTION_PUSH*/
"set-option", /*OP_SET_OPTION*/
-
+
// single byte versions
"anychar-sb", /*OP_ANYCHAR*/
"anychar-ml-sb", /*OP_ANYCHAR_ML*/
@@ -254,21 +254,21 @@ public interface OPCode {
"cclass-sb", /*OP_CCLASS*/
"cclass-not-sb", /*OP_CCLASS_NOT*/
-
+
"word-sb", /*OP_WORD*/
"not-word-sb", /*OP_NOT_WORD*/
"word-bound-sb", /*OP_WORD_BOUND*/
"not-word-bound-sb", /*OP_NOT_WORD_BOUND*/
"word-begin-sb", /*OP_WORD_BEGIN*/
"word-end-sb", /*OP_WORD_END*/
-
+
"look-behind-sb", /*OP_LOOK_BEHIND*/
-
+
"exact1-ic-sb", /*OP_EXACT1_IC*/
"exactn-ic-sb", /*OP_EXACTN_IC*/
} : null;
-
+
public final int OpCodeArgTypes[] = Config.DEBUG_COMPILE ? new int[] {
Arguments.NON, /*OP_FINISH*/
Arguments.NON, /*OP_END*/
@@ -358,7 +358,7 @@ public interface OPCode {
Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
Arguments.OPTION, /*OP_SET_OPTION_PUSH*/
Arguments.OPTION, /*OP_SET_OPTION*/
-
+
// single byte versions
Arguments.NON, /*OP_ANYCHAR*/
Arguments.NON, /*OP_ANYCHAR_ML*/
@@ -380,7 +380,7 @@ public interface OPCode {
Arguments.NON, /*OP_WORD_END*/
Arguments.SPECIAL, /*OP_LOOK_BEHIND*/
-
+
Arguments.SPECIAL, /*OP_EXACT1_IC*/
Arguments.SPECIAL, /*OP_EXACTN_IC*/
} : null;
diff --git a/src/org/joni/constants/OPSize.java b/src/org/joni/constants/OPSize.java
index dcd419b..d5595ad 100644
--- a/src/org/joni/constants/OPSize.java
+++ b/src/org/joni/constants/OPSize.java
@@ -1,26 +1,26 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
public interface OPSize {
-
+
// this might be helpful for potential byte[] migration
final int OPCODE = 1;
final int RELADDR = 1;
@@ -32,9 +32,10 @@ public interface OPSize {
final int OPTION = 1;
final int CODE_POINT = 1;
final int POINTER = 1;
-
+ final int INDEX = 1;
+
/* op-code + arg size */
-
+
final int ANYCHAR_STAR = OPCODE;
final int ANYCHAR_STAR_PEEK_NEXT = (OPCODE + 1);
final int JUMP = (OPCODE + RELADDR);
diff --git a/src/org/joni/constants/Reduce.java b/src/org/joni/constants/Reduce.java
index e62de7f..07b5e18 100644
--- a/src/org/joni/constants/Reduce.java
+++ b/src/org/joni/constants/Reduce.java
@@ -1,23 +1,24 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
+
import static org.joni.constants.Reduce.ReduceType.A;
import static org.joni.constants.Reduce.ReduceType.AQ;
import static org.joni.constants.Reduce.ReduceType.ASIS;
@@ -27,7 +28,7 @@ import static org.joni.constants.Reduce.ReduceType.P_QQ;
import static org.joni.constants.Reduce.ReduceType.QQ;
public interface Reduce {
-
+
enum ReduceType {
ASIS, /* as is */
DEL, /* delete parent */
@@ -44,17 +45,17 @@ public interface Reduce {
{A, A, DEL, ASIS, P_QQ, DEL}, /* '+' */
{DEL, AQ, AQ, DEL, AQ, AQ}, /* '??' */
{DEL, DEL, DEL, DEL, DEL, DEL}, /* '*?' */
- {ASIS, PQ_Q, DEL, AQ, AQ, DEL} /* '+?' */
+ {ASIS, PQ_Q, DEL, AQ, AQ, DEL} /* '+?' */
};
-
-
+
+
final String PopularQStr[] = new String[] {
"?", "*", "+", "??", "*?", "+?"
};
-
+
String ReduceQStr[]= new String[] {
"", "", "*", "*?", "??", "+ and ??", "+? and ?"
- };
-
+ };
+
}
diff --git a/src/org/joni/constants/RegexState.java b/src/org/joni/constants/RegexState.java
index acc6d84..72dd3ff 100644
--- a/src/org/joni/constants/RegexState.java
+++ b/src/org/joni/constants/RegexState.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
diff --git a/src/org/joni/constants/StackPopLevel.java b/src/org/joni/constants/StackPopLevel.java
index f1f93bd..f5be8f4 100644
--- a/src/org/joni/constants/StackPopLevel.java
+++ b/src/org/joni/constants/StackPopLevel.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
diff --git a/src/org/joni/constants/StackType.java b/src/org/joni/constants/StackType.java
index 34ea41f..4a6527c 100644
--- a/src/org/joni/constants/StackType.java
+++ b/src/org/joni/constants/StackType.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
diff --git a/src/org/joni/constants/StringType.java b/src/org/joni/constants/StringType.java
index 46972e4..e1a6239 100644
--- a/src/org/joni/constants/StringType.java
+++ b/src/org/joni/constants/StringType.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
diff --git a/src/org/joni/constants/SyntaxProperties.java b/src/org/joni/constants/SyntaxProperties.java
index 3fd5b4c..61f2269 100644
--- a/src/org/joni/constants/SyntaxProperties.java
+++ b/src/org/joni/constants/SyntaxProperties.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
@@ -96,14 +96,14 @@ public interface SyntaxProperties {
/* syntax (behavior); warning */
final int WARN_CC_OP_NOT_ESCAPED = (1<<24); /* [,-,] */
final int WARN_REDUNDANT_NESTED_REPEAT = (1<<25); /* (?:a*);+ */
-
+
final int POSIX_COMMON_OP =
OP_DOT_ANYCHAR | OP_POSIX_BRACKET |
OP_DECIMAL_BACKREF |
OP_BRACKET_CC | OP_ASTERISK_ZERO_INF |
OP_LINE_ANCHOR |
OP_ESC_CONTROL_CHARS;
-
+
final int GNU_REGEX_OP =
OP_DOT_ANYCHAR | OP_BRACKET_CC |
OP_POSIX_BRACKET | OP_DECIMAL_BACKREF |
@@ -116,7 +116,7 @@ public interface SyntaxProperties {
OP_ESC_B_WORD_BOUND | OP_ESC_LTGT_WORD_BEGIN_END |
OP_ESC_S_WHITE_SPACE | OP_ESC_D_DIGIT |
OP_LINE_ANCHOR;
-
+
final int GNU_REGEX_BV =
CONTEXT_INDEP_ANCHORS | CONTEXT_INDEP_REPEAT_OPS |
CONTEXT_INVALID_REPEAT_OPS | ALLOW_INVALID_INTERVAL |
diff --git a/src/org/joni/constants/TargetInfo.java b/src/org/joni/constants/TargetInfo.java
index 3fdbe5a..ffec783 100644
--- a/src/org/joni/constants/TargetInfo.java
+++ b/src/org/joni/constants/TargetInfo.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
diff --git a/src/org/joni/constants/TokenType.java b/src/org/joni/constants/TokenType.java
index 9ea159d..59aa094 100644
--- a/src/org/joni/constants/TokenType.java
+++ b/src/org/joni/constants/TokenType.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
diff --git a/src/org/joni/constants/Traverse.java b/src/org/joni/constants/Traverse.java
index 1c08ea5..035e9f7 100644
--- a/src/org/joni/constants/Traverse.java
+++ b/src/org/joni/constants/Traverse.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.constants;
diff --git a/src/org/joni/exception/ErrorMessages.java b/src/org/joni/exception/ErrorMessages.java
index d1c1279..f490713 100644
--- a/src/org/joni/exception/ErrorMessages.java
+++ b/src/org/joni/exception/ErrorMessages.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.exception;
@@ -24,10 +24,10 @@ import org.joni.Config;
public interface ErrorMessages extends org.jcodings.exception.ErrorMessages {
final String MISMATCH = "mismatch";
final String NO_SUPPORT_CONFIG = "no support in this configuration";
-
+
/* internal error */
final String ERR_MEMORY = "fail to memory allocation";
- final String ERR_MATCH_STACK_LIMIT_OVER = "match-stack limit over";
+ final String ERR_MATCH_STACK_LIMIT_OVER = "match-stack limit over";
final String ERR_TYPE_BUG = "undefined type (bug)";
final String ERR_PARSER_BUG = "internal parser error (bug)";
final String ERR_STACK_BUG = "stack error (bug)";
@@ -38,7 +38,7 @@ public interface ErrorMessages extends org.jcodings.exception.ErrorMessages {
/* general error */
final String ERR_INVALID_ARGUMENT = "invalid argument";
-
+
/* syntax error */
final String ERR_END_PATTERN_AT_LEFT_BRACE = "end pattern at left brace";
final String ERR_END_PATTERN_AT_LEFT_BRACKET = "end pattern at left bracket";
@@ -62,7 +62,7 @@ public interface ErrorMessages extends org.jcodings.exception.ErrorMessages {
final String ERR_INVALID_POSIX_BRACKET_TYPE = "invalid POSIX bracket type";
final String ERR_INVALID_LOOK_BEHIND_PATTERN = "invalid pattern in look-behind";
final String ERR_INVALID_REPEAT_RANGE_PATTERN = "invalid repeat range {lower,upper}";
-
+
/* values error (syntax error) */
final String ERR_TOO_BIG_NUMBER = "too big number";
final String ERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE = "too big number for repeat range";
diff --git a/src/org/joni/exception/InternalException.java b/src/org/joni/exception/InternalException.java
index 959f44f..b41e0aa 100644
--- a/src/org/joni/exception/InternalException.java
+++ b/src/org/joni/exception/InternalException.java
@@ -1,27 +1,27 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.exception;
public class InternalException extends JOniException{
private static final long serialVersionUID = -3871816465397927992L;
-
+
public InternalException(String message) {
super(message);
}
diff --git a/src/org/joni/exception/JOniException.java b/src/org/joni/exception/JOniException.java
index f5d728c..c2c5d47 100644
--- a/src/org/joni/exception/JOniException.java
+++ b/src/org/joni/exception/JOniException.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.exception;
diff --git a/src/org/joni/exception/SyntaxException.java b/src/org/joni/exception/SyntaxException.java
index 7b00d1c..7e50cf5 100644
--- a/src/org/joni/exception/SyntaxException.java
+++ b/src/org/joni/exception/SyntaxException.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.exception;
diff --git a/src/org/joni/exception/ValueException.java b/src/org/joni/exception/ValueException.java
index b07ac42..790f354 100644
--- a/src/org/joni/exception/ValueException.java
+++ b/src/org/joni/exception/ValueException.java
@@ -1,35 +1,35 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.exception;
public class ValueException extends SyntaxException{
private static final long serialVersionUID = -196013852479929134L;
-
+
public ValueException(String message) {
super(message);
}
-
+
public ValueException(String message, String str) {
super(message.replaceAll("%n", str));
}
-
+
public ValueException(String message, byte[]bytes, int p, int end) {
this(message, new String(bytes, p, end - p));
}
diff --git a/test/org/joni/test/Test.java b/test/org/joni/test/Test.java
index 1a9cec6..dda5c3e 100644
--- a/test/org/joni/test/Test.java
+++ b/test/org/joni/test/Test.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.test;
@@ -31,31 +31,32 @@ import org.jcodings.Encoding;
import org.joni.exception.JOniException;
public abstract class Test {
+ static final boolean VERBOSE = false;
int nsucc;
int nerror;
int nfail;
-
+
public abstract int option();
public abstract Encoding encoding();
public abstract String testEncoding();
public abstract Syntax syntax();
-
+
protected String repr(byte[]bytes) {
return new String(bytes);
}
-
+
protected int length(byte[]bytes) {
return bytes.length;
}
-
+
public void xx(byte[]pattern, byte[]str, int from, int to, int mem, boolean not) {
xx(pattern, str, from, to, mem, not, option());
}
-
+
public void xx(byte[]pattern, byte[]str, int from, int to, int mem, boolean not, int option) {
Regex reg;
-
+
try {
reg = new Regex(pattern, 0, length(pattern), option, encoding(), syntax());
} catch (JOniException je) {
@@ -69,9 +70,9 @@ public abstract class Test {
e.printStackTrace(Config.err);
Config.err.println("SEVERE ERROR: " + e.getMessage());
nerror++;
- return;
+ return;
}
-
+
Matcher m = reg.matcher(str, 0, length(str));
Region region;
@@ -90,12 +91,12 @@ public abstract class Test {
e.printStackTrace(Config.err);
Config.err.println("SEVERE ERROR: " + e.getMessage());
nerror++;
- return;
+ return;
}
-
+
if (r == -1) {
if (not) {
- Config.log.println("OK(N): /" + repr(pattern) + "/ '" + repr(str) + "'");
+ if (VERBOSE) Config.log.println("OK(N): /" + repr(pattern) + "/ '" + repr(str) + "'");
nsucc++;
} else {
Config.log.println("FAIL: /" + repr(pattern) + "/ '" + repr(str) + "'");
@@ -107,7 +108,7 @@ public abstract class Test {
nfail++;
} else {
if (region.beg[mem] == from && region.end[mem] == to) {
- Config.log.println("OK: /" + repr(pattern) + "/ '" +repr(str) + "'");
+ if (VERBOSE) Config.log.println("OK: /" + repr(pattern) + "/ '" +repr(str) + "'");
nsucc++;
} else {
Config.log.println("FAIL: /" + repr(pattern) + "/ '" + repr(str) + "' " +
@@ -118,23 +119,31 @@ public abstract class Test {
}
}
}
-
+
protected void x2(byte[]pattern, byte[]str, int from, int to) {
xx(pattern, str, from, to, 0, false);
}
-
+
+ protected void x2(byte[]pattern, byte[]str, int from, int to, int option) {
+ xx(pattern, str, from, to, 0, false, option);
+ }
+
protected void x3(byte[]pattern, byte[]str, int from, int to, int mem) {
xx(pattern, str, from, to, mem, false);
}
-
+
protected void n(byte[]pattern, byte[]str) {
xx(pattern, str, 0, 0, 0, true);
}
+ protected void n(byte[]pattern, byte[]str, int option) {
+ xx(pattern, str, 0, 0, 0, true, option);
+ }
+
public void xxs(String pattern, String str, int from, int to, int mem, boolean not) {
xxs(pattern, str, from, to, mem, not, option());
}
-
+
public void xxs(String pattern, String str, int from, int to, int mem, boolean not, int option) {
try{
xx(pattern.getBytes(testEncoding()), str.getBytes(testEncoding()), from, to, mem, not, option);
@@ -146,7 +155,7 @@ public abstract class Test {
public void x2s(String pattern, String str, int from, int to) {
x2s(pattern, str, from, to, option());
}
-
+
public void x2s(String pattern, String str, int from, int to, int option) {
try{
xx(pattern.getBytes(testEncoding()), str.getBytes(testEncoding()), from, to, 0, false, option);
@@ -154,41 +163,40 @@ public abstract class Test {
uee.printStackTrace();
}
}
-
+
public void x3s(String pattern, String str, int from, int to, int mem) {
x3s(pattern, str, from, to, mem, option());
}
-
+
public void x3s(String pattern, String str, int from, int to, int mem, int option) {
- try{
+ try{
xx(pattern.getBytes(testEncoding()), str.getBytes(testEncoding()), from, to, mem, false, option);
} catch (UnsupportedEncodingException uee) {
uee.printStackTrace();
}
}
-
+
public void ns(String pattern, String str) {
ns(pattern, str, option());
}
-
+
public void ns(String pattern, String str, int option) {
- try{
+ try{
xx(pattern.getBytes(testEncoding()), str.getBytes(testEncoding()), 0, 0, 0, true, option);
} catch (UnsupportedEncodingException uee) {
uee.printStackTrace();
}
}
-
+
public void printResults() {
- Config.log.println("\nRESULT SUCC: " + nsucc + ", FAIL: " + nfail + ", ERROR: " + nerror +
- " (by JONI)");
+ Config.log.println("RESULT SUCC: " + nsucc + ", FAIL: " + nfail + ", ERROR: " + nerror + " Test: " + getClass().getSimpleName() + ", Encoding: " + encoding());
}
-
+
public abstract void test();
-
+
public final void run() {
test();
printResults();
}
-
+
}
diff --git a/test/org/joni/test/TestA.java b/test/org/joni/test/TestA.java
index bc3ebf5..f73153a 100644
--- a/test/org/joni/test/TestA.java
+++ b/test/org/joni/test/TestA.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.test;
@@ -33,14 +33,14 @@ public class TestA extends Test {
public Encoding encoding() {
return ASCIIEncoding.INSTANCE;
}
-
+
public String testEncoding() {
return "iso-8859-2";
}
public Syntax syntax() {
return Syntax.DEFAULT;
- }
+ }
public void test() {
x2s("", "", 0, 0);
@@ -451,11 +451,11 @@ public class TestA extends Test {
x2s("x((.)*)*x(?i:\\1)\\Z", "0x1x2x1X2", 1, 9);
x2s("(?:()|()|()|()|()|())*\\2\\5", "", 0, 0);
x2s("(?:()|()|()|(x)|()|())*\\2b\\5", "b", 0, 1);
-
+
x3s("\\A(?<a>|.|(?:(?<b>.)\\g<a>\\k<b+0>))\\z", "reer", 0, 4, 1);
x3s("(?-i:\\g<name>)(?i:(?<name>a)){0}", "A", 0, 1, 1);
-
- String pat =
+
+ String pat =
"(?<element> \\g<stag> \\g<content>* \\g<etag> ){0}" +
"(?<stag> < \\g<name> \\s* > ){0}" +
"(?<name> [a-zA-Z_:]+ ){0}" +
@@ -464,7 +464,7 @@ public class TestA extends Test {
"\\g<element>";
String str = "<foo>f<bar>bbb</bar>f</foo>";
-
+
x3s(pat, str, 0, 27, 0, Option.EXTEND);
x3s(pat, str, 0, 27, 1, Option.EXTEND);
x3s(pat, str, 6, 11, 2, Option.EXTEND);
@@ -473,8 +473,32 @@ public class TestA extends Test {
x3s(pat, str, 21, 27, 5, Option.EXTEND);
x2s("(a)b\\k<1>", "aba", 0, 3);
+ x2s("^(?>(?=a)(a|))++$", "a", 0, 1);
+ x2s("\\k", "k", 0, 1);
+ x2s("\\kx", "kx", 0, 2);
+ x2s("\\g", "g", 0, 1);
+ x2s("\\gx", "gx", 0, 2);
+ x2s("\\k\\g", "kg", 0, 2);
+ ns("\\00", "00");
+ ns("\\70", "70");
+ x2s("\\80", "80", 0, 2);
+ x2s("\\90", "90", 0, 2);
+
+ ns("(?<!b|aa)c", "Aac", Option.IGNORECASE);
+ x2s("(?<!b|aa)", "Aac", 0, 0, Option.IGNORECASE);
+ x2s("(?<=b|aa)c", "Aac", 2, 3, Option.IGNORECASE);
+ x2s("(?<=b|aa)", "Aac", 2, 2, Option.IGNORECASE);
+
+ ns("\\A[a-f&&[^b-c]&&[^e]]\\z", "e");
+ ns("[[^a]&&e&&[^e]]", "e");
+
+ x2s("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0, 35, Option.IGNORECASE);
+ x2s("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 0, 35, Option.IGNORECASE);
+ x2s("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaAAAAAAAAAAAAAAAAA", 0, 35, Option.IGNORECASE);
+
+ x2s("(?mix)", "", 0, 0);
}
-
+
public static void main(String[] args) throws Throwable{
new TestA().run();
}
diff --git a/test/org/joni/test/TestC.java b/test/org/joni/test/TestC.java
index 94f4218..9af3941 100644
--- a/test/org/joni/test/TestC.java
+++ b/test/org/joni/test/TestC.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.test;
@@ -34,14 +34,14 @@ public class TestC extends Test {
public Encoding encoding() {
return EUCJPEncoding.INSTANCE;
}
-
+
public String testEncoding() {
return "cp1250";
}
public Syntax syntax() {
return Syntax.DEFAULT;
- }
+ }
public void test() {
x2s("", "", 0, 0);
@@ -465,9 +465,9 @@ public class TestC extends Test {
if (Config.VANILLA) x2s("\\xca\\xb8", "\u0118\u00b8", 0, 2);
x2s(".", "\u00a4\u02d8", 0, 2);
x2s("..", "\u00a4\u00ab\u00a4\u00ad", 0, 4);
- x2s("\\w", "\u00a4\u015e", 0, 2);
- ns("\\W", "\u00a4\u02d8");
- x2s("[\\W]", "\u00a4\u00a6$", 2, 3);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\\w", "\u00a4\u015e", 0, 2);
+ if (!org.joni.Config.NON_UNICODE_SDW) ns("\\W", "\u00a4\u02d8");
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("[\\W]", "\u00a4\u00a6$", 2, 3);
x2s("\\S", "\u00a4\u02dd", 0, 2);
x2s("\\S", "\u00b4\u00c1", 0, 2);
x2s("\\b", "\u00b5\u00a4 ", 0, 0);
@@ -479,27 +479,27 @@ public class TestC extends Test {
ns("[\u00a4\u0118\u00a4\u00cb]", "\u00a4\u011a");
x2s("[\u00a4\u00a6-\u00a4\u015e]", "\u00a4\u00a8", 0, 2);
ns("[^\u00a4\u00b1]", "\u00a4\u00b1");
- x2s("[\\w]", "\u00a4\u00cd", 0, 2);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("[\\w]", "\u00a4\u00cd", 0, 2);
ns("[\\d]", "\u00a4\u0150");
x2s("[\\D]", "\u00a4\u010e", 0, 2);
ns("[\\s]", "\u00a4\u017b");
x2s("[\\S]", "\u00a4\u0158", 0, 2);
- x2s("[\\w\\d]", "\u00a4\u010d", 0, 2);
- x2s("[\\w\\d]", " \u00a4\u010d", 3, 5);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("[\\w\\d]", "\u00a4\u010d", 0, 2);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("[\\w\\d]", " \u00a4\u010d", 3, 5);
ns("\\w\u00b5\u00b4\u013d\u00d6", " \u00b5\u00b4\u013d\u00d6");
x2s("\u00b5\u00b4\\W\u013d\u00d6", "\u00b5\u00b4 \u013d\u00d6", 0, 5);
x2s("\u00a4\u02d8.\u00a4\u00a4.\u00a4\u00a6", "\u00a4\u02d8\u00a4\u02d8\u00a4\u00a4\u00a4\u00a4\u00a4\u00a6", 0, 10);
- x2s(".\\w\u00a4\u00a6\\W..\u00a4\u013e", "\u00a4\u00a8\u00a4\u00a6\u00a4\u00a6 \u00a4\u00a6\u00a4\u013e\u00a4\u013e", 0, 13);
- x2s("\\s\\w\u00a4\u0142\u00a4\u0142\u00a4\u0142", " \u00a4\u0142\u00a4\u0142\u00a4\u0142\u00a4\u0142", 0, 9);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s(".\\w\u00a4\u00a6\\W..\u00a4\u013e", "\u00a4\u00a8\u00a4\u00a6\u00a4\u00a6 \u00a4\u00a6\u00a4\u013e\u00a4\u013e", 0, 13);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\\s\\w\u00a4\u0142\u00a4\u0142\u00a4\u0142", " \u00a4\u0142\u00a4\u0142\u00a4\u0142\u00a4\u0142", 0, 9);
x2s("\u00a4\u02d8\u00a4\u02d8.\u00a4\u00b1", "\u00a4\u02d8\u00a4\u02d8\u00a4\u00b1\u00a4\u00b1", 0, 8);
ns(".\u00a4\u00a4", "\u00a4\u00a4\u00a4\u00a8");
x2s(".\u00a4\u015e", "\u00a4\u015e\u00a4\u015e", 0, 4);
x2s("^\u00a4\u02d8", "\u00a4\u02d8", 0, 2);
x2s("^\u00a4\u0155$", "\u00a4\u0155", 0, 2);
- x2s("^\\w$", "\u00a4\u00cb", 0, 2);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("^\\w$", "\u00a4\u00cb", 0, 2);
x2s("^\\w\u00a4\u00ab\u00a4\u00ad\u00a4\u017b\u00a4\u00b1\u00a4\u0142$", "z\u00a4\u00ab\u00a4\u00ad\u00a4\u017b\u00a4\u00b1\u00a4\u0142", 0, 11);
x2s("^\\w...\u00a4\u00a6\u00a4\u00a8\u00a4\u015e$", "z\u00a4\u02d8\u00a4\u00a4\u00a4\u00a6\u00a4\u00a6\u00a4\u00a8\u00a4\u015e", 0, 13);
- x2s("\\w\\w\\s\\W\u00a4\u015e\u00a4\u015e\u00a4\u015e\\d", "a\u00a4\u015e \u00a4\u015e\u00a4\u015e\u00a4\u015e4", 0, 12);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\\w\\w\\s\\W\u00a4\u015e\u00a4\u015e\u00a4\u015e\\d", "a\u00a4\u015e \u00a4\u015e\u00a4\u015e\u00a4\u015e4", 0, 12);
x2s("\\A\u00a4\u017c\u00a4\u00c1\u00a4\u00c4", "\u00a4\u017c\u00a4\u00c1\u00a4\u00c4", 0, 6);
x2s("\u00a4\u0155\u00a4\u00e1\u00a4\u00e2\\Z", "\u00a4\u0155\u00a4\u00e1\u00a4\u00e2", 0, 6);
x2s("\u00a4\u00ab\u00a4\u00ad\u00a4\u017b\\z", "\u00a4\u00ab\u00a4\u00ad\u00a4\u017b", 0, 6);
@@ -555,9 +555,9 @@ public class TestC extends Test {
x2s("\u00b5\u00b4|\u013d\u00d6\\Z", "\u013d\u00d6\n", 0, 2);
x2s("\u00b5\u00b4|\u013d\u00d6\\z", "\u013d\u00d6\u00b5\u00b4", 2, 4);
x2s("\u00b5\u00b4|\u013d\u00d6\\z", "\u013d\u00d6", 0, 2);
- x2s("\\w|\\s", "\u00a4\u015e", 0, 2);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\\w|\\s", "\u00a4\u015e", 0, 2);
x2s("\\w|%", "%\u00a4\u015e", 0, 1);
- x2s("\\w|[&$]", "\u00a4\u00a6&", 0, 2);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\\w|[&$]", "\u00a4\u00a6&", 0, 2);
x2s("[\u00a4\u00a4-\u00a4\u00b1]", "\u00a4\u00a6", 0, 2);
x2s("[\u00a4\u00a4-\u00a4\u00b1]|[^\u00a4\u00ab-\u00a4\u0142]", "\u00a4\u02d8", 0, 2);
x2s("[\u00a4\u00a4-\u00a4\u00b1]|[^\u00a4\u00ab-\u00a4\u0142]", "\u00a4\u00ab", 0, 2);
@@ -688,7 +688,7 @@ public class TestC extends Test {
x3s("(((((((\u00a4\u00dd*)\u00a4\u00da))))))\u00a4\u00d4\\7", "\u00a4\u00dd\u00a4\u00dd\u00a4\u00dd\u00a4\u00da\u00a4\u00d4\u00a4\u00dd\u00a4\u00dd\u00a4\u00dd", 0, 6, 7);
x2s("(\u00a4\u010e)(\u00a4\u0147)(\u00a4\u0150)\\2\\1\\3", "\u00a4\u010e\u00a4\u0147\u00a4\u0150\u00a4\u0147\u00a4\u010e\u00a4\u0150", 0, 12);
x2s("([\u00a4\u00ad-\u00a4\u00b1])\\1", "\u00a4\u017b\u00a4\u017b", 0, 4);
- x2s("(\\w\\d\\s)\\1", "\u00a4\u02d85 \u00a4\u02d85 ", 0, 8);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("(\\w\\d\\s)\\1", "\u00a4\u02d85 \u00a4\u02d85 ", 0, 8);
ns("(\\w\\d\\s)\\1", "\u00a4\u02d85 \u00a4\u02d85");
x2s("(\u0102\u017b\u02c7\u00a9|[\u00a4\u02d8-\u00a4\u00a6]{3})\\1", "\u0102\u017b\u02c7\u00a9\u0102\u017b\u02c7\u00a9", 0, 8);
x2s("...(\u0102\u017b\u02c7\u00a9|[\u00a4\u02d8-\u00a4\u00a6]{3})\\1", "\u00a4\u02d8a\u00a4\u02d8\u0102\u017b\u02c7\u00a9\u0102\u017b\u02c7\u00a9", 0, 13);
@@ -729,7 +729,7 @@ public class TestC extends Test {
x2s("a<b>\u0104\u0110\u02c7\u013d\u0104\u00b8\u0104\u00e7\u0104\u00f3\u00a4\u00ce\u0104\u0154\u0104\u00a6\u0104\u00f3\u0104\u00ed\u02c7\u013d\u0104\u00c9<\\/b>", "a<b>\u0104\u0110\u02c7\u013d\u0104\u00b8\u0104\u00e7\u0104\u00f3\u00a4\u00ce\u0104\u0154\u0104\u00a6\u0104\u00f3\u0104\u00ed\u02c7\u013d\u0104\u00c9</b>", 0, 32);
x2s(".<b>\u0104\u0110\u02c7\u013d\u0104\u00b8\u0104\u00e7\u0104\u00f3\u00a4\u00ce\u0104\u0154\u0104\u00a6\u0104\u00f3\u0104\u00ed\u02c7\u013d\u0104\u00c9<\\/b>", "a<b>\u0104\u0110\u02c7\u013d\u0104\u00b8\u0104\u00e7\u0104\u00f3\u00a4\u00ce\u0104\u0154\u0104\u00a6\u0104\u00f3\u0104\u00ed\u02c7\u013d\u0104\u00c9</b>", 0, 32);
}
-
+
public static void main(String[] args) throws Throwable{
new TestC().run();
}
diff --git a/test/org/joni/test/TestCornerCases.java b/test/org/joni/test/TestCornerCases.java
index b2b8377..717766d 100644
--- a/test/org/joni/test/TestCornerCases.java
+++ b/test/org/joni/test/TestCornerCases.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.test;
@@ -35,14 +35,14 @@ public class TestCornerCases extends Test {
public Encoding encoding() {
return ASCIIEncoding.INSTANCE;
}
-
+
public String testEncoding() {
return "cp1250";
}
public Syntax syntax() {
return Syntax.DEFAULT;
- }
+ }
public void test() {
byte[] reg = "l.".getBytes();
@@ -55,7 +55,7 @@ public class TestCornerCases extends Test {
nfail++;
}
}
-
+
public static void main(String[] args) throws Throwable{
new TestCornerCases().run();
}
diff --git a/test/org/joni/test/TestCrnl.java b/test/org/joni/test/TestCrnl.java
index a8ef6a6..9a8c65c 100644
--- a/test/org/joni/test/TestCrnl.java
+++ b/test/org/joni/test/TestCrnl.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.test;
@@ -34,14 +34,14 @@ public class TestCrnl extends Test {
public Encoding encoding() {
return ASCIIEncoding.INSTANCE;
}
-
+
public String testEncoding() {
return "ascii";
}
public Syntax syntax() {
return Syntax.DEFAULT;
- }
+ }
public void test() {
x2s("", "\r\n", 0, 0);
@@ -76,10 +76,10 @@ public class TestCrnl extends Test {
x2s("(?=a\\Z).", "a\r\n", 0, 1);
ns("(?=a\\Z).", "a\r");
x2s("(?!a\\Z)..", "a\r", 0, 2);
-
+
if (nfail > 0 || nerror > 0) Config.err.println("make sure to enable USE_CRNL_AS_LINE_TERMINATOR");
}
-
+
public static void main(String[] args) throws Throwable{
new TestCrnl().run();
}
diff --git a/test/org/joni/test/TestJoni.java b/test/org/joni/test/TestJoni.java
index f1cb9ec..a94ed56 100644
--- a/test/org/joni/test/TestJoni.java
+++ b/test/org/joni/test/TestJoni.java
@@ -1,34 +1,57 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
package org.joni.test;
import junit.framework.TestCase;
public class TestJoni extends TestCase {
-
+
private Test testa;
private Test testc;
private Test testu;
private Test testnsu8;
-
+ private Test testLookBehind;
+ private Test testu8;
+
protected void setUp() {
testa = new TestA();
testc = new TestC();
testu = new TestU();
testnsu8 = new TestNSU8();
+ testu8 = new TestU8();
+ testLookBehind = new TestLookBehind();
}
-
+
protected void tearDown() {
}
-
+
private void testJoniTest(Test test) {
test.run();
assertEquals(test.nerror, 0);
assertEquals(test.nfail, 0);
}
-
+
public void testAscii() {
testJoniTest(testa);
}
-
+
public void testEUCJP() {
testJoniTest(testc);
}
@@ -36,5 +59,10 @@ public class TestJoni extends TestCase {
public void testUnicode() {
testJoniTest(testu);
testJoniTest(testnsu8);
+ testJoniTest(testu8);
+ }
+
+ public void testLookBehind() {
+ testJoniTest(testLookBehind);
}
}
diff --git a/src/org/joni/OptEnvironment.java b/test/org/joni/test/TestLookBehind.java
similarity index 57%
copy from src/org/joni/OptEnvironment.java
copy to test/org/joni/test/TestLookBehind.java
index 4b59c31..9ae4379 100644
--- a/src/org/joni/OptEnvironment.java
+++ b/test/org/joni/test/TestLookBehind.java
@@ -1,39 +1,54 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-package org.joni;
+package org.joni.test;
import org.jcodings.Encoding;
+import org.jcodings.specific.ASCIIEncoding;
+import org.joni.Option;
+import org.joni.Syntax;
+
+public class TestLookBehind extends Test {
+
+ public int option() {
+ return Option.DEFAULT;
+ }
+
+ public Encoding encoding() {
+ return ASCIIEncoding.INSTANCE;
+ }
+
+ public String testEncoding() {
+ return "iso-8859-1";
+ }
+
+ public Syntax syntax() {
+ return Syntax.DEFAULT;
+ }
+
+ @Override
+ public void test() {
+ x2s("(?<=a).*b", "aab", 1, 3);
+ }
+
+ public static void main(String[] args) throws Throwable {
+ new TestLookBehind().run();
+ }
-// remove this one in future and pass mmd directly
-final class OptEnvironment {
- final MinMaxLen mmd = new MinMaxLen();
- Encoding enc;
- int options;
- int caseFoldFlag;
- ScanEnvironment scanEnv;
-
- void copy(OptEnvironment other) {
- mmd.copy(other.mmd);
- enc = other.enc;
- options = other.options;
- caseFoldFlag = other.caseFoldFlag;
- scanEnv = other.scanEnv;
- }
}
diff --git a/test/org/joni/test/TestNSU8.java b/test/org/joni/test/TestNSU8.java
index 54dd902..ec4ed2d 100644
--- a/test/org/joni/test/TestNSU8.java
+++ b/test/org/joni/test/TestNSU8.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.test;
@@ -29,19 +29,19 @@ public class TestNSU8 extends Test {
public int option() {
return Option.DEFAULT;
}
-
+
public Encoding encoding() {
return NonStrictUTF8Encoding.INSTANCE;
}
-
+
public String testEncoding() {
return "utf-8";
}
-
+
public Syntax syntax() {
return Syntax.DEFAULT;
}
-
+
public void test() {
xx("([^\\[\\]]+)".getBytes(), new byte[]{(byte)240, (byte)32, (byte)32, (byte)32, (byte)32}, 0, 5, 1, false);
xx("([^\\[\\]]+)".getBytes(), new byte[]{(byte)240, (byte)32, (byte)32, (byte)32}, 0, 4, 1, false);
@@ -58,7 +58,7 @@ public class TestNSU8 extends Test {
xx("([^\\[\\]]+)".getBytes(), new byte[]{(byte)192, (byte)32}, 0, 2, 1, false);
xx("([^\\[\\]]+)".getBytes(), new byte[]{(byte)192}, 0, 1, 1, false);
}
-
+
public static void main(String[] args) throws Throwable {
new TestNSU8().run();
}
diff --git a/test/org/joni/test/TestU.java b/test/org/joni/test/TestU.java
index ee12227..eb4a2a7 100644
--- a/test/org/joni/test/TestU.java
+++ b/test/org/joni/test/TestU.java
@@ -1,20 +1,20 @@
/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.joni.test;
@@ -29,23 +29,23 @@ public class TestU extends Test {
public int option() {
return Option.DEFAULT;
}
-
+
public Encoding encoding() {
return UTF16BEEncoding.INSTANCE;
}
-
+
public String testEncoding() {
return "iso-8859-1";
}
-
+
public Syntax syntax() {
return Syntax.DEFAULT;
}
-
+
private int ulen(byte[]bytes) {
return encoding().strByteLengthNull(bytes, 0, bytes.length);
}
-
+
private String uconv(byte []bytes, int len) {
StringBuilder sb = new StringBuilder();
@@ -61,22 +61,22 @@ public class TestU extends Test {
}
} else {
sb.append(String.format("\\%03o", c));
- c = bytes[i+1] & 0xff;
+ c = bytes[i+1] & 0xff;
sb.append(String.format("\\%03o", c));
}
}
-
+
return sb.toString();
}
-
+
protected String repr(byte[]bytes) {
return uconv(bytes, ulen(bytes));
}
-
+
protected int length(byte[]bytes) {
return ulen(bytes);
}
-
+
public void test() {
x2s("\000\000", "\000\000", 0, 0);
x2s("\000^\000\000", "\000\000", 0, 0);
@@ -107,12 +107,12 @@ public class TestU extends Test {
x2s("\000.\000\000", "\000a\000\000", 0, 2);
ns("\000.\000\000", "\000\000");
x2s("\000.\000.\000\000", "\000a\000b\000\000", 0, 4);
- x2s("\000\134\000w\000\000", "\000e\000\000", 0, 2);
- ns("\000\134\000W\000\000", "\000e\000\000");
- x2s("\000\134\000s\000\000", "\000 \000\000", 0, 2);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000\134\000w\000\000", "\000e\000\000", 0, 2);
+ if (!org.joni.Config.NON_UNICODE_SDW) ns("\000\134\000W\000\000", "\000e\000\000");
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000\134\000s\000\000", "\000 \000\000", 0, 2);
x2s("\000\134\000S\000\000", "\000b\000\000", 0, 2);
- x2s("\000\134\000d\000\000", "\0004\000\000", 0, 2);
- ns("\000\134\000D\000\000", "\0004\000\000");
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000\134\000d\000\000", "\0004\000\000", 0, 2);
+ if (!org.joni.Config.NON_UNICODE_SDW) ns("\000\134\000D\000\000", "\0004\000\000");
x2s("\000\134\000b\000\000", "\000z\000 \000\000", 0, 0);
x2s("\000\134\000b\000\000", "\000 \000z\000\000", 2, 2);
x2s("\000\134\000B\000\000", "\000z\000z\000 \000\000", 2, 2);
@@ -128,18 +128,18 @@ public class TestU extends Test {
x2s("\000[\000\134\000^\000]\000+\000\000", "\0000\000^\000^\0001\000\000", 2, 6);
x2s("\000[\000b\000-\000]\000\000", "\000b\000\000", 0, 2);
x2s("\000[\000b\000-\000]\000\000", "\000-\000\000", 0, 2);
- x2s("\000[\000\134\000w\000]\000\000", "\000z\000\000", 0, 2);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000[\000\134\000w\000]\000\000", "\000z\000\000", 0, 2);
ns("\000[\000\134\000w\000]\000\000", "\000 \000\000");
- x2s("\000[\000\134\000W\000]\000\000", "\000b\000$\000\000", 2, 4);
- x2s("\000[\000\134\000d\000]\000\000", "\0005\000\000", 0, 2);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000[\000\134\000W\000]\000\000", "\000b\000$\000\000", 2, 4);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000[\000\134\000d\000]\000\000", "\0005\000\000", 0, 2);
ns("\000[\000\134\000d\000]\000\000", "\000e\000\000");
x2s("\000[\000\134\000D\000]\000\000", "\000t\000\000", 0, 2);
- ns("\000[\000\134\000D\000]\000\000", "\0003\000\000");
- x2s("\000[\000\134\000s\000]\000\000", "\000 \000\000", 0, 2);
+ if (!org.joni.Config.NON_UNICODE_SDW) ns("\000[\000\134\000D\000]\000\000", "\0003\000\000");
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000[\000\134\000s\000]\000\000", "\000 \000\000", 0, 2);
ns("\000[\000\134\000s\000]\000\000", "\000a\000\000");
x2s("\000[\000\134\000S\000]\000\000", "\000b\000\000", 0, 2);
- ns("\000[\000\134\000S\000]\000\000", "\000 \000\000");
- x2s("\000[\000\134\000w\000\134\000d\000]\000\000", "\0002\000\000", 0, 2);
+ if (!org.joni.Config.NON_UNICODE_SDW) ns("\000[\000\134\000S\000]\000\000", "\000 \000\000");
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000[\000\134\000w\000\134\000d\000]\000\000", "\0002\000\000", 0, 2);
ns("\000[\000\134\000w\000\134\000d\000]\000\000", "\000 \000\000");
x2s("\000[\000[\000:\000u\000p\000p\000e\000r\000:\000]\000]\000\000", "\000B\000\000", 0, 2);
x2s("\000[\000*\000[\000:\000x\000d\000i\000g\000i\000t\000:\000]\000+\000]\000\000", "\000+\000\000", 0, 2);
@@ -176,19 +176,19 @@ public class TestU extends Test {
ns("\000\134\000w\000a\000b\000c\000\000", "\000 \000a\000b\000c\000\000");
x2s("\000a\000\134\000W\000b\000c\000\000", "\000a\000 \000b\000c\000\000", 0, 8);
x2s("\000a\000.\000b\000.\000c\000\000", "\000a\000a\000b\000b\000c\000\000", 0, 10);
- x2s("\000.\000\134\000w\000b\000\134\000W\000.\000.\000c\000\000", "\000a\000b\000b\000 \000b\000c\000c\000\000", 0, 14);
- x2s("\000\134\000s\000\134\000w\000z\000z\000z\000\000", "\000 \000z\000z\000z\000z\000\000", 0, 10);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000.\000\134\000w\000b\000\134\000W\000.\000.\000c\000\000", "\000a\000b\000b\000 \000b\000c\000c\000\000", 0, 14);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000\134\000s\000\134\000w\000z\000z\000z\000\000", "\000 \000z\000z\000z\000z\000\000", 0, 10);
x2s("\000a\000a\000.\000b\000\000", "\000a\000a\000b\000b\000\000", 0, 8);
ns("\000.\000a\000\000", "\000a\000b\000\000");
x2s("\000.\000a\000\000", "\000a\000a\000\000", 0, 4);
x2s("\000^\000a\000\000", "\000a\000\000", 0, 2);
x2s("\000^\000a\000$\000\000", "\000a\000\000", 0, 2);
- x2s("\000^\000\134\000w\000$\000\000", "\000a\000\000", 0, 2);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000^\000\134\000w\000$\000\000", "\000a\000\000", 0, 2);
ns("\000^\000\134\000w\000$\000\000", "\000 \000\000");
- x2s("\000^\000\134\000w\000a\000b\000$\000\000", "\000z\000a\000b\000\000", 0, 6);
- x2s("\000^\000\134\000w\000a\000b\000c\000d\000e\000f\000$\000\000", "\000z\000a\000b\000c\000d\000e\000f\000\000", 0, 14);
- x2s("\000^\000\134\000w\000.\000.\000.\000d\000e\000f\000$\000\000", "\000z\000a\000b\000c\000d\000e\000f\000\000", 0, 14);
- x2s("\000\134\000w\000\134\000w\000\134\000s\000\134\000W\000a\000a\000a\000\134\000d\000\000", "\000a\000a\000 \000 \000a\000a\000a\0004\000\000", 0, 16);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000^\000\134\000w\000a\000b\000$\000\000", "\000z\000a\000b\000\000", 0, 6);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000^\000\134\000w\000a\000b\000c\000d\000e\000f\000$\000\000", "\000z\000a\000b\000c\000d\000e\000f\000\000", 0, 14);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000^\000\134\000w\000.\000.\000.\000d\000e\000f\000$\000\000", "\000z\000a\000b\000c\000d\000e\000f\000\000", 0, 14);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000\134\000w\000\134\000w\000\134\000s\000\134\000W\000a\000a\000a\000\134\000d\000\000", "\000a\000a\000 \000 \000a\000a\000a\0004\000\000", 0, 16);
x2s("\000\134\000A\000\134\000Z\000\000", "\000\000", 0, 0);
x2s("\000\134\000A\000x\000y\000z\000\000", "\000x\000y\000z\000\000", 0, 6);
x2s("\000x\000y\000z\000\134\000Z\000\000", "\000x\000y\000z\000\000", 0, 6);
@@ -202,8 +202,8 @@ public class TestU extends Test {
x2s("\000\134\000^\000\134\000$\000\000", "\000^\000$\000\000", 0, 4);
x2s("\000^\000x\000?\000y\000\000", "\000x\000y\000\000", 0, 4);
x2s("\000^\000(\000x\000?\000y\000)\000\000", "\000x\000y\000\000", 0, 4);
- x2s("\000\134\000w\000\000", "\000_\000\000", 0, 2);
- ns("\000\134\000W\000\000", "\000_\000\000");
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000\134\000w\000\000", "\000_\000\000", 0, 2);
+ if (!org.joni.Config.NON_UNICODE_SDW) ns("\000\134\000W\000\000", "\000_\000\000");
x2s("\000(\000?\000=\000z\000)\000z\000\000", "\000z\000\000", 0, 2);
ns("\000(\000?\000=\000z\000)\000.\000\000", "\000a\000\000");
x2s("\000(\000?\000!\000z\000)\000a\000\000", "\000a\000\000", 0, 2);
@@ -278,7 +278,7 @@ public class TestU extends Test {
x2s("\000a\000|\000b\000\134\000Z\000\000", "\000b\000\000", 0, 2);
x2s("\000a\000|\000b\000\134\000z\000\000", "\000b\000a\000\000", 2, 4);
x2s("\000a\000|\000b\000\134\000z\000\000", "\000b\000\000", 0, 2);
- x2s("\000\134\000w\000|\000\134\000s\000\000", "\000 \000\000", 0, 2);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000\134\000w\000|\000\134\000s\000\000", "\000 \000\000", 0, 2);
ns("\000\134\000w\000|\000\134\000w\000\000", "\000 \000\000");
x2s("\000\134\000w\000|\000%\000\000", "\000%\000\000", 0, 2);
x2s("\000\134\000w\000|\000[\000&\000$\000]\000\000", "\000&\000\000", 0, 2);
@@ -360,7 +360,7 @@ public class TestU extends Test {
x2s("\000(\000?\000:\000X\000*\000)\000(\000?\000i\000:\000x\000a\000)\000\000", "\000X\000X\000X\000a\000\000", 0, 8);
x2s("\000(\000d\000+\000)\000(\000[\000^\000a\000b\000c\000]\000z\000)\000\000", "\000d\000d\000d\000z\000\000", 0, 8);
x2s("\000(\000[\000^\000a\000b\000c\000]\000*\000)\000(\000[\000^\000a\000b\000c\000]\000z\000)\000\000", "\000d\000d\000d\000z\000\000", 0, 8);
- x2s("\000(\000\134\000w\000+\000)\000(\000\134\000w\000z\000)\000\000", "\000d\000d\000d\000z\000\000", 0, 8);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000(\000\134\000w\000+\000)\000(\000\134\000w\000z\000)\000\000", "\000d\000d\000d\000z\000\000", 0, 8);
x3s("\000(\000a\000)\000\000", "\000a\000\000", 0, 2, 1);
x3s("\000(\000a\000b\000)\000\000", "\000a\000b\000\000", 0, 4, 1);
x2s("\000(\000(\000a\000b\000)\000)\000\000", "\000a\000b\000\000", 0, 4);
@@ -423,7 +423,7 @@ public class TestU extends Test {
x3s("\000(\000(\000(\000(\000(\000(\000(\000a\000*\000)\000b\000)\000)\000)\000)\000)\000)\000c\000\134\0007\000\000", "\000a\000a\000a\000b\000c\000a\000a\000a\000\000", 0, 6, 7);
x2s("\000(\000a\000)\000(\000b\000)\000(\000c\000)\000\134\0002\000\134\0001\000\134\0003\000\000", "\000a\000b\000c\000b\000a\000c\000\000", 0, 12);
x2s("\000(\000[\000a\000-\000d\000]\000)\000\134\0001\000\000", "\000c\000c\000\000", 0, 4);
- x2s("\000(\000\134\000w\000\134\000d\000\134\000s\000)\000\134\0001\000\000", "\000f\0005\000 \000f\0005\000 \000\000", 0, 12);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000(\000\134\000w\000\134\000d\000\134\000s\000)\000\134\0001\000\000", "\000f\0005\000 \000f\0005\000 \000\000", 0, 12);
ns("\000(\000\134\000w\000\134\000d\000\134\000s\000)\000\134\0001\000\000", "\000f\0005\000 \000f\0005\000\000");
x2s("\000(\000w\000h\000o\000|\000[\000a\000-\000c\000]\000{\0003\000}\000)\000\134\0001\000\000", "\000w\000h\000o\000w\000h\000o\000\000", 0, 12);
x2s("\000.\000.\000.\000(\000w\000h\000o\000|\000[\000a\000-\000c\000]\000{\0003\000}\000)\000\134\0001\000\000", "\000a\000b\000c\000w\000h\000o\000w\000h\000o\000\000", 0, 18);
@@ -435,7 +435,7 @@ public class TestU extends Test {
x2s("\000(\000a\000*\000\134\000Z\000)\000\134\0001\000\000", "\000a\000\000", 2, 2);
x2s("\000.\000(\000a\000*\000\134\000Z\000)\000\134\0001\000\000", "\000b\000a\000\000", 2, 4);
x3s("\000(\000.\000(\000a\000b\000c\000)\000\134\0002\000)\000\000", "\000z\000a\000b\000c\000a\000b\000c\000\000", 0, 14, 1);
- x3s("\000(\000.\000(\000.\000.\000\134\000d\000.\000)\000\134\0002\000)\000\000", "\000z\0001\0002\0003\0004\0001\0002\0003\0004\000\000", 0, 18, 1);
+ if (!org.joni.Config.NON_UNICODE_SDW) x3s("\000(\000.\000(\000.\000.\000\134\000d\000.\000)\000\134\0002\000)\000\000", "\000z\0001\0002\0003\0004\0001\0002\0003\0004\000\000", 0, 18, 1);
x2s("\000(\000(\000?\000i\000:\000a\000z\000)\000)\000\134\0001\000\000", "\000A\000z\000A\000z\000\000", 0, 8);
ns("\000(\000(\000?\000i\000:\000a\000z\000)\000)\000\134\0001\000\000", "\000A\000z\000a\000z\000\000");
x2s("\000(\000?\000<\000=\000a\000)\000b\000\000", "\000a\000b\000\000", 2, 4);
@@ -459,10 +459,10 @@ public class TestU extends Test {
x2s("\000\134\000g\000<\000n\000>\000(\000a\000b\000c\000|\000d\000f\000(\000?\000<\000n\000>\000.\000Y\000Z\000)\000{\0002\000,\0008\000}\000)\000{\0000\000}\000\000", "\000X\000Y\000Z\000\000", 0, 6);
x2s("\000\134\000A\000(\000?\000<\000n\000>\000(\000a\000\134\000g\000<\000n\000>\000)\000|\000)\000\134\000z\000\000", "\000a\000a\000a\000a\000\000", 0, 8);
x2s("\000(\000?\000<\000n\000>\000|\000\134\000g\000<\000m\000>\000\134\000g\000<\000n\000>\000)\000\134\000z\000|\000\134\000z\000E\000N\000D\000 \000(\000?\000<\000m\000>\000a\000|\000(\000b\000)\000\134\000g\000<\000m\000>\000)\000\000", "\000b\000b\000b\000b\000a\000b\000b\000a\000\000", 0, 16);
- x2s("\000(\000?\000<\000n\000a\000m\000e\0001\0002\0004\0000\000>\000\134\000w\000+\000\134\000s\000x\000)\000a\000+\000\134\000k\000<\000n\000a\000m\000e\0001\0002\0004\0000\000>\000\000", "\000 \000 \000f\000g\000 \000x\000a\000a\000a\000a\000a\000a\000a\000a\000f\000g\000 \000x\000\000", 4, 36);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000(\000?\000<\000n\000a\000m\000e\0001\0002\0004\0000\000>\000\134\000w\000+\000\134\000s\000x\000)\000a\000+\000\134\000k\000<\000n\000a\000m\000e\0001\0002\0004\0000\000>\000\000", "\000 \000 \000f\000g\000 \000x\000a\000a\000a\000a\000a\000a\000a\000a\000f\000g\000 \000x\000\000", 4, 36);
x3s("\000(\000z\000)\000(\000)\000(\000)\000(\000?\000<\000_\0009\000>\000a\000)\000\134\000g\000<\000_\0009\000>\000\000", "\000z\000a\000a\000\000", 4, 6, 1);
x2s("\000(\000.\000)\000(\000(\000(\000?\000<\000_\000>\000a\000)\000)\000)\000\134\000k\000<\000_\000>\000\000", "\000z\000a\000a\000\000", 0, 6);
- x2s("\000(\000(\000?\000<\000n\000a\000m\000e\0001\000>\000\134\000d\000)\000|\000(\000?\000<\000n\000a\000m\000e\0002\000>\000\134\000w\000)\000)\000(\000\134\000k\000<\000n\000a\000m\000e\0001\000>\000|\000\134\000k\000<\000n\000a\000m\000e\0002\000>\000)\000\000", "\000f\000f\000\000", 0, 4);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000(\000(\000?\000<\000n\000a\000m\000e\0001\000>\000\134\000d\000)\000|\000(\000?\000<\000n\000a\000m\000e\0002\000>\000\134\000w\000)\000)\000(\000\134\000k\000<\000n\000a\000m\000e\0001\000>\000|\000\134\000k\000<\000n\000a\000m\000e\0002\000>\000)\000\000", "\000f\000f\000\000", 0, 4);
x2s("\000(\000?\000:\000(\000?\000<\000x\000>\000)\000|\000(\000?\000<\000x\000>\000e\000f\000g\000)\000)\000\134\000k\000<\000x\000>\000\000", "\000\000", 0, 0);
x2s("\000(\000?\000:\000(\000?\000<\000x\000>\000a\000b\000c\000)\000|\000(\000?\000<\000x\000>\000e\000f\000g\000)\000)\000\134\000k\000<\000x\000>\000\000", "\000a\000b\000c\000e\000f\000g\000e\000f\000g\000\000", 6, 18);
ns("\000(\000?\000:\000(\000?\000<\000x\000>\000a\000b\000c\000)\000|\000(\000?\000<\000x\000>\000e\000f\000g\000)\000)\000\134\000k\000<\000x\000>\000\000", "\000a\000b\000c\000e\000f\000g\000\000");
@@ -501,7 +501,7 @@ public class TestU extends Test {
x2s("\000.\000.\000\000", "0K0M\000\000", 0, 4);
x2s("\000\134\000w\000\000", "0J\000\000", 0, 2);
ns("\000\134\000W\000\000", "0B\000\000");
- x2s("\000[\000\134\000W\000]\000\000", "0F\000$\000\000", 2, 4);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000[\000\134\000W\000]\000\000", "0F\000$\000\000", 2, 4);
x2s("\000\134\000S\000\000", "0]\000\000", 0, 2);
x2s("\000\134\000S\000\000", "o\042\000\000", 0, 2);
x2s("\000\134\000b\000\000", "l\027\000 \000\000", 0, 0);
@@ -514,7 +514,7 @@ public class TestU extends Test {
x2s("\000[0F\000-0J\000]\000\000", "0H\000\000", 0, 2);
ns("\000[\000^0Q\000]\000\000", "0Q\000\000");
x2s("\000[\000\134\000w\000]\000\000", "0m\000\000", 0, 2);
- ns("\000[\000\134\000d\000]\000\000", "0u\000\000");
+ if (!org.joni.Config.NON_UNICODE_SDW) ns("\000[\000\134\000d\000]\000\000", "0u\000\000");
x2s("\000[\000\134\000D\000]\000\000", "0o\000\000", 0, 2);
ns("\000[\000\134\000s\000]\000\000", "0O\000\000");
x2s("\000[\000\134\000S\000]\000\000", "0x\000\000", 0, 2);
@@ -524,16 +524,16 @@ public class TestU extends Test {
x2s("\233<\000\134\000W\216\312\000\000", "\233<\000 \216\312\000\000", 0, 6);
x2s("0B\000.0D\000.0F\000\000", "0B0B0D0D0F\000\000", 0, 10);
x2s("\000.\000\134\000w0F\000\134\000W\000.\000.0^\000\000", "0H0F0F\000 0F0^0^\000\000", 0, 14);
- x2s("\000\134\000s\000\134\000w0S0S0S\000\000", "\000 0S0S0S0S\000\000", 0, 10);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000\134\000s\000\134\000w0S0S0S\000\000", "\000 0S0S0S0S\000\000", 0, 10);
x2s("0B0B\000.0Q\000\000", "0B0B0Q0Q\000\000", 0, 8);
ns("\000.0D\000\000", "0D0H\000\000");
x2s("\000.0J\000\000", "0J0J\000\000", 0, 4);
x2s("\000^0B\000\000", "0B\000\000", 0, 2);
x2s("\000^0\200\000$\000\000", "0\200\000\000", 0, 2);
x2s("\000^\000\134\000w\000$\000\000", "0k\000\000", 0, 2);
- x2s("\000^\000\134\000w0K0M0O0Q0S\000$\000\000", "\000z0K0M0O0Q0S\000\000", 0, 12);
- x2s("\000^\000\134\000w\000.\000.\000.0F0H0J\000$\000\000", "\000z0B0D0F0F0H0J\000\000", 0, 14);
- x2s("\000\134\000w\000\134\000w\000\134\000s\000\134\000W0J0J0J\000\134\000d\000\000", "\000a0J\000 \000 0J0J0J\0004\000\000", 0, 16);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000^\000\134\000w0K0M0O0Q0S\000$\000\000", "\000z0K0M0O0Q0S\000\000", 0, 12);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000^\000\134\000w\000.\000.\000.0F0H0J\000$\000\000", "\000z0B0D0F0F0H0J\000\000", 0, 14);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000\134\000w\000\134\000w\000\134\000s\000\134\000W0J0J0J\000\134\000d\000\000", "\000a0J\000 \000 0J0J0J\0004\000\000", 0, 16);
x2s("\000\134\000A0_0a0d\000\000", "0_0a0d\000\000", 0, 6);
x2s("0\2000\2010\202\000\134\000Z\000\000", "0\2000\2010\202\000\000", 0, 6);
x2s("0K0M0O\000\134\000z\000\000", "0K0M0O\000\000", 0, 6);
@@ -722,7 +722,7 @@ public class TestU extends Test {
x3s("\000(\000(\000(\000(\000(\000(\000(0}\000*\000)0z\000)\000)\000)\000)\000)\000)0t\000\134\0007\000\000", "0}0}0}0z0t0}0}0}\000\000", 0, 6, 7);
x2s("\000(0o\000)\000(0r\000)\000(0u\000)\000\134\0002\000\134\0001\000\134\0003\000\000", "0o0r0u0r0o0u\000\000", 0, 12);
x2s("\000(\000[0M\000-0Q\000]\000)\000\134\0001\000\000", "0O0O\000\000", 0, 4);
- x2s("\000(\000\134\000w\000\134\000d\000\134\000s\000)\000\134\0001\000\000", "0B\0005\000 0B\0005\000 \000\000", 0, 12);
+ if (!org.joni.Config.NON_UNICODE_SDW) x2s("\000(\000\134\000w\000\134\000d\000\134\000s\000)\000\134\0001\000\000", "0B\0005\000 0B\0005\000 \000\000", 0, 12);
ns("\000(\000\134\000w\000\134\000d\000\134\000s\000)\000\134\0001\000\000", "0B\0005\000 0B\0005\000\000");
x2s("\000(\212\260\377\037\000|\000[0B\000-0F\000]\000{\0003\000}\000)\000\134\0001\000\000", "\212\260\377\037\212\260\377\037\000\000", 0, 8);
x2s("\000.\000.\000.\000(\212\260\377\037\000|\000[0B\000-0F\000]\000{\0003\000}\000)\000\134\0001\000\000", "0B\000a0B\212\260\377\037\212\260\377\037\000\000", 0, 14);
@@ -734,7 +734,7 @@ public class TestU extends Test {
x2s("\000(0B\000*\000\134\000Z\000)\000\134\0001\000\000", "0B\000\000", 2, 2);
x2s("\000.\000(0B\000*\000\134\000Z\000)\000\134\0001\000\000", "0D0B\000\000", 2, 4);
x3s("\000(\000.\000(0\2040D0\206\000)\000\134\0002\000)\000\000", "\000z0\2040D0\2060\2040D0\206\000\000", 0, 14, 1);
- x3s("\000(\000.\000(\000.\000.\000\134\000d\000.\000)\000\134\0002\000)\000\000", "0B\0001\0002\0003\0004\0001\0002\0003\0004\000\000", 0, 18, 1);
+ if (!org.joni.Config.NON_UNICODE_SDW) x3s("\000(\000.\000(\000.\000.\000\134\000d\000.\000)\000\134\0002\000)\000\000", "0B\0001\0002\0003\0004\0001\0002\0003\0004\000\000", 0, 18, 1);
x2s("\000(\000(\000?\000i\000:0B\000v0Z\000)\000)\000\134\0001\000\000", "0B\000v0Z0B\000v0Z\000\000", 0, 12);
x2s("\000(\000?\000<a\0320K\000>Y\011\000|\000\134\000(\000\134\000g\000<a\0320K\000>\000\134\000)\000)\000\000", "\000(\000(\000(\000(\000(\000(Y\011\000)\000)\000)\000)\000)\000)\000\000", 0, 26);
x2s("\000\134\000A\000(\000?\000:\000\134\000g\000<\226?\000_\0001\000>\000|\000\134\000g\000<N\221\000_\0002\000>\000|\000\134\000z}BN\206\000 \000 \000(\000?\000<\226?\000_\0001\000>\211\263\000|\201\352\000\134\000g\000<N\221\000_\0002\000>\201\352\000)\000(\000?\000<N\221\000_\0002\000>W(\000|\203\351\205\251\000\134\000g\000<\226?\000_\0001\000>\203\351\205\251\000)\000)\000$\000\000", "\203\351\205\251\201\352\203\351\205\251\201\352W(\201\352\203\351\205\251\201\352\203\35 [...]
@@ -763,7 +763,7 @@ public class TestU extends Test {
x2s("\000a\000<\000b\000>0\3200\3740\2700\3470\3630n0\3000\2460\3630\3550\3740\311\000<\000\134\000/\000b\000>\000\000", "\000a\000<\000b\000>0\3200\3740\2700\3470\3630n0\3000\2460\3630\3550\3740\311\000<\000/\000b\000>\000\000", 0, 40);
x2s("\000.\000<\000b\000>0\3200\3740\2700\3470\3630n0\3000\2460\3630\3550\3740\311\000<\000\134\000/\000b\000>\000\000", "\000a\000<\000b\000>0\3200\3740\2700\3470\3630n0\3000\2460\3630\3550\3740\311\000<\000/\000b\000>\000\000", 0, 40);
}
-
+
public static void main(String[] args) throws Throwable {
new TestU().run();
}
diff --git a/test/org/joni/test/TestU8.java b/test/org/joni/test/TestU8.java
new file mode 100644
index 0000000..53400f6
--- /dev/null
+++ b/test/org/joni/test/TestU8.java
@@ -0,0 +1,84 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package org.joni.test;
+
+import org.jcodings.Encoding;
+import org.jcodings.specific.UTF8Encoding;
+import org.joni.Option;
+import org.joni.Syntax;
+
+public class TestU8 extends Test {
+
+ public int option() {
+ return Option.DEFAULT;
+ }
+
+ public Encoding encoding() {
+ return UTF8Encoding.INSTANCE;
+ }
+
+ public String testEncoding() {
+ return "iso-8859-1";
+ }
+
+ public Syntax syntax() {
+ return Syntax.DEFAULT;
+ }
+
+ public void test() {
+ xx("^\\d\\d\\d-".getBytes(), new byte []{-30, -126, -84, 48, 45}, 0, 0, 0, true);
+ x2s("x{2}", "xx", 0, 2, Option.IGNORECASE);
+ x2s("x{2}", "XX", 0, 2, Option.IGNORECASE);
+ x2s("x{3}", "XxX", 0, 3, Option.IGNORECASE);
+ ns("x{2}", "x", Option.IGNORECASE);
+ ns("x{2}", "X", Option.IGNORECASE);
+
+ byte[] pat = new byte[] {(byte)227, (byte)131, (byte)160, (byte)40, (byte)46, (byte)41};
+ byte[] str = new byte[]{(byte)227, (byte)130, (byte)185, (byte)227, (byte)131, (byte)145, (byte)227, (byte)131, (byte)160, (byte)227, (byte)131, (byte)143, (byte)227, (byte)131, (byte)179, (byte)227, (byte)130, (byte)175};
+
+ x2(pat, str, 6, 12);
+
+ x2s("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0, 35, Option.IGNORECASE);
+ x2s("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 0, 35, Option.IGNORECASE);
+ x2s("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaAAAAAAAAAAAAAAAAA", 0, 35, Option.IGNORECASE);
+
+ pat = new byte[]{94, 40, (byte)239, (byte)188, (byte)161, 41, 92, 49, 36};
+ str = new byte[]{(byte)239, (byte)188, (byte)161, 65};
+
+ n(pat, str, Option.IGNORECASE);
+
+ pat = new byte[]{94, (byte)195, (byte)159, 123, 50, 125, 36};
+ str = new byte[]{(byte)195, (byte)159, 115, 115};
+
+ x2(pat, str, 0, 4, Option.IGNORECASE);
+
+ String str2 = new String(new byte[]{-61, -123, -61, -123});
+ String pat2 = new String(new byte[]{'^', -61, -123, '{', '2', '}', '$'});
+
+ // x2s(pat2, str2, 4, 4);
+ // x2s(pat2, str2, 4, 4, Option.IGNORECASE);
+
+ ns("(?i-mx:ak)a", "ema");
+ }
+
+ public static void main(String[] args) throws Throwable {
+ new TestU8().run();
+ }
+}
--
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