This commit was manufactured by cvs2svn to create tag
'GROOVY_1_0_JSR_03'.
git-svn-id: http://svn.codehaus.org/groovy/tags/GROOVY_1_0_JSR_03@2714 a5544e8c-8a19-0410-ba12-f9af4593a198
diff --git a/CVSROOT/checkoutlist b/CVSROOT/checkoutlist
deleted file mode 100644
index d326583..0000000
--- a/CVSROOT/checkoutlist
+++ /dev/null
@@ -1,15 +0,0 @@
-# The "checkoutlist" file is used to support additional version controlled
-# administrative files in $CVSROOT/CVSROOT, such as template files.
-#
-# The first entry on a line is a filename which will be checked out from
-# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
-# The remainder of the line is an error message to use if the file cannot
-# be checked out.
-#
-# File format:
-#
-# [<whitespace>]<filename><whitespace><error message><end-of-line>
-#
-# comment lines begin with '#'
-passwd
-log_accum.conf
\ No newline at end of file
diff --git a/CVSROOT/commitinfo b/CVSROOT/commitinfo
deleted file mode 100644
index b19e7b7..0000000
--- a/CVSROOT/commitinfo
+++ /dev/null
@@ -1,15 +0,0 @@
-# The "commitinfo" file is used to control pre-commit checks.
-# The filter on the right is invoked with the repository and a list
-# of files to check. A non-zero exit of the filter program will
-# cause the commit to be aborted.
-#
-# The first entry on a line is a regular expression which is tested
-# against the directory that the change is being committed to, relative
-# to the $CVSROOT. For the first match that is found, then the remainder
-# of the line is the name of the filter to run.
-#
-# If the repository name does not match any of the regular expressions in this
-# file, the "DEFAULT" line is used, if it is specified.
-#
-# If the name "ALL" appears as a regular expression it is always used
-# in addition to the first matching regex or "DEFAULT".
diff --git a/CVSROOT/damagecontrol-groovy.conf b/CVSROOT/damagecontrol-groovy.conf
deleted file mode 100644
index 623fc62..0000000
--- a/CVSROOT/damagecontrol-groovy.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-project_name: Groovy
-scm_spec: ":ext:dcontrol@localhost:/home/projects/groovy/scm:groovy/groovy-core"
-build_command_line: "maven dc"
-nag_email: groovy-dev@groovy.codehaus.org
-...
\ No newline at end of file
diff --git a/CVSROOT/dctrigger.rb b/CVSROOT/dctrigger.rb
deleted file mode 100644
index a6545a5..0000000
--- a/CVSROOT/dctrigger.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-require 'xmlrpc/client'
-
-url = ARGV[0]
-project_name = ARGV[1]
-
-puts "Nudging DamageControl on #{url} to build project #{project_name}"
-client = XMLRPC::Client.new2(url)
-build = client.proxy("build")
-result = build.trig(project_name, Time.now.utc.strftime("%Y%m%d%H%M%S"))
-puts result
diff --git a/CVSROOT/editinfo b/CVSROOT/editinfo
deleted file mode 100644
index d78886c..0000000
--- a/CVSROOT/editinfo
+++ /dev/null
@@ -1,21 +0,0 @@
-# The "editinfo" file is used to allow verification of logging
-# information. It works best when a template (as specified in the
-# rcsinfo file) is provided for the logging procedure. Given a
-# template with locations for, a bug-id number, a list of people who
-# reviewed the code before it can be checked in, and an external
-# process to catalog the differences that were code reviewed, the
-# following test can be applied to the code:
-#
-# Making sure that the entered bug-id number is correct.
-# Validating that the code that was reviewed is indeed the code being
-# checked in (using the bug-id number or a seperate review
-# number to identify this particular code set.).
-#
-# If any of the above test failed, then the commit would be aborted.
-#
-# Actions such as mailing a copy of the report to each reviewer are
-# better handled by an entry in the loginfo file.
-#
-# One thing that should be noted is the the ALL keyword is not
-# supported. There can be only one entry that matches a given
-# repository.
diff --git a/CVSROOT/log_accum.conf b/CVSROOT/log_accum.conf
deleted file mode 100644
index 6343eb0..0000000
--- a/CVSROOT/log_accum.conf
+++ /dev/null
@@ -1,83 +0,0 @@
-# The "log_accum.conf" file overrides the the defaults hard-coded in
-# the "log_accum.pl" script allowing admins to setup the log_accum.pl
-# once as executable, but not writable. Each project can then have
-# it's own "log_accum.conf" to configure the behaviour of their own
-# cvs commit messages.
-
-
-# MAIL TO
-#
-# When set, specifies the email address(es) to
-# receive commit messages. When left unset, the
-# script will attempt to guess the correct
-# mailing list using the repository name and
-# the MLISTHOST option.
-#
-MAIL_TO = scm@groovy.codehaus.org
-
-# MAIL FROM
-#
-# When set, specifies the email address that
-# all commit messages will be sent from.
-# Very usefull for setting up a "no reply"
-# address for commit messages.
-#
-# When not set, the script will guess the sender's
-# address by prefixing the cvs user's name to the
-# MLISTHOST option.
-#
-#MAIL_FROM = noreply@codehaus.org
-
-# MAIL HOST ADDRESS
-#
-# The host address to use when guessing either
-# the TO or FROM addresses.
-#MLISTHOST = codehaus.org
-
-# X-SENDER EMAIL HEADER
-#
-# When specified, adds an X-Sender header to the
-# emails sent so that users can use it to more
-# easily filter out cvs messages. This is very
-# nice for when there is no mailing list
-# dedicated to cvs commit messages.
-#
-XSENDER = Groovy-CVS
-
-# REPLY-TO EMAIL ADDRESS
-#
-# When REPLYTO is set an SMTP "Reply-To" email
-# header will be added. This is very useful
-# for keeping development discussion on a
-# dev list even when cvs messages go a cvs list.
-#
-REPLYTO = dev@groovy.codehaus.org
-
-# SUBJECT PREFIX
-#
-# This text, plus a space, will be prepended
-# to the subject line of the commit message.
-# When the option specified with no value, no
-# prefix will be used.
-#
-SUBJECT_PREFIX =
-
-# MESSAGE SIZE LIMIT
-#
-# If the delta info exceeds this threshold, no diff will be
-# mailed/logged; as a replacement for this, URLs pointing
-# to the corresponding ViewCVS diffs will be constructed and
-# included in the mail/log message.
-#
-# 0 = no treshold, unlimited diffs
-# x = maximum size of the diff in kb
-#
-#SIZELIMIT = 100;
-
-# VIEWCVS URL
-#
-# Specify here the URL to ViewCVS (without trailing slash!)
-# If left unset, the script will attempt to guess the correct
-# value.
-#
-VIEWCVS = "http://cvs.groovy.codehaus.org/groovy";
diff --git a/CVSROOT/modules b/CVSROOT/modules
deleted file mode 100644
index cb9e9ef..0000000
--- a/CVSROOT/modules
+++ /dev/null
@@ -1,26 +0,0 @@
-# Three different line formats are valid:
-# key -a aliases...
-# key [options] directory
-# key [options] directory files...
-#
-# Where "options" are composed of:
-# -i prog Run "prog" on "cvs commit" from top-level of module.
-# -o prog Run "prog" on "cvs checkout" of module.
-# -e prog Run "prog" on "cvs export" of module.
-# -t prog Run "prog" on "cvs rtag" of module.
-# -u prog Run "prog" on "cvs update" of module.
-# -d dir Place module in directory "dir" instead of module name.
-# -l Top-level directory only -- do not recurse.
-#
-# NOTE: If you change any of the "Run" options above, you'll have to
-# release and re-checkout any working directories of these modules.
-#
-# And "directory" is a path to a directory relative to $CVSROOT.
-#
-# The "-a" option specifies an alias. An alias is interpreted as if
-# everything on the right of the "-a" had been typed on the command line.
-#
-# You can encode a module within a module by using the special '&'
-# character to interpose another module into the current module. This
-# can be useful for creating a module that consists of many directories
-# spread out over the entire source repository.
diff --git a/CVSROOT/notify b/CVSROOT/notify
deleted file mode 100644
index 74ae6f9..0000000
--- a/CVSROOT/notify
+++ /dev/null
@@ -1,12 +0,0 @@
-# The "notify" file controls where notifications from watches set by
-# "cvs watch add" or "cvs edit" are sent. The first entry on a line is
-# a regular expression which is tested against the directory that the
-# change is being made to, relative to the $CVSROOT. If it matches,
-# then the remainder of the line is a filter program that should contain
-# one occurrence of %s for the user to notify, and information on its
-# standard input.
-#
-# "ALL" or "DEFAULT" can be used in place of the regular expression.
-#
-# For example:
-#ALL mail -s "CVS notification" %s
diff --git a/CVSROOT/rcsinfo b/CVSROOT/rcsinfo
deleted file mode 100644
index 49e59f4..0000000
--- a/CVSROOT/rcsinfo
+++ /dev/null
@@ -1,13 +0,0 @@
-# The "rcsinfo" file is used to control templates with which the editor
-# is invoked on commit and import.
-#
-# The first entry on a line is a regular expression which is tested
-# against the directory that the change is being made to, relative to the
-# $CVSROOT. For the first match that is found, then the remainder of the
-# line is the name of the file that contains the template.
-#
-# If the repository name does not match any of the regular expressions in this
-# file, the "DEFAULT" line is used, if it is specified.
-#
-# If the name "ALL" appears as a regular expression it is always used
-# in addition to the first matching regex or "DEFAULT".
diff --git a/CVSROOT/taginfo b/CVSROOT/taginfo
deleted file mode 100644
index 274a46d..0000000
--- a/CVSROOT/taginfo
+++ /dev/null
@@ -1,20 +0,0 @@
-# The "taginfo" file is used to control pre-tag checks.
-# The filter on the right is invoked with the following arguments:
-#
-# $1 -- tagname
-# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
-# $3 -- repository
-# $4-> file revision [file revision ...]
-#
-# A non-zero exit of the filter program will cause the tag to be aborted.
-#
-# The first entry on a line is a regular expression which is tested
-# against the directory that the change is being committed to, relative
-# to the $CVSROOT. For the first match that is found, then the remainder
-# of the line is the name of the filter to run.
-#
-# If the repository name does not match any of the regular expressions in this
-# file, the "DEFAULT" line is used, if it is specified.
-#
-# If the name "ALL" appears as a regular expression it is always used
-# in addition to the first matching regex or "DEFAULT".
diff --git a/CVSROOT/verifymsg b/CVSROOT/verifymsg
deleted file mode 100644
index 86f747c..0000000
--- a/CVSROOT/verifymsg
+++ /dev/null
@@ -1,21 +0,0 @@
-# The "verifymsg" file is used to allow verification of logging
-# information. It works best when a template (as specified in the
-# rcsinfo file) is provided for the logging procedure. Given a
-# template with locations for, a bug-id number, a list of people who
-# reviewed the code before it can be checked in, and an external
-# process to catalog the differences that were code reviewed, the
-# following test can be applied to the code:
-#
-# Making sure that the entered bug-id number is correct.
-# Validating that the code that was reviewed is indeed the code being
-# checked in (using the bug-id number or a seperate review
-# number to identify this particular code set.).
-#
-# If any of the above test failed, then the commit would be aborted.
-#
-# Actions such as mailing a copy of the report to each reviewer are
-# better handled by an entry in the loginfo file.
-#
-# One thing that should be noted is the the ALL keyword is not
-# supported. There can be only one entry that matches a given
-# repository.
diff --git a/groovy/groovy-core/project.properties b/groovy/groovy-core/project.properties
index 3e93bf7..fe7fff6 100644
--- a/groovy/groovy-core/project.properties
+++ b/groovy/groovy-core/project.properties
@@ -50,6 +50,18 @@
maven.remote.group = groovy
+# Deployment properties
+maven.repo.list=codehaus
+
+maven.repo.codehaus=scp://${pom.distributionSite}
+maven.repo.codehaus.directory=${pom.distributionDirectory}
+maven.repo.codehaus.group=groovy
+
+# The following properties must be set in your build.properties or on the command line
+#maven.repo.codehaus.username=
+#maven.repo.codehaus.privatekey=
+#maven.repo.codehaus.passphrase=
+
#####################################################
# emma code coverage
#####################################################
diff --git a/groovy/groovy-core/src/bin/groovy.bat b/groovy/groovy-core/src/bin/groovy.bat
index 6593c38..7bc3748 100644
--- a/groovy/groovy-core/src/bin/groovy.bat
+++ b/groovy/groovy-core/src/bin/groovy.bat
@@ -66,8 +66,8 @@
@rem Regular WinNT shell
set CP=
-if "x%1" == "x-cp" set CP=%2
-if "x%1" == "x-classpath" set CP=%2
+if "x%1" == "x-cp" set CP=%~2
+if "x%1" == "x-classpath" set CP=%~2
if not "x" == "x%CP%" shift /1
if not "x" == "x%CP%" shift /1
set CMD_LINE_ARGS=%1 %2 %3 %4 %5 %6 %7 %8 %9
@@ -113,4 +113,3 @@
@rem Optional pause the batch file
if "%GROOVY_BATCH_PAUSE%" == "on" pause
-
diff --git a/groovy/groovy-core/src/main/groovy/util/Node.java b/groovy/groovy-core/src/main/groovy/util/Node.java
index 41620af..123b88e 100644
--- a/groovy/groovy-core/src/main/groovy/util/Node.java
+++ b/groovy/groovy-core/src/main/groovy/util/Node.java
@@ -66,7 +66,7 @@
* @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
* @version $Revision$
*/
-public class Node {
+public class Node implements java.io.Serializable {
private Node parent;
private Object name;
diff --git a/groovy/groovy-core/src/main/org/codehaus/groovy/ant/Groovyc.java b/groovy/groovy-core/src/main/org/codehaus/groovy/ant/Groovyc.java
index ee12c50..da38095 100644
--- a/groovy/groovy-core/src/main/org/codehaus/groovy/ant/Groovyc.java
+++ b/groovy/groovy-core/src/main/org/codehaus/groovy/ant/Groovyc.java
@@ -45,11 +45,16 @@
*/
package org.codehaus.groovy.ant;
+import groovy.lang.GroovyClassLoader;
+
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.charset.Charset;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
@@ -71,6 +76,7 @@
* <li>sourcedir
* <li>destdir
* <li>classpath
+ * <li>stacktrace
* </ul>
* Of these arguments, the <b>sourcedir</b> and <b>destdir</b> are required.
* <p>
@@ -81,6 +87,7 @@
* Based heavily on the Javac implementation in Ant
*
* @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ * @author Hein Meling
* @version $Revision$
*/
public class Groovyc extends MatchingTask {
@@ -189,6 +196,15 @@
}
/**
+ * Enable compiler to report stack trace information if a problem occurs
+ * during compilation.
+ * @param stacktrace
+ */
+ public void setStacktrace(boolean stacktrace) {
+ configuration.setDebug(stacktrace);
+ }
+
+ /**
* Gets the destination directory into which the java source files
* should be compiled.
* @return the destination directory
@@ -432,8 +448,10 @@
String filename = compileList[i].getAbsolutePath();
// TODO this logging does not seem to appear in the maven build??
+ // COMMENT Hein: This is not ant's problem;
+ // fix it in maven instead if you really need this from maven!
log(filename);
- System.out.println("compiling: " + filename);
+// System.out.println("compiling: " + filename);
}
}
@@ -448,9 +466,9 @@
configuration.setSourceEncoding(encoding);
}
- CompilationUnit unit = new CompilationUnit( configuration );
- unit.addSources( compileList );
- unit.compile( );
+ CompilationUnit unit = new CompilationUnit(configuration, null, buildClassLoaderFor());
+ unit.addSources(compileList);
+ unit.compile();
}
catch (Exception e) {
@@ -468,4 +486,32 @@
}
}
}
+
+ private GroovyClassLoader buildClassLoaderFor() {
+ ClassLoader parent = this.getClass().getClassLoader();
+ if (parent instanceof AntClassLoader) {
+ AntClassLoader antLoader = (AntClassLoader) parent;
+ String[] pathElm = antLoader.getClasspath().split(File.pathSeparator);
+ List classpath = configuration.getClasspath();
+ /*
+ * Iterate over the classpath provided to groovyc, and add any missing path
+ * entries to the AntClassLoader. This is a workaround, since for some reason
+ * 'directory' classpath entries were not added to the AntClassLoader' classpath.
+ */
+ for (Iterator iter = classpath.iterator(); iter.hasNext();) {
+ String cpEntry = (String) iter.next();
+ boolean found = false;
+ for (int i = 0; i < pathElm.length; i++) {
+ if (cpEntry.equals(pathElm[i])) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ antLoader.addPathElement(cpEntry);
+ }
+ }
+ return new GroovyClassLoader(parent, configuration);
+ }
+
}
diff --git a/groovy/groovy-core/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/groovy/groovy-core/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index 63115c6..f36ba85 100644
--- a/groovy/groovy-core/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/groovy/groovy-core/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -1395,29 +1395,122 @@
}
/**
- * Support the subscript operator for a regex Matcher
+ * Support the subscript operator, e.g. matcher[index], for a regex Matcher.
+ *
+ * For an example using no group match, <code><pre>
+ * def p = /ab[d|f]/
+ * def m = "abcabdabeabf" =~ p
+ * for (i in 0..<m.count) {
+ * println( "m.groupCount() = " + m.groupCount())
+ * println( " " + i + ": " + m[i] ) // m[i] is a String
+ * }
+ * </pre></code>
+ *
+ * For an example using group matches, <code><pre>
+ * def p = /(?:ab([c|d|e|f]))/ `
+ * def m = "abcabdabeabf" =~ p
+ * for (i in 0..<m.count) {
+ * println( "m.groupCount() = " + m.groupCount())
+ * println( " " + i + ": " + m[i] ) // m[i] is a List
+ * }
+ * </pre></code>
+ *
+ * For another example using group matches, <code><pre>
+ * def m = "abcabdabeabfabxyzabx" =~ /(?:ab([d|x-z]+))/
+ * m.count.times {
+ * println( "m.groupCount() = " + m.groupCount())
+ * println( " " + it + ": " + m[it] ) // m[it] is a List
+ * }
+ * </pre></code>
*
* @param matcher a Matcher
* @param idx an index
- * @return the group at the given index
+ * @return object a matched String if no groups matched, list of matched groups otherwise.
*/
- public static String getAt(Matcher matcher, int idx) {
- matcher.reset();
- idx = normaliseIndex(idx, matcher.groupCount());
-
- // are we using groups?
- if (matcher.groupCount() > 0) {
- // yes, so return the specified group
- matcher.find();
- return matcher.group(idx);
- } else {
- // not using groups, so return the nth
- // occurrence of the pattern
+ public static Object getAt(Matcher matcher, int idx) {
+ try {
+ int count = getCount(matcher);
+ if (idx < -count || idx >= count) {
+ throw new IndexOutOfBoundsException("index is out of range " + (-count) + ".." + (count - 1) + " (index = " + idx + ")");
+ }
+ idx = normaliseIndex(idx, count);
+ matcher.reset();
for (int i = 0; i <= idx; i++) {
matcher.find();
}
- return matcher.group();
+
+ if (hasGroup(matcher)) {
+ // are we using groups?
+ // yes, so return the specified group as list
+ ArrayList list = new ArrayList(matcher.groupCount());
+ for (int i = 0; i <= matcher.groupCount(); i++) {
+ list.add(matcher.group(i));
+ }
+ return list;
+ } else {
+ // not using groups, so return the nth
+ // occurrence of the pattern
+ return matcher.group();
+ }
}
+ catch (IllegalStateException ex) {
+ return null;
+ }
+ }
+
+ /**
+ * Set the position of the given Matcher to the given index.
+ *
+ * @param matcher a Matcher
+ * @param idx the index number
+ */
+ public static void setIndex(Matcher matcher, int idx) {
+ int count = getCount(matcher);
+ if (idx < -count || idx >= count) {
+ throw new IndexOutOfBoundsException("index is out of range " + (-count) + ".." + (count - 1) + " (index = " + idx + ")");
+ }
+ if (idx == 0) {
+ matcher.reset();
+ }
+ else if (idx > 0) {
+ matcher.reset();
+ for (int i = 0; i < idx; i++) {
+ matcher.find();
+ }
+ }
+ else if (idx < 0) {
+ matcher.reset();
+ idx += getCount(matcher);
+ for (int i = 0; i < idx; i++) {
+ matcher.find();
+ }
+ }
+ }
+
+ /**
+ * Find the number of Strings matched to the given Matcher.
+ *
+ * @param matcher a Matcher
+ * @return int the number of Strings matched to the given matcher.
+ */
+ public static int getCount(Matcher matcher) {
+ int counter = 0;
+ matcher.reset();
+ while (matcher.find()) {
+ counter++;
+ }
+ matcher.reset();
+ return counter;
+ }
+
+ /**
+ * Check whether a Matcher contains a group or not.
+ *
+ * @param matcher a Matcher
+ * @return boolean <code>true</code> if matcher contains at least one group.
+ */
+ public static boolean hasGroup(Matcher matcher) {
+ return matcher.groupCount() > 0;
}
/**
@@ -3790,6 +3883,15 @@
}
public static void upto(Long self, Number to, Closure closure) {
+ long self1 = self.longValue();
+ long to1 = to.longValue();
+ if (self1 <= to1) {
+ for (long i = self1; i <= to1; i++) {
+ closure.callSpecial(new Long(i));
+ }
+ }
+ else
+ throw new GroovyRuntimeException("Infinite loop in " + self + ".upto(" + to +")");
}
public static void upto(float self, Number to, Closure closure) {
diff --git a/groovy/groovy-core/src/test/UberTestCase.java b/groovy/groovy-core/src/test/UberTestCase.java
index 0af6a3d..a13b422 100644
--- a/groovy/groovy-core/src/test/UberTestCase.java
+++ b/groovy/groovy-core/src/test/UberTestCase.java
@@ -203,6 +203,7 @@
suite.addTestSuite(PropertyWithoutDotTest.class);
suite.addTestSuite(RangeTest.class);
suite.addTestSuite(ReadLineTest.class);
+ suite.addTestSuite(RegExpGroupMatchTest.class);
suite.addTestSuite(RegularExpressionsTest.class);
suite.addTestSuite(ReturnTest.class);
suite.addTestSuite(RodsBooleanBug.class);
diff --git a/groovy/groovy-core/src/test/groovy/RegExpGroupMatchTest.groovy b/groovy/groovy-core/src/test/groovy/RegExpGroupMatchTest.groovy
new file mode 100644
index 0000000..38c46c3
--- /dev/null
+++ b/groovy/groovy-core/src/test/groovy/RegExpGroupMatchTest.groovy
@@ -0,0 +1,100 @@
+/**
+ * Test for fixing the Jira issue GROOVY-1000
+ *
+ * Fix an infinite loop when getting after group matching in regular expression.
+ * Graham Miller has given this idea.
+ *
+ * @author Pilho Kim
+ * @version $Revision$
+ */
+
+import java.util.regex.Matcher
+import java.util.regex.Pattern
+
+class RegExpGroupMatchTest extends GroovyTestCase {
+
+ void testFirst() {
+ assert "cheesecheese" =~ "cheese"
+ assert "cheesecheese" =~ /cheese/
+ assert "cheese" == /cheese/ /*they are both string syntaxes*/
+ }
+
+ void testSecond() {
+ // Lets create a regex Pattern
+ def pattern = ~/foo/
+ assert pattern instanceof Pattern
+ assert pattern.matcher("foo").matches()
+ }
+
+ void testThird() {
+ // Lets create a Matcher
+ def matcher = "cheesecheese" =~ /cheese/
+ assert matcher instanceof Matcher
+
+ def answer = matcher.replaceAll("edam")
+ println answer
+ }
+
+ void testFourth() {
+ // Lets do some replacement
+ def cheese = ("cheesecheese" =~ /cheese/).replaceFirst("nice")
+ assert cheese == "nicecheese"
+ }
+
+ void testFifth() {
+ // Group demo
+ def matcher = "\$abc." =~ "\\\$(.*)\\."
+ matcher.matches(); // must be invoked
+ assert matcher.group(1) == "abc" // is one, not zero
+ // assert matcher[1] == "abc" // This has worked only before jsr-03-release
+ println (matcher[0])
+ assert matcher[0] == ["\$abc.", "abc"]
+ assert matcher[0][1] == "abc"
+ }
+
+ void testSixth() {
+ // Group demo
+ // Avoid having to double all the backslash escaping characters.
+ def matcher = "\$abc." =~ /\$(.*)\./ // no need to double-escape!
+ assert "\\\$(.*)\\." == /\$(.*)\./
+ matcher.matches(); // must be invoked
+ assert matcher.group(1) == "abc" // is one, not zero
+ // assert matcher[1] == "abc" // This has worked only before jsr-03-release
+ println (matcher[0])
+ assert matcher[0] == ["\$abc.", "abc"]
+ assert matcher[0][1] == "abc"
+ }
+
+ // Test no group match.
+ void testNoGroupMatcherAndGet() {
+ def p = /ab[d|f]/
+ def m = "abcabdabeabf" =~ p
+
+ for (i in 0..<m.count) {
+ println( "m.groupCount() = " + m.groupCount())
+ println( " " + i + ": " + m[i] ) // m[i] is a String
+ }
+ }
+
+ // Test group matches.
+ void testGroupMatcherAndGet() {
+ def p = /(?:ab([c|d|e|f]))/
+ def m = "abcabdabeabf" =~ p
+
+ for (i in 0..<m.count) {
+ println( "m.groupCount() = " + m.groupCount())
+ println( " " + i + ": " + m[i] ) // m[i] is a String
+ }
+ }
+
+ // Test group matches.
+ void testAnotherGroupMatcherAndGet() {
+ def m = "abcabdabeabfabxyzabx" =~ /(?:ab([d|x-z]+))/
+
+ m.count.times {
+ println( "m.groupCount() = " + m.groupCount())
+ println( " " + it + ": " + m[it] ) // m[it] is a String
+ }
+ }
+}
+