/*
 * pattern.c: Implementation of selectors for nodes
 *
 * Reference:
 *   http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/
 *   to some extent
 *   http://www.w3.org/TR/1999/REC-xml-19991116
 *
 * See Copyright for the status of this software.
 *
 * daniel@veillard.com
 */

/*
 * TODO:
 * - compilation flags to check for specific syntaxes
 *   using flags of xmlPatterncompile()
 * - making clear how pattern starting with / or . need to be handled,
 *   currently push(NULL, NULL) means a reset of the streaming context
 *   and indicating we are on / (the document node), probably need
 *   something similar for .
 * - get rid of the "compile" starting with lowercase
 * - DONE (2006-05-16): get rid of the Strdup/Strndup in case of dictionary
 */

#define IN_LIBXML
#include "libxml.h"

#include <string.h>
#include <libxml/xmlmemory.h>
#include <libxml/tree.h>
#include <libxml/hash.h>
#include <libxml/dict.h>
#include <libxml/xmlerror.h>
#include <libxml/parserInternals.h>
#include <libxml/pattern.h>

#ifdef LIBXML_PATTERN_ENABLED

/* #define DEBUG_STREAMING */

#ifdef ERROR
#undef ERROR
#endif
#define ERROR(a, b, c, d)
#define ERROR5(a, b, c, d, e)

#define XML_STREAM_STEP_DESC	1
#define XML_STREAM_STEP_FINAL	2
#define XML_STREAM_STEP_ROOT	4
#define XML_STREAM_STEP_ATTR	8
#define XML_STREAM_STEP_NODE	16
#define XML_STREAM_STEP_IN_SET	32

/*
* NOTE: Those private flags (XML_STREAM_xxx) are used
*   in _xmlStreamCtxt->flag. They extend the public
*   xmlPatternFlags, so be careful not to interfere with the
*   reserved values for xmlPatternFlags.
*/
#define XML_STREAM_FINAL_IS_ANY_NODE 1<<14
#define XML_STREAM_FROM_ROOT 1<<15
#define XML_STREAM_DESC 1<<16

/*
* XML_STREAM_ANY_NODE is used for comparison against
* xmlElementType enums, to indicate a node of any type.
*/
#define XML_STREAM_ANY_NODE 100

#define XML_PATTERN_NOTPATTERN  (XML_PATTERN_XPATH | \
				 XML_PATTERN_XSSEL | \
				 XML_PATTERN_XSFIELD)

#define XML_STREAM_XS_IDC(c) ((c)->flags & \
    (XML_PATTERN_XSSEL | XML_PATTERN_XSFIELD))

#define XML_STREAM_XS_IDC_SEL(c) ((c)->flags & XML_PATTERN_XSSEL)

#define XML_STREAM_XS_IDC_FIELD(c) ((c)->flags & XML_PATTERN_XSFIELD)

#define XML_PAT_COPY_NSNAME(c, r, nsname) \
    if ((c)->comp->dict) \
	r = (xmlChar *) xmlDictLookup((c)->comp->dict, BAD_CAST nsname, -1); \
    else r = xmlStrdup(BAD_CAST nsname);

#define XML_PAT_FREE_STRING(c, r) if ((c)->comp->dict == NULL) xmlFree(r);

typedef struct _xmlStreamStep xmlStreamStep;
typedef xmlStreamStep *xmlStreamStepPtr;
struct _xmlStreamStep {
    int flags;			/* properties of that step */
    const xmlChar *name;	/* first string value if NULL accept all */
    const xmlChar *ns;		/* second string value */
    int nodeType;		/* type of node */
};

typedef struct _xmlStreamComp xmlStreamComp;
typedef xmlStreamComp *xmlStreamCompPtr;
struct _xmlStreamComp {
    xmlDict *dict;		/* the dictionary if any */
    int nbStep;			/* number of steps in the automata */
    int maxStep;		/* allocated number of steps */
    xmlStreamStepPtr steps;	/* the array of steps */
    int flags;
};

struct _xmlStreamCtxt {
    struct _xmlStreamCtxt *next;/* link to next sub pattern if | */
    xmlStreamCompPtr comp;	/* the compiled stream */
    int nbState;		/* number of states in the automata */
    int maxState;		/* allocated number of states */
    int level;			/* how deep are we ? */
    int *states;		/* the array of step indexes */
    int flags;			/* validation options */
    int blockLevel;
};

static void xmlFreeStreamComp(xmlStreamCompPtr comp);

/*
 * Types are private:
 */

typedef enum {
    XML_OP_END=0,
    XML_OP_ROOT,
    XML_OP_ELEM,
    XML_OP_CHILD,
    XML_OP_ATTR,
    XML_OP_PARENT,
    XML_OP_ANCESTOR,
    XML_OP_NS,
    XML_OP_ALL
} xmlPatOp;


typedef struct _xmlStepState xmlStepState;
typedef xmlStepState *xmlStepStatePtr;
struct _xmlStepState {
    int step;
    xmlNodePtr node;
};

typedef struct _xmlStepStates xmlStepStates;
typedef xmlStepStates *xmlStepStatesPtr;
struct _xmlStepStates {
    int nbstates;
    int maxstates;
    xmlStepStatePtr states;
};

typedef struct _xmlStepOp xmlStepOp;
typedef xmlStepOp *xmlStepOpPtr;
struct _xmlStepOp {
    xmlPatOp op;
    const xmlChar *value;
    const xmlChar *value2; /* The namespace name */
};

#define PAT_FROM_ROOT	(1<<8)
#define PAT_FROM_CUR	(1<<9)

struct _xmlPattern {
    void *data;		/* the associated template */
    xmlDictPtr dict;		/* the optional dictionary */
    struct _xmlPattern *next;	/* next pattern if | is used */
    const xmlChar *pattern;	/* the pattern */
    int flags;			/* flags */
    int nbStep;
    int maxStep;
    xmlStepOpPtr steps;        /* ops for computation */
    xmlStreamCompPtr stream;	/* the streaming data if any */
};

typedef struct _xmlPatParserContext xmlPatParserContext;
typedef xmlPatParserContext *xmlPatParserContextPtr;
struct _xmlPatParserContext {
    const xmlChar *cur;			/* the current char being parsed */
    const xmlChar *base;		/* the full expression */
    int	           error;		/* error code */
    xmlDictPtr     dict;		/* the dictionary if any */
    xmlPatternPtr  comp;		/* the result */
    xmlNodePtr     elem;		/* the current node if any */
    const xmlChar **namespaces;		/* the namespaces definitions */
    int   nb_namespaces;		/* the number of namespaces */
};

/************************************************************************
 *									*
 *			Type functions					*
 *									*
 ************************************************************************/

/**
 * xmlNewPattern:
 *
 * Create a new XSLT Pattern
 *
 * Returns the newly allocated xmlPatternPtr or NULL in case of error
 */
static xmlPatternPtr
xmlNewPattern(void) {
    xmlPatternPtr cur;

    cur = (xmlPatternPtr) xmlMalloc(sizeof(xmlPattern));
    if (cur == NULL) {
	ERROR(NULL, NULL, NULL,
		"xmlNewPattern : malloc failed\n");
	return(NULL);
    }
    memset(cur, 0, sizeof(xmlPattern));
    cur->maxStep = 10;
    cur->steps = (xmlStepOpPtr) xmlMalloc(cur->maxStep * sizeof(xmlStepOp));
    if (cur->steps == NULL) {
        xmlFree(cur);
	ERROR(NULL, NULL, NULL,
		"xmlNewPattern : malloc failed\n");
	return(NULL);
    }
    return(cur);
}

/**
 * xmlFreePattern:
 * @comp:  an XSLT comp
 *
 * Free up the memory allocated by @comp
 */
void
xmlFreePattern(xmlPatternPtr comp) {
    xmlFreePatternList(comp);
}

static void
xmlFreePatternInternal(xmlPatternPtr comp) {
    xmlStepOpPtr op;
    int i;

    if (comp == NULL)
	return;
    if (comp->stream != NULL)
        xmlFreeStreamComp(comp->stream);
    if (comp->pattern != NULL)
	xmlFree((xmlChar *)comp->pattern);
    if (comp->steps != NULL) {
        if (comp->dict == NULL) {
	    for (i = 0;i < comp->nbStep;i++) {
		op = &comp->steps[i];
		if (op->value != NULL)
		    xmlFree((xmlChar *) op->value);
		if (op->value2 != NULL)
		    xmlFree((xmlChar *) op->value2);
	    }
	}
	xmlFree(comp->steps);
    }
    if (comp->dict != NULL)
        xmlDictFree(comp->dict);

    memset(comp, -1, sizeof(xmlPattern));
    xmlFree(comp);
}

/**
 * xmlFreePatternList:
 * @comp:  an XSLT comp list
 *
 * Free up the memory allocated by all the elements of @comp
 */
void
xmlFreePatternList(xmlPatternPtr comp) {
    xmlPatternPtr cur;

    while (comp != NULL) {
	cur = comp;
	comp = comp->next;
	cur->next = NULL;
	xmlFreePatternInternal(cur);
    }
}

/**
 * xmlNewPatParserContext:
 * @pattern:  the pattern context
 * @dict:  the inherited dictionary or NULL
 * @namespaces: the prefix definitions, array of [URI, prefix] terminated
 *              with [NULL, NULL] or NULL if no namespace is used
 *
 * Create a new XML pattern parser context
 *
 * Returns the newly allocated xmlPatParserContextPtr or NULL in case of error
 */
