/*
* testRegexp.c: simple module for testing regular expressions
*
* See Copyright for the status of this software.
*
* Daniel Veillard <veillard@redhat.com>
*/
#include "libxml.h"
#ifdef LIBXML_AUTOMATA_ENABLED
#include <string.h>
#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 expr[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);
return;
}
states[0] = xmlAutomataGetInitState(am);
if (states[0] == NULL) {
xmlGenericError(xmlGenericErrorContext,
"Cannot get start state\n");
xmlFreeAutomata(am);
fclose(input);
return;
}
ret = 0;
while (fgets(expr, 4500, input) != NULL) {
if (expr[0] == '#')
continue;
len = strlen(expr);
len--;
while ((len >= 0) &&
((expr[len] == '\n') || (expr[len] == '\t') ||
(expr[len] == '\r') || (expr[len] == ' '))) len--;
expr[len + 1] = 0;
if (len >= 0) {
if ((am != NULL) && (expr[0] == 't') && (expr[1] == ' ')) {
char *ptr = &expr[2];
int from, to;
from = scanNumber(&ptr);
if (*ptr != ' ') {
xmlGenericError(xmlGenericErrorContext,
"Bad line %s\n", expr);
break;
}
if (states[from] == NULL)
states[from] = xmlAutomataNewState(am);
ptr++;
to = scanNumber(&ptr);
if (*ptr != ' ') {
xmlGenericError(xmlGenericErrorContext,
"Bad line %s\n", expr);
break;
}
if (states[to] == NULL)
states[to] = xmlAutomataNewState(am);
ptr++;
xmlAutomataNewTransition(am, states[from], states[to],
BAD_CAST ptr, NULL);
} else if ((am != NULL) && (expr[0] == 'e') && (expr[1] == ' ')) {
char *ptr = &expr[2];
int from, to;
from = scanNumber(&ptr);
if (*ptr != ' ') {
xmlGenericError(xmlGenericErrorContext,
"Bad line %s\n", expr);
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) && (expr[0] == 'f') && (expr[1] == ' ')) {
char *ptr = &expr[2];
int state;
state = scanNumber(&ptr);
if (states[state] == NULL) {
xmlGenericError(xmlGenericErrorContext,
"Bad state %d : %s\n", state, expr);
break;
}
xmlAutomataSetFinalState(am, states[state]);
} else if ((am != NULL) && (expr[0] == 'c') && (expr[1] == ' ')) {
char *ptr = &expr[2];
int from, to;
int min, max;
from = scanNumber(&ptr);
if (*ptr != ' ') {
xmlGenericError(xmlGenericErrorContext,
"Bad line %s\n", expr);
break;
}
if (states[from] == NULL)
states[from] = xmlAutomataNewState(am);
ptr++;
to = scanNumber(&ptr);
if (*ptr != ' ') {
xmlGenericError(xmlGenericErrorContext,
"Bad line %s\n", expr);
break;
}
if (states[to] == NULL)
states[to] = xmlAutomataNewState(am);
ptr++;
min = scanNumber(&ptr);
if (*ptr != ' ') {
xmlGenericError(xmlGenericErrorContext,
"Bad line %s\n", expr);
break;
}
ptr++;
max = scanNumber(&ptr);
if (*ptr != ' ') {
xmlGenericError(xmlGenericErrorContext,
"Bad line %s\n", expr);
break;
}
ptr++;
xmlAutomataNewCountTrans(am, states[from], states[to],
BAD_CAST ptr, min, max, NULL);
} else if ((am != NULL) && (expr[0] == '-') && (expr[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 ((expr[0] == '=') && (expr[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 expr, NULL);
} else {
xmlGenericError(xmlGenericErrorContext,
"Unexpected line %s\n", expr);
}
}
}
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 ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
printf("%s : Automata support not compiled in\n", argv[0]);
return(0);
}
#endif /* LIBXML_AUTOMATA_ENABLED */