- package com.sun.org.apache.regexp.internal;
-
- /*
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999 The Apache Software Foundation. All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- * any, must include the following acknowlegement:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowlegement may appear in the software itself,
- * if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Jakarta-Regexp", and "Apache Software
- * Foundation" must not be used to endorse or promote products derived
- * from this software without prior written permission. For written
- * permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- * nor may "Apache" appear in their names without prior written
- * permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
- import java.io.*;
-
- /**
- * Data driven (and optionally interactive) testing harness to exercise regular
- * expression compiler and matching engine.
- *
- * @author <a href="mailto:jonl@muppetlabs.com">Jonathan Locke</a>
- * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
- * @version $Id: RETest.java,v 1.2 2000/04/30 20:42:35 jon Exp $
- */
- public class RETest
- {
- // Construct a matcher and a debug compiler
- RE r = new RE();
- REDebugCompiler compiler = new REDebugCompiler();
-
- // True if we want to see output from success cases
- static final boolean showSuccesses = false;
-
- /**
- * Main program entrypoint. If an argument is given, it will be compiled
- * and interactive matching will ensue. If no argument is given, the
- * file RETest.txt will be used as automated testing input.
- * @param arg Command line arguments (optional regular expression)
- */
- public static void _main(String[] arg)
- {
- try
- {
- //new RETest(arg);
- test();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- /**
- * Testing entrypoint.
- * @param arg Command line arguments
- * @exception Exception thrown in case of error
- */
- public static boolean test() throws Exception
- {
- RETest test = new RETest();
- test.runAutomatedTests("docs/RETest.txt");
- return test.failures == 0;
- }
-
- /**
- * Constructor
- */
- public RETest()
- {
- }
-
- /**
- * Constructor for test
- * @param arg Command line arguments
- */
- public RETest(String[] arg)
- {
- try
- {
- // Run interactive tests against a single regexp
- if (arg.length == 2)
- {
- runInteractiveTests(arg[1]);
- }
- else if (arg.length == 1)
- {
- // Run automated tests
- runAutomatedTests(arg[0]);
- }
- else
- {
- System.out.println ( "Usage: RETest ([-i] [regex]) ([/path/to/testfile.txt])" );
- }
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- /**
- * Compile and test matching against a single expression
- * @param expr Expression to compile and test
- */
- void runInteractiveTests(String expr)
- {
- try
- {
- // Compile expression
- r.setProgram(compiler.compile(expr));
-
- // Show expression
- say("\n" + expr + "\n");
-
- // Show program for compiled expression
- compiler.dumpProgram(new PrintWriter(System.out));
-
- // Test matching against compiled expression
- while (true)
- {
- // Read from keyboard
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
- System.out.print("> ");
- System.out.flush();
- String match = br.readLine();
-
- // Try a match against the keyboard input
- if (r.match(match))
- {
- say("Match successful.");
- }
- else
- {
- say("Match failed.");
- }
-
- // Show subparen registers
- showParens(r);
- }
- }
- catch (Exception e)
- {
- say("Error: " + e.toString());
- e.printStackTrace();
- }
- }
-
- /**
- * Exit with a fatal error.
- * @param s Last famous words before exiting
- */
- void die(String s)
- {
- say("FATAL ERROR: " + s);
- System.exit(0);
- }
-
- /**
- * Fail with an error
- * @param s Failure description
- */
- void fail(String s)
- {
- failures++;
- say("\n");
- say("*******************************************************");
- say("********************* FAILURE! **********************");
- say("*******************************************************");
- say("\n");
- say(s);
- say("");
- compiler.dumpProgram(new PrintWriter(System.out));
- say("\n");
- }
-
- /**
- * Show a success
- * @param s Success story
- */
- void success(String s)
- {
- if (showSuccesses)
- {
- show();
- say("Success: " + s);
- }
- }
-
- /**
- * Say something to standard out
- * @param s What to say
- */
- void say(String s)
- {
- System.out.println (s);
- }
-
- /**
- * Show an expression
- */
- void show()
- {
- say("\n-----------------------\n");
- say("Expression #" + (n) + " \"" + expr + "\" ");
- }
-
- /**
- * Dump parenthesized subexpressions found by a regular expression matcher object
- * @param r Matcher object with results to show
- */
- void showParens(RE r)
- {
- // Loop through each paren
- for (int i = 0; i < r.getParenCount(); i++)
- {
- // Show paren register
- say("$" + i + " = " + r.getParen(i));
- }
- }
-
- // Pre-compiled regular expression "a*b"
- char[] re1Instructions =
- {
- 0x007c, 0x0000, 0x001a, 0x007c, 0x0000, 0x000d, 0x0041,
- 0x0001, 0x0004, 0x0061, 0x007c, 0x0000, 0x0003, 0x0047,
- 0x0000, 0xfff6, 0x007c, 0x0000, 0x0003, 0x004e, 0x0000,
- 0x0003, 0x0041, 0x0001, 0x0004, 0x0062, 0x0045, 0x0000,
- 0x0000,
- };
-
- REProgram re1 = new REProgram(re1Instructions);
-
- /*
- * Current expression and number in automated test
- */
- String expr;
- int n = 0;
-
- /*
- * Count of failures in automated test
- */
- int failures = 0;
-
- /**
- * Run automated tests in RETest.txt file (from Perl 4.0 test battery)
- * @exception Exception thrown in case of error
- */
- void runAutomatedTests(String testDocument) throws Exception
- {
- long ms = System.currentTimeMillis();
-
- // Simple test of pre-compiled regular expressions
- RE r = new RE(re1);
- say("a*b");
- say("aaaab = " + r.match("aaab"));
- showParens(r);
- say("b = " + r.match("b"));
- showParens(r);
- say("c = " + r.match("c"));
- showParens(r);
- say("ccccaaaaab = " + r.match("ccccaaaaab"));
- showParens(r);
-
- r = new RE("a*b");
- String[] s = r.split("xxxxaabxxxxbyyyyaaabzzz");
- r = new RE("x+");
- s = r.grep(s);
- for (int i = 0; i < s.length; i++)
- {
- System.out.println ("s[" + i + "] = " + s[i]);
- }
-
- r = new RE("a*b");
- String s1 = r.subst("aaaabfooaaabgarplyaaabwackyb", "-");
- System.out.println ("s = " + s1);
-
- // Test from script file
- File testInput = new File(testDocument);
- if (! testInput.exists())
- throw new Exception ("Could not find: " + testDocument);
- BufferedReader br = new BufferedReader(new FileReader(testInput));
- try
- {
- // While input is available, parse lines
- while (br.ready())
- {
- // Find next re test case
- String number = "";
- String yesno;
- while (br.ready())
- {
- number = br.readLine();
- if (number == null)
- {
- break;
- }
- number = number.trim();
- if (number.startsWith("#"))
- {
- break;
- }
- if (!number.equals(""))
- {
- System.out.println ("Script error. Line = " + number);
- System.exit(0);
- }
- }
-
- // Are we done?
- if (!br.ready())
- {
- break;
- }
-
- // Get expression
- expr = br.readLine();
- n++;
- say("");
- say(n + ". " + expr);
- say("");
-
- // Compile it
- try
- {
- r.setProgram(compiler.compile(expr));
- }
-
- // Some expressions *should* cause exceptions to be thrown
- catch (Exception e)
- {
- // Get expected result
- yesno = br.readLine().trim();
-
- // If it was supposed to be an error, report success and continue
- if (yesno.equals("ERR"))
- {
- say(" Match: ERR");
- success("Produces an error (" + e.toString() + "), as expected.");
- continue;
- }
-
- // Wasn't supposed to be an error
- fail("Produces the unexpected error \"" + e.getMessage() + "\"");
- }
- catch (Error e)
- {
- // Internal error happened
- fail("Compiler threw fatal error \"" + e.getMessage() + "\"");
- e.printStackTrace();
- }
-
- // Get string to match against
- String matchAgainst = br.readLine().trim();
- say(" Match against: '" + matchAgainst + "'");
-
- // Expression didn't cause an expected error
- if (matchAgainst.equals("ERR"))
- {
- fail("Was expected to be an error, but wasn't.");
- continue;
- }
-
- // Try matching
- try
- {
- // Match against the string
- boolean b = r.match(matchAgainst);
-
- // Get expected result
- yesno = br.readLine().trim();
-
- // If match succeeded
- if (b)
- {
- // Status
- say(" Match: YES");
-
- // Match wasn't supposed to succeed
- if (yesno.equals("NO"))
- {
- fail("Matched \"" + matchAgainst + "\", when not expected to.");
- }
- else
- if (yesno.equals("YES"))
- {
- // Match succeeded as expected
- success("Matched \"" + matchAgainst + "\", as expected:");
-
- // Show subexpression registers
- if (showSuccesses)
- {
- showParens(r);
- }
-
- say(" Paren count: " + r.getParenCount());
-
- // Check registers against expected contents
- for (int p = 0; p < r.getParenCount(); p++)
- {
- // Get next register
- String register = br.readLine().trim();
- say(" Paren " + p + " : " + r.getParen(p));
-
- // Compare expected result with actual
- if (!register.equals(r.getParen(p)))
- {
- // Register isn't what it was supposed to be
- fail("Register " + p + " should be = \"" + register + "\", but is \"" + r.getParen(p) + "\" instead.");
- }
- }
- }
- else
- {
- // Bad test script
- die("Test script error!");
- }
- }
- else
- {
- // Status
- say(" Match: NO");
-
- // Match failed
- if (yesno.equals("YES"))
- {
- // Should have failed
- fail("Did not match \"" + matchAgainst + "\", when expected to.");
- }
- else
- if (yesno.equals("NO"))
- {
- // Should have failed
- success("Did not match \"" + matchAgainst + "\", as expected.");
- }
- else
- {
- // Bad test script
- die("Test script error!");
- }
- }
- }
-
- // Matcher blew it
- catch (Exception e)
- {
- fail("Matcher threw exception: " + e.toString());
- e.printStackTrace();
- }
-
- // Internal error
- catch (Error e)
- {
- fail("Matcher threw fatal error \"" + e.getMessage() + "\"");
- e.printStackTrace();
- }
- }
- }
- finally
- {
- br.close();
- }
-
- // Show match time
- System.out.println ("\n\nMatch time = " + (System.currentTimeMillis() - ms) + " ms.");
-
- // Print final results
- System.out.println ("\nTests complete. " + n + " tests, " + failures + " failure(s).");
- }
- }