static xmlPatParserContextPtr
xmlNewPatParserContext(const xmlChar *pattern, xmlDictPtr dict,
                       const xmlChar **namespaces) {
    xmlPatParserContextPtr cur;

    if (pattern == NULL)
        return(NULL);

    cur = (xmlPatParserContextPtr) xmlMalloc(sizeof(xmlPatParserContext));
    if (cur == NULL) {
	ERROR(NULL, NULL, NULL,
		"xmlNewPatParserContext : malloc failed\n");
	return(NULL);
    }
    memset(cur, 0, sizeof(xmlPatParserContext));
    cur->dict = dict;
    cur->cur = pattern;
    cur->base = pattern;
    if (namespaces != NULL) {
        int i;
        for (i = 0;namespaces[2 * i] != NULL;i++)
            ;
        cur->nb_namespaces = i;
    } else {
        cur->nb_namespaces = 0;
    }
    cur->namespaces = namespaces;
    return(cur);
}

/**
 * xmlFreePatParserContext:
 * @ctxt:  an XSLT parser context
 *
 * Free up the memory allocated by @ctxt
 */
static void
xmlFreePatParserContext(xmlPatParserContextPtr ctxt) {
    if (ctxt == NULL)
	return;
    memset(ctxt, -1, sizeof(xmlPatParserContext));
    xmlFree(ctxt);
}

/**
 * xmlPatternAdd:
 * @comp:  the compiled match expression
 * @op:  an op
 * @value:  the first value
 * @value2:  the second value
 *
 * Add a step to an XSLT Compiled Match
 *
 * Returns -1 in case of failure, 0 otherwise.
 */
static int
xmlPatternAdd(xmlPatParserContextPtr ctxt ATTRIBUTE_UNUSED,
                xmlPatternPtr comp,
                xmlPatOp op, xmlChar * value, xmlChar * value2)
{
    if (comp->nbStep >= comp->maxStep) {
        xmlStepOpPtr temp;
	temp = (xmlStepOpPtr) xmlRealloc(comp->steps, comp->maxStep * 2 *
	                                 sizeof(xmlStepOp));
        if (temp == NULL) {
	    ERROR(ctxt, NULL, NULL,
			     "xmlPatternAdd: realloc failed\n");
	    return (-1);
	}
	comp->steps = temp;
	comp->maxStep *= 2;
    }
    comp->steps[comp->nbStep].op = op;
    comp->steps[comp->nbStep].value = value;
    comp->steps[comp->nbStep].value2 = value2;
    comp->nbStep++;
    return (0);
}

#if 0
/**
 * xsltSwapTopPattern:
 * @comp:  the compiled match expression
 *
 * reverse the two top steps.
 */
static void
xsltSwapTopPattern(xmlPatternPtr comp) {
    int i;
    int j = comp->nbStep - 1;

    if (j > 0) {
	register const xmlChar *tmp;
	register xmlPatOp op;
	i = j - 1;
	tmp = comp->steps[i].value;
	comp->steps[i].value = comp->steps[j].value;
	comp->steps[j].value = tmp;
	tmp = comp->steps[i].value2;
	comp->steps[i].value2 = comp->steps[j].value2;
	comp->steps[j].value2 = tmp;
	op = comp->steps[i].op;
	comp->steps[i].op = comp->steps[j].op;
	comp->steps[j].op = op;
    }
}
#endif

/**
 * xmlReversePattern:
 * @comp:  the compiled match expression
 *
 * reverse all the stack of expressions
 *
 * returns 0 in case of success and -1 in case of error.
 */
static int
xmlReversePattern(xmlPatternPtr comp) {
    int i, j;

    /*
     * remove the leading // for //a or .//a
     */
    if ((comp->nbStep > 0) && (comp->steps[0].op == XML_OP_ANCESTOR)) {
        for (i = 0, j = 1;j < comp->nbStep;i++,j++) {
	    comp->steps[i].value = comp->steps[j].value;
	    comp->steps[i].value2 = comp->steps[j].value2;
	    comp->steps[i].op = comp->steps[j].op;
	}
	comp->nbStep--;
    }
    if (comp->nbStep >= comp->maxStep) {
        xmlStepOpPtr temp;
	temp = (xmlStepOpPtr) xmlRealloc(comp->steps, comp->maxStep * 2 *
	                                 sizeof(xmlStepOp));
        if (temp == NULL) {
	    ERROR(ctxt, NULL, NULL,
			     "xmlReversePattern: realloc failed\n");
	    return (-1);
	}
	comp->steps = temp;
	comp->maxStep *= 2;
    }
    i = 0;
    j = comp->nbStep - 1;
    while (j > i) {
	register const xmlChar *tmp;
	register xmlPatOp op;
	tmp = comp->steps[i].value;
	comp->steps[i].value = comp->steps[j].value;
	comp->steps[j].value = tmp;
	tmp = comp->steps[i].value2;
	comp->steps[i].value2 = comp->steps[j].value2;
	comp->steps[j].value2 = tmp;
	op = comp->steps[i].op;
	comp->steps[i].op = comp->steps[j].op;
	comp->steps[j].op = op;
	j--;
	i++;
    }
    comp->steps[comp->nbStep].value = NULL;
    comp->steps[comp->nbStep].value2 = NULL;
    comp->steps[comp->nbStep++].op = XML_OP_END;
    return(0);
}

/************************************************************************
 *									*
 *		The interpreter for the precompiled patterns		*
 *									*
 ************************************************************************/

static int
xmlPatPushState(xmlStepStates *states, int step, xmlNodePtr node) {
    if ((states->states == NULL) || (states->maxstates <= 0)) {
        states->maxstates = 4;
	states->nbstates = 0;
	states->states = xmlMalloc(4 * sizeof(xmlStepState));
    }
    else if (states->maxstates <= states->nbstates) {
        xmlStepState *tmp;

	tmp = (xmlStepStatePtr) xmlRealloc(states->states,
			       2 * states->maxstates * sizeof(xmlStepState));
	if (tmp == NULL)
	    return(-1);
	states->states = tmp;
	states->maxstates *= 2;
    }
    states->states[states->nbstates].step = step;
    states->states[states->nbstates++].node = node;
#if 0
    fprintf(stderr, "Push: %d, %s\n", step, node->name);
#endif
    return(0);
}

/**
 * xmlPatMatch:
 * @comp: the precompiled pattern
 * @node: a node
 *
 * Test whether the node matches the pattern
 *
 * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure
 */
static int
xmlPatMatch(xmlPatternPtr comp, xmlNodePtr node) {
    int i;
    xmlStepOpPtr step;
    xmlStepStates states = {0, 0, NULL}; /* // may require backtrack */

    if ((comp == NULL) || (node == NULL)) return(-1);
    i = 0;
restart:
    for (;i < comp->nbStep;i++) {
	step = &comp->steps[i];
	switch (step->op) {
            case XML_OP_END:
		goto found;
            case XML_OP_ROOT:
		if (node->type == XML_NAMESPACE_DECL)
		    goto rollback;
		node = node->parent;
		if ((node->type == XML_DOCUMENT_NODE) ||
#ifdef LIBXML_DOCB_ENABLED
		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
#endif
		    (node->type == XML_HTML_DOCUMENT_NODE))
		    continue;
		goto rollback;
            case XML_OP_ELEM:
		if (node->type != XML_ELEMENT_NODE)
		    goto rollback;
		if (step->value == NULL)
		    continue;
		if (step->value[0] != node->name[0])
		    goto rollback;
		if (!xmlStrEqual(step->value, node->name))
		    goto rollback;

		/* Namespace test */
		if (node->ns == NULL) {
		    if (step->value2 != NULL)
			goto rollback;
		} else if (node->ns->href != NULL) {
		    if (step->value2 == NULL)
			goto rollback;
		    if (!xmlStrEqual(step->value2, node->ns->href))
			goto rollback;
		}
		continue;
            case XML_OP_CHILD: {
		xmlNodePtr lst;

		if ((node->type != XML_ELEMENT_NODE) &&
		    (node->type != XML_DOCUMENT_NODE) &&
#ifdef LIBXML_DOCB_ENABLED
		    (node->type != XML_DOCB_DOCUMENT_NODE) &&
#endif
		    (node->type != XML_HTML_DOCUMENT_NODE))
		    goto rollback;

		lst = node->children;

		if (step->value != NULL) {
		    while (lst != NULL) {
			if ((lst->type == XML_ELEMENT_NODE) &&
			    (step->value[0] == lst->name[0]) &&
			    (xmlStrEqual(step->value, lst->name)))
			    break;
			lst = lst->next;
		    }
		    if (lst != NULL)
			continue;
		}
		goto rollback;
	    }
            case XML_OP_ATTR:
		if (node->type != XML_ATTRIBUTE_NODE)
		    goto rollback;
		if (step->value != NULL) {
		    if (step->value[0] != node->name[0])
			goto rollback;
		    if (!xmlStrEqual(step->value, node->name))
			goto rollback;
		}
		/* Namespace test */
		if (node->ns == NULL) {
		    if (step->value2 != NULL)
			goto rollback;
		} else if (step->value2 != NULL) {
		    if (!xmlStrEqual(step->value2, node->ns->href))
			goto rollback;
		}
		continue;
            case XML_OP_PARENT:
		if ((node->type == XML_DOCUMENT_NODE) ||
		    (node->type == XML_HTML_DOCUMENT_NODE) ||
#ifdef LIBXML_DOCB_ENABLED
		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
#endif
		    (node->type == XML_NAMESPACE_DECL))
		    goto rollback;
		node = node->parent;
		if (node == NULL)
		    goto rollback;
		if (step->value == NULL)
		    continue;
		if (step->value[0] != node->name[0])
		    goto rollback;
		if (!xmlStrEqual(step->value, node->name))
		    goto rollback;
		/* Namespace test */
		if (node->ns == NULL) {
		    if (step->value2 != NULL)
			goto rollback;
		} else if (node->ns->href != NULL) {
		    if (step->value2 == NULL)
			goto rollback;
		    if (!xmlStrEqual(step->value2, node->ns->href))
			goto rollback;
		}
		continue;
            case XML_OP_ANCESTOR:
		/* TODO: implement coalescing of ANCESTOR/NODE ops */
		if (step->value == NULL) {
		    i++;
		    step = &comp->steps[i];
		    if (step->op == XML_OP_ROOT)
			goto found;
		    if (step->op != XML_OP_ELEM)
			goto rollback;
		    if (step->value == NULL)
			return(-1);
		}
		if (node == NULL)
		    goto rollback;
		if ((node->type == XML_DOCUMENT_NODE) ||
		    (node->type == XML_HTML_DOCUMENT_NODE) ||
#ifdef LIBXML_DOCB_ENABLED
		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
#endif
		    (node->type == XML_NAMESPACE_DECL))
		    goto rollback;
		node = node->parent;
		while (node != NULL) {
		    if ((node->type == XML_ELEMENT_NODE) &&
			(step->value[0] == node->name[0]) &&
			(xmlStrEqual(step->value, node->name))) {
			/* Namespace test */
			if (node->ns == NULL) {
			    if (step->value2 == NULL)
				break;
			} else if (node->ns->href != NULL) {
			    if ((step->value2 != NULL) &&
			        (xmlStrEqual(step->value2, node->ns->href)))
				break;
			}
		    }
		    node = node->parent;
		}
		if (node == NULL)
		    goto rollback;
		/*
		 * prepare a potential rollback from here
		 * for ancestors of that node.
		 */
		if (step->op == XML_OP_ANCESTOR)
		    xmlPatPushState(&states, i, node);
		else
		    xmlPatPushState(&states, i - 1, node);
		continue;
            case XML_OP_NS:
		if (node->type != XML_ELEMENT_NODE)
		    goto rollback;
		if (node->ns == NULL) {
		    if (step->value != NULL)
			goto rollback;
		} else if (node->ns->href != NULL) {
		    if (step->value == NULL)
			goto rollback;
		    if (!xmlStrEqual(step->value, node->ns->href))
			goto rollback;
		}
		break;
            case XML_OP_ALL:
		if (node->type != XML_ELEMENT_NODE)
		    goto rollback;
		break;
	}
    }
found:
    if (states.states != NULL) {
        /* Free the rollback states */
	xmlFree(states.states);
    }
    return(1);
rollback:
    /* got an error try to rollback */
    if (states.states == NULL)
	return(0);
    if (states.nbstates <= 0) {
	xmlFree(states.states);
	return(0);
    }
    states.nbstates--;
    i = states.states[states.nbstates].step;
    node = states.states[states.nbstates].node;
#if 0
    fprintf(stderr, "Pop: %d, %s\n", i, node->name);
#endif
    goto restart;
}

