This is the mail archive of the
frysk@sources.redhat.com
mailing list for the frysk project.
Two patches to add bi-arch test in frysk.
- From: Yong Zheng <zhengyo at cn dot ibm dot com>
- To: frysk at sourceware dot org
- Date: Wed, 13 Sep 2006 15:08:58 +0800
- Subject: Two patches to add bi-arch test in frysk.
hi,
On PPC64, applications are compiled into 32-bit mode by default, which
means most applications running on PPC64 are in 32-bit mode. So it's
necessary for frysk to do bi-arch test on PPC64. On X86_64, although
applications are compiled into 64-bit mode by default, it's also needed
for us to do bi-arch test. We ever discussed this problem and got some
precious feedbacks. Read the following URL for details:
http://sourceware.org/ml/frysk/2006-q3/msg00278.html.
Based on the feedbacks from the previous discussion, we take the
following two steps to implement the bi-arch test:
1)Automatically generate 32-bit executable cases on PPC64 and X86_64.
The file "common/Makefile.gen.sh" is modified to generate the rules for
bi-arch test during frysk's configuration. As we all know, bi-arch tests
are unnecessary on X86, so the file "common/m4/frysk-do-biarch-test.m4"
is added, in which one macro is defined to control whether the rules for
bi-arch test will take effect or not.
After the above modifications, the 32-bit cases will be generated under
$(BUILD)/frysk-core/frysk/pkglibexecdir/biarch after building frysk.
2)Modify the funit and TestRunner cases to support running bi-arch test.
We expect the bi-arch test will do no changes on the previous usage of
funit or TestRunner. So we add two options(-i and -b) to support
bi-arch test in both funit and TestRunner. If no one of above two
options is given, the funit or TestRunner will do what they used to do.
The Runner.java(located at $(FRYSK)/frysk-imports/frysk/junit/) is
refactored to achieve the above purpose.
We split the modifications into two patches:
frysk_common_for_biarch.patch and frysk_supplement_for_biarch.patch.
The former patch is for $(FRYSK)/common and
$(FRYSK)/frysk-<module>/common. You may need to apply the patch for each
directories(we just do one patch for each sub-directoies "common" under
$(FRYSK) and $(FRYSK)/frysk-<module> because they are of the same). And
the latter patch should be applied just once at top directory $(FRYSK).
After compiling frysk, you can take the following steps to run bi-arch
test:
cd $(build)/frysk-core
./TestRunner -i
or
./TestRunner -b
Of course, you also can do bi-arch test with the similar options through
funit. If you don't want any bi-arch test , just run TestRunner or funit
without the option "-i" or "-b".
Note: the option "-i" means running bi-arch test after finishing running
the common test cases; but the option "-b" means just running bi-arch
test. You can choose freely according to your request.
2006-09-13 Yong Zheng <zhengyo@cn.ibm.com>
* common/acinclude.m4: Call FRYSK_DO_BIARCH_TEST.
* common/Makefile.gen.sh: (echo_biarch_PROGRAMS): Output of
rules for bi-arch test.
* common/Makefile.rules (pkglibexec_biarch_PROGRAMS,
pkglibexec_biarchdir): Define.
* common/TestRunner.javain: Refactor to suport bi-arch test.
* common/m4/frysk-do-biarch-test.m4: New file, defines
FRYSK_DO_BIARCH_TEST.
* frysk-imports/frysk/Config.javain (PKGLIBEXEC_BIARCHDIR):
Add.
* frysk-core/frysk/pkglibexecdir/funit.java (main): Add support
for bi-arch test.
* frysk-imports/frysk/ju0nit/Runner.java (repeatValue,
justBiarchTest, includingBiarchTest, testCases, parser): New.
(usage): New method.
(setTestCases, GetTestCases): New methods.
(doRunner): New method.
(doBiarchTestRunner): New method.
(Runner): Refactor to support bi-arch test.
Rebuilt and tested based on frysk cvs(09-09) on X86/X86_64/PPC64. Please
review and any comments are welcome!
Best regards
Yong Zheng
--- /dev/null 2006-09-01 09:26:05.441569750 +0800
+++ common/m4/frysk-do-biarch-test.m4 2006-09-08 17:24:43.000000000 +0800
@@ -0,0 +1,48 @@
+# This file is part of the program FRYSK.
+#
+# Copyright 2006, IBM Co.
+#
+# FRYSK is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# FRYSK is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with FRYSK; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+#
+# In addition, as a special exception, Red Hat, Inc. gives You the
+# additional right to link the code of FRYSK with code not covered
+# under the GNU General Public License ("Non-GPL Code") and to
+# distribute linked combinations including the two, subject to the
+# limitations in this paragraph. Non-GPL Code permitted under this
+# exception must only link to the code of FRYSK through those well
+# defined interfaces identified in the file named EXCEPTION found in
+# the source code files (the "Approved Interfaces"). The files of
+# Non-GPL Code may instantiate templates or use macros or inline
+# functions from the Approved Interfaces without causing the
+# resulting work to be covered by the GNU General Public
+# License. Only Red Hat, Inc. may make changes or additions to the
+# list of Approved Interfaces. You must obey the GNU General Public
+# License in all respects for all of the FRYSK code and other code
+# used in conjunction with FRYSK except the Non-GPL Code covered by
+# this exception. If you modify this file, you may extend this
+# exception to your version of the file, but you are not obligated to
+# do so. If you do not wish to provide this exception without
+# modification, you must delete this exception statement from your
+# version and license this file solely under the GPL without
+# exception.
+
+AC_DEFUN([FRYSK_DO_BIARCH_TEST], [
+AC_REQUIRE([AC_CANONICAL_TARGET])
+case $target_cpu in
+x86_64|powerpc64|ppc64)
+ do_biarch_test=yes;;
+*) do_biarch_test=no;;
+esac
+AM_CONDITIONAL([DO_BIARCH_TEST], [test $do_biarch_test = yes])
+])
--- common/acinclude.m4 2006-07-01 01:04:58.000000000 +0800
+++ ../common/acinclude.m4 2006-09-08 17:34:10.000000000 +0800
@@ -133,3 +133,5 @@
test $UUDECODE = no && AC_ERROR([no uudecode program found, please install sharutils package])
FRYSK_USE_LIBUNWIND
+
+FRYSK_DO_BIARCH_TEST
--- common/Makefile.rules 2006-08-30 08:37:09.000000000 +0800
+++ common/Makefile.rules.edited 2006-09-11 12:45:06.000000000 +0800
@@ -51,6 +51,10 @@
libexec_PROGRAMS =
pkglibexec_PROGRAMS =
pkglibexecdir = $(libexecdir)/@PACKAGE@
+
+pkglibexec_biarch_PROGRAMS =
+pkglibexec_biarchdir = $(pkglibexecdir)/biarch
+
noinst_LIBRARIES =
man_MANS =
LDADD =
@@ -227,6 +231,7 @@
-e 's,[@]pkglibdir[@],$(pkglibdir),g' \
-e 's,[@]pkgincludedir[@],$(pkgincludedir),g' \
-e 's,[@]pkglibexecdir[@],$(pkglibexecdir),g' \
+ -e 's,[@]pkglibexec_biarchdir[@],$(pkglibexec_biarchdir),g' \
-e 's,[@]GEN_PACKAGENAME[@],$(GEN_PACKAGENAME),g' \
-e 's,[@]VERSION[@],$(VERSION),g' \
-e 's,[@]target_cpu[@],@target_cpu@,g'
--- common/Makefile.gen.sh 2006-08-30 08:37:09.000000000 +0800
+++ common/Makefile.gen.sh.edited 2006-09-12 13:10:39.000000000 +0800
@@ -140,6 +140,49 @@
esac
}
+echo_biarch_PROGRAMS()
+{
+ case "$1" in
+ *dir/* )
+ # extract the directory prefix
+ local dir=`echo /"$1" | sed -e 's,.*/\([a-z]*\)dir/.*,\1,'`
+ #echo "ZY: in biarch, dir=${dir}"
+ local dname=`dirname $1`
+
+ dname=`dirname ${dname}`
+ if [ "${dir}" = "pkglibexec" ] && [ "${dname}" = "frysk" ]; then
+ local file="$2"
+ local dir_name=`dirname $1`
+ local base_name=`basename $1`
+ local name="${dir_name}/biarch/${base_name}"
+
+ local name_=`echo ${name} | sed -e 'y,/-,__,'`
+ local ldflags="${name_}_LDFLAGS = -m32 -g"
+
+ echo "${name_}_SOURCES = ${file}"
+ echo "am_${name_}_OBJECTS = ${dir_name}/biarch/${base_name}.\$(OBJEXT)"
+ echo "${ldflags}"
+
+ test ${suffix} = .cxx && echo "${name_}_LINK = \$(CXXLINK)"
+
+cat <<EOF
+${dir_name}/biarch/${base_name}.\$(OBJEXT): \$(${name_}_SOURCES) frysk/pkglibexecdir/biarch/\$(am__dirstamp)
+ \$(COMPILE) \$(${3}) -c -o \$@ $<
+EOF
+
+ echo "${dir}_biarch_PROGRAMS += ${dir_name}/biarch/${base_name}"
+
+ if grep pthread.h ${file} > /dev/null 2>&1 ; then
+ echo "${name_}_LDADD = -lpthread"
+ fi
+
+ fi
+ ;;
+ * )
+ ;;
+ esac
+}
+
# Convert path to the automake equivalent (/ replaced with _).
echo_name_ ()
{
@@ -397,9 +440,37 @@
else
echo "${sources} += ${file}"
fi
+
done
done
+biarch_cflags_output=0
+echo "if DO_BIARCH_TEST"
+for suffix in .cxx .c .hxx ; do
+ print_header "... ${suffix}"
+ find ${dirs} \
+ -name "[A-Za-z]*${suffix}" -print \
+ | sort -f | while read file ; do
+ d=`dirname ${file}`
+ b=`basename ${file} ${suffix}`
+ name=${d}/${b}
+ name_=`echo ${name} | sed -e 'y,/-,__,'`
+ if has_main ${file} ; then
+
+ if [ $biarch_cflags_output -eq 0 ]; then
+ biarch_path="${d}/biarch"
+ biarch_cflag_name=`echo ${biarch_path} | sed -e 'y,/-,__,'`
+ echo "${biarch_cflag_name}=-m32 -g"
+ fi
+
+ echo_biarch_PROGRAMS ${name} ${file} ${biarch_cflag_name}
+
+ biarch_cflags_output=1
+ fi
+
+ done
+done
+echo "endif"
# Grep the cni/*.cxx files forming a list of included files. Assume
# these are all generated from .class files. The list can be pruned a
--- common/TestRunner.javain 2006-02-06 13:58:01.000000000 +0800
+++ common/TestRunner.javain.edited 2006-09-12 19:51:05.000000000 +0800
@@ -49,10 +49,17 @@
*/
public class TestRunner
-{
+{
public static void main (String[] args)
{
+ Runner testRunner = new Runner (args);
+
+ // Set the execPrefix path and then do the common test.
Paths.setExecPrefix (Build.ABS_BUILDDIR + "/frysk/pkglibexecdir/");
- new Runner (args, JUnitTests.get ());
+ testRunner.doRunner(JUnitTests.get ());
+
+ // Set the execPrefix of biarch and then do the biarch test.
+ Paths.setExecPrefix(Build.ABS_BUILDDIR + "/frysk/pkglibexecdir/biarch/");
+ testRunner.doBiarchTestRunner(JUnitTests.get ());
}
}
Index: frysk-imports/frysk/Config.javain
===================================================================
RCS file: /cvs/frysk/frysk-imports/frysk/Config.javain,v
retrieving revision 1.9
diff -u -r1.9 Config.javain
--- frysk-imports/frysk/Config.javain 16 Aug 2006 19:09:52 -0000 1.9
+++ frysk-imports/frysk/Config.javain 12 Sep 2006 11:29:09 -0000
@@ -60,6 +60,7 @@
public static final String PKGLIBEXECDIR = "@pkglibexecdir@";
public static final String PKGINCLUDEDIR = "@pkgincludedir@";
+ public static final String PKGLIBEXEC_BIARCHDIR = "@pkglibexec_biarchdir@";
public static final String VERSION = "@VERSION@";
// User's config directory.
Index: frysk-core/frysk/pkglibexecdir/funit.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/pkglibexecdir/funit.java,v
retrieving revision 1.4
diff -u -r1.4 funit.java
--- frysk-core/frysk/pkglibexecdir/funit.java 6 Feb 2006 06:17:26 -0000 1.4
+++ frysk-core/frysk/pkglibexecdir/funit.java 12 Sep 2006 11:32:19 -0000
@@ -40,6 +40,8 @@
import frysk.Config;
import frysk.junit.Paths;
import frysk.junit.Runner;
+
+import java.io.File;
import java.util.LinkedList;
/**
@@ -48,14 +50,26 @@
*/
public class funit
-{
+{
public static void main (String[] args)
{
LinkedList list = new LinkedList ();
list.addAll (frysk.imports.JUnitTests.get ());
list.addAll (frysk.sys.JUnitTests.get ());
list.addAll (frysk.core.JUnitTests.get ());
- Paths.setExecPrefix (Config.PKGLIBEXECDIR + "/");
- new Runner (args, list);
+
+ Runner testRunner = new Runner (args);
+
+ // Set the pkglibexec's directroy according to configuration
+ // and then do the test.
+ Paths.setExecPrefix (Config.PKGLIBEXECDIR + "/");
+ testRunner.doRunner(list);
+
+ // It's unnecessary for other modules(such as frysk-import) to
+ // do biarch test, so we just add the frysk-core's JUnitTests.
+ LinkedList biarchList = new LinkedList();
+ biarchList.addAll(frysk.core.JUnitTests.get ());
+ Paths.setExecPrefix(Config.PKGLIBEXEC_BIARCHDIR + File.separator);
+ testRunner.doBiarchTestRunner(biarchList);
}
}
Index: frysk-imports/frysk/junit/Runner.java
===================================================================
RCS file: /cvs/frysk/frysk-imports/frysk/junit/Runner.java,v
retrieving revision 1.2
diff -u -r1.2 Runner.java
--- frysk-imports/frysk/junit/Runner.java 27 Mar 2006 03:03:46 -0000 1.2
+++ frysk-imports/frysk/junit/Runner.java 12 Sep 2006 12:14:21 -0000
@@ -63,6 +63,16 @@
extends TestRunner
{
static Logger logger;
+
+ // Reapeat onece by default.
+ private int repeatValue = 1;
+ private boolean justBiarchTest = false;
+ private boolean includingBiarchTest = false;
+
+ private Collection testCases = null;
+
+ private CmdLineParser parser = null;
+
/**
* Overide JUnit's print methods with a version that displays each
* test as it is run. Makes tracking down problems when the run
@@ -116,112 +126,240 @@
}
}
+ public static void usage(String message, int exitVal)
+ {
+ System.out.println (message);
+ System.out.println ("Usage: [ -c <console-level> ] [ -l <log-level> ]" +
+ " [ -r <repeat-count> ] [-i] [-b] [ class ... ]");
+ System.out.println ("Options: ");
+ System.out.println (" -c <console-level>");
+ System.out.println (" Set the console level. The " +
+ "console-level can be [ OFF | SEVERE | WARNING | INFO " +
+ "| CONFIG | FINE | FINER | FINEST].");
+ System.out.println (" -l <log-level>");
+ System.out.println (" Set the log level. The log-level " +
+ "can be [ OFF | SEVERE | WARNING | INFO | CONFIG | FINE " +
+ "| FINER | FINEST].");
+ System.out.println (" -r <repeat-count>");
+ System.out.println (" Set the count of repeating the test.");
+ System.out.println (" -i do the biarch test after running the " +
+ "common test.");
+ System.out.println (" -b just do the biarch test(not run the " +
+ "common test).");
+ System.out.println (" If the -i is given together with -b " +
+ "option, -i will be ignored.");
+ System.exit (exitVal);
+ }
+
+ public void setTestCases(Collection testCases)
+ {
+ this.testCases = testCases;
+ }
+
+ public Collection getTestCases()
+ {
+ return this.testCases;
+ }
+
+ /**
+ * Run the testcases carried by testClasses.
+ *
+ * @param testClasses
+ * @return int the value of exit.
+ */
+ public int doRunner(Collection testClasses)
+ {
+ // Check whether we should just run biarch test
+ if (true == this.justBiarchTest)
+ return SUCCESS_EXIT;
+
+ // Create the testsuite to be run, either as specified on the
+ // command line, or from the provided list of classes. XXX:
+ // It would be good if individual tests from within a testcase
+ // could be identified and run.
+ String[] otherArgs = parser.getRemainingArgs ();
+
+ TestSuite testSuite = new TestSuite ();
+
+ if (otherArgs.length > 0)
+ {
+ // Construct the testsuite from the list of names.
+ for (int i = 0; i < otherArgs.length; i++)
+ {
+ if (otherArgs[i].charAt (0) == '-')
+ this.repeatValue = -Integer.parseInt (otherArgs[i]);
+ else
+ testSuite.addTest (getTest (otherArgs[i]));
+ }
+ }
+ else
+ {
+ for (Iterator i = testClasses.iterator (); i.hasNext (); )
+ {
+ Class testClass = (Class) i.next ();
+ testSuite.addTest (new TestSuite (testClass));
+ }
+ }
+
+ // Run the TestSuite <<repeat>> times.
+ try
+ {
+ for (int i = 0; i < this.repeatValue; i++)
+ {
+ TestResult testResult = doRun (testSuite);
+
+ if (!testResult.wasSuccessful())
+ return FAILURE_EXIT;
+ }
+ }
+ catch(Exception e)
+ {
+ System.err.println(e.getMessage());
+
+ return EXCEPTION_EXIT;
+ }
+
+ return SUCCESS_EXIT;
+ }
+
+ /**
+ * Run bi-arch test when the "-i" or "-b" option is given.
+ * When doing bi-arch test, all cases are the same as the
+ * common test except for the execPrefix path. So after the
+ * correct execPrefix is set before calling this function
+ * in frysk.junit.Paths, we do the same procedures as the doRunner().
+ *
+ * @param testClasses
+ * @return
+ * @see frysk.junit.Paths
+ */
+ public int doBiarchTestRunner(Collection testClasses)
+ {
+ if ((true == this.includingBiarchTest) &&
+ (false == this.justBiarchTest))
+ {
+ System.out.println("+====================================================+");
+ System.out.println("| |");
+ System.out.println("| The following is Biarch Test |");
+ System.out.println("| |");
+ System.out.println("+====================================================+");
+ }
+
+ if ((false == this.justBiarchTest) &&
+ (false == this.includingBiarchTest))
+ return SUCCESS_EXIT;
+ else if (true == this.justBiarchTest)
+ this.justBiarchTest = false;
+
+ return this.doRunner(testClasses);
+ }
+
/**
* Create a JUnit TestRunner, using command-line arguments args,
* and the supplied testClasses.
*/
- public Runner (String[] args, Collection testClasses)
+ public Runner (String[] args)
{
// Override the print methods.
super (new Results (System.out));
// Create the command line parser, and use it to parse all
// command line options.
- CmdLineParser parser = new CmdLineParser ();
+ parser = new CmdLineParser ();
+
CmdLineParser.Option levelOption
= parser.addStringOption ('l', "level");
CmdLineParser.Option consoleOption
= parser.addStringOption ('c', "console");
CmdLineParser.Option repeatOption
= parser.addIntegerOption ('r', "repeat");
- try {
+
+ CmdLineParser.Option onlyDoBiarchTestOption
+ = parser.addBooleanOption('b', "biarch");
+ CmdLineParser.Option includingBiarchTestOption
+ = parser.addBooleanOption('i', "including-biarch");
+
+ try
+ {
parser.parse(args);
+ }
+ catch (CmdLineParser.OptionException e)
+ {
+ Runner.usage(e.getMessage(), FAILURE_EXIT);
+ }
+
+ boolean includingBiarchTest = false;
+ boolean onlyDoBiarchTest = false;
+
+ Object biarchOptionObj = null;
+
+ biarchOptionObj = parser.getOptionValue (includingBiarchTestOption);
+ if (null != biarchOptionObj)
+ {
+ includingBiarchTest = ((Boolean)biarchOptionObj).booleanValue();
}
- catch (CmdLineParser.OptionException e) {
- System.out.println (e.getMessage());
- System.out.println ("Usage: [ -c <console-level> ] [ -l <log-level> ] [ -r <repeat-count> ] [ class ... ]");
- System.exit (FAILURE_EXIT);
+
+ biarchOptionObj = parser.getOptionValue (onlyDoBiarchTestOption);
+ if (null != biarchOptionObj)
+ {
+ onlyDoBiarchTest = ((Boolean)biarchOptionObj).booleanValue();
}
-
+
+ this.justBiarchTest = onlyDoBiarchTest;
+ this.includingBiarchTest = includingBiarchTest;
+
// Create the file logger, and then set it's level to that
// specified on the command line.
logger = EventLogger.get ("logs/", "frysk_core_event.log");
String levelValue = (String) parser.getOptionValue (levelOption);
- if (levelValue != null) {
- Level level = null;
- try {
- level = Level.parse (levelValue);
- }
- catch (IllegalArgumentException e) {
- System.out.println ("Invalid log level: " + levelValue);
- System.exit (FAILURE_EXIT);
- }
- logger.setLevel (level);
+ if (levelValue != null)
+ {
+ Level level = null;
+ try
+ {
+ level = Level.parse (levelValue);
+ }
+ catch (IllegalArgumentException e)
+ {
+ Runner.usage("Invalid log level: " + levelValue, FAILURE_EXIT);
+ }
+ logger.setLevel (level);
}
// Need to set both the console and the main logger as
// otherwize the console won't see the log messages.
String consoleValue = (String) parser.getOptionValue (consoleOption);
- if (consoleValue != null) {
- Level consoleLevel = null;
- try {
- consoleLevel = Level.parse (consoleValue);
- }
- catch (IllegalArgumentException e) {
- System.out.println ("Invalid log console: " + consoleValue);
- System.exit (FAILURE_EXIT);
- }
- System.out.println ("console " + consoleLevel);
- Handler consoleHandler = new ConsoleHandler ();
- consoleHandler.setLevel (consoleLevel);
- logger.addHandler (consoleHandler);
- logger.setLevel (consoleLevel);
- System.out.println (consoleHandler);
+ if (consoleValue != null)
+ {
+ Level consoleLevel = null;
+ try
+ {
+ consoleLevel = Level.parse (consoleValue);
+ }
+ catch (IllegalArgumentException e)
+ {
+ Runner.usage("Invalid log console: " +
+ consoleValue, FAILURE_EXIT);
+ }
+
+ System.out.println ("console " + consoleLevel);
+ Handler consoleHandler = new ConsoleHandler ();
+ consoleHandler.setLevel (consoleLevel);
+ logger.addHandler (consoleHandler);
+ logger.setLevel (consoleLevel);
+ System.out.println (consoleHandler);
}
// Determine the number of times that the testsuite should be
// run.
+ int repeats = 1;
Integer repeatValue = (Integer) parser.getOptionValue (repeatOption);
- int repeats = 1;
- if (repeatValue != null) {
- repeats = repeatValue.intValue ();
- }
-
- // Create the testsuite to be run, either as specified on the
- // command line, or from the provided list of classes. XXX:
- // It would be good if individual tests from within a testcase
- // could be identified and run.
- String[] otherArgs = parser.getRemainingArgs ();
- TestSuite testSuite = new TestSuite ();
- if (otherArgs.length > 0) {
- // Construct the testsuite from the list of names.
- for (int i = 0; i < otherArgs.length; i++) {
- if (otherArgs[i].charAt (0) == '-')
- repeats = -Integer.parseInt (otherArgs[i]);
- else
- testSuite.addTest (getTest (otherArgs[i]));
- }
- }
- else {
- for (Iterator i = testClasses.iterator (); i.hasNext (); ) {
- Class testClass = (Class) i.next ();
- testSuite.addTest (new TestSuite (testClass));
- }
-
- }
-
- // Run the TestSuite <<repeat>> times.
- try {
- for (int i = 0; i < repeats; i++) {
- TestResult testResult = doRun (testSuite);
- if (!testResult.wasSuccessful())
- System.exit (FAILURE_EXIT);
- }
- } catch(Exception e) {
- System.err.println(e.getMessage());
- System.exit (EXCEPTION_EXIT);
+
+ if (repeatValue != null)
+ {
+ repeats = repeatValue.intValue ();
}
- System.exit (SUCCESS_EXIT);
+ this.repeatValue = repeats;
}
}