/*
 * testRegexp.c: simple module for testing regular expressions
 *
 * See Copyright for the status of this software.
 *
 * Daniel Veillard <veillard@redhat.com>
 */

#include <string.h>
#include "libxml.h"
#ifdef LIBXML_AUTOMATA_ENABLED

#include <libxml/tree.h>
#include <libxml/xmlautomata.h>

static int scanNumber(char **ptr) {
    int ret = 0;
    char *cur;

    cur = *ptr;
    while ((*cur >= '0') && (*cur <= '9')) {
	ret = ret * 10 + (*cur - '0');
	cur++;
    }
    *ptr = cur;
    return(ret);
}

static void
testRegexpFile(const char *filename) {
    FILE *input;
    char exp[5000];
    int len;
    int ret;
    int i;
    xmlAutomataPtr am;
    xmlAutomataStatePtr states[1000];
    xmlRegexpPtr regexp = NULL;
    xmlRegExecCtxtPtr exec = NULL;

    for (i = 0;i<1000;i++)
	states[i] = NULL;

    input = fopen(filename, "r");
    if (input == NULL) {
        xmlGenericError(xmlGenericErrorContext,
		"Cannot open %s for reading\n", filename);
	return;
    }

    am = xmlNewAutomata();
    if (am == NULL) {
        xmlGenericError(xmlGenericErrorContext,
		"Cannot create automata\n");
	fclose(input);
    }
    states[0] = xmlAutomataGetInitState(am);
    if (states[0] == NULL) {
        xmlGenericError(xmlGenericErrorContext,
		"Cannot get start state\n");
	xmlFreeAutomata(am);
	fclose(input);
    }
    ret = 0;

    while (fgets(exp, 4500, input) != NULL) {
	if (exp[0] == '#')
	    continue;
	len = strlen(exp);
	len--;
	while ((len >= 0) && 
	       ((exp[len] == '\n') || (exp[len] == '\t') ||
		(exp[len] == '\r') || (exp[len] == ' '))) len--;
	exp[len + 1] = 0;      
	if (len >= 0) {
	    if ((am != NULL) && (exp[0] == 't') && (exp[1] == ' ')) {
		char *ptr = &exp[2];
		int from, to;

		from = scanNumber(&ptr);
		if (*ptr != ' ') {
		    xmlGenericError(xmlGenericErrorContext,
			    "Bad line %s\n", exp);
		    break;
		}
		if (states[from] == NULL)
		    states[from] = xmlAutomataNewState(am);
		ptr++;
		to = scanNumber(&ptr);
		if (*ptr != ' ') {
		    xmlGenericError(xmlGenericErrorContext,
			    "Bad line %s\n", exp);
		    break;
		}
		if (states[to] == NULL)
		    states[to] = xmlAutomataNewState(am);
		ptr++;
		xmlAutomataNewTransition(am, states[from], states[to],
			                 BAD_CAST ptr, NULL);
	    } else if ((am != NULL) && (exp[0] == 'e') && (exp[1] == ' ')) {
		char *ptr = &exp[2];
		int from, to;

		from = scanNumber(&ptr);
		if (*ptr != ' ') {
		    xmlGenericError(xmlGenericErrorContext,
			    "Bad line %s\n", exp);
		    break;
		}
		if (states[from] == NULL)
		    states[from] = xmlAutomataNewState(am);
		ptr++;
		to = scanNumber(&ptr);
		if (states[to] == NULL)
		    states[to] = xmlAutomataNewState(am);
		xmlAutomataNewEpsilon(am, states[from], states[to]);
	    } else if ((am != NULL) && (exp[0] == 'f') && (exp[1] == ' ')) {
		char *ptr = &exp[2];
		int state;

		state = scanNumber(&ptr);
		if (states[state] == NULL) {
		    xmlGenericError(xmlGenericErrorContext,
			    "Bad state %d : %s\n", state, exp);
		    break;
		}
		xmlAutomataSetFinalState(am, states[state]);
	    } else if ((am != NULL) && (exp[0] == 'c') && (exp[1] == ' ')) {
		char *ptr = &exp[2];
		int from, to;
		int min, max;

		from = scanNumber(&ptr);
		if (*ptr != ' ') {
		    xmlGenericError(xmlGenericErrorContext,
			    "Bad line %s\n", exp);
		    break;
		}
		if (states[from] == NULL)
		    states[from] = xmlAutomataNewState(am);
		ptr++;
		to = scanNumber(&ptr);
		if (*ptr != ' ') {
		    xmlGenericError(xmlGenericErrorContext,
			    "Bad line %s\n", exp);
		    break;
		}
		if (states[to] == NULL)
		    states[to] = xmlAutomataNewState(am);
		ptr++;
		min = scanNumber(&ptr);
		if (*ptr != ' ') {
		    xmlGenericError(xmlGenericErrorContext,
			    "Bad line %s\n", exp);
		    break;
		}
		ptr++;
		max = scanNumber(&ptr);
		if (*ptr != ' ') {
		    xmlGenericError(xmlGenericErrorContext,
			    "Bad line %s\n", exp);
		    break;
		}
		ptr++;
		xmlAutomataNewCountTrans(am, states[from], states[to],
			                 BAD_CAST ptr, min, max, NULL);
	    } else if ((am != NULL) && (exp[0] == '-') && (exp[1] == '-')) {
		/* end of the automata */
		regexp = xmlAutomataCompile(am);
		xmlFreeAutomata(am);
		am = NULL;
		if (regexp == NULL) {
		    xmlGenericError(xmlGenericErrorContext,
			    "Failed to compile the automata");
		    break;
		}
	    } else if ((exp[0] == '=') && (exp[1] == '>')) {
		if (regexp == NULL) {
		    printf("=> failed not compiled\n");
		} else {
		    if (exec == NULL)
			exec = xmlRegNewExecCtxt(regexp, NULL, NULL);
		    if (ret == 0) {
			ret = xmlRegExecPushString(exec, NULL, NULL);
		    }
		    if (ret == 1)
			printf("=> Passed\n");
		    else if ((ret == 0) || (ret == -1))
			printf("=> Failed\n");
		    else if (ret < 0)
			printf("=> Error\n");
		    xmlRegFreeExecCtxt(exec);
		    exec = NULL;
		}
		ret = 0;
	    } else if (regexp != NULL) {
		if (exec == NULL)
		    exec = xmlRegNewExecCtxt(regexp, NULL, NULL);
		ret = xmlRegExecPushString(exec, BAD_CAST exp, NULL);
	    } else {
		xmlGenericError(xmlGenericErrorContext,
			"Unexpected line %s\n", exp);
	    }
	}
    }
    fclose(input);
    if (regexp != NULL)
	xmlRegFreeRegexp(regexp);
    if (exec != NULL)
	xmlRegFreeExecCtxt(exec);
    if (am != NULL)
	xmlFreeAutomata(am);
}