/************************************************************************
 *									*
 *			Dedicated parser for templates			*
 *									*
 ************************************************************************/

#define TODO								\
    xmlGenericError(xmlGenericErrorContext,				\
	    "Unimplemented block at %s:%d\n",				\
            __FILE__, __LINE__);
#define CUR (*ctxt->cur)
#define SKIP(val) ctxt->cur += (val)
#define NXT(val) ctxt->cur[(val)]
#define PEEKPREV(val) ctxt->cur[-(val)]
#define CUR_PTR ctxt->cur

#define SKIP_BLANKS							\
    while (IS_BLANK_CH(CUR)) NEXT

#define CURRENT (*ctxt->cur)
#define NEXT ((*ctxt->cur) ?  ctxt->cur++: ctxt->cur)


#define PUSH(op, val, val2)						\
    if (xmlPatternAdd(ctxt, ctxt->comp, (op), (val), (val2))) goto error;

#define XSLT_ERROR(X)							\
    { xsltError(ctxt, __FILE__, __LINE__, X);				\
      ctxt->error = (X); return; }

#define XSLT_ERROR0(X)							\
    { xsltError(ctxt, __FILE__, __LINE__, X);				\
      ctxt->error = (X); return(0); }

#if 0
/**
 * xmlPatScanLiteral:
 * @ctxt:  the XPath Parser context
 *
 * Parse an XPath Literal:
 *
 * [29] Literal ::= '"' [^"]* '"'
 *                | "'" [^']* "'"
 *
 * Returns the Literal parsed or NULL
 */

static xmlChar *
xmlPatScanLiteral(xmlPatParserContextPtr ctxt) {
    const xmlChar *q, *cur;
    xmlChar *ret = NULL;
    int val, len;

    SKIP_BLANKS;
    if (CUR == '"') {
        NEXT;
	cur = q = CUR_PTR;
	val = xmlStringCurrentChar(NULL, cur, &len);
	while ((IS_CHAR(val)) && (val != '"')) {
	    cur += len;
	    val = xmlStringCurrentChar(NULL, cur, &len);
	}
	if (!IS_CHAR(val)) {
	    ctxt->error = 1;
	    return(NULL);
	} else {
	    if (ctxt->dict)
		ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
	    else
		ret = xmlStrndup(q, cur - q);
        }
	cur += len;
	CUR_PTR = cur;
    } else if (CUR == '\'') {
        NEXT;
	cur = q = CUR_PTR;
	val = xmlStringCurrentChar(NULL, cur, &len);
	while ((IS_CHAR(val)) && (val != '\'')) {
	    cur += len;
	    val = xmlStringCurrentChar(NULL, cur, &len);
	}
	if (!IS_CHAR(val)) {
	    ctxt->error = 1;
	    return(NULL);
	} else {
	    if (ctxt->dict)
		ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
	    else
		ret = xmlStrndup(q, cur - q);
        }
	cur += len;
	CUR_PTR = cur;
    } else {
	/* XP_ERROR(XPATH_START_LITERAL_ERROR); */
	ctxt->error = 1;
	return(NULL);
    }
    return(ret);
}
#endif

/**
 * xmlPatScanName:
 * @ctxt:  the XPath Parser context
 *
 * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' |
 *                  CombiningChar | Extender
 *
 * [5] Name ::= (Letter | '_' | ':') (NameChar)*
 *
 * [6] Names ::= Name (S Name)*
 *
 * Returns the Name parsed or NULL
 */

static xmlChar *
xmlPatScanName(xmlPatParserContextPtr ctxt) {
    const xmlChar *q, *cur;
    xmlChar *ret = NULL;
    int val, len;

    SKIP_BLANKS;

    cur = q = CUR_PTR;
    val = xmlStringCurrentChar(NULL, cur, &len);
    if (!IS_LETTER(val) && (val != '_') && (val != ':'))
	return(NULL);

    while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
           (val == '.') || (val == '-') ||
	   (val == '_') ||
	   (IS_COMBINING(val)) ||
	   (IS_EXTENDER(val))) {
	cur += len;
	val = xmlStringCurrentChar(NULL, cur, &len);
    }
    if (ctxt->dict)
	ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
    else
	ret = xmlStrndup(q, cur - q);
    CUR_PTR = cur;
    return(ret);
}

/**
 * xmlPatScanNCName:
 * @ctxt:  the XPath Parser context
 *
 * Parses a non qualified name
 *
 * Returns the Name parsed or NULL
 */

static xmlChar *
xmlPatScanNCName(xmlPatParserContextPtr ctxt) {
    const xmlChar *q, *cur;
    xmlChar *ret = NULL;
    int val, len;

    SKIP_BLANKS;

    cur = q = CUR_PTR;
    val = xmlStringCurrentChar(NULL, cur, &len);
    if (!IS_LETTER(val) && (val != '_'))
	return(NULL);

    while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
           (val == '.') || (val == '-') ||
	   (val == '_') ||
	   (IS_COMBINING(val)) ||
	   (IS_EXTENDER(val))) {
	cur += len;
	val = xmlStringCurrentChar(NULL, cur, &len);
    }
    if (ctxt->dict)
	ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
    else
	ret = xmlStrndup(q, cur - q);
    CUR_PTR = cur;
    return(ret);
}

#if 0
/**
 * xmlPatScanQName:
 * @ctxt:  the XPath Parser context
 * @prefix:  the place to store the prefix
 *
 * Parse a qualified name
 *
 * Returns the Name parsed or NULL
 */

static xmlChar *
xmlPatScanQName(xmlPatParserContextPtr ctxt, xmlChar **prefix) {
    xmlChar *ret = NULL;

    *prefix = NULL;
    ret = xmlPatScanNCName(ctxt);
    if (CUR == ':') {
        *prefix = ret;
	NEXT;
	ret = xmlPatScanNCName(ctxt);
    }
    return(ret);
}
#endif

/**
 * xmlCompileAttributeTest:
 * @ctxt:  the compilation context
 *
 * Compile an attribute test.
 */
static void
xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) {
    xmlChar *token = NULL;
    xmlChar *name = NULL;
    xmlChar *URL = NULL;

    SKIP_BLANKS;
    name = xmlPatScanNCName(ctxt);
    if (name == NULL) {
	if (CUR == '*') {
	    PUSH(XML_OP_ATTR, NULL, NULL);
	    NEXT;
	} else {
	    ERROR(NULL, NULL, NULL,
		"xmlCompileAttributeTest : Name expected\n");
	    ctxt->error = 1;
	}
	return;
    }
    if (CUR == ':') {
	int i;
	xmlChar *prefix = name;

	NEXT;

	if (IS_BLANK_CH(CUR)) {
	    ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);
	    XML_PAT_FREE_STRING(ctxt, prefix);
	    ctxt->error = 1;
	    goto error;
	}
	/*
	* This is a namespace match
	*/
	token = xmlPatScanName(ctxt);
	if ((prefix[0] == 'x') &&
	    (prefix[1] == 'm') &&
	    (prefix[2] == 'l') &&
	    (prefix[3] == 0))
	{
	    XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE);
	} else {
	    for (i = 0;i < ctxt->nb_namespaces;i++) {
		if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
		    XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i])
		    break;
		}
	    }
	    if (i >= ctxt->nb_namespaces) {
		ERROR5(NULL, NULL, NULL,
		    "xmlCompileAttributeTest : no namespace bound to prefix %s\n",
		    prefix);
	        XML_PAT_FREE_STRING(ctxt, prefix);
		ctxt->error = 1;
		goto error;
	    }
	}
	XML_PAT_FREE_STRING(ctxt, prefix);
	if (token == NULL) {
	    if (CUR == '*') {
		NEXT;
		PUSH(XML_OP_ATTR, NULL, URL);
	    } else {
		ERROR(NULL, NULL, NULL,
		    "xmlCompileAttributeTest : Name expected\n");
		ctxt->error = 1;
		goto error;
	    }
	} else {
	    PUSH(XML_OP_ATTR, token, URL);
	}
    } else {
	PUSH(XML_OP_ATTR, name, NULL);
    }
    return;
