root/third_party/libxml/src/testAutomata.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. scanNumber
  2. testRegexpFile
  3. main
  4. main

/*
 * 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 */

/* [<][>][^][v][top][bottom][index][help] */