int main(int argc, char **argv) {

    xmlInitMemory();

    if (argc == 1) {
	int ret;
	xmlAutomataPtr am;
	xmlAutomataStatePtr start, cur;
	xmlRegexpPtr regexp;
	xmlRegExecCtxtPtr exec;

	am = xmlNewAutomata();
	start = xmlAutomataGetInitState(am);

	/* generate a[ba]*a */
	cur = xmlAutomataNewTransition(am, start, NULL, BAD_CAST"a", NULL);
	xmlAutomataNewTransition(am, cur, cur, BAD_CAST"b", NULL);
	xmlAutomataNewTransition(am, cur, cur, BAD_CAST"a", NULL);
	cur = xmlAutomataNewCountTrans(am, cur, NULL, BAD_CAST"a", 2, 3, NULL);
	xmlAutomataSetFinalState(am, cur);

	/* compile it in a regexp and free the automata */
	regexp = xmlAutomataCompile(am);
	xmlFreeAutomata(am);

	/* test the regexp */
	xmlRegexpPrint(stdout, regexp);
	exec = xmlRegNewExecCtxt(regexp, NULL, NULL);
	ret = xmlRegExecPushString(exec, BAD_CAST"a", NULL);
	if (ret == 1)
	    printf("final\n");
	else if (ret < 0)
	    printf("error\n");
	ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
	if (ret == 1)
	    printf("final\n");
	else if (ret < 0)
	    printf("error\n");
	ret =xmlRegExecPushString(exec, BAD_CAST"b", NULL);
	if (ret == 1)
	    printf("final\n");
	else if (ret < 0)
	    printf("error\n");
	ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
	if (ret == 1)
	    printf("final\n");
	else if (ret < 0)
	    printf("error\n");
	ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
	if (ret == 1)
	    printf("final\n");
	else if (ret < 0)
	    printf("error\n");
	ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
	if (ret == 1)
	    printf("final\n");
	else if (ret < 0)
	    printf("error\n");
	ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
	if (ret == 1)
	    printf("final\n");
	else if (ret < 0)
	    printf("error\n");
	if (ret == 0) {
	    ret = xmlRegExecPushString(exec, NULL, NULL);
	    if (ret == 1)
		printf("final\n");
	    else if (ret < 0)
		printf("error\n");
	}
	xmlRegFreeExecCtxt(exec);

	/* free the regexp */
	xmlRegFreeRegexp(regexp);
    } else {
	int i;

	for (i = 1;i < argc;i++)
	    testRegexpFile(argv[i]);
    }

    xmlCleanupParser();
    xmlMemoryDump();
    return(0);
}

#else
#include <stdio.h>
int main(int argc, char **argv) {
    printf("%s : Automata support not compiled in\n", argv[0]);
    return(0);
}
#endif /* LIBXML_AUTOMATA_ENABLED */