error:
    if (URL != NULL)
	XML_PAT_FREE_STRING(ctxt, URL)
    if (token != NULL)
	XML_PAT_FREE_STRING(ctxt, token);
}

/**
 * xmlCompileStepPattern:
 * @ctxt:  the compilation context
 *
 * Compile the Step Pattern and generates a precompiled
 * form suitable for fast matching.
 *
 * [3]    Step    ::=    '.' | NameTest
 * [4]    NameTest    ::=    QName | '*' | NCName ':' '*'
 */

static void
xmlCompileStepPattern(xmlPatParserContextPtr ctxt) {
    xmlChar *token = NULL;
    xmlChar *name = NULL;
    xmlChar *URL = NULL;
    int hasBlanks = 0;

    SKIP_BLANKS;
    if (CUR == '.') {
	/*
	* Context node.
	*/
	NEXT;
	PUSH(XML_OP_ELEM, NULL, NULL);
	return;
    }
    if (CUR == '@') {
	/*
	* Attribute test.
	*/
	if (XML_STREAM_XS_IDC_SEL(ctxt->comp)) {
	    ERROR5(NULL, NULL, NULL,
		"Unexpected attribute axis in '%s'.\n", ctxt->base);
	    ctxt->error = 1;
	    return;
	}
	NEXT;
	xmlCompileAttributeTest(ctxt);
	if (ctxt->error != 0)
	    goto error;
	return;
    }
    name = xmlPatScanNCName(ctxt);
    if (name == NULL) {
	if (CUR == '*') {
	    NEXT;
	    PUSH(XML_OP_ALL, NULL, NULL);
	    return;
	} else {
	    ERROR(NULL, NULL, NULL,
		    "xmlCompileStepPattern : Name expected\n");
	    ctxt->error = 1;
	    return;
	}
    }
    if (IS_BLANK_CH(CUR)) {
	hasBlanks = 1;
	SKIP_BLANKS;
    }
    if (CUR == ':') {
	NEXT;
	if (CUR != ':') {
	    xmlChar *prefix = name;
	    int i;

	    if (hasBlanks || IS_BLANK_CH(CUR)) {
		ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);
		ctxt->error = 1;
		goto error;
	    }
	    /*
	     * This is a namespace match
	     */
	    token = xmlPatScanName(ctxt);
	    if ((prefix[0] == 'x') &&
		(prefix[1] == 'm') &&
		(prefix[2] == 'l') &&
		(prefix[3] == 0))
	    {
		XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE)
	    } else {
		for (i = 0;i < ctxt->nb_namespaces;i++) {
		    if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
			XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i])
			break;
		    }
		}
		if (i >= ctxt->nb_namespaces) {
		    ERROR5(NULL, NULL, NULL,
			"xmlCompileStepPattern : no namespace bound to prefix %s\n",
			prefix);
		    ctxt->error = 1;
		    goto error;
		}
	    }
	    XML_PAT_FREE_STRING(ctxt, prefix);
	    name = NULL;
	    if (token == NULL) {
		if (CUR == '*') {
		    NEXT;
		    PUSH(XML_OP_NS, URL, NULL);
		} else {
		    ERROR(NULL, NULL, NULL,
			    "xmlCompileStepPattern : Name expected\n");
		    ctxt->error = 1;
		    goto error;
		}
	    } else {
		PUSH(XML_OP_ELEM, token, URL);
	    }
	} else {
	    NEXT;
	    if (xmlStrEqual(name, (const xmlChar *) "child")) {
		XML_PAT_FREE_STRING(ctxt, name);
		name = xmlPatScanName(ctxt);
		if (name == NULL) {
		    if (CUR == '*') {
			NEXT;
			PUSH(XML_OP_ALL, NULL, NULL);
			return;
		    } else {
			ERROR(NULL, NULL, NULL,
			    "xmlCompileStepPattern : QName expected\n");
			ctxt->error = 1;
			goto error;
		    }
		}
		if (CUR == ':') {
		    xmlChar *prefix = name;
		    int i;

		    NEXT;
		    if (IS_BLANK_CH(CUR)) {
			ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);
			ctxt->error = 1;
			goto error;
		    }
		    /*
		    * This is a namespace match
		    */
		    token = xmlPatScanName(ctxt);
		    if ((prefix[0] == 'x') &&
			(prefix[1] == 'm') &&
			(prefix[2] == 'l') &&
			(prefix[3] == 0))
		    {
			XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE)
		    } else {
			for (i = 0;i < ctxt->nb_namespaces;i++) {
			    if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
				XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i])
				break;
			    }
			}
			if (i >= ctxt->nb_namespaces) {
			    ERROR5(NULL, NULL, NULL,
				"xmlCompileStepPattern : no namespace bound "
				"to prefix %s\n", prefix);
			    ctxt->error = 1;
			    goto error;
			}
		    }
		    XML_PAT_FREE_STRING(ctxt, prefix);
		    name = NULL;
		    if (token == NULL) {
			if (CUR == '*') {
			    NEXT;
			    PUSH(XML_OP_NS, URL, NULL);
			} else {
			    ERROR(NULL, NULL, NULL,
				"xmlCompileStepPattern : Name expected\n");
			    ctxt->error = 1;
			    goto error;
			}
		    } else {
			PUSH(XML_OP_CHILD, token, URL);
		    }
		} else
		    PUSH(XML_OP_CHILD, name, NULL);
		return;
	    } else if (xmlStrEqual(name, (const xmlChar *) "attribute")) {
		XML_PAT_FREE_STRING(ctxt, name)
		name = NULL;
		if (XML_STREAM_XS_IDC_SEL(ctxt->comp)) {
		    ERROR5(NULL, NULL, NULL,
			"Unexpected attribute axis in '%s'.\n", ctxt->base);
		    ctxt->error = 1;
		    goto error;
		}
		xmlCompileAttributeTest(ctxt);
		if (ctxt->error != 0)
		    goto error;
		return;
	    } else {
		ERROR5(NULL, NULL, NULL,
		    "The 'element' or 'attribute' axis is expected.\n", NULL);
		ctxt->error = 1;
		goto error;
	    }
	}
    } else if (CUR == '*') {
        if (name != NULL) {
	    ctxt->error = 1;
	    goto error;
	}
	NEXT;
	PUSH(XML_OP_ALL, token, NULL);
    } else {
	PUSH(XML_OP_ELEM, name, NULL);
    }
    return;
error:
    if (URL != NULL)
	XML_PAT_FREE_STRING(ctxt, URL)
    if (token != NULL)
	XML_PAT_FREE_STRING(ctxt, token)
    if (name != NULL)
	XML_PAT_FREE_STRING(ctxt, name)
}

/**
 * xmlCompilePathPattern:
 * @ctxt:  the compilation context
 *
 * Compile the Path Pattern and generates a precompiled
 * form suitable for fast matching.
 *
 * [5]    Path    ::=    ('.//')? ( Step '/' )* ( Step | '@' NameTest )
 */
static void
xmlCompilePathPattern(xmlPatParserContextPtr ctxt) {
    SKIP_BLANKS;
    if (CUR == '/') {
        ctxt->comp->flags |= PAT_FROM_ROOT;
    } else if ((CUR == '.') || (ctxt->comp->flags & XML_PATTERN_NOTPATTERN)) {
        ctxt->comp->flags |= PAT_FROM_CUR;
    }

    if ((CUR == '/') && (NXT(1) == '/')) {
	PUSH(XML_OP_ANCESTOR, NULL, NULL);
	NEXT;
	NEXT;
    } else if ((CUR == '.') && (NXT(1) == '/') && (NXT(2) == '/')) {
	PUSH(XML_OP_ANCESTOR, NULL, NULL);
	NEXT;
	NEXT;
	NEXT;
	/* Check for incompleteness. */
	SKIP_BLANKS;
	if (CUR == 0) {
	    ERROR5(NULL, NULL, NULL,
	       "Incomplete expression '%s'.\n", ctxt->base);
	    ctxt->error = 1;
	    goto error;
	}
    }
    if (CUR == '@') {
	NEXT;
	xmlCompileAttributeTest(ctxt);
	SKIP_BLANKS;
	/* TODO: check for incompleteness */
	if (CUR != 0) {
	    xmlCompileStepPattern(ctxt);
	    if (ctxt->error != 0)
		goto error;
	}
    } else {
        if (CUR == '/') {
	    PUSH(XML_OP_ROOT, NULL, NULL);
	    NEXT;
	    /* Check for incompleteness. */
	    SKIP_BLANKS;
	    if (CUR == 0) {
		ERROR5(NULL, NULL, NULL,
		    "Incomplete expression '%s'.\n", ctxt->base);
		ctxt->error = 1;
		goto error;
	    }
	}
	xmlCompileStepPattern(ctxt);
	if (ctxt->error != 0)
	    goto error;
	SKIP_BLANKS;
	while (CUR == '/') {
	    if (NXT(1) == '/') {
	        PUSH(XML_OP_ANCESTOR, NULL, NULL);
		NEXT;
		NEXT;
		SKIP_BLANKS;
		xmlCompileStepPattern(ctxt);
		if (ctxt->error != 0)
		    goto error;
	    } else {
	        PUSH(XML_OP_PARENT, NULL, NULL);
		NEXT;
		SKIP_BLANKS;
		if (CUR == 0) {
		    ERROR5(NULL, NULL, NULL,
		    "Incomplete expression '%s'.\n", ctxt->base);
		    ctxt->error = 1;
		    goto error;
		}
		xmlCompileStepPattern(ctxt);
		if (ctxt->error != 0)
		    goto error;
	    }
	}
    }
    if (CUR != 0) {
	ERROR5(NULL, NULL, NULL,
	       "Failed to compile pattern %s\n", ctxt->base);
	ctxt->error = 1;
    }
error:
    return;
}

