Edit

kc3-lang/libxml2/testAutomata.c

Branch :

  • Show log

    Commit

  • Author : Daniel Veillard
    Date : 2002-09-24 14:13:13
    Hash : 118aed78
    Message : fixed the data callback on transition functionality which was broken when * xmlregexp.c: fixed the data callback on transition functionality which was broken when using the compact form * result/schemas/*: updated the results, less verbose, all tests pass like before * DOCBparser.c testAutomata.c testC14N.c testSchemas.c testThreads.c testXPath.c valid.c xinclude.c xmllint.c xmlregexp.c xmlschemas.c xmlschemastypes.c xpath.c python/libxml.c: removed a bunch of annoying warnings * xpath.c: try to provide better error report when possible Daniel

  • testAutomata.c
  • /*
     * 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 */