15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * testRegexp.c: simple module for testing regular expressions
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See Copyright for the status of this software.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Daniel Veillard <veillard@redhat.com>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "libxml.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_REGEXP_ENABLED
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/tree.h>
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlregexp.h>
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int repeat = 0;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int debug = 0;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void testRegexp(xmlRegexpPtr comp, const char *value) {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = xmlRegexpExec(comp, (const xmlChar *) value);
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == 1)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("%s: Ok\n", value);
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (ret == 0)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("%s: Fail\n", value);
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("%s: Error: %d\n", value, ret);
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (repeat) {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int j;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (j = 0;j < 999999;j++)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpExec(comp, (const xmlChar *) value);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)testRegexpFile(const char *filename) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegexpPtr comp = NULL;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FILE *input;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char expression[5000];
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int len;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    input = fopen(filename, "r");
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (input == NULL) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlGenericError(xmlGenericErrorContext,
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"Cannot open %s for reading\n", filename);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (fgets(expression, 4500, input) != NULL) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	len = strlen(expression);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	len--;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while ((len >= 0) &&
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       ((expression[len] == '\n') || (expression[len] == '\t') ||
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(expression[len] == '\r') || (expression[len] == ' '))) len--;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	expression[len + 1] = 0;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (len >= 0) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (expression[0] == '#')
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((expression[0] == '=') && (expression[1] == '>')) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		char *pattern = &expression[2];
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (comp != NULL) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlRegFreeRegexp(comp);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    comp = NULL;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("Regexp: %s\n", pattern) ;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		comp = xmlRegexpCompile((const xmlChar *) pattern);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (comp == NULL) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("   failed to compile\n");
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (comp == NULL) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("Regexp: %s\n", expression) ;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		comp = xmlRegexpCompile((const xmlChar *) expression);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (comp == NULL) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("   failed to compile\n");
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (comp != NULL) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		testRegexp(comp, expression);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fclose(input);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (comp != NULL)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegFreeRegexp(comp);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_EXPR_ENABLED
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)runFileTest(xmlExpCtxtPtr ctxt, const char *filename) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpNodePtr expr = NULL, sub;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FILE *input;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char expression[5000];
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int len;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    input = fopen(filename, "r");
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (input == NULL) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlGenericError(xmlGenericErrorContext,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"Cannot open %s for reading\n", filename);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (fgets(expression, 4500, input) != NULL) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	len = strlen(expression);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	len--;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while ((len >= 0) &&
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       ((expression[len] == '\n') || (expression[len] == '\t') ||
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(expression[len] == '\r') || (expression[len] == ' '))) len--;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	expression[len + 1] = 0;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (len >= 0) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (expression[0] == '#')
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((expression[0] == '=') && (expression[1] == '>')) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		char *str = &expression[2];
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (expr != NULL) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlExpFree(ctxt, expr);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (xmlExpCtxtNbNodes(ctxt) != 0)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        printf(" Parse/free of Expression leaked %d\n",
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       xmlExpCtxtNbNodes(ctxt));
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    expr = NULL;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("Expression: %s\n", str) ;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		expr = xmlExpParse(ctxt, str);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (expr == NULL) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("   parsing Failed\n");
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (expr != NULL) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        int expect = -1;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int nodes1, nodes2;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (expression[0] == '0')
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    expect = 0;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (expression[0] == '1')
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    expect = 1;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("Subexp: %s", expression + 2) ;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		nodes1 = xmlExpCtxtNbNodes(ctxt);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		sub = xmlExpParse(ctxt, expression + 2);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (sub == NULL) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("   parsing Failed\n");
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int ret;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    nodes2 = xmlExpCtxtNbNodes(ctxt);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ret = xmlExpSubsume(ctxt, expr, sub);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if ((expect == 1) && (ret == 1)) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf(" => accept, Ok\n");
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else if ((expect == 0) && (ret == 0)) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        printf(" => reject, Ok\n");
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else if ((expect == 1) && (ret == 0)) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf(" => reject, Failed\n");
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else if ((expect == 0) && (ret == 1)) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf(" => accept, Failed\n");
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        printf(" => fail internally\n");
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (xmlExpCtxtNbNodes(ctxt) > nodes2) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        printf(" Subsume leaked %d\n",
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       xmlExpCtxtNbNodes(ctxt) - nodes2);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			nodes1 += xmlExpCtxtNbNodes(ctxt) - nodes2;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlExpFree(ctxt, sub);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (xmlExpCtxtNbNodes(ctxt) > nodes1) {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        printf(" Parse/free leaked %d\n",
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       xmlExpCtxtNbNodes(ctxt) - nodes1);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (expr != NULL) {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlExpFree(ctxt, expr);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (xmlExpCtxtNbNodes(ctxt) != 0)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf(" Parse/free of Expression leaked %d\n",
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   xmlExpCtxtNbNodes(ctxt));
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fclose(input);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)testReduce(xmlExpCtxtPtr ctxt, xmlExpNodePtr expr, const char *tst) {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlBufferPtr xmlExpBuf;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpNodePtr sub, deriv;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpBuf = xmlBufferCreate();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sub = xmlExpParse(ctxt, tst);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sub == NULL) {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printf("Subset %s failed to parse\n", tst);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpDump(xmlExpBuf, sub);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("Subset parsed as: %s\n",
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           (const char *) xmlBufferContent(xmlExpBuf));
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    deriv = xmlExpExpDerive(ctxt, expr, sub);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (deriv == NULL) {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printf("Derivation led to an internal error, report this !\n");
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlBufferEmpty(xmlExpBuf);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlExpDump(xmlExpBuf, deriv);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (xmlExpIsNillable(deriv))
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf("Resulting nillable derivation: %s\n",
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	           (const char *) xmlBufferContent(xmlExpBuf));
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf("Resulting derivation: %s\n",
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	           (const char *) xmlBufferContent(xmlExpBuf));
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlExpFree(ctxt, deriv);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpFree(ctxt, sub);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)exprDebug(xmlExpCtxtPtr ctxt, xmlExpNodePtr expr) {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlBufferPtr xmlExpBuf;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpNodePtr deriv;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *list[40];
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpBuf = xmlBufferCreate();
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (expr == NULL) {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printf("Failed to parse\n");
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpDump(xmlExpBuf, expr);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("Parsed as: %s\n", (const char *) xmlBufferContent(xmlExpBuf));
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("Max token input = %d\n", xmlExpMaxToken(expr));
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (xmlExpIsNillable(expr) == 1)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("Is nillable\n");
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = xmlExpGetLanguage(ctxt, expr, (const xmlChar **) &list[0], 40);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret < 0)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("Failed to get list: %d\n", ret);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int i;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("Language has %d strings, testing string derivations\n", ret);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0;i < ret;i++) {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    deriv = xmlExpStringDerive(ctxt, expr, BAD_CAST list[i], -1);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (deriv == NULL) {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("  %s -> derivation failed\n", list[i]);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlBufferEmpty(xmlExpBuf);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlExpDump(xmlExpBuf, deriv);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("  %s -> %s\n", list[i],
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       (const char *) xmlBufferContent(xmlExpBuf));
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, deriv);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlBufferFree(xmlExpBuf);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void usage(const char *name) {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(stderr, "Usage: %s [flags]\n", name);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(stderr, "Testing tool for libxml2 string and pattern regexps\n");
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(stderr, "   --debug: switch on debugging\n");
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(stderr, "   --repeat: loop on the operation\n");
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_EXPR_ENABLED
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(stderr, "   --expr: test xmlExp and not xmlRegexp\n");
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(stderr, "   --input filename: use the given filename for regexp\n");
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(stderr, "   --input filename: use the given filename for exp\n");
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, char **argv) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegexpPtr comp = NULL;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_EXPR_ENABLED
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpNodePtr expr = NULL;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int use_exp = 0;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpCtxtPtr ctxt = NULL;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *pattern = NULL;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *filename = NULL;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlInitMemory();
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (argc <= 1) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	usage(argv[0]);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(1);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 1; i < argc ; i++) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!strcmp(argv[i], "-"))
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (argv[i][0] != '-')
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    continue;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!strcmp(argv[i], "--"))
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug"))) {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    debug++;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if ((!strcmp(argv[i], "-repeat")) ||
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	         (!strcmp(argv[i], "--repeat"))) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    repeat++;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_EXPR_ENABLED
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if ((!strcmp(argv[i], "-expr")) ||
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	         (!strcmp(argv[i], "--expr"))) {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    use_exp++;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if ((!strcmp(argv[i], "-i")) || (!strcmp(argv[i], "-f")) ||
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   (!strcmp(argv[i], "--input")))
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    filename = argv[++i];
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(stderr, "Unknown option %s\n", argv[i]);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    usage(argv[0]);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_EXPR_ENABLED
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (use_exp)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt = xmlExpNewCtxt(0, NULL);
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (filename != NULL) {
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_EXPR_ENABLED
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (use_exp)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    runFileTest(ctxt, filename);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    testRegexpFile(filename);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int  data = 0;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_EXPR_ENABLED
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (use_exp) {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (i = 1; i < argc ; i++) {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        if (strcmp(argv[i], "--") == 0)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    data = 1;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0) ||
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (data == 1)) {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (pattern == NULL) {
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			pattern = argv[i];
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf("Testing expr %s:\n", pattern);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			expr = xmlExpParse(ctxt, pattern);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (expr == NULL) {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    printf("   failed to compile\n");
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    break;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (debug) {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    exprDebug(ctxt, expr);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else {
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			testReduce(ctxt, expr, argv[i]);
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (expr != NULL) {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlExpFree(ctxt, expr);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		expr = NULL;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (i = 1; i < argc ; i++) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        if (strcmp(argv[i], "--") == 0)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    data = 1;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0) ||
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		         (data == 1)) {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (pattern == NULL) {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			pattern = argv[i];
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf("Testing %s:\n", pattern);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			comp = xmlRegexpCompile((const xmlChar *) pattern);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (comp == NULL) {
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    printf("   failed to compile\n");
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    break;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (debug)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    xmlRegexpPrint(stdout, comp);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			testRegexp(comp, argv[i]);
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (comp != NULL)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlRegFreeRegexp(comp);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_EXPR_ENABLED
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt != NULL) {
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("Ops: %d nodes, %d cons\n",
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       xmlExpCtxtNbNodes(ctxt), xmlExpCtxtNbCons(ctxt));
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlExpFreeCtxt(ctxt);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlCleanupParser();
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlMemoryDump();
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("%s : Regexp support not compiled in\n", argv[0]);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* LIBXML_REGEXP_ENABLED */
403