/**
 * xmlCompileIDCXPathPath:
 * @ctxt:  the compilation context
 *
 * Compile the Path Pattern and generates a precompiled
 * form suitable for fast matching.
 *
 * [5]    Path    ::=    ('.//')? ( Step '/' )* ( Step | '@' NameTest )
 */
static void
xmlCompileIDCXPathPath(xmlPatParserContextPtr ctxt) {
    SKIP_BLANKS;
    if (CUR == '/') {
	ERROR5(NULL, NULL, NULL,
	    "Unexpected selection of the document root in '%s'.\n",
	    ctxt->base);
	goto error;
    }
    ctxt->comp->flags |= PAT_FROM_CUR;

    if (CUR == '.') {
	/* "." - "self::node()" */
	NEXT;
	SKIP_BLANKS;
	if (CUR == 0) {
	    /*
	    * Selection of the context node.
	    */
	    PUSH(XML_OP_ELEM, NULL, NULL);
	    return;
	}
	if (CUR != '/') {
	    /* TODO: A more meaningful error message. */
	    ERROR5(NULL, NULL, NULL,
	    "Unexpected token after '.' in '%s'.\n", ctxt->base);
	    goto error;
	}
	/* "./" - "self::node()/" */
	NEXT;
	SKIP_BLANKS;
	if (CUR == '/') {
	    if (IS_BLANK_CH(PEEKPREV(1))) {
		/*
		* Disallow "./ /"
		*/
		ERROR5(NULL, NULL, NULL,
		    "Unexpected '/' token in '%s'.\n", ctxt->base);
		goto error;
	    }
	    /* ".//" - "self:node()/descendant-or-self::node()/" */
	    PUSH(XML_OP_ANCESTOR, NULL, NULL);
	    NEXT;
	    SKIP_BLANKS;
	}
	if (CUR == 0)
	    goto error_unfinished;
    }
    /*
    * Process steps.
    */
    do {
	xmlCompileStepPattern(ctxt);
	if (ctxt->error != 0)
	    goto error;
	SKIP_BLANKS;
	if (CUR != '/')
	    break;
	PUSH(XML_OP_PARENT, NULL, NULL);
	NEXT;
	SKIP_BLANKS;
	if (CUR == '/') {
	    /*
	    * Disallow subsequent '//'.
	    */
	    ERROR5(NULL, NULL, NULL,
		"Unexpected subsequent '//' in '%s'.\n",
		ctxt->base);
	    goto error;
	}
	if (CUR == 0)
	    goto error_unfinished;

    } while (CUR != 0);

    if (CUR != 0) {
	ERROR5(NULL, NULL, NULL,
	    "Failed to compile expression '%s'.\n", ctxt->base);
	ctxt->error = 1;
    }
    return;
error:
    ctxt->error = 1;
    return;

error_unfinished:
    ctxt->error = 1;
    ERROR5(NULL, NULL, NULL,
	"Unfinished expression '%s'.\n", ctxt->base);
    return;
}

/************************************************************************
 *									*
 *			The streaming code				*
 *									*
 ************************************************************************/

#ifdef DEBUG_STREAMING
static void
xmlDebugStreamComp(xmlStreamCompPtr stream) {
    int i;

    if (stream == NULL) {
        printf("Stream: NULL\n");
	return;
    }
    printf("Stream: %d steps\n", stream->nbStep);
    for (i = 0;i < stream->nbStep;i++) {
	if (stream->steps[i].ns != NULL) {
	    printf("{%s}", stream->steps[i].ns);
	}
        if (stream->steps[i].name == NULL) {
	    printf("* ");
	} else {
	    printf("%s ", stream->steps[i].name);
	}
	if (stream->steps[i].flags & XML_STREAM_STEP_ROOT)
	    printf("root ");
	if (stream->steps[i].flags & XML_STREAM_STEP_DESC)
	    printf("// ");
	if (stream->steps[i].flags & XML_STREAM_STEP_FINAL)
	    printf("final ");
	printf("\n");
    }
}
static void
xmlDebugStreamCtxt(xmlStreamCtxtPtr ctxt, int match) {
    int i;

    if (ctxt == NULL) {
        printf("Stream: NULL\n");
	return;
    }
    printf("Stream: level %d, %d states: ", ctxt->level, ctxt->nbState);
    if (match)
        printf("matches\n");
    else
        printf("\n");
    for (i = 0;i < ctxt->nbState;i++) {
        if (ctxt->states[2 * i] < 0)
	    printf(" %d: free\n", i);
	else {
	    printf(" %d: step %d, level %d", i, ctxt->states[2 * i],
	           ctxt->states[(2 * i) + 1]);
            if (ctxt->comp->steps[ctxt->states[2 * i]].flags &
	        XML_STREAM_STEP_DESC)
	        printf(" //\n");
	    else
	        printf("\n");
	}
    }
}
#endif
/**
 * xmlNewStreamComp:
 * @size: the number of expected steps
 *
 * build a new compiled pattern for streaming
 *
 * Returns the new structure or NULL in case of error.
 */
static xmlStreamCompPtr
xmlNewStreamComp(int size) {
    xmlStreamCompPtr cur;

    if (size < 4)
        size  = 4;

    cur = (xmlStreamCompPtr) xmlMalloc(sizeof(xmlStreamComp));
    if (cur == NULL) {
	ERROR(NULL, NULL, NULL,
		"xmlNewStreamComp: malloc failed\n");
	return(NULL);
    }
    memset(cur, 0, sizeof(xmlStreamComp));
    cur->steps = (xmlStreamStepPtr) xmlMalloc(size * sizeof(xmlStreamStep));
    if (cur->steps == NULL) {
	xmlFree(cur);
	ERROR(NULL, NULL, NULL,
	      "xmlNewStreamComp: malloc failed\n");
	return(NULL);
    }
    cur->nbStep = 0;
    cur->maxStep = size;
    return(cur);
}

/**
 * xmlFreeStreamComp:
 * @comp: the compiled pattern for streaming
 *
 * Free the compiled pattern for streaming
 */
static void
xmlFreeStreamComp(xmlStreamCompPtr comp) {
    if (comp != NULL) {
        if (comp->steps != NULL)
	    xmlFree(comp->steps);
	if (comp->dict != NULL)
	    xmlDictFree(comp->dict);
        xmlFree(comp);
    }
}

/**
 * xmlStreamCompAddStep:
 * @comp: the compiled pattern for streaming
 * @name: the first string, the name, or NULL for *
 * @ns: the second step, the namespace name
 * @flags: the flags for that step
 *
 * Add a new step to the compiled pattern
 *
 * Returns -1 in case of error or the step index if successful
 */
static int
xmlStreamCompAddStep(xmlStreamCompPtr comp, const xmlChar *name,
                     const xmlChar *ns, int nodeType, int flags) {
    xmlStreamStepPtr cur;

    if (comp->nbStep >= comp->maxStep) {
	cur = (xmlStreamStepPtr) xmlRealloc(comp->steps,
				 comp->maxStep * 2 * sizeof(xmlStreamStep));
	if (cur == NULL) {
	    ERROR(NULL, NULL, NULL,
		  "xmlNewStreamComp: malloc failed\n");
	    return(-1);
	}
	comp->steps = cur;
        comp->maxStep *= 2;
    }
    cur = &comp->steps[comp->nbStep++];
    cur->flags = flags;
    cur->name = name;
    cur->ns = ns;
    cur->nodeType = nodeType;
    return(comp->nbStep - 1);
}

/**
 * xmlStreamCompile:
 * @comp: the precompiled pattern
 *
 * Tries to stream compile a pattern
 *
 * Returns -1 in case of failure and 0 in case of success.
 */
