package local;

import java.io.*;

class RegExpr {

    private byte[] expbuf = new byte[1024];

    /** Create (compile) new regular expression from given string */
    public RegExpr(String expr) throws InvalidRegExprException {
	compile(expr);
    }

    /** Return true if given string matches this regular expression */
    public native boolean match(String str);

    private native void compile(String expr) throws InvalidRegExprException;

    public static void main(String[] args) {
	if (args.length < 1)
	    error("usage: RegExpr expr [files]");

	try {
	    RegExpr regExpr = null;
	    try {
		regExpr = new RegExpr(args[0]);
	    } catch (InvalidRegExprException e) {
		error("Invalid regular expression: " + e.getMessage());
	    }

	    for (int i = 1; i < args.length; i++) {
		DataInputStream in = new DataInputStream(
		    new FileInputStream(args[i]));
		while (true) {
		    String line = in.readLine();
		    if (line == null)
			break;
		    if (regExpr.match(line))
			System.out.println(line);
		}
	    }
	} catch (IOException e) {
	    error("I/O Exception: " + e.toString());
	}
    }

    public static void error(String err) {
	System.err.println("RegExpr: " + err);
	System.exit(1); // non-zero argument means "not good"
    }

    static {
	System.loadLibrary("RegExpr");
    }
}



#include "local_RegExpr.h"
#include <regexpr.h>
#include <javaString.h>

void
local_RegExpr_compile(
    struct Hlocal_RegExpr *this_h,
    Hjava_lang_String *expr_h)
{
    char *expr, *result;
    HArrayOfByte *expbuf_h;
    long len;
    ArrayOfByte *expbuf;

    expr = makeCString(expr_h);
    if (expr == NULL)
	return;

    expbuf_h = unhand(this_h)->expbuf;
    len = obj_length(expbuf_h);
    expbuf = unhand(expbuf_h);
    result = compile(expr, &expbuf->body[0], &expbuf->body[len]);
    if (result == NULL) {
	char *errmsg;
	switch (regerrno) {
	  case 11:
	    errmsg = "Range endpoint too large";
	    break;
	  case 16:
	    errmsg = "Bad number";
	    break;
	  case 25:
	    errmsg = "``\\digit'' out of range";
	    break;
	  case 36:
	    errmsg = "Illegal or missing delimiter";
	    break;
	  case 41:
	    errmsg = "No remembered search string";
	    break;
	  case 42:
	    errmsg = "\\(~\\) imbalance";
	    break;
	  case 43:
	    errmsg = "Too many \\(";
	    break;
	  case 44:
	    errmsg = "More than 2 numbers given in \\{~\\}";
	    break;
	  case 45:
	    errmsg = "} expected after \\";
	    break;
	  case 46:
	    errmsg = "First number exceeds second in \\{~\\}";
	    break;
	  case 49:
	    errmsg = "[ ] imbalance";
	    break;
	  case 50:
	    errmsg = "Regular expression overflow";
	    break;
	  default:
	    errmsg = "(Unknown error)";
	}
	SignalError(EE(),
	    "local/InvalidRegExprException",
	    errmsg);
	return;
    }
}

long
local_RegExpr_match(
    struct Hlocal_RegExpr *this_h,
    Hjava_lang_String *str_h)
{
    char *str;
    HArrayOfByte *expbuf_h;
    ArrayOfByte *expbuf;
    int result;

    str = makeCString(str_h);
    if (str == NULL)
	return;

    expbuf_h = unhand(this_h)->expbuf;
    expbuf = unhand(expbuf_h);
    result = step(str, &expbuf->body[0]);
    if (result != 0)
	return 1;
    else
	return 0;
}