static int
xmlStreamCompile(xmlPatternPtr comp) {
    xmlStreamCompPtr stream;
    int i, s = 0, root = 0, flags = 0, prevs = -1;
    xmlStepOp step;

    if ((comp == NULL) || (comp->steps == NULL))
        return(-1);
    /*
     * special case for .
     */
    if ((comp->nbStep == 1) &&
        (comp->steps[0].op == XML_OP_ELEM) &&
	(comp->steps[0].value == NULL) &&
	(comp->steps[0].value2 == NULL)) {
	stream = xmlNewStreamComp(0);
	if (stream == NULL)
	    return(-1);
	/* Note that the stream will have no steps in this case. */
	stream->flags |= XML_STREAM_FINAL_IS_ANY_NODE;
	comp->stream = stream;
	return(0);
    }

    stream = xmlNewStreamComp((comp->nbStep / 2) + 1);
    if (stream == NULL)
        return(-1);
    if (comp->dict != NULL) {
        stream->dict = comp->dict;
	xmlDictReference(stream->dict);
    }

    i = 0;
    if (comp->flags & PAT_FROM_ROOT)
	stream->flags |= XML_STREAM_FROM_ROOT;

    for (;i < comp->nbStep;i++) {
	step = comp->steps[i];
        switch (step.op) {
	    case XML_OP_END:
	        break;
	    case XML_OP_ROOT:
	        if (i != 0)
		    goto error;
		root = 1;
		break;
	    case XML_OP_NS:
		s = xmlStreamCompAddStep(stream, NULL, step.value,
		    XML_ELEMENT_NODE, flags);
		if (s < 0)
		    goto error;
		prevs = s;
		flags = 0;
		break;
	    case XML_OP_ATTR:
		flags |= XML_STREAM_STEP_ATTR;
		prevs = -1;
		s = xmlStreamCompAddStep(stream,
		    step.value, step.value2, XML_ATTRIBUTE_NODE, flags);
		flags = 0;
		if (s < 0)
		    goto error;
		break;
	    case XML_OP_ELEM:
	        if ((step.value == NULL) && (step.value2 == NULL)) {
		    /*
		    * We have a "." or "self::node()" here.
		    * Eliminate redundant self::node() tests like in "/./."
		    * or "//./"
		    * The only case we won't eliminate is "//.", i.e. if
		    * self::node() is the last node test and we had
		    * continuation somewhere beforehand.
		    */
		    if ((comp->nbStep == i + 1) &&
			(flags & XML_STREAM_STEP_DESC)) {
			/*
			* Mark the special case where the expression resolves
			* to any type of node.
			*/
			if (comp->nbStep == i + 1) {
			    stream->flags |= XML_STREAM_FINAL_IS_ANY_NODE;
			}
			flags |= XML_STREAM_STEP_NODE;
			s = xmlStreamCompAddStep(stream, NULL, NULL,
			    XML_STREAM_ANY_NODE, flags);
			if (s < 0)
			    goto error;
			flags = 0;
			/*
			* If there was a previous step, mark it to be added to
			* the result node-set; this is needed since only
			* the last step will be marked as "final" and only
			* "final" nodes are added to the resulting set.
			*/
			if (prevs != -1) {
			    stream->steps[prevs].flags |= XML_STREAM_STEP_IN_SET;
			    prevs = -1;
			}
			break;

		    } else {
			/* Just skip this one. */
			continue;
		    }
		}
		/* An element node. */
	        s = xmlStreamCompAddStep(stream, step.value, step.value2,
		    XML_ELEMENT_NODE, flags);
		if (s < 0)
		    goto error;
		prevs = s;
		flags = 0;
		break;
	    case XML_OP_CHILD:
		/* An element node child. */
	        s = xmlStreamCompAddStep(stream, step.value, step.value2,
		    XML_ELEMENT_NODE, flags);
		if (s < 0)
		    goto error;
		prevs = s;
		flags = 0;
		break;
	    case XML_OP_ALL:
	        s = xmlStreamCompAddStep(stream, NULL, NULL,
		    XML_ELEMENT_NODE, flags);
		if (s < 0)
		    goto error;
		prevs = s;
		flags = 0;
		break;
	    case XML_OP_PARENT:
	        break;
	    case XML_OP_ANCESTOR:
		/* Skip redundant continuations. */
		if (flags & XML_STREAM_STEP_DESC)
		    break;
	        flags |= XML_STREAM_STEP_DESC;
		/*
		* Mark the expression as having "//".
		*/
		if ((stream->flags & XML_STREAM_DESC) == 0)
		    stream->flags |= XML_STREAM_DESC;
		break;
	}
    }
    if ((! root) && (comp->flags & XML_PATTERN_NOTPATTERN) == 0) {
	/*
	* If this should behave like a real pattern, we will mark
	* the first step as having "//", to be reentrant on every
	* tree level.
	*/
	if ((stream->flags & XML_STREAM_DESC) == 0)
	    stream->flags |= XML_STREAM_DESC;

	if (stream->nbStep > 0) {
	    if ((stream->steps[0].flags & XML_STREAM_STEP_DESC) == 0)
		stream->steps[0].flags |= XML_STREAM_STEP_DESC;
	}
    }
    if (stream->nbStep <= s)
	goto error;
    stream->steps[s].flags |= XML_STREAM_STEP_FINAL;
    if (root)
	stream->steps[0].flags |= XML_STREAM_STEP_ROOT;
#ifdef DEBUG_STREAMING
    xmlDebugStreamComp(stream);
#endif
    comp->stream = stream;
    return(0);
error:
    xmlFreeStreamComp(stream);
    return(0);
}

/**
 * xmlNewStreamCtxt:
 * @size: the number of expected states
 *
 * build a new stream context
 *
 * Returns the new structure or NULL in case of error.
 */
static xmlStreamCtxtPtr
xmlNewStreamCtxt(xmlStreamCompPtr stream) {
    xmlStreamCtxtPtr cur;

    cur = (xmlStreamCtxtPtr) xmlMalloc(sizeof(xmlStreamCtxt));
    if (cur == NULL) {
	ERROR(NULL, NULL, NULL,
		"xmlNewStreamCtxt: malloc failed\n");
	return(NULL);
    }
    memset(cur, 0, sizeof(xmlStreamCtxt));
    cur->states = (int *) xmlMalloc(4 * 2 * sizeof(int));
    if (cur->states == NULL) {
	xmlFree(cur);
	ERROR(NULL, NULL, NULL,
	      "xmlNewStreamCtxt: malloc failed\n");
	return(NULL);
    }
    cur->nbState = 0;
    cur->maxState = 4;
    cur->level = 0;
    cur->comp = stream;
    cur->blockLevel = -1;
    return(cur);
}

/**
 * xmlFreeStreamCtxt:
 * @stream: the stream context
 *
 * Free the stream context
 */
void
xmlFreeStreamCtxt(xmlStreamCtxtPtr stream) {
    xmlStreamCtxtPtr next;

    while (stream != NULL) {
        next = stream->next;
        if (stream->states != NULL)
	    xmlFree(stream->states);
        xmlFree(stream);
	stream = next;
    }
}

/**
 * xmlStreamCtxtAddState:
 * @comp: the stream context
 * @idx: the step index for that streaming state
 *
 * Add a new state to the stream context
 *
 * Returns -1 in case of error or the state index if successful
 */
static int
xmlStreamCtxtAddState(xmlStreamCtxtPtr comp, int idx, int level) {
    int i;
    for (i = 0;i < comp->nbState;i++) {
        if (comp->states[2 * i] < 0) {
	    comp->states[2 * i] = idx;
	    comp->states[2 * i + 1] = level;
	    return(i);
	}
    }
    if (comp->nbState >= comp->maxState) {
        int *cur;

	cur = (int *) xmlRealloc(comp->states,
				 comp->maxState * 4 * sizeof(int));
	if (cur == NULL) {
	    ERROR(NULL, NULL, NULL,
		  "xmlNewStreamCtxt: malloc failed\n");
	    return(-1);
	}
	comp->states = cur;
        comp->maxState *= 2;
    }
    comp->states[2 * comp->nbState] = idx;
    comp->states[2 * comp->nbState++ + 1] = level;
    return(comp->nbState - 1);
}

/**
 * xmlStreamPushInternal:
 * @stream: the stream context
 * @name: the current name
 * @ns: the namespace name
 * @nodeType: the type of the node
 *
 * Push new data onto the stream. NOTE: if the call xmlPatterncompile()
 * indicated a dictionary, then strings for name and ns will be expected
 * to come from the dictionary.
 * Both @name and @ns being NULL means the / i.e. the root of the document.
 * This can also act as a reset.
 *
 * Returns: -1 in case of error, 1 if the current state in the stream is a
 *    match and 0 otherwise.
 */
static int
xmlStreamPushInternal(xmlStreamCtxtPtr stream,
		      const xmlChar *name, const xmlChar *ns,
		      int nodeType) {
    int ret = 0, err = 0, final = 0, tmp, i, m, match, stepNr, desc;
    xmlStreamCompPtr comp;
    xmlStreamStep step;
#ifdef DEBUG_STREAMING
    xmlStreamCtxtPtr orig = stream;
#endif

    if ((stream == NULL) || (stream->nbState < 0))
        return(-1);

    while (stream != NULL) {
	comp = stream->comp;

	if ((nodeType == XML_ELEMENT_NODE) &&
	    (name == NULL) && (ns == NULL)) {
	    /* We have a document node here (or a reset). */
	    stream->nbState = 0;
	    stream->level = 0;
	    stream->blockLevel = -1;
	    if (comp->flags & XML_STREAM_FROM_ROOT) {
		if (comp->nbStep == 0) {
		    /* TODO: We have a "/." here? */
		    ret = 1;
		} else {
		    if ((comp->nbStep == 1) &&
			(comp->steps[0].nodeType == XML_STREAM_ANY_NODE) &&
			(comp->steps[0].flags & XML_STREAM_STEP_DESC))
		    {
			/*
			* In the case of "//." the document node will match
			* as well.
			*/
			ret = 1;
		    } else if (comp->steps[0].flags & XML_STREAM_STEP_ROOT) {
			/* TODO: Do we need this ? */
			tmp = xmlStreamCtxtAddState(stream, 0, 0);
			if (tmp < 0)
			    err++;
		    }
		}
	    }
	    stream = stream->next;
	    continue; /* while */
	}

	/*
	* Fast check for ".".
	*/
	if (comp->nbStep == 0) {
	    /*
	     * / and . are handled at the XPath node set creation
	     * level by checking min depth
	     */
	    if (stream->flags & XML_PATTERN_XPATH) {
		stream = stream->next;
		continue; /* while */
	    }
	    /*
	    * For non-pattern like evaluation like XML Schema IDCs
	    * or traditional XPath expressions, this will match if
	    * we are at the first level only, otherwise on every level.
	    */
	    if ((nodeType != XML_ATTRIBUTE_NODE) &&
		(((stream->flags & XML_PATTERN_NOTPATTERN) == 0) ||
		(stream->level == 0))) {
		    ret = 1;
	    }
	    stream->level++;
	    goto stream_next;
	}
	if (stream->blockLevel != -1) {
	    /*
	    * Skip blocked expressions.
	    */
	    stream->level++;
	    goto stream_next;
	}

	if ((nodeType != XML_ELEMENT_NODE) &&
	    (nodeType != XML_ATTRIBUTE_NODE) &&
	    ((comp->flags & XML_STREAM_FINAL_IS_ANY_NODE) == 0)) {
	    /*
	    * No need to process nodes of other types if we don't
	    * resolve to those types.
	    * TODO: Do we need to block the context here?
	    */
	    stream->level++;
	    goto stream_next;
	}

	/*
	 * Check evolution of existing states
	 */
	i = 0;
	m = stream->nbState;
	while (i < m) {
	    if ((comp->flags & XML_STREAM_DESC) == 0) {
		/*
		* If there is no "//", then only the last
		* added state is of interest.
		*/
		stepNr = stream->states[2 * (stream->nbState -1)];
		/*
		* TODO: Security check, should not happen, remove it.
		*/
		if (stream->states[(2 * (stream->nbState -1)) + 1] <
		    stream->level) {
		    return (-1);
		}
		desc = 0;
		/* loop-stopper */
		i = m;
	    } else {
		/*
		* If there are "//", then we need to process every "//"
		* occurring in the states, plus any other state for this
		* level.
		*/
		stepNr = stream->states[2 * i];

		/* TODO: should not happen anymore: dead states */
		if (stepNr < 0)
		    goto next_state;

		tmp = stream->states[(2 * i) + 1];

		/* skip new states just added */
		if (tmp > stream->level)
		    goto next_state;

		/* skip states at ancestor levels, except if "//" */
		desc = comp->steps[stepNr].flags & XML_STREAM_STEP_DESC;
		if ((tmp < stream->level) && (!desc))
		    goto next_state;
	    }
	    /*
	    * Check for correct node-type.
	    */
	    step = comp->steps[stepNr];
	    if (step.nodeType != nodeType) {
		if (step.nodeType == XML_ATTRIBUTE_NODE) {
		    /*
		    * Block this expression for deeper evaluation.
		    */
		    if ((comp->flags & XML_STREAM_DESC) == 0)
			stream->blockLevel = stream->level +1;
		    goto next_state;
		} else if (step.nodeType != XML_STREAM_ANY_NODE)
		    goto next_state;
	    }
	    /*
	    * Compare local/namespace-name.
	    */
	    match = 0;
	    if (step.nodeType == XML_STREAM_ANY_NODE) {
		match = 1;
	    } else if (step.name == NULL) {
		if (step.ns == NULL) {
		    /*
		    * This lets through all elements/attributes.
		    */
		    match = 1;
		} else if (ns != NULL)
		    match = xmlStrEqual(step.ns, ns);
	    } else if (((step.ns != NULL) == (ns != NULL)) &&
		(name != NULL) &&
		(step.name[0] == name[0]) &&
		xmlStrEqual(step.name, name) &&
		((step.ns == ns) || xmlStrEqual(step.ns, ns)))
	    {
		match = 1;
	    }
#if 0
/*
* TODO: Pointer comparison won't work, since not guaranteed that the given
*  values are in the same dict; especially if it's the namespace name,
*  normally coming from ns->href. We need a namespace dict mechanism !
*/
	    } else if (comp->dict) {
		if (step.name == NULL) {
		    if (step.ns == NULL)
			match = 1;
		    else
			match = (step.ns == ns);
		} else {
		    match = ((step.name == name) && (step.ns == ns));
		}
#endif /* if 0 ------------------------------------------------------- */
	    if (match) {
		final = step.flags & XML_STREAM_STEP_FINAL;
		if (desc) {
		    if (final) {
			ret = 1;
		    } else {
			/* descending match create a new state */
			xmlStreamCtxtAddState(stream, stepNr + 1,
			                      stream->level + 1);
		    }
		} else {
		    if (final) {
			ret = 1;
		    } else {
			xmlStreamCtxtAddState(stream, stepNr + 1,
			                      stream->level + 1);
		    }
		}
		if ((ret != 1) && (step.flags & XML_STREAM_STEP_IN_SET)) {
		    /*
		    * Check if we have a special case like "foo/bar//.", where
		    * "foo" is selected as well.
		    */
		    ret = 1;
		}
	    }
	    if (((comp->flags & XML_STREAM_DESC) == 0) &&
		((! match) || final))  {
		/*
		* Mark this expression as blocked for any evaluation at
		* deeper levels. Note that this includes "/foo"
		* expressions if the *pattern* behaviour is used.
		*/
		stream->blockLevel = stream->level +1;
	    }
next_state:
	    i++;
	}

	stream->level++;

	/*
	* Re/enter the expression.
	* Don't reenter if it's an absolute expression like "/foo",
	*   except "//foo".
	*/
	step = comp->steps[0];
	if (step.flags & XML_STREAM_STEP_ROOT)
	    goto stream_next;

	desc = step.flags & XML_STREAM_STEP_DESC;
	if (stream->flags & XML_PATTERN_NOTPATTERN) {
	    /*
	    * Re/enter the expression if it is a "descendant" one,
	    * or if we are at the 1st level of evaluation.
	    */

	    if (stream->level == 1) {
		if (XML_STREAM_XS_IDC(stream)) {
		    /*
		    * XS-IDC: The missing "self::node()" will always
		    * match the first given node.
		    */
		    goto stream_next;
		} else
		    goto compare;
	    }
	    /*
	    * A "//" is always reentrant.
	    */
	    if (desc)
		goto compare;

	    /*
	    * XS-IDC: Process the 2nd level, since the missing
	    * "self::node()" is responsible for the 2nd level being
	    * the real start level.
	    */
	    if ((stream->level == 2) && XML_STREAM_XS_IDC(stream))
		goto compare;

	    goto stream_next;
	}

compare:
	/*
	* Check expected node-type.
	*/
	if (step.nodeType != nodeType) {
	    if (nodeType == XML_ATTRIBUTE_NODE)
		goto stream_next;
	    else if (step.nodeType != XML_STREAM_ANY_NODE)
		goto stream_next;
	}
	/*
	* Compare local/namespace-name.
	*/
	match = 0;
	if (step.nodeType == XML_STREAM_ANY_NODE) {
	    match = 1;
	} else if (step.name == NULL) {
	    if (step.ns == NULL) {
		/*
		* This lets through all elements/attributes.
		*/
		match = 1;
	    } else if (ns != NULL)
		match = xmlStrEqual(step.ns, ns);
	} else if (((step.ns != NULL) == (ns != NULL)) &&
	    (name != NULL) &&
	    (step.name[0] == name[0]) &&
	    xmlStrEqual(step.name, name) &&
	    ((step.ns == ns) || xmlStrEqual(step.ns, ns)))
	{
	    match = 1;
	}
	final = step.flags & XML_STREAM_STEP_FINAL;
	if (match) {
	    if (final)
		ret = 1;
	    else
		xmlStreamCtxtAddState(stream, 1, stream->level);
	    if ((ret != 1) && (step.flags & XML_STREAM_STEP_IN_SET)) {
		/*
		* Check if we have a special case like "foo//.", where
		* "foo" is selected as well.
		*/
		ret = 1;
	    }
	}
	if (((comp->flags & XML_STREAM_DESC) == 0) &&
	    ((! match) || final))  {
	    /*
	    * Mark this expression as blocked for any evaluation at
	    * deeper levels.
	    */
	    stream->blockLevel = stream->level;
	}

stream_next:
        stream = stream->next;
    } /* while stream != NULL */

    if (err > 0)
        ret = -1;
#ifdef DEBUG_STREAMING
    xmlDebugStreamCtxt(orig, ret);
#endif
    return(ret);
}

/**
 * xmlStreamPush:
 * @stream: the stream context
 * @name: the current name
 * @ns: the namespace name
 *
 * Push new data onto the stream. NOTE: if the call xmlPatterncompile()
 * indicated a dictionary, then strings for name and ns will be expected
 * to come from the dictionary.
 * Both @name and @ns being NULL means the / i.e. the root of the document.
 * This can also act as a reset.
 * Otherwise the function will act as if it has been given an element-node.
 *
 * Returns: -1 in case of error, 1 if the current state in the stream is a
 *    match and 0 otherwise.
 */
int
xmlStreamPush(xmlStreamCtxtPtr stream,
              const xmlChar *name, const xmlChar *ns) {
    return (xmlStreamPushInternal(stream, name, ns, (int) XML_ELEMENT_NODE));
}

/**
 * xmlStreamPushNode:
 * @stream: the stream context
 * @name: the current name
 * @ns: the namespace name
 * @nodeType: the type of the node being pushed
 *
 * Push new data onto the stream. NOTE: if the call xmlPatterncompile()
 * indicated a dictionary, then strings for name and ns will be expected
 * to come from the dictionary.
 * Both @name and @ns being NULL means the / i.e. the root of the document.
 * This can also act as a reset.
 * Different from xmlStreamPush() this function can be fed with nodes of type:
 * element-, attribute-, text-, cdata-section-, comment- and
 * processing-instruction-node.
 *
 * Returns: -1 in case of error, 1 if the current state in the stream is a
 *    match and 0 otherwise.
 */
int
xmlStreamPushNode(xmlStreamCtxtPtr stream,
		  const xmlChar *name, const xmlChar *ns,
		  int nodeType)
{
    return (xmlStreamPushInternal(stream, name, ns,
	nodeType));
}

/**
* xmlStreamPushAttr:
* @stream: the stream context
* @name: the current name
* @ns: the namespace name
*
* Push new attribute data onto the stream. NOTE: if the call xmlPatterncompile()
* indicated a dictionary, then strings for name and ns will be expected
* to come from the dictionary.
* Both @name and @ns being NULL means the / i.e. the root of the document.
* This can also act as a reset.
* Otherwise the function will act as if it has been given an attribute-node.
*
* Returns: -1 in case of error, 1 if the current state in the stream is a
*    match and 0 otherwise.
*/
int
xmlStreamPushAttr(xmlStreamCtxtPtr stream,
		  const xmlChar *name, const xmlChar *ns) {
    return (xmlStreamPushInternal(stream, name, ns, (int) XML_ATTRIBUTE_NODE));
}

/**
 * xmlStreamPop:
 * @stream: the stream context
 *
 * push one level from the stream.
 *
 * Returns: -1 in case of error, 0 otherwise.
 */
int
xmlStreamPop(xmlStreamCtxtPtr stream) {
    int i, lev;

    if (stream == NULL)
        return(-1);
    while (stream != NULL) {
	/*
	* Reset block-level.
	*/
	if (stream->blockLevel == stream->level)
	    stream->blockLevel = -1;

	/*
	 *  stream->level can be zero when XML_FINAL_IS_ANY_NODE is set
	 *  (see the thread at
	 *  http://mail.gnome.org/archives/xslt/2008-July/msg00027.html)
	 */
	if (stream->level)
	    stream->level--;
	/*
	 * Check evolution of existing states
	 */
	for (i = stream->nbState -1; i >= 0; i--) {
	    /* discard obsoleted states */
	    lev = stream->states[(2 * i) + 1];
	    if (lev > stream->level)
		stream->nbState--;
	    if (lev <= stream->level)
		break;
	}
	stream = stream->next;
    }
    return(0);
}

/**
 * xmlStreamWantsAnyNode:
 * @streamCtxt: the stream context
 *
 * Query if the streaming pattern additionally needs to be fed with
 * text-, cdata-section-, comment- and processing-instruction-nodes.
 * If the result is 0 then only element-nodes and attribute-nodes
 * need to be pushed.
 *
 * Returns: 1 in case of need of nodes of the above described types,
 *          0 otherwise. -1 on API errors.
 */
int
xmlStreamWantsAnyNode(xmlStreamCtxtPtr streamCtxt)
{
    if (streamCtxt == NULL)
	return(-1);
    while (streamCtxt != NULL) {
	if (streamCtxt->comp->flags & XML_STREAM_FINAL_IS_ANY_NODE)
	    return(1);
	streamCtxt = streamCtxt->next;
    }
    return(0);
}

/************************************************************************
 *									*
 *			The public interfaces				*
 *									*
 ************************************************************************/

/**
 * xmlPatterncompile:
 * @pattern: the pattern to compile
 * @dict: an optional dictionary for interned strings
 * @flags: compilation flags, see xmlPatternFlags
 * @namespaces: the prefix definitions, array of [URI, prefix] or NULL
 *
 * Compile a pattern.
 *
 * Returns the compiled form of the pattern or NULL in case of error
 */
xmlPatternPtr
xmlPatterncompile(const xmlChar *pattern, xmlDict *dict, int flags,
                  const xmlChar **namespaces) {
    xmlPatternPtr ret = NULL, cur;
    xmlPatParserContextPtr ctxt = NULL;
    const xmlChar *or, *start;
    xmlChar *tmp = NULL;
    int type = 0;
    int streamable = 1;

    if (pattern == NULL)
        return(NULL);

    start = pattern;
    or = start;
    while (*or != 0) {
	tmp = NULL;
	while ((*or != 0) && (*or != '|')) or++;
        if (*or == 0)
	    ctxt = xmlNewPatParserContext(start, dict, namespaces);
	else {
	    tmp = xmlStrndup(start, or - start);
	    if (tmp != NULL) {
		ctxt = xmlNewPatParserContext(tmp, dict, namespaces);
	    }
	    or++;
	}
	if (ctxt == NULL) goto error;
	cur = xmlNewPattern();
	if (cur == NULL) goto error;
	/*
	* Assign string dict.
	*/
	if (dict) {
	    cur->dict = dict;
	    xmlDictReference(dict);
	}
	if (ret == NULL)
	    ret = cur;
	else {
	    cur->next = ret->next;
	    ret->next = cur;
	}
	cur->flags = flags;
	ctxt->comp = cur;

	if (XML_STREAM_XS_IDC(cur))
	    xmlCompileIDCXPathPath(ctxt);
	else
	    xmlCompilePathPattern(ctxt);
	if (ctxt->error != 0)
	    goto error;
	xmlFreePatParserContext(ctxt);
	ctxt = NULL;


        if (streamable) {
	    if (type == 0) {
	        type = cur->flags & (PAT_FROM_ROOT | PAT_FROM_CUR);
	    } else if (type == PAT_FROM_ROOT) {
	        if (cur->flags & PAT_FROM_CUR)
		    streamable = 0;
	    } else if (type == PAT_FROM_CUR) {
	        if (cur->flags & PAT_FROM_ROOT)
		    streamable = 0;
	    }
	}
	if (streamable)
	    xmlStreamCompile(cur);
	if (xmlReversePattern(cur) < 0)
	    goto error;
	if (tmp != NULL) {
	    xmlFree(tmp);
	    tmp = NULL;
	}
	start = or;
    }
    if (streamable == 0) {
        cur = ret;
	while (cur != NULL) {
	    if (cur->stream != NULL) {
		xmlFreeStreamComp(cur->stream);
		cur->stream = NULL;
	    }
	    cur = cur->next;
	}
    }

    return(ret);
error:
    if (ctxt != NULL) xmlFreePatParserContext(ctxt);
    if (ret != NULL) xmlFreePattern(ret);
    if (tmp != NULL) xmlFree(tmp);
    return(NULL);
}

/**
 * xmlPatternMatch:
 * @comp: the precompiled pattern
 * @node: a node
 *
 * Test whether the node matches the pattern
 *
 * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure
 */
int
xmlPatternMatch(xmlPatternPtr comp, xmlNodePtr node)
{
    int ret = 0;

    if ((comp == NULL) || (node == NULL))
        return(-1);

    while (comp != NULL) {
        ret = xmlPatMatch(comp, node);
	if (ret != 0)
	    return(ret);
	comp = comp->next;
    }
    return(ret);
}

/**
 * xmlPatternGetStreamCtxt:
 * @comp: the precompiled pattern
 *
 * Get a streaming context for that pattern
 * Use xmlFreeStreamCtxt to free the context.
 *
 * Returns a pointer to the context or NULL in case of failure
 */
xmlStreamCtxtPtr
xmlPatternGetStreamCtxt(xmlPatternPtr comp)
{
    xmlStreamCtxtPtr ret = NULL, cur;

    if ((comp == NULL) || (comp->stream == NULL))
        return(NULL);

    while (comp != NULL) {
        if (comp->stream == NULL)
	    goto failed;
	cur = xmlNewStreamCtxt(comp->stream);
	if (cur == NULL)
	    goto failed;
	if (ret == NULL)
	    ret = cur;
	else {
	    cur->next = ret->next;
	    ret->next = cur;
	}
	cur->flags = comp->flags;
	comp = comp->next;
    }
    return(ret);
failed:
    xmlFreeStreamCtxt(ret);
    return(NULL);
}

/**
 * xmlPatternStreamable:
 * @comp: the precompiled pattern
 *
 * Check if the pattern is streamable i.e. xmlPatternGetStreamCtxt()
 * should work.
 *
 * Returns 1 if streamable, 0 if not and -1 in case of error.
 */
int
xmlPatternStreamable(xmlPatternPtr comp) {
    if (comp == NULL)
        return(-1);
    while (comp != NULL) {
        if (comp->stream == NULL)
	    return(0);
	comp = comp->next;
    }
    return(1);
}

/**
 * xmlPatternMaxDepth:
 * @comp: the precompiled pattern
 *
 * Check the maximum depth reachable by a pattern
 *
 * Returns -2 if no limit (using //), otherwise the depth,
 *         and -1 in case of error
 */
int
xmlPatternMaxDepth(xmlPatternPtr comp) {
    int ret = 0, i;
    if (comp == NULL)
        return(-1);
    while (comp != NULL) {
        if (comp->stream == NULL)
	    return(-1);
	for (i = 0;i < comp->stream->nbStep;i++)
	    if (comp->stream->steps[i].flags & XML_STREAM_STEP_DESC)
	        return(-2);
	if (comp->stream->nbStep > ret)
	    ret = comp->stream->nbStep;
	comp = comp->next;
    }
    return(ret);
}

/**
 * xmlPatternMinDepth:
 * @comp: the precompiled pattern
 *
 * Check the minimum depth reachable by a pattern, 0 mean the / or . are
 * part of the set.
 *
 * Returns -1 in case of error otherwise the depth,
 *
 */
int
xmlPatternMinDepth(xmlPatternPtr comp) {
    int ret = 12345678;
    if (comp == NULL)
        return(-1);
    while (comp != NULL) {
        if (comp->stream == NULL)
	    return(-1);
	if (comp->stream->nbStep < ret)
	    ret = comp->stream->nbStep;
	if (ret == 0)
	    return(0);
	comp = comp->next;
    }
    return(ret);
}

/**
 * xmlPatternFromRoot:
 * @comp: the precompiled pattern
 *
 * Check if the pattern must be looked at from the root.
 *
 * Returns 1 if true, 0 if false and -1 in case of error
 */
int
xmlPatternFromRoot(xmlPatternPtr comp) {
    if (comp == NULL)
        return(-1);
    while (comp != NULL) {
        if (comp->stream == NULL)
	    return(-1);
	if (comp->flags & PAT_FROM_ROOT)
	    return(1);
	comp = comp->next;
    }
    return(0);

}

#define bottom_pattern
#include "elfgcchack.h"
#endif /* LIBXML_PATTERN_ENABLED */
