/*
 * xpath.c: XML Path Language implementation
 *          XPath is a language for addressing parts of an XML document,
 *          designed to be used by both XSLT and XPointer.
 *
 * Reference: W3C Working Draft internal 5 July 1999
 *     http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html
 * Public reference:
 *     http://www.w3.org/TR/WD-xpath/
 *
 * See COPYRIGHT for the status of this software
 *
 * Author: Daniel.Veillard@w3.org
 */

#include <malloc.h>
#include <math.h>
#include <stdio.h>
#include "tree.h"
#include "xpath.h"
#include "parserInternals.h"

/*
 * TODO: create a pseudo document element and affect it as the 
 *       actual root.
 */
/*
 * Setup stuff for floating point
 */
double xmlXPathNAN = 0;
double xmlXPathPINF = 1;
double xmlXPathMINF = -1;

/**
 * xmlXPathInit:
 *
 * Initialize the XPath environment
 */
void
xmlXPathInit(void) {
    static int initialized = 0;

    if (initialized) return;

    xmlXPathNAN = 0;
    xmlXPathNAN /= 0;

    xmlXPathPINF = 1;
    xmlXPathPINF /= 0;

    xmlXPathMINF = -1;
    xmlXPathMINF /= 0;

    initialized = 1;
}

/* #define DEBUG */
/* #define DEBUG_STEP */
/* #define DEBUG_EXPR */

FILE *xmlXPathDebug = NULL;

#define TODO 								\
    fprintf(xmlXPathDebug, "Unimplemented block at %s:%d\n",		\
            __FILE__, __LINE__);

#define STRANGE 							\
    fprintf(xmlXPathDebug, "Internal error at %s:%d\n",			\
            __FILE__, __LINE__);

double xmlXPathStringEvalNumber(const CHAR *str);

/************************************************************************
 *									*
 * 		Parser stacks related functions and macros		*
 *									*
 ************************************************************************/

/*
 * Generic function for accessing stacks in the Parser Context
 */

#define PUSH_AND_POP(type, name)					\
extern int name##Push(xmlXPathParserContextPtr ctxt, type value) {	\
    if (ctxt->name##Nr >= ctxt->name##Max) {				\
	ctxt->name##Max *= 2;						\
        ctxt->name##Tab = (void *) realloc(ctxt->name##Tab,		\
	             ctxt->name##Max * sizeof(ctxt->name##Tab[0]));	\
        if (ctxt->name##Tab == NULL) {					\
	    fprintf(xmlXPathDebug, "realloc failed !\n");			\
	    exit(1);							\
	}								\
    }									\
    ctxt->name##Tab[ctxt->name##Nr] = value;				\
    ctxt->name = value;							\
    return(ctxt->name##Nr++);						\
}									\
extern type name##Pop(xmlXPathParserContextPtr ctxt) {			\
    type ret;								\
    if (ctxt->name##Nr <= 0) return(0);					\
    ctxt->name##Nr--;							\
    if (ctxt->name##Nr > 0)						\
	ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1];		\
    else								\
        ctxt->name = NULL;						\
    ret = ctxt->name##Tab[ctxt->name##Nr];				\
    ctxt->name##Tab[ctxt->name##Nr] = 0;				\
    return(ret);							\
}									\

PUSH_AND_POP(xmlXPathObjectPtr, value)

/*
 * Macros for accessing the content. Those should be used only by the parser,
 * and not exported.
 *
 * Dirty macros, i.e. one need to make assumption on the context to use them
 *
 *   CUR_PTR return the current pointer to the CHAR to be parsed.
 *   CUR     returns the current CHAR value, i.e. a 8 bit value if compiled
 *           in ISO-Latin or UTF-8, and the current 16 bit value if compiled
 *           in UNICODE mode. This should be used internally by the parser
 *           only to compare to ASCII values otherwise it would break when
 *           running with UTF-8 encoding.
 *   NXT(n)  returns the n'th next CHAR. Same as CUR is should be used only
 *           to compare on ASCII based substring.
 *   SKIP(n) Skip n CHAR, and must also be used only to skip ASCII defined
 *           strings within the parser.
 *   CURRENT Returns the current char value, with the full decoding of
 *           UTF-8 if we are using this mode. It returns an int.
 *   NEXT    Skip to the next character, this does the proper decoding
 *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
 *           It returns the pointer to the current CHAR.
 */

#define CUR (*ctxt->cur)
#define SKIP(val) ctxt->cur += (val)
#define NXT(val) ctxt->cur[(val)]
#define CUR_PTR ctxt->cur

#define SKIP_BLANKS 							\
    while (IS_BLANK(*(ctxt->cur))) NEXT

#ifndef USE_UTF_8
#define CURRENT (*ctxt->cur)
#define NEXT ((*ctxt->cur) ?  ctxt->cur++: ctxt->cur)
#else
#endif

/************************************************************************
 *									*
 *			Error handling routines				*
 *									*
 ************************************************************************/

#define XPATH_EXPRESSION_OK		0
#define XPATH_NUMBER_ERROR		1
#define XPATH_UNFINISHED_LITERAL_ERROR	2
#define XPATH_START_LITERAL_ERROR	3
#define XPATH_VARIABLE_REF_ERROR	4
#define XPATH_UNDEF_VARIABLE_ERROR	5
#define XPATH_INVALID_PREDICATE_ERROR	6
#define XPATH_EXPR_ERROR		7
#define XPATH_UNCLOSED_ERROR		8
#define XPATH_UNKNOWN_FUNC_ERROR	9
#define XPATH_INVALID_OPERAND		10
#define XPATH_INVALID_TYPE		11
#define XPATH_INVALID_ARITY		12

const char *xmlXPathErrorMessages[] = {
    "Ok",
    "Number encoding",
    "Unfinished litteral",
    "Start of litteral",
    "Expected $ for variable reference",
    "Undefined variable",
    "Invalid predicate",
    "Invalid expression",
    "Missing closing curly brace",
    "Unregistered function",
    "Invalid operand",
    "Invalid type",
    "Invalid number of arguments",
};

/**
 * xmlXPathError:
 * @ctxt:  the XPath Parser context
 * @file:  the file name
 * @line:  the line number
 * @no:  the error number
 *
 * Create a new xmlNodeSetPtr of type double and of value @val
 *
 * Returns the newly created object.
 */
void
xmlXPatherror(xmlXPathParserContextPtr ctxt, const char *file,
              int line, int no) {
    int n;
    const char *cur;
    const char *base;

    fprintf(xmlXPathDebug, "Error %s:%d: %s\n", file, line,
            xmlXPathErrorMessages[no]);

    cur = ctxt->cur;
    base = ctxt->base;
    while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
	cur--;
    }
    n = 0;
    while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
        cur--;
    if ((*cur == '\n') || (*cur == '\r')) cur++;
    base = cur;
    n = 0;
    while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
        fprintf(xmlXPathDebug, "%c", (unsigned char) *cur++);
	n++;
    }
    fprintf(xmlXPathDebug, "\n");
    cur = ctxt->cur;
    while ((*cur == '\n') || (*cur == '\r'))
	cur--;
    n = 0;
    while ((cur != base) && (n++ < 80)) {
        fprintf(xmlXPathDebug, " ");
        base++;
    }
    fprintf(xmlXPathDebug,"^\n");
}

#define CHECK_ERROR							\
    if (ctxt->error != XPATH_EXPRESSION_OK) return

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

#define CHECK_TYPE(typeval)						\
    if ((ctxt->value == NULL) || (ctxt->value->type != typeval))	\
        ERROR(XPATH_INVALID_TYPE)					\


/************************************************************************
 *									*
 *			Routines to handle NodeSets			*
 *									*
 ************************************************************************/

#define XML_NODESET_DEFAULT	10
/**
 * xmlXPathNodeSetCreate:
 * @val:  an initial xmlNodePtr, or NULL
 *
 * Create a new xmlNodeSetPtr of type double and of value @val
 *
 * Returns the newly created object.
 */
xmlNodeSetPtr
xmlXPathNodeSetCreate(xmlNodePtr val) {
    xmlNodeSetPtr ret;

    ret = (xmlNodeSetPtr) malloc(sizeof(xmlNodeSet));
    if (ret == NULL) {
        fprintf(xmlXPathDebug, "xmlXPathNewNodeSet: out of memory\n");
	return(NULL);
    }
    memset(ret, 0 , (size_t) sizeof(xmlNodeSet));
    if (val != NULL) {
        ret->nodeTab = (xmlNodePtr *) malloc(XML_NODESET_DEFAULT *
					     sizeof(xmlNodePtr));
	if (ret->nodeTab == NULL) {
	    fprintf(xmlXPathDebug, "xmlXPathNewNodeSet: out of memory\n");
	    return(NULL);
	}
	memset(ret->nodeTab, 0 ,
	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
        ret->nodeMax = XML_NODESET_DEFAULT;
	ret->nodeTab[ret->nodeNr++] = val;
    }
    return(ret);
}

/**
 * xmlXPathNodeSetAdd:
 * @cur:  the initial node set
 * @val:  a new xmlNodePtr
 *
 * add a new xmlNodePtr ot an existing NodeSet
 */
void
xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
    int i;

    if (val == NULL) return;

    /*
     * check against doublons
     */
    for (i = 0;i < cur->nodeNr;i++)
        if (cur->nodeTab[i] == val) return;

    /*
     * grow the nodeTab if needed
     */
    if (cur->nodeMax == 0) {
        cur->nodeTab = (xmlNodePtr *) malloc(XML_NODESET_DEFAULT *
					     sizeof(xmlNodePtr));
	if (cur->nodeTab == NULL) {
	    fprintf(xmlXPathDebug, "xmlXPathNodeSetAdd: out of memory\n");
	    return;
	}
	memset(cur->nodeTab, 0 ,
	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
        cur->nodeMax = XML_NODESET_DEFAULT;
    } else if (cur->nodeNr == cur->nodeMax) {
        xmlNodePtr *temp;

        cur->nodeMax *= 2;
	temp = (xmlNodePtr *) realloc(cur->nodeTab, cur->nodeMax *
				      sizeof(xmlNodePtr));
	if (temp == NULL) {
	    fprintf(xmlXPathDebug, "xmlXPathNodeSetAdd: out of memory\n");
	    return;
	}
    }
    cur->nodeTab[cur->nodeNr++] = val;
}

/**
 * xmlXPathNodeSetMerge:
 * @val1:  the first NodeSet
 * @val2:  the second NodeSet
 *
 * Merges two nodesets, all nodes from @val2 are added to @val1
 *
 * Returns val1 once extended or NULL in case of error.
 */
xmlNodeSetPtr
xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
    int i;

    if (val1 == NULL) return(NULL);
    if (val2 == NULL) return(val1);

    /*
     * !!!!! this can be optimized a lot, knowing that both
     *       val1 and val2 already have unicity of their values.
     */

    for (i = 0;i < val2->nodeNr;i++)
        xmlXPathNodeSetAdd(val1, val2->nodeTab[i]);

    return(val1);
}

/**
 * xmlXPathNodeSetDel:
 * @cur:  the initial node set
 * @val:  an xmlNodePtr
 *
 * Removes an xmlNodePtr from an existing NodeSet
 */
void
xmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val) {
    int i;

    if (cur == NULL) return;
    if (val == NULL) return;

    /*
     * check against doublons
     */
    for (i = 0;i < cur->nodeNr;i++)
        if (cur->nodeTab[i] == val) break;

    if (i >= cur->nodeNr) {
#ifdef DEBUG
        fprintf(xmlXPathDebug, 
	        "xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n",
		val->name);
#endif
        return;
    }
    cur->nodeNr--;
    for (;i < cur->nodeNr;i++)
        cur->nodeTab[i] = cur->nodeTab[i + 1];
    cur->nodeTab[cur->nodeNr] = NULL;
}

/**
 * xmlXPathNodeSetRemove:
 * @cur:  the initial node set
 * @val:  the index to remove
 *
 * Removes an entry from an existing NodeSet list.
 */
void
xmlXPathNodeSetRemove(xmlNodeSetPtr cur, int val) {
    if (cur == NULL) return;
    if (val >= cur->nodeNr) return;
    cur->nodeNr--;
    for (;val < cur->nodeNr;val++)
        cur->nodeTab[val] = cur->nodeTab[val + 1];
    cur->nodeTab[cur->nodeNr] = NULL;
}

/**
 * xmlXPathFreeNodeSet:
 * @obj:  the xmlNodeSetPtr to free
 *
 * Free the NodeSet compound (not the actual nodes !).
 */
void
xmlXPathFreeNodeSet(xmlNodeSetPtr obj) {
    if (obj == NULL) return;
    if (obj->nodeTab != NULL) {
#ifdef DEBUG
	memset(obj->nodeTab, 0xB , (size_t) sizeof(xmlNodePtr) * obj->nodeMax);
#endif
	free(obj->nodeTab);
    }
#ifdef DEBUG
    memset(obj, 0xB , (size_t) sizeof(xmlNodeSet));
#endif
    free(obj);
}

#ifdef DEBUG
/**
 * xmlXPathDebugNodeSet:
 * @output:  a FILE * for the output
 * @obj:  the xmlNodeSetPtr to free
 *
 * Quick display of a NodeSet
 */
void
xmlXPathDebugNodeSet(FILE *output, xmlNodeSetPtr obj) {
    int i;

    if (output == NULL) output = xmlXPathDebug;
    if (obj == NULL)  {
        fprintf(output, "NodeSet == NULL !\n");
	return;
    }
    if (obj->nodeNr == 0) {
        fprintf(output, "NodeSet is empty\n");
	return;
    }
    if (obj->nodeTab == NULL) {
	fprintf(output, " nodeTab == NULL !\n");
	return;
    }
    for (i = 0; i < obj->nodeNr; i++) {
        if (obj->nodeTab[i] == NULL) {
	    fprintf(output, " NULL !\n");
	    return;
        }
	if (obj->nodeTab[i]->name == NULL)
	    fprintf(output, " noname!");
	else fprintf(output, " %s", obj->nodeTab[i]->name);
    }
    fprintf(output, "\n");
}
#endif

/************************************************************************
 *									*
 *			Routines to handle Variable			*
 *									*
 *			UNIMPLEMENTED CURRENTLY				*
 *									*
 ************************************************************************/

/**
 * xmlXPathVariablelookup:
 * @ctxt:  the XPath Parser context
 * @prefix:  the variable name namespace if any
 * @name:  the variable name
 *
 * Search in the Variable array of the context for the given
 * variable value.
 *
 * UNIMPLEMENTED: always return NULL.
 *
 * Returns the value or NULL if not found
 */
xmlXPathObjectPtr
xmlXPathVariablelookup(xmlXPathParserContextPtr ctxt,
                       const CHAR *prefix, const CHAR *name) {
    return(NULL);
}

/************************************************************************
 *									*
 *			Routines to handle Values			*
 *									*
 ************************************************************************/

/* Allocations are terrible, one need to optimize all this !!! */

/**
 * xmlXPathNewFloat:
 * @val:  the double value
 *
 * Create a new xmlXPathObjectPtr of type double and of value @val
 *
 * Returns the newly created object.
 */
xmlXPathObjectPtr
xmlXPathNewFloat(double val) {
    xmlXPathObjectPtr ret;

    ret = (xmlXPathObjectPtr) malloc(sizeof(xmlXPathObject));
    if (ret == NULL) {
        fprintf(xmlXPathDebug, "xmlXPathNewFloat: out of memory\n");
	return(NULL);
    }
    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
    ret->type = XPATH_NUMBER;
    ret->floatval = val;
    return(ret);
}

/**
 * xmlXPathNewBoolean:
 * @val:  the boolean value
 *
 * Create a new xmlXPathObjectPtr of type boolean and of value @val
 *
 * Returns the newly created object.
 */
xmlXPathObjectPtr
xmlXPathNewBoolean(int val) {
    xmlXPathObjectPtr ret;

    ret = (xmlXPathObjectPtr) malloc(sizeof(xmlXPathObject));
    if (ret == NULL) {
        fprintf(xmlXPathDebug, "xmlXPathNewFloat: out of memory\n");
	return(NULL);
    }
    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
    ret->type = XPATH_BOOLEAN;
    ret->boolval = (val != 0);
    return(ret);
}

/**
 * xmlXPathNewBoolean:
 * @val:  the CHAR * value
 *
 * Create a new xmlXPathObjectPtr of type string and of value @val
 *
 * Returns the newly created object.
 */
xmlXPathObjectPtr
xmlXPathNewString(const CHAR *val) {
    xmlXPathObjectPtr ret;

    ret = (xmlXPathObjectPtr) malloc(sizeof(xmlXPathObject));
    if (ret == NULL) {
        fprintf(xmlXPathDebug, "xmlXPathNewFloat: out of memory\n");
	return(NULL);
    }
    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
    ret->type = XPATH_STRING;
    ret->stringval = xmlStrdup(val);
    return(ret);
}

/**
 * xmlXPathNewNodeSet:
 * @val:  the NodePtr value
 *
 * Create a new xmlXPathObjectPtr of type NodeSet and initialize
 * it with the single Node @val
 *
 * Returns the newly created object.
 */
xmlXPathObjectPtr
xmlXPathNewNodeSet(xmlNodePtr val) {
    xmlXPathObjectPtr ret;

    ret = (xmlXPathObjectPtr) malloc(sizeof(xmlXPathObject));
    if (ret == NULL) {
        fprintf(xmlXPathDebug, "xmlXPathNewFloat: out of memory\n");
	return(NULL);
    }
    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
    ret->type = XPATH_NODESET;
    ret->nodesetval = xmlXPathNodeSetCreate(val);
    return(ret);
}

/**
 * xmlXPathNewNodeSetList:
 * @val:  an existing NodeSet
 *
 * Create a new xmlXPathObjectPtr of type NodeSet and initialize
 * it with the Nodeset @val
 *
 * Returns the newly created object.
 */
xmlXPathObjectPtr
xmlXPathNewNodeSetList(xmlNodeSetPtr val) {
    xmlXPathObjectPtr ret;

    ret = (xmlXPathObjectPtr) malloc(sizeof(xmlXPathObject));
    if (ret == NULL) {
        fprintf(xmlXPathDebug, "xmlXPathNewFloat: out of memory\n");
	return(NULL);
    }
    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
    ret->type = XPATH_NODESET;
    ret->nodesetval = val;
    return(ret);
}

/**
 * xmlXPathFreeObject:
 * @obj:  the object to free
 *
 * Free up an xmlXPathObjectPtr object.
 */
void
xmlXPathFreeObject(xmlXPathObjectPtr obj) {
    if (obj == NULL) return;
    if (obj->nodesetval != NULL)
        xmlXPathFreeNodeSet(obj->nodesetval);
    if (obj->stringval != NULL)
        free(obj->stringval);
#ifdef DEBUG
    memset(obj, 0xB , (size_t) sizeof(xmlXPathObject));
#endif
    free(obj);
}

/************************************************************************
 *									*
 *		Routines to handle XPath contexts			*
 *									*
 ************************************************************************/

/**
 * xmlXPathNewContext:
 * @doc:  the XML document
 * @variables:  the variable list
 * @functions:  the function list
 * @namespaces:  the namespace list
 *
 * Create a new xmlXPathContext
 *
 * Returns the xmlXPathContext just allocated.
 */
xmlXPathContextPtr
xmlXPathNewContext(xmlDocPtr doc, void *variables, void *functions,
                   void *namespaces) {
    xmlXPathContextPtr ret;

    ret = (xmlXPathContextPtr) malloc(sizeof(xmlXPathContext));
    if (ret == NULL) {
        fprintf(xmlXPathDebug, "xmlXPathNewContext: out of memory\n");
	return(NULL);
    }
    memset(ret, 0 , (size_t) sizeof(xmlXPathContext));
    ret->doc = doc;
    ret->variables = variables;
    ret->functions = functions;
    ret->namespaces = namespaces;
    return(ret);
}

/**
 * xmlXPathFreeContext:
 * @ctxt:  the context to free
 *
 * Free up an xmlXPathContext
 */
void
xmlXPathFreeContext(xmlXPathContextPtr ctxt) {
#ifdef DEBUG
    memset(ctxt, 0xB , (size_t) sizeof(xmlXPathContext));
#endif
    free(ctxt);
}

/************************************************************************
 *									*
 *		Routines to handle XPath parser contexts		*
 *									*
 ************************************************************************/

#define CHECK_CTXT							\
    if (ctxt == NULL) { 						\
        fprintf(xmlXPathDebug, "%s:%d Internal error: ctxt == NULL\n",	\
	        __FILE__, __LINE__);					\
    }									\


#define CHECK_CONTEXT							\
    if (ctxt == NULL) { 						\
        fprintf(xmlXPathDebug, "%s:%d Internal error: no context\n",	\
	        __FILE__, __LINE__);					\
    }									\
    if (ctxt->doc == NULL) { 						\
        fprintf(xmlXPathDebug, "%s:%d Internal error: no document\n",	\
	        __FILE__, __LINE__);					\
    }									\
    if (ctxt->doc->root == NULL) { 					\
        fprintf(xmlXPathDebug,						\
	        "%s:%d Internal error: document without root\n",	\
	        __FILE__, __LINE__);					\
    }									\


/**
 * xmlXPathNewParserContext:
 * @str:  the XPath expression
 * @ctxt:  the XPath context
 *
 * Create a new xmlXPathParserContext
 *
 * Returns the xmlXPathParserContext just allocated.
 */
xmlXPathParserContextPtr
xmlXPathNewParserContext(const CHAR *str, xmlXPathContextPtr ctxt) {
    xmlXPathParserContextPtr ret;

    ret = (xmlXPathParserContextPtr) malloc(sizeof(xmlXPathParserContext));
    if (ret == NULL) {
        fprintf(xmlXPathDebug, "xmlXPathNewParserContext: out of memory\n");
	return(NULL);
    }
    memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext));
    ret->cur = ret->base = str;
    ret->context = ctxt;

    /* Allocate the value stack */
    ret->valueTab = (xmlXPathObjectPtr *) 
                     malloc(10 * sizeof(xmlXPathObjectPtr));
    ret->valueNr = 0;
    ret->valueMax = 10;
    ret->value = NULL;
    return(ret);
}

/**
 * xmlXPathFreeParserContext:
 * @ctxt:  the context to free
 *
 * Free up an xmlXPathParserContext
 */
void
xmlXPathFreeParserContext(xmlXPathParserContextPtr ctxt) {
    if (ctxt->valueTab != NULL) {
#ifdef DEBUG
        memset(ctxt->valueTab, 0xB , 10 * (size_t) sizeof(xmlXPathObjectPtr));
#endif
        free(ctxt->valueTab);
    }
#ifdef DEBUG
    memset(ctxt, 0xB , (size_t) sizeof(xmlXPathParserContext));
#endif
    free(ctxt);
}

/************************************************************************
 *									*
 *		The implicit core function library			*
 *									*
 ************************************************************************/

/*
 * TODO: check the semantic for all these operations in case of operands
 *       with different types, Cast function probably need to be provided
 *       to simplify the coding.
 */

/*
 * Auto-pop and cast to a number
 */
void xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs);

#define CHECK_ARITY(x)						\
    if (nargs != (x)) {						\
        ERROR(XPATH_INVALID_ARITY);				\
    }								\


#define POP_FLOAT						\
    arg = valuePop(ctxt);					\
    if (arg == NULL) {						\
	ERROR(XPATH_INVALID_OPERAND);				\
    }								\
    if (arg->type != XPATH_NUMBER) {				\
        valuePush(ctxt, arg);					\
        xmlXPathNumberFunction(ctxt, 1);			\
	arg = valuePop(ctxt);					\
    }

/**
 * xmlXPathEqualValues:
 * @arg1:  first XPath object argument
 * @arg2:  second XPath object argument
 *
 * Implement the equal operation on XPath objects content: @arg1 == @arg2
 *
 * Returns 0 or 1 depending on the results of the test.
 * TODO: rewrite using the stack for evaluation
 */
int
xmlXPathEqualValues(xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) {
    if (arg1 == arg2) {
#ifdef DEBUG_EXPR
        fprintf(xmlXPathDebug, "Equal: by pointer\n");
#endif
        return(1);
    }
    if ((arg1 == NULL) || (arg2 == NULL)) {
#ifdef DEBUG_EXPR
        fprintf(xmlXPathDebug, "Equal: arg NULL\n");
#endif
        return(0);
    }
    if (arg1->type != arg2->type) {
        /* TODO : see 4.3 Boolean section !!!!!!!!!!! */
#ifdef DEBUG_EXPR
        fprintf(xmlXPathDebug, "Equal: distinct types\n");
#endif
        return(0);
    }
    switch (arg1->type) {
        case XPATH_UNDEFINED:
#ifdef DEBUG_EXPR
	    fprintf(xmlXPathDebug, "Equal: undefined\n");
#endif
	    return(0);
        case XPATH_NODESET:
	    TODO /* compare nodesets */
	    break;
        case XPATH_BOOLEAN:
#ifdef DEBUG_EXPR
	    fprintf(xmlXPathDebug, "Equal: %d boolean %d \n",
	            arg1->boolval, arg2->boolval);
#endif
	    return(arg1->boolval == arg2->boolval);
        case XPATH_NUMBER:
#ifdef DEBUG_EXPR
	    fprintf(xmlXPathDebug, "Equal: %f number %f \n",
	            arg1->floatval, arg2->floatval);
#endif
	    return(arg1->floatval == arg2->floatval);
        case XPATH_STRING:
#ifdef DEBUG_EXPR
	    fprintf(xmlXPathDebug, "Equal: %s string %s \n",
	            arg1->stringval, arg2->stringval);
#endif
	    return(!xmlStrcmp(arg1->stringval, arg2->stringval));
    }
    return(1);
}

/**
 * xmlXPathCompareValues:
 * @inf:  less than (1) or greater than (2)
 * @strict:  is the comparison strict
 * @arg1:  first XPath object argument
 * @arg2:  second XPath object argument
 *
 * Implement the compare operation on XPath objects: 
 *     @arg1 < @arg2    (1, 1, ...
 *     @arg1 <= @arg2   (1, 0, ...
 *     @arg1 > @arg2    (0, 1, ...
 *     @arg1 >= @arg2   (0, 0, ...
 *
 * Returns 0 or 1 depending on the results of the test.
 */
int
xmlXPathCompareValues(int inf, int strict, xmlXPathObjectPtr arg1,
                      xmlXPathObjectPtr arg2) {
    TODO /* compare */
    return(0);
}

/**
 * xmlXPathValueFlipSign:
 * @ctxt:  the XPath Parser context
 *
 * Implement the unary - operation on an XPath object
 * The numeric operators convert their operands to numbers as if
 * by calling the number function.
 */
void
xmlXPathValueFlipSign(xmlXPathParserContextPtr ctxt) {
    xmlXPathObjectPtr arg;
    
    POP_FLOAT
    arg->floatval = -arg->floatval;
    valuePush(ctxt, arg);
}

/**
 * xmlXPathAddValues:
 * @ctxt:  the XPath Parser context
 *
 * Implement the add operation on XPath objects:
 * The numeric operators convert their operands to numbers as if
 * by calling the number function.
 */
void
xmlXPathAddValues(xmlXPathParserContextPtr ctxt) {
    xmlXPathObjectPtr arg;
    double val;

    POP_FLOAT
    val = arg->floatval;
    xmlXPathFreeObject(arg);

    POP_FLOAT
    arg->floatval += val;
    valuePush(ctxt, arg);
}

/**
 * xmlXPathSubValues:
 * @ctxt:  the XPath Parser context
 *
 * Implement the substraction operation on XPath objects:
 * The numeric operators convert their operands to numbers as if
 * by calling the number function.
 */
void
xmlXPathSubValues(xmlXPathParserContextPtr ctxt) {
    xmlXPathObjectPtr arg;
    double val;

    POP_FLOAT
    val = arg->floatval;
    xmlXPathFreeObject(arg);

    POP_FLOAT
    arg->floatval -= val;
    valuePush(ctxt, arg);
}

/**
 * xmlXPathMultValues:
 * @ctxt:  the XPath Parser context
 *
 * Implement the multiply operation on XPath objects:
 * The numeric operators convert their operands to numbers as if
 * by calling the number function.
 */
void
xmlXPathMultValues(xmlXPathParserContextPtr ctxt) {
    xmlXPathObjectPtr arg;
    double val;

    POP_FLOAT
    val = arg->floatval;
    xmlXPathFreeObject(arg);

    POP_FLOAT
    arg->floatval *= val;
    valuePush(ctxt, arg);
}

/**
 * xmlXPathDivValues:
 * @ctxt:  the XPath Parser context
 *
 * Implement the div operation on XPath objects:
 * The numeric operators convert their operands to numbers as if
 * by calling the number function.
 */
void
xmlXPathDivValues(xmlXPathParserContextPtr ctxt) {
    xmlXPathObjectPtr arg;
    double val;

    POP_FLOAT
    val = arg->floatval;
    xmlXPathFreeObject(arg);

    POP_FLOAT
    arg->floatval /= val;
    valuePush(ctxt, arg);
}

/**
 * xmlXPathModValues:
 * @ctxt:  the XPath Parser context
 *
 * Implement the div operation on XPath objects: @arg1 / @arg2
 * The numeric operators convert their operands to numbers as if
 * by calling the number function.
 */
void
xmlXPathModValues(xmlXPathParserContextPtr ctxt) {
    xmlXPathObjectPtr arg;
    double val;

    POP_FLOAT
    val = arg->floatval;
    xmlXPathFreeObject(arg);

    POP_FLOAT
    arg->floatval /= val;
    valuePush(ctxt, arg);
}

/************************************************************************
 *									*
 *		The traversal functions					*
 *									*
 ************************************************************************/

#define AXIS_ANCESTOR			1
#define AXIS_ANCESTOR_OR_SELF		2
#define AXIS_ATTRIBUTE			3
#define AXIS_CHILD			4
#define AXIS_DESCENDANT			5
#define AXIS_DESCENDANT_OR_SELF		6
#define AXIS_FOLLOWING			7
#define AXIS_FOLLOWING_SIBLING		8
#define AXIS_NAMESPACE			9
#define AXIS_PARENT			10
#define AXIS_PRECEDING			11
#define AXIS_PRECEDING_SIBLING		12
#define AXIS_SELF			13

/*
 * A traversal function enumerates nodes along an axis.
 * Initially it must be called with NULL, and it indicates
 * termination on the axis by returning NULL.
 */
typedef xmlNodePtr (*xmlXPathTraversalFunction)
                    (xmlXPathParserContextPtr ctxt, xmlNodePtr cur);

/**
 * mlXPathNextSelf:
 * @ctxt:  the XPath Parser context
 * @cur:  the current node in the traversal
 *
 * Traversal function for the "self" direction
 * he self axis contains just the context node itself
 */
xmlNodePtr
xmlXPathNextSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
    if (cur == NULL)
        return(ctxt->context->node);
    return(NULL);
}

/**
 * mlXPathNextChild:
 * @ctxt:  the XPath Parser context
 * @cur:  the current node in the traversal
 *
 * Traversal function for the "child" direction
 * The child axis contains the children of the context node in document order.
 */
xmlNodePtr
xmlXPathNextChild(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
    if (cur == NULL)
        return(ctxt->context->node->childs);
    return(cur->next);
}

/**
 * mlXPathNextDescendant:
 * @ctxt:  the XPath Parser context
 * @cur:  the current node in the traversal
 *
 * Traversal function for the "descendant" direction
 * the descendant axis contains the descendants of the context node in document
 * order; a descendant is a child or a child of a child and so on.
 */
xmlNodePtr
xmlXPathNextDescendant(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
    if (cur == NULL)
        return(ctxt->context->node->childs);

    if (cur->childs != NULL) return(cur->childs);
    if (cur->next != NULL) return(cur->next);
    
    do {
        cur = cur->parent;
	if (cur == NULL) return(NULL);
	if (cur == ctxt->context->node) return(NULL);
	if (cur->next != NULL) {
	    cur = cur->next;
	    return(cur);
	}
    } while (cur != NULL);
    return(cur);
}

/**
 * mlXPathNextDescendantOrSelf:
 * @ctxt:  the XPath Parser context
 * @cur:  the current node in the traversal
 *
 * Traversal function for the "descendant-or-self" direction
 * the descendant-or-self axis contains the context node and the descendants
 * of the context node in document order; thus the context node is the first
 * node on the axis, and the first child of the context node is the second node
 * on the axis
 */
xmlNodePtr
xmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
    if (cur == NULL)
        return(ctxt->context->node);

    if (cur->childs != NULL) return(cur->childs);
    if (cur->next != NULL) return(cur->next);
    
    do {
        cur = cur->parent;
	if (cur == NULL) return(NULL);
	if (cur == ctxt->context->node) return(NULL);
	if (cur->next != NULL) {
	    cur = cur->next;
	    return(cur);
	}
    } while (cur != NULL);
    return(cur);
}

/**
 * xmlXPathNextParent:
 * @ctxt:  the XPath Parser context
 * @cur:  the current node in the traversal
 *
 * Traversal function for the "parent" direction
 * The parent axis contains the parent of the context node, if there is one.
 */
xmlNodePtr
xmlXPathNextParent(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
    /*
     * !!!!!!!!!!!!!
     * the parent of an attribute or namespace node is the element
     * to which the attribute or namespace node is attached
     */
    if (cur == NULL)
        return(ctxt->context->node->parent);
    return(NULL);
}

/**
 * xmlXPathNextAncestor:
 * @ctxt:  the XPath Parser context
 * @cur:  the current node in the traversal
 *
 * Traversal function for the "ancestor" direction
 * the ancestor axis contains the ancestors of the context node; the ancestors
 * of the context node consist of the parent of context node and the parent's
 * parent and so on; the nodes are ordered in reverse document order; thus the
 * parent is the first node on the axis, and the parent's parent is the second
 * node on the axis
 */
xmlNodePtr
xmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
    /*
     * !!!!!!!!!!!!!
     * the parent of an attribute or namespace node is the element
     * to which the attribute or namespace node is attached
     */
    if (cur == NULL)
        return(ctxt->context->node->parent);
    if (cur == ctxt->context->doc->root) return(NULL);
    return(cur->parent);
}

/**
 * xmlXPathNextAncestorOrSelf:
 * @ctxt:  the XPath Parser context
 * @cur:  the current node in the traversal
 *
 * Traversal function for the "ancestor-or-self" direction
 * he ancestor-or-self axis contains the context node and ancestors of the context
 * node in reverse document order; thus the context node is the first node on the
 * axis, and the context node's parent the second; parent here is defined the same
 * as with the parent axis.
 */
xmlNodePtr
xmlXPathNextAncestorOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
    /*
     * !!!!!!!!!!!!!
     * the parent of an attribute or namespace node is the element
     * to which the attribute or namespace node is attached
     */
    if (cur == NULL)
        return(ctxt->context->node);
    if (cur == ctxt->context->doc->root) return(NULL);
    return(cur->parent);
}

/**
 * xmlXPathNextFollowingSibling:
 * @ctxt:  the XPath Parser context
 * @cur:  the current node in the traversal
 *
 * Traversal function for the "following-sibling" direction
 * The following-sibling axis contains the following siblings of the context
 * node in document order.
 */
xmlNodePtr
xmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
    if (cur == NULL)
        return(ctxt->context->node->next);
    return(cur->next);
}

/**
 * xmlXPathNextPrecedingSibling:
 * @ctxt:  the XPath Parser context
 * @cur:  the current node in the traversal
 *
 * Traversal function for the "preceding-sibling" direction
 * The preceding-sibling axis contains the preceding siblings of the context
 * node in reverse document order; the first preceding sibling is first on the
 * axis; the sibling preceding that node is the second on the axis and so on.
 */
xmlNodePtr
xmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
    if (cur == NULL)
        return(ctxt->context->node->prev);
    return(cur->prev);
}

/**
 * xmlXPathNextFollowing:
 * @ctxt:  the XPath Parser context
 * @cur:  the current node in the traversal
 *
 * Traversal function for the "following" direction
 * The following axis contains all nodes in the same document as the context
 * node that are after the context node in document order, excluding any
 * descendants and excluding attribute nodes and namespace nodes; the nodes
 * are ordered in document order
 */
xmlNodePtr
xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
    if (cur == NULL)
        return(ctxt->context->node->next);; /* !!!!!!!!! */
    if (cur->childs != NULL) return(cur->childs);
    if (cur->next != NULL) return(cur->next);
    
    do {
        cur = cur->parent;
	if (cur == NULL) return(NULL);
	if (cur == ctxt->context->doc->root) return(NULL);
	if (cur->next != NULL) {
	    cur = cur->next;
	    return(cur);
	}
    } while (cur != NULL);
    return(cur);
}

/**
 * xmlXPathNextPreceding:
 * @ctxt:  the XPath Parser context
 * @cur:  the current node in the traversal
 *
 * Traversal function for the "preceding" direction
 * the preceding axis contains all nodes in the same document as the context
 * node that are before the context node in document order, excluding any
 * ancestors and excluding attribute nodes and namespace nodes; the nodes are
 * ordered in reverse document order
 */
xmlNodePtr
xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
    if (cur == NULL)
        return(ctxt->context->node->prev); /* !!!!!!!!! */
    if (cur->last != NULL) return(cur->last);
    if (cur->prev != NULL) return(cur->prev);
    
    do {
        cur = cur->parent;
	if (cur == NULL) return(NULL);
	if (cur == ctxt->context->doc->root) return(NULL);
	if (cur->prev != NULL) {
	    cur = cur->prev;
	    return(cur);
	}
    } while (cur != NULL);
    return(cur);
}

/**
 * xmlXPathNextNamespace:
 * @ctxt:  the XPath Parser context
 * @cur:  the current attribute in the traversal
 *
 * Traversal function for the "namespace" direction
 * the namespace axis contains the namespace nodes of the context node;
 * the order of nodes on this axis is implementation-defined; the axis will
 * be empty unless the context node is an element
 */
xmlAttrPtr
xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlAttrPtr cur) {
    TODO /* namespace traversal */
    return(NULL);
}

/**
 * xmlXPathNextAttribute:
 * @ctxt:  the XPath Parser context
 * @cur:  the current attribute in the traversal
 *
 * Traversal function for the "attribute" direction
 */
xmlAttrPtr
xmlXPathNextAttribute(xmlXPathParserContextPtr ctxt, xmlAttrPtr cur) {
    if (cur == NULL)
        return(ctxt->context->node->properties);
    return(cur->next);
}

/************************************************************************
 *									*
 *		NodeTest Functions					*
 *									*
 ************************************************************************/

#define NODE_TEST_NONE	0
#define NODE_TEST_TYPE	1
#define NODE_TEST_PI	2
#define NODE_TEST_ALL	3
#define NODE_TEST_NS	4
#define NODE_TEST_NAME	5

#define NODE_TYPE_COMMENT		50
#define NODE_TYPE_TEXT			51
#define NODE_TYPE_PI			52
#define NODE_TYPE_NODE			53

#define IS_FUNCTION			200

/**
 * xmlXPathNodeCollectAndTest:
 * @ctxt:  the XPath Parser context
 * @cur:  the current node to test
 *
 * This is the function implementing a step: based on the current list
 * of nodes, it builds up a new list, looking at all nodes under that
 * axis and selecting them.
 *
 * Returns the new NodeSet resulting from the search.
 */
xmlNodeSetPtr
xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, int axis,
                 int test, int type, const CHAR *prefix, const CHAR *name) {
#ifdef DEBUG_STEP
    int n = 0, t = 0;
#endif
    int i;
    xmlNodeSetPtr ret;
    xmlXPathTraversalFunction next = NULL;
    xmlNodePtr cur = NULL;

    if (ctxt->context->nodelist == NULL) {
	if (ctxt->context->node == NULL) {
	    fprintf(xmlXPathDebug,
	     "xmlXPathNodeCollectAndTest %s:%d : nodelist and node are NULL\n",
	            __FILE__, __LINE__);
	    return(NULL);
	}
        STRANGE
        return(NULL);
    }
#ifdef DEBUG_STEP
    fprintf(xmlXPathDebug, "new step : ");
#endif
    switch (axis) {
        case AXIS_ANCESTOR:
#ifdef DEBUG_STEP
	    fprintf(xmlXPathDebug, "axis 'ancestors' ");
#endif
	    next = xmlXPathNextAncestor; break;
        case AXIS_ANCESTOR_OR_SELF:
#ifdef DEBUG_STEP
	    fprintf(xmlXPathDebug, "axis 'ancestors-or-self' ");
#endif
	    next = xmlXPathNextAncestorOrSelf; break;
        case AXIS_ATTRIBUTE:
#ifdef DEBUG_STEP
	    fprintf(xmlXPathDebug, "axis 'attributes' ");
#endif
	    TODO /* attribute axis */
	    break;
        case AXIS_CHILD:
#ifdef DEBUG_STEP
	    fprintf(xmlXPathDebug, "axis 'child' ");
#endif
	    next = xmlXPathNextChild; break;
        case AXIS_DESCENDANT:
#ifdef DEBUG_STEP
	    fprintf(xmlXPathDebug, "axis 'descendant' ");
#endif
	    next = xmlXPathNextDescendant; break;
        case AXIS_DESCENDANT_OR_SELF:
#ifdef DEBUG_STEP
	    fprintf(xmlXPathDebug, "axis 'descendant-or-self' ");
#endif
	    next = xmlXPathNextDescendantOrSelf; break;
        case AXIS_FOLLOWING:
#ifdef DEBUG_STEP
	    fprintf(xmlXPathDebug, "axis 'following' ");
#endif
	    next = xmlXPathNextFollowing; break;
        case AXIS_FOLLOWING_SIBLING:
#ifdef DEBUG_STEP
	    fprintf(xmlXPathDebug, "axis 'following-siblings' ");
#endif
	    next = xmlXPathNextFollowingSibling; break;
        case AXIS_NAMESPACE:
#ifdef DEBUG_STEP
	    fprintf(xmlXPathDebug, "axis 'namespace' ");
#endif
	    TODO /* namespace axis */
	    break;
        case AXIS_PARENT:
#ifdef DEBUG_STEP
	    fprintf(xmlXPathDebug, "axis 'parent' ");
#endif
	    next = xmlXPathNextParent; break;
        case AXIS_PRECEDING:
#ifdef DEBUG_STEP
	    fprintf(xmlXPathDebug, "axis 'preceding' ");
#endif
	    next = xmlXPathNextPreceding; break;
        case AXIS_PRECEDING_SIBLING:
#ifdef DEBUG_STEP
	    fprintf(xmlXPathDebug, "axis 'preceding-sibling' ");
#endif
	    next = xmlXPathNextPrecedingSibling; break;
        case AXIS_SELF:
#ifdef DEBUG_STEP
	    fprintf(xmlXPathDebug, "axis 'self' ");
#endif
	    next = xmlXPathNextSelf; break;
    }
    if (next == NULL) return(NULL);
    ret = xmlXPathNodeSetCreate(NULL);
#ifdef DEBUG_STEP
    fprintf(xmlXPathDebug, " context contains %d nodes\n",
            ctxt->context->nodelist->nodeNr);
    switch (test) {
	case NODE_TEST_NONE:
	    fprintf(xmlXPathDebug, "           seaching for none !!!\n");
	    break;
	case NODE_TEST_TYPE:
	    fprintf(xmlXPathDebug, "           seaching for type %d\n", type);
	    break;
	case NODE_TEST_PI:
	    fprintf(xmlXPathDebug, "           seaching for PI !!!\n");
	    TODO /* PI search */
	    break;
	case NODE_TEST_ALL:
	    fprintf(xmlXPathDebug, "           seaching for *\n");
	    break;
	case NODE_TEST_NS:
	    fprintf(xmlXPathDebug, "           seaching for namespace %s\n",
	            prefix);
	    break;
	case NODE_TEST_NAME:
	    fprintf(xmlXPathDebug, "           seaching for name %s\n", name);
	    if (prefix != NULL)
		fprintf(xmlXPathDebug, "           with namespace %s\n",
		        prefix);
	    break;
    }
    fprintf(xmlXPathDebug, "Testing : ");
#endif
    for (i = 0;i < ctxt->context->nodelist->nodeNr; i++) {
        ctxt->context->node = ctxt->context->nodelist->nodeTab[i];

	cur = NULL;
	do {
	    cur = next(ctxt, cur);
	    if (cur == NULL) break;
#ifdef DEBUG_STEP
            t++;
            fprintf(xmlXPathDebug, " %s", cur->name);
#endif
	    switch (test) {
                case NODE_TEST_NONE:
		    STRANGE
		    return(NULL);
                case NODE_TEST_TYPE:
		    if (cur->type == type) {
#ifdef DEBUG_STEP
                        n++;
#endif
		        xmlXPathNodeSetAdd(ret, cur);
		    }
		    break;
                case NODE_TEST_PI:
		    TODO /* PI search */
		    break;
                case NODE_TEST_ALL:
		    if (cur->type == XML_ELEMENT_NODE) {
#ifdef DEBUG_STEP
                        n++;
#endif
		        xmlXPathNodeSetAdd(ret, cur);
		    }
		    break;
                case NODE_TEST_NS:
		    TODO /* NS search */
		    break;
                case NODE_TEST_NAME:
		    if (!xmlStrcmp(name, cur->name) && 
			(((prefix == NULL) ||
			  ((cur->ns != NULL) && 
			   (!xmlStrcmp(prefix, cur->ns->href)))))) {
#ifdef DEBUG_STEP
                        n++;
#endif
			xmlXPathNodeSetAdd(ret, cur);
		    }
	            break;
		    
	    }
	} while (cur != NULL);
    }
#ifdef DEBUG_STEP
    fprintf(xmlXPathDebug,
            "\nExamined %d nodes, found %d nodes at that step\n", t, n);
#endif
    return(ret);
}


/************************************************************************
 *									*
 *		Implicit tree core function library			*
 *									*
 ************************************************************************/

/**
 * xmlXPathRoot:
 * @ctxt:  the XPath Parser context
 *
 * Initialize the context to the root of the document
 */
void
xmlXPathRoot(xmlXPathParserContextPtr ctxt) {
    if (ctxt->context->nodelist != NULL)
        xmlXPathFreeNodeSet(ctxt->context->nodelist);
    ctxt->context->node = ctxt->context->doc->root;
    ctxt->context->nodelist = xmlXPathNodeSetCreate(ctxt->context->doc->root);
}

/**
 * xmlXPathSearchPI:
 * @ctxt:  the XPath Parser context
 *
 * Search a processing instruction by name. The name is
 * in the object on the stack.
 */
void
xmlXPathSearchPI(xmlXPathParserContextPtr ctxt, int nargs) {
    TODO /* Search PI */
    CHECK_ARITY(0);
    CHECK_TYPE(XPATH_NUMBER)
}

/************************************************************************
 *									*
 *		The explicit core function library			*
 *http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html#corelib	*
 *									*
 ************************************************************************/


/**
 * xmlXPathLastFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the last() XPath function
 * The last function returns the number of nodes in the context node list.
 */
void
xmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    CHECK_ARITY(0);
    if ((ctxt->context->nodelist == NULL) ||
        (ctxt->context->node == NULL) ||
        (ctxt->context->nodelist->nodeNr == 0)) {
	valuePush(ctxt, xmlXPathNewFloat((double) 0));
    } else {
	valuePush(ctxt, 
	          xmlXPathNewFloat((double) ctxt->context->nodelist->nodeNr));
    }
}

/**
 * xmlXPathPositionFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the position() XPath function
 * The position function returns the position of the context node in the
 * context node list. The first position is 1, and so the last positionr
 * will be equal to last().
 */
void
xmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    int i;

    CHECK_ARITY(0);
    if ((ctxt->context->nodelist == NULL) ||
        (ctxt->context->node == NULL) ||
        (ctxt->context->nodelist->nodeNr == 0)) {
	valuePush(ctxt, xmlXPathNewFloat((double) 0));
    }
    for (i = 0; i < ctxt->context->nodelist->nodeNr;i++) {
        if (ctxt->context->node == ctxt->context->nodelist->nodeTab[i]) {
	    valuePush(ctxt, xmlXPathNewFloat((double) i + 1));
	    return;
	}
    }
    valuePush(ctxt, xmlXPathNewFloat((double) 0));
}

/**
 * xmlXPathCountFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the count() XPath function
 */
void
xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    xmlXPathObjectPtr cur;

    CHECK_ARITY(1);
    CHECK_TYPE(XPATH_NODESET);
    cur = valuePop(ctxt);

    valuePush(ctxt, xmlXPathNewFloat((double) cur->nodesetval->nodeNr));
    xmlXPathFreeObject(cur);
}

/**
 * xmlXPathIdFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the id() XPath function
 * The id function selects elements by their unique ID
 * (see [5.2.1 Unique IDs]). When the argument to id is of type node-set,
 * then the result is the union of the result of applying id to the
 * string value of each of the nodes in the argument node-set. When the
 * argument to id is of any other type, the argument is converted to a
 * string as if by a call to the string function; the string is split
 * into a whitespace-separated list of tokens (whitespace is any sequence
 * of characters matching the production S); the result is a node-set
 * containing the elements in the same document as the context node that
 * have a unique ID equal to any of the tokens in the list.
 */
void
xmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    CHECK_ARITY(1);
    TODO /* Write ID/IDREF support in libxml first */
}

/**
 * xmlXPathLocalPartFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the local-part() XPath function
 * The local-part function returns a string containing the local part
 * of the name of the node in the argument node-set that is first in
 * document order. If the node-set is empty or the first node has no
 * name, an empty string is returned. If the argument is omitted it
 * defaults to the context node.
 */
void
xmlXPathLocalPartFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    xmlXPathObjectPtr cur;

    CHECK_ARITY(1);
    CHECK_TYPE(XPATH_NODESET);
    cur = valuePop(ctxt);

    if (cur->nodesetval->nodeNr == 0) {
	valuePush(ctxt, xmlXPathNewString(""));
    } else {
	int i = 0; /* Should be first in document order !!!!! */
	valuePush(ctxt, xmlXPathNewString(cur->nodesetval->nodeTab[i]->name));
    }
    xmlXPathFreeObject(cur);
}

/**
 * xmlXPathNamespaceFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the namespace() XPath function
 * The namespace function returns a string containing the namespace URI
 * of the expanded name of the node in the argument node-set that is
 * first in document order. If the node-set is empty, the first node has
 * no name, or the expanded name has no namespace URI, an empty string
 * is returned. If the argument is omitted it defaults to the context node.
 */
void
xmlXPathNamespaceFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    xmlXPathObjectPtr cur;

    CHECK_ARITY(1);
    CHECK_TYPE(XPATH_NODESET);
    cur = valuePop(ctxt);

    if (cur->nodesetval->nodeNr == 0) {
	valuePush(ctxt, xmlXPathNewString(""));
    } else {
	int i = 0; /* Should be first in document order !!!!! */

	if (cur->nodesetval->nodeTab[i]->ns == NULL)
	    valuePush(ctxt, xmlXPathNewString(""));
	else
	    valuePush(ctxt, xmlXPathNewString(
		      cur->nodesetval->nodeTab[i]->ns->href));
    }
    xmlXPathFreeObject(cur);
}

/**
 * xmlXPathNameFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the name() XPath function
 * The name function returns a string containing a QName representing
 * the name of the node in the argument node-set that is first in documenti
 * order. The QName must represent the name with respect to the namespace
 * declarations in effect on the node whose name is being represented.
 * Typically, this will be the form in which the name occurred in the XML
 * source. This need not be the case if there are namespace declarations
 * in effect on the node that associate multiple prefixes with the same
 * namespace. However, an implementation may include information about
 * the original prefix in its representation of nodes; in this case, an
 * implementation can ensure that the returned string is always the same
 * as the QName used in the XML source. If the argument it omitted it
 * defaults to the context node.
 * Libxml keep the original prefix so the "real qualified name" used is
 * returned.
 */
void
xmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    xmlXPathObjectPtr cur;

    CHECK_ARITY(1);
    CHECK_TYPE(XPATH_NODESET);
    cur = valuePop(ctxt);

    if (cur->nodesetval->nodeNr == 0) {
	valuePush(ctxt, xmlXPathNewString(""));
    } else {
	int i = 0; /* Should be first in document order !!!!! */

	if (cur->nodesetval->nodeTab[i]->ns == NULL)
	    valuePush(ctxt, xmlXPathNewString(
	                cur->nodesetval->nodeTab[i]->name));
	    
	else {
	    CHAR name[2000];
	    sprintf(name, "%s:%s", cur->nodesetval->nodeTab[i]->ns->prefix,
	            cur->nodesetval->nodeTab[i]->name);
	    valuePush(ctxt, xmlXPathNewString(name));
        }
    }
    xmlXPathFreeObject(cur);
}

/**
 * xmlXPathStringFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the string() XPath function
 * he string function converts an object to a string as follows:
 *    - A node-set is converted to a string by returning the value of
 *      the node in the node-set that is first in document order.
 *      If the node-set is empty, an empty string is returned.
 *    - A number is converted to a string as follows
 *      + NaN is converted to the string NaN 
 *      + positive zero is converted to the string 0 
 *      + negative zero is converted to the string 0 
 *      + positive infinity is converted to the string Infinity 
 *      + negative infinity is converted to the string -Infinity 
 *      + if the number is an integer, the number is represented in
 *        decimal form as a Number with no decimal point and no leading
 *        zeros, preceded by a minus sign (-) if the number is negative
 *      + otherwise, the number is represented in decimal form as a
 *        Number including a decimal point with at least one digit
 *        before the decimal point and at least one digit after the
 *        decimal point, preceded by a minus sign (-) if the number
 *        is negative; there must be no leading zeros before the decimal
 *        point apart possibly from the one required digit immediatelyi
 *        before the decimal point; beyond the one required digit
 *        after the decimal point there must be as many, but only as
 *        many, more digits as are needed to uniquely distinguish the
 *        number from all other IEEE 754 numeric values.
 *    - The boolean false value is converted to the string false.
 *      The boolean true value is converted to the string true.
 */
void
xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    xmlXPathObjectPtr cur;

    CHECK_ARITY(1);
    cur = valuePop(ctxt);
    if (cur == NULL) ERROR(XPATH_INVALID_OPERAND);
    switch (cur->type) {
        case XPATH_NODESET:
	    if (cur->nodesetval->nodeNr == 0) {
		valuePush(ctxt, xmlXPathNewString(""));
	    } else {
		CHAR *res;
	        int i = 0; /* Should be first in document order !!!!! */
		res = xmlNodeGetContent(cur->nodesetval->nodeTab[i]);
		valuePush(ctxt, xmlXPathNewString(res));
		free(res);
	    }
	    xmlXPathFreeObject(cur);
	    return;
	case XPATH_STRING:
	    valuePush(ctxt, cur);
	    return;
        case XPATH_BOOLEAN:
	    if (cur->boolval) valuePush(ctxt, xmlXPathNewString("true"));
	    else valuePush(ctxt, xmlXPathNewString("false"));
	    xmlXPathFreeObject(cur);
	    return;
	case XPATH_NUMBER: {
	    CHAR buf[100];

	    if (isnan(cur->floatval))
	        sprintf(buf, "NaN");
	    else if (isinf(cur->floatval) > 0)
	        sprintf(buf, "+Infinity");
	    else if (isinf(cur->floatval) < 0)
	        sprintf(buf, "-Infinity");
	    else
		sprintf(buf, "%0g", cur->floatval);
	    valuePush(ctxt, xmlXPathNewString(buf));
	    xmlXPathFreeObject(cur);
	    return;
	}
    }
    STRANGE
}

/**
 * xmlXPathStringLengthFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the string-length() XPath function
 * The string-length returns the number of characters in the string
 * (see [3.6 Strings]). If the argument is omitted, it defaults to
 * the context node converted to a string, in other words the value
 * of the context node.
 */
void
xmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    xmlXPathObjectPtr cur;

    if (nargs == 0) {
	if (ctxt->context->node == NULL) {
	    valuePush(ctxt, xmlXPathNewFloat(0));
	} else {
	    CHAR *content;

	    content = xmlNodeGetContent(ctxt->context->node);
	    valuePush(ctxt, xmlXPathNewFloat(xmlStrlen(content)));
	    free(content);
	}
	return;
    }
    CHECK_ARITY(1);
    CHECK_TYPE(XPATH_STRING);
    cur = valuePop(ctxt);
    valuePush(ctxt, xmlXPathNewFloat(xmlStrlen(cur->stringval)));
    xmlXPathFreeObject(cur);
}

/**
 * xmlXPathConcatFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the concat() XPath function
 * The concat function returns the concatenation of its arguments.
 */
void
xmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    xmlXPathObjectPtr cur, new;
    CHAR *tmp;

    if (nargs < 2) {
	CHECK_ARITY(2);
    }

    cur = valuePop(ctxt);
    if ((cur == NULL) || (cur->type != XPATH_STRING)) {
        xmlXPathFreeObject(cur);
	return;
    }
    nargs--;

    while (nargs > 0) {
	new = valuePop(ctxt);
	if ((new == NULL) || (new->type != XPATH_STRING)) {
	    xmlXPathFreeObject(new);
	    xmlXPathFreeObject(cur);
	    ERROR(XPATH_INVALID_TYPE);
	}
	tmp = xmlStrcat(new->stringval, cur->stringval);
	new->stringval = cur->stringval;
	cur->stringval = tmp;

	xmlXPathFreeObject(new);
	nargs--;
    }
    valuePush(ctxt, cur);
}

/**
 * xmlXPathContainsFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the contains() XPath function
 * The contains function returns true if the first argument string
 * contains the second argument string, and otherwise returns false.
 */
void
xmlXPathContainsFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    xmlXPathObjectPtr hay, needle;

    CHECK_ARITY(2);
    CHECK_TYPE(XPATH_STRING);
    needle = valuePop(ctxt);
    hay = valuePop(ctxt);
    if ((hay == NULL) || (hay->type != XPATH_STRING)) {
        xmlXPathFreeObject(hay);
        xmlXPathFreeObject(needle);
	ERROR(XPATH_INVALID_TYPE);
    }
    if (xmlStrstr(hay->stringval, needle->stringval))
        valuePush(ctxt, xmlXPathNewBoolean(1));
    else
        valuePush(ctxt, xmlXPathNewBoolean(0));
    xmlXPathFreeObject(hay);
    xmlXPathFreeObject(needle);
}

/**
 * xmlXPathStartsWithFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the starts-with() XPath function
 * The starts-with function returns true if the first argument string
 * starts with the second argument string, and otherwise returns false.
 */
void
xmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    xmlXPathObjectPtr hay, needle;
    int n;

    CHECK_ARITY(2);
    CHECK_TYPE(XPATH_STRING);
    needle = valuePop(ctxt);
    hay = valuePop(ctxt);
    if ((hay == NULL) || (hay->type != XPATH_STRING)) {
        xmlXPathFreeObject(hay);
        xmlXPathFreeObject(needle);
	ERROR(XPATH_INVALID_TYPE);
    }
    n = xmlStrlen(needle->stringval);
    if (xmlStrncmp(hay->stringval, needle->stringval, n))
        valuePush(ctxt, xmlXPathNewBoolean(0));
    else
        valuePush(ctxt, xmlXPathNewBoolean(1));
    xmlXPathFreeObject(hay);
    xmlXPathFreeObject(needle);
}

/**
 * xmlXPathSubstringFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the substring() XPath function
 * The substring function returns the substring of the first argument
 * starting at the position specified in the second argument with
 * length specified in the third argument. For example,
 * substring("12345",2,3) returns "234". If the third argument is not
 * specified, it returns the substring starting at the position specified
 * in the second argument and continuing to the end of the string. For
 * example, substring("12345",2) returns "2345".  More precisely, each
 * character in the string (see [3.6 Strings]) is considered to have a
 * numeric position: the position of the first character is 1, the position
 * of the second character is 2 and so on. The returned substring contains
 * those characters for which the position of the character is greater than
 * or equal to the second argument and, if the third argument is specified,
 * less than the sum of the second and third arguments; the comparisons
 * and addition used for the above follow the standard IEEE 754 rules. Thus:
 *  - substring("12345", 1.5, 2.6) returns "234" 
 *  - substring("12345", 0, 3) returns "12" 
 *  - substring("12345", 0 div 0, 3) returns "" 
 *  - substring("12345", 1, 0 div 0) returns "" 
 *  - substring("12345", -42, 1 div 0) returns "12345" 
 *  - substring("12345", -1 div 0, 1 div 0) returns "" 
 */
void
xmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    xmlXPathObjectPtr str, start, len;
    double le, in;
    int i, l;
    CHAR *ret;

    /* 
     * Conformance needs to be checked !!!!!
     */
    if (nargs < 2) {
	CHECK_ARITY(2);
    }
    if (nargs > 3) {
	CHECK_ARITY(3);
    }
    if (nargs == 3) {
	CHECK_TYPE(XPATH_NUMBER);
	len = valuePop(ctxt);
	le = len->floatval;
        xmlXPathFreeObject(len);
    } else {
	le = 2000000000;
    }
    CHECK_TYPE(XPATH_NUMBER);
    start = valuePop(ctxt);
    in = start->floatval;
    xmlXPathFreeObject(start);
    CHECK_TYPE(XPATH_STRING);
    str = valuePop(ctxt);
    le += in;

    /* integer index of the first char */
    i = in;
    if (((double)i) != in) i++;
    
    /* integer index of the last char */
    l = le;
    if (((double)l) != le) l++;

    /* back to a zero based len */
    i--;
    l--;

    /* check against the string len */
    if (l > 1024) {
        l = xmlStrlen(str->stringval);
    }
    if (i < 0) {
        i = 0;
    }

    /* number of chars to copy */
    l -= i;

    ret = xmlStrsub(str->stringval, i, l);
    if (ret == NULL)
	valuePush(ctxt, xmlXPathNewString(""));
    else {
	valuePush(ctxt, xmlXPathNewString(ret));
	free(ret);
    }
    xmlXPathFreeObject(str);
}

/**
 * xmlXPathSubstringBeforeFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the substring-before() XPath function
 * The substring-before function returns the substring of the first
 * argument string that precedes the first occurrence of the second
 * argument string in the first argument string, or the empty string
 * if the first argument string does not contain the second argument
 * string. For example, substring-before("1999/04/01","/") returns 1999.
 */
void
xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    CHECK_ARITY(2);
    TODO /* substring before */
}

/**
 * xmlXPathSubstringAfterFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the substring-after() XPath function
 * The substring-after function returns the substring of the first
 * argument string that follows the first occurrence of the second
 * argument string in the first argument string, or the empty stringi
 * if the first argument string does not contain the second argument
 * string. For example, substring-after("1999/04/01","/") returns 04/01,
 * and substring-after("1999/04/01","19") returns 99/04/01.
 */
void
xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    CHECK_ARITY(2);
    TODO /* substring after */
}

/**
 * xmlXPathNormalizeFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the normalize() XPath function
 * The normalize function returns the argument string with white
 * space normalized by stripping leading and trailing whitespace
 * and replacing sequences of whitespace characters by a single
 * space. Whitespace characters are the same allowed by the S production
 * in XML. If the argument is omitted, it defaults to the context
 * node converted to a string, in other words the value of the context node.
 */
void
xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    CHECK_ARITY(1);
    TODO /* normalize isn't as boring as translate, but pretty much */
}

/**
 * xmlXPathTranslateFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the translate() XPath function
 * The translate function returns the first argument string with
 * occurrences of characters in the second argument string replaced
 * by the character at the corresponding position in the third argument
 * string. For example, translate("bar","abc","ABC") returns the string
 * BAr. If there is a character in the second argument string with no
 * character at a corresponding position in the third argument string
 * (because the second argument string is longer than the third argument
 * string), then occurrences of that character in the first argument
 * string are removed. For example, translate("--aaa--","abc-","ABC")
 * returns "AAA". If a character occurs more than once in second
 * argument string, then the first occurrence determines the replacement
 * character. If the third argument string is longer than the second
 * argument string, then excess characters are ignored.
 */
void
xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    CHECK_ARITY(3);
    TODO /* translate is boring, waiting for UTF-8 representation too */
}

/**
 * xmlXPathBooleanFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the boolean() XPath function
 * he boolean function converts its argument to a boolean as follows:
 *    - a number is true if and only if it is neither positive or
 *      negative zero nor NaN
 *    - a node-set is true if and only if it is non-empty
 *    - a string is true if and only if its length is non-zero
 */
void
xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    xmlXPathObjectPtr cur;
    int res = 0;

    CHECK_ARITY(1);
    cur = valuePop(ctxt);
    if (cur == NULL) ERROR(XPATH_INVALID_OPERAND);
    switch (cur->type) {
        case XPATH_NODESET:
	    if ((cur->nodesetval == NULL) ||
	        (cur->nodesetval->nodeNr == 0)) res = 0;
	    else 
	        res = 1;
	    break;
	case XPATH_STRING:
	    if ((cur->stringval == NULL) ||
	        (cur->stringval[0] == 0)) res = 0;
	    else 
	        res = 1;
	    break;
        case XPATH_BOOLEAN:
	    valuePush(ctxt, cur);
	    return;
	case XPATH_NUMBER:
	    if (cur->floatval) res = 1;
	    break;
	default:
	    STRANGE
    }
    xmlXPathFreeObject(cur);
    valuePush(ctxt, xmlXPathNewBoolean(res));
}

/**
 * xmlXPathNotFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the not() XPath function
 * The not function returns true if its argument is false,
 * and false otherwise.
 */
void
xmlXPathNotFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    CHECK_ARITY(1);
    CHECK_TYPE(XPATH_BOOLEAN);
    ctxt->value->boolval = ! ctxt->value->boolval;
}

/**
 * xmlXPathTrueFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the true() XPath function
 */
void
xmlXPathTrueFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    CHECK_ARITY(0);
    valuePush(ctxt, xmlXPathNewBoolean(1));
}

/**
 * xmlXPathFalseFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the false() XPath function
 */
void
xmlXPathFalseFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    CHECK_ARITY(0);
    valuePush(ctxt, xmlXPathNewBoolean(0));
}

/**
 * xmlXPathLangFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the lang() XPath function
 * The lang function returns true or false depending on whether the
 * language of the context node as specified by xml:lang attributes
 * is the same as or is a sublanguage of the language specified by
 * the argument string. The language of the context node is determined
 * by the value of the xml:lang attribute on the context node, or, if
 * the context node has no xml:lang attribute, by the value of the
 * xml:lang attribute on the nearest ancestor of the context node that
 * has an xml:lang attribute. If there is no such attribute, then lang
 * returns false. If there is such an attribute, then lang returns
 * true if the attribute value is equal to the argument ignoring case,
 * or if there is some suffix starting with - such that the attribute
 * value is equal to the argument ignoring that suffix of the attribute
 * value and ignoring case.
 */
void
xmlXPathLangFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    CHECK_ARITY(0);
    TODO /* Write down xml:lang support in libxml first */
}

/**
 * xmlXPathNumberFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the number() XPath function
 */
void
xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    xmlXPathObjectPtr cur;
    double res;

    CHECK_ARITY(1);
    cur = valuePop(ctxt);
    switch (cur->type) {
        case XPATH_NODESET:
	    valuePush(ctxt, cur);
	    xmlXPathStringFunction(ctxt, 1);
	    cur = valuePop(ctxt);
	case XPATH_STRING:
	    res = xmlXPathStringEvalNumber(cur->stringval);
	    valuePush(ctxt, xmlXPathNewFloat(res));
	    xmlXPathFreeObject(cur);
	    return;
        case XPATH_BOOLEAN:
	    if (cur->boolval) valuePush(ctxt, xmlXPathNewFloat(1.0));
	    else valuePush(ctxt, xmlXPathNewFloat(0.0));
	    xmlXPathFreeObject(cur);
	    return;
	case XPATH_NUMBER:
	    valuePush(ctxt, cur);
	    return;
    }
    STRANGE
}

/**
 * xmlXPathSumFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the sum() XPath function
 * The sum function returns the sum of the values of the nodes in
 * the argument node-set.
 */
void
xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    CHECK_ARITY(1);
    TODO /* BUG Sum : don't understand the definition */
}

/**
 * xmlXPathFloorFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the floor() XPath function
 * The floor function returns the largest (closest to positive infinity)
 * number that is not greater than the argument and that is an integer.
 */
void
xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    CHECK_ARITY(1);
    CHECK_TYPE(XPATH_NUMBER);
    /* floor(0.999999999999) => 1.0 !!!!!!!!!!! */
    ctxt->value->floatval = (double)((int) ctxt->value->floatval);
}

/**
 * xmlXPathCeilingFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the ceiling() XPath function
 * The ceiling function returns the smallest (closest to negative infinity)
 * number that is not less than the argument and that is an integer.
 */
void
xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    double f;

    CHECK_ARITY(1);
    CHECK_TYPE(XPATH_NUMBER);
    f = (double)((int) ctxt->value->floatval);
    if (f != ctxt->value->floatval)
	ctxt->value->floatval = f + 1;
}

/**
 * xmlXPathRoundFunction:
 * @ctxt:  the XPath Parser context
 *
 * Implement the round() XPath function
 * The round function returns the number that is closest to the
 * argument and that is an integer. If there are two such numbers,
 * then the one that is even is returned.
 */
void
xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    double f;

    CHECK_ARITY(1);
    CHECK_TYPE(XPATH_NUMBER);
    /* round(0.50000001) => 0  !!!!! */
    f = (double)((int) ctxt->value->floatval);
    if (ctxt->value->floatval < f + 0.5)
        ctxt->value->floatval = f;
    else if (ctxt->value->floatval == f + 0.5)
        ctxt->value->floatval = f; /* !!!! Not following the spec here */
    else 
        ctxt->value->floatval = f + 1;
}

/************************************************************************
 *									*
 *			The Parser					*
 *									*
 ************************************************************************/

/*
 * a couple of forward declarations since we use a recursive call based
 * implementation.
 */
void xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt);
void xmlXPathEvalPredicate(xmlXPathParserContextPtr ctxt);
void xmlXPathEvalLocationPath(xmlXPathParserContextPtr ctxt);
void xmlXPathEvalRelativeLocationPath(xmlXPathParserContextPtr ctxt);

/**
 * xmlXPathParseNCName:
 * @ctxt:  the XPath Parser context
 *
 * parse an XML namespace non qualified name.
 *
 * [NS 3] NCName ::= (Letter | '_') (NCNameChar)*
 *
 * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
 *                       CombiningChar | Extender
 *
 * Returns the namespace name or NULL
 */

CHAR *
xmlXPathParseNCName(xmlXPathParserContextPtr ctxt) {
    const CHAR *q;
    CHAR *ret = NULL;

    if (!IS_LETTER(CUR) && (CUR != '_')) return(NULL);
    q = NEXT;

    while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
           (CUR == '.') || (CUR == '-') ||
	   (CUR == '_') ||
	   (IS_COMBINING(CUR)) ||
	   (IS_EXTENDER(CUR)))
	NEXT;
    
    ret = xmlStrndup(q, CUR_PTR - q);

    return(ret);
}

/**
 * xmlXPathParseQName:
 * @ctxt:  the XPath Parser context
 * @prefix:  a CHAR ** 
 *
 * parse an XML qualified name
 *
 * [NS 5] QName ::= (Prefix ':')? LocalPart
 *
 * [NS 6] Prefix ::= NCName
 *
 * [NS 7] LocalPart ::= NCName
 *
 * Returns the function returns the local part, and prefix is updated
 *   to get the Prefix if any.
 */

CHAR *
xmlXPathParseQName(xmlXPathParserContextPtr ctxt, CHAR **prefix) {
    CHAR *ret = NULL;

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

/**
 * xmlXPathStringEvalNumber:
 * @str:  A string to scan
 *
 *  [30]   Number ::=   Digits ('.' Digits)?
 *                    | '.' Digits 
 *  [31]   Digits ::=   [0-9]+
 *
 * Parse and evaluate a Number in the string
 *
 * BUG: "1.' is not valid ... James promised correction
 *       as Digits ('.' Digits?)?
 *
 * Returns the double value.
 */
double
xmlXPathStringEvalNumber(const CHAR *str) {
    const CHAR *cur = str;
    double ret = 0.0;
    double mult = 1;
    int ok = 0;

    while (*cur == ' ') cur++;
    if ((*cur != '.') && ((*cur < '0') || (*cur > '9'))) {
        return(xmlXPathNAN);
    }
    while ((*cur >= '0') && (*cur <= '9')) {
        ret = ret * 10 + (*cur - '0');
	ok = 1;
	cur++;
    }
    if (*cur == '.') {
        cur++;
	if (((*cur < '0') || (*cur > '9')) && (!ok)) {
	    return(xmlXPathNAN);
	}
	while ((*cur >= '0') && (*cur <= '9')) {
	    mult /= 10;
	    ret = ret  + (*cur - '0') * mult;
	    cur++;
	}
    }
    while (*cur == ' ') cur++;
    if (*cur != 0) return(xmlXPathNAN);
    return(ret);
}

/**
 * xmlXPathEvalNumber:
 * @ctxt:  the XPath Parser context
 *
 *  [30]   Number ::=   Digits ('.' Digits)?
 *                    | '.' Digits 
 *  [31]   Digits ::=   [0-9]+
 *
 * Parse and evaluate a Number, then push it on the stack
 *
 * BUG: "1.' is not valid ... James promised correction
 *       as Digits ('.' Digits?)?
 */
void
xmlXPathEvalNumber(xmlXPathParserContextPtr ctxt) {
    double ret = 0.0;
    double mult = 1;
    int ok = 0;

    CHECK_ERROR;
    if ((CUR != '.') && ((CUR < '0') || (CUR > '9'))) {
        ERROR(XPATH_NUMBER_ERROR);
    }
    while ((CUR >= '0') && (CUR <= '9')) {
        ret = ret * 10 + (CUR - '0');
	ok = 1;
	NEXT;
    }
    if (CUR == '.') {
        NEXT;
	if (((CUR < '0') || (CUR > '9')) && (!ok)) {
	     ERROR(XPATH_NUMBER_ERROR);
	}
	while ((CUR >= '0') && (CUR <= '9')) {
	    mult /= 10;
	    ret = ret  + (CUR - '0') * mult;
	    NEXT;
	}
    }
    valuePush(ctxt, xmlXPathNewFloat(ret));
}

/**
 * xmlXPathEvalLiteral:
 * @ctxt:  the XPath Parser context
 *
 * Parse a Literal and push it on the stack.
 *
 *  [29]   Literal ::=   '"' [^"]* '"'
 *                    | "'" [^']* "'"
 *
 * TODO: memory allocation could be improved.
 */
void
xmlXPathEvalLiteral(xmlXPathParserContextPtr ctxt) {
    const CHAR *q;
    CHAR *ret = NULL;

    if (CUR == '"') {
        NEXT;
	q = CUR_PTR;
	while ((IS_CHAR(CUR)) && (CUR != '"'))
	    NEXT;
	if (!IS_CHAR(CUR)) {
	    ERROR(XPATH_UNFINISHED_LITERAL_ERROR);
	} else {
	    ret = xmlStrndup(q, CUR_PTR - q);
	    NEXT;
        }
    } else if (CUR == '\'') {
        NEXT;
	q = CUR_PTR;
	while ((IS_CHAR(CUR)) && (CUR != '\''))
	    NEXT;
	if (!IS_CHAR(CUR)) {
	    ERROR(XPATH_UNFINISHED_LITERAL_ERROR);
	} else {
	    ret = xmlStrndup(q, CUR_PTR - q);
	    NEXT;
        }
    } else {
	ERROR(XPATH_START_LITERAL_ERROR);
    }
    if (ret == NULL) return;
    valuePush(ctxt, xmlXPathNewString(ret));
    free(ret);
}

/**
 * xmlXPathEvalVariableReference:
 * @ctxt:  the XPath Parser context
 *
 * Parse a VariableReference, evaluate it and push it on the stack.
 *
 * The variable bindings consist of a mapping from variable names
 * to variable values. The value of a variable is an object, which
 * of any of the types that are possible for the value of an expression,
 * and may also be of additional types not specified here.
 *
 * Early evaluation is possible since:
 * The variable bindings [...] used to evaluate a subexpression are
 * always the same as those used to evaluate the containing expression. 
 *
 *  [36]   VariableReference ::=   '$' QName 
 */
void
xmlXPathEvalVariableReference(xmlXPathParserContextPtr ctxt) {
    CHAR *name;
    CHAR *prefix;
    xmlXPathObjectPtr value;

    if (CUR != '$') {
	ERROR(XPATH_VARIABLE_REF_ERROR);
    }
    name = xmlXPathParseQName(ctxt, &prefix);
    if (name == NULL) {
	ERROR(XPATH_VARIABLE_REF_ERROR);
    }
    value = xmlXPathVariablelookup(ctxt, prefix, name);
    if (value == NULL) {
	ERROR(XPATH_UNDEF_VARIABLE_ERROR);
    }
    valuePush(ctxt, value);
    if (prefix != NULL) free(prefix);
    free(name);
}

 
/**
 * xmlXPathFunctionLookup:
 * @ctxt:  the XPath Parser context
 * @name:  a name string
 *
 * Search for a function of the given name
 *
 *  [35]   FunctionName ::=   QName - NodeType 
 *
 * TODO: for the moment the list is hardcoded from the spec !!!!
 *
 * Returns the xmlXPathFunction if found, or NULL otherwise
 */
xmlXPathFunction
xmlXPathIsFunction(xmlXPathParserContextPtr ctxt, CHAR *name) {
    switch (name[0]) {
        case 'b':
	    if (!xmlStrcmp(name, "boolean"))
	        return(xmlXPathBooleanFunction);
	    break;
        case 'c':
	    if (!xmlStrcmp(name, "ceiling"))
	        return(xmlXPathCeilingFunction);
	    if (!xmlStrcmp(name, "count"))
	        return(xmlXPathCountFunction);
	    if (!xmlStrcmp(name, "concat"))
	        return(xmlXPathConcatFunction);
	    if (!xmlStrcmp(name, "contains"))
	        return(xmlXPathContainsFunction);
	    break;
        case 'i':
	    if (!xmlStrcmp(name, "id"))
	        return(xmlXPathIdFunction);
	    break;
        case 'f':
	    if (!xmlStrcmp(name, "false"))
	        return(xmlXPathFalseFunction);
	    if (!xmlStrcmp(name, "floor"))
	        return(xmlXPathFloorFunction);
	    break;
        case 'l':
	    if (!xmlStrcmp(name, "last"))
	        return(xmlXPathLastFunction);
	    if (!xmlStrcmp(name, "lang"))
	        return(xmlXPathLangFunction);
	    if (!xmlStrcmp(name, "local-part"))
	        return(xmlXPathLocalPartFunction);
	    break;
        case 'n':
	    if (!xmlStrcmp(name, "not"))
	        return(xmlXPathNotFunction);
	    if (!xmlStrcmp(name, "name"))
	        return(xmlXPathNameFunction);
	    if (!xmlStrcmp(name, "namespace"))
	        return(xmlXPathNamespaceFunction);
	    if (!xmlStrcmp(name, "normalize"))
	        return(xmlXPathNormalizeFunction);
	    if (!xmlStrcmp(name, "number"))
	        return(xmlXPathNumberFunction);
	    break;
        case 'p':
	    if (!xmlStrcmp(name, "position"))
	        return(xmlXPathPositionFunction);
	    break;
        case 'r':
	    if (!xmlStrcmp(name, "round"))
	        return(xmlXPathRoundFunction);
	    break;
        case 's':
	    if (!xmlStrcmp(name, "string"))
	        return(xmlXPathStringFunction);
	    if (!xmlStrcmp(name, "string-length"))
	        return(xmlXPathStringLengthFunction);
	    if (!xmlStrcmp(name, "starts-with"))
	        return(xmlXPathStartsWithFunction);
	    if (!xmlStrcmp(name, "substring"))
	        return(xmlXPathSubstringFunction);
	    if (!xmlStrcmp(name, "substring-before"))
	        return(xmlXPathSubstringBeforeFunction);
	    if (!xmlStrcmp(name, "substring-after"))
	        return(xmlXPathSubstringAfterFunction);
	    if (!xmlStrcmp(name, "sum"))
	        return(xmlXPathSumFunction);
	    break;
        case 't':
	    if (!xmlStrcmp(name, "true"))
	        return(xmlXPathTrueFunction);
	    if (!xmlStrcmp(name, "translate"))
	        return(xmlXPathTranslateFunction);
	    break;
    }
    return(NULL);
}

/**
 * xmlXPathEvalLocationPathName:
 * @ctxt:  the XPath Parser context
 * @name:  a name string
 *
 * Various names in the beginning of a LocationPath expression
 * indicate whether that's an Axis, a node type, 
 *
 *  [6]   AxisName ::=   'ancestor'
 *               | 'ancestor-or-self'
 *               | 'attribute'
 *               | 'child'
 *               | 'descendant'
 *               | 'descendant-or-self'
 *               | 'following'
 *               | 'following-sibling'
 *               | 'namespace'
 *               | 'parent'
 *               | 'preceding'
 *               | 'preceding-sibling'
 *               | 'self'
 *  [38]   NodeType ::=   'comment'
 *                    | 'text'
 *                    | 'processing-instruction'
 *                    | 'node'
 */
int
xmlXPathGetNameType(xmlXPathParserContextPtr ctxt, CHAR *name) {
    switch (name[0]) {
        case 'a':
	    if (!xmlStrcmp(name, "ancestor")) return(AXIS_ANCESTOR);
	    if (!xmlStrcmp(name, "ancestor-or-self")) return(AXIS_ANCESTOR_OR_SELF);
            if (!xmlStrcmp(name, "attribute")) return(AXIS_ATTRIBUTE);
	    break;
        case 'c':
            if (!xmlStrcmp(name, "child")) return(AXIS_CHILD);
            if (!xmlStrcmp(name, "comment")) return(NODE_TYPE_COMMENT);
	    break;
        case 'd':
            if (!xmlStrcmp(name, "descendant")) return(AXIS_DESCENDANT);
            if (!xmlStrcmp(name, "descendant-or-self")) return(AXIS_DESCENDANT_OR_SELF);
	    break;
        case 'f':
            if (!xmlStrcmp(name, "following")) return(AXIS_FOLLOWING);
            if (!xmlStrcmp(name, "following-sibling")) return(AXIS_FOLLOWING_SIBLING);
	    break;
        case 'n':
            if (!xmlStrcmp(name, "namespace")) return(AXIS_NAMESPACE);
            if (!xmlStrcmp(name, "node")) return(NODE_TYPE_NODE);
	    break;
        case 'p':
            if (!xmlStrcmp(name, "parent")) return(AXIS_PARENT);
            if (!xmlStrcmp(name, "preceding")) return(AXIS_PRECEDING);
            if (!xmlStrcmp(name, "preceding-sibling")) return(AXIS_PRECEDING_SIBLING);
            if (!xmlStrcmp(name, "processing-instruction")) return(NODE_TYPE_PI);
	    break;
        case 's':
            if (!xmlStrcmp(name, "self")) return(AXIS_SELF);
	    break;
        case 't':
            if (!xmlStrcmp(name, "text")) return(NODE_TYPE_TEXT);
	    break;
    }
    if (xmlXPathIsFunction(ctxt, name)) return(IS_FUNCTION);
    return(0);
}
 
/**
 * xmlXPathEvalFunctionCall:
 * @ctxt:  the XPath Parser context
 *
 *  [16]   FunctionCall ::=   FunctionName '(' ( Argument ( ',' Argument)*)? ')'
 *  [17]   Argument ::=   Expr 
 *
 * Parse and evaluate a function call, the evaluation of all arguments are
 * pushed on the stack
 */
void
xmlXPathEvalFunctionCall(xmlXPathParserContextPtr ctxt) {
    CHAR *name;
    CHAR *prefix;
    xmlXPathFunction func;
    int nbargs = 0;

    name = xmlXPathParseQName(ctxt, &prefix);
    if (name == NULL) {
	ERROR(XPATH_EXPR_ERROR);
    }
    func = xmlXPathIsFunction(ctxt, name);
    if (func == NULL) {
        free(name);
	ERROR(XPATH_UNKNOWN_FUNC_ERROR);
    }
#ifdef DEBUG_EXPR
    fprintf(xmlXPathDebug, "Calling function %s\n", name);
#endif

    if (CUR != '(') {
        free(name);
	ERROR(XPATH_EXPR_ERROR);
    }
    NEXT;

    while (CUR != ')') {
        xmlXPathEvalExpr(ctxt);
	nbargs++;
	if (CUR == ')') break;
	if (CUR != ',') {
	    free(name);
	    ERROR(XPATH_EXPR_ERROR);
	}
	NEXT;
    }
    NEXT;
    free(name);
    func(ctxt, nbargs);
}

/**
 * xmlXPathEvalPrimaryExpr:
 * @ctxt:  the XPath Parser context
 *
 *  [15]   PrimaryExpr ::=   VariableReference 
 *                | '(' Expr ')'
 *                | Literal 
 *                | Number 
 *                | FunctionCall 
 *
 * Parse and evaluate a primary expression, then push the result on the stack
 */
void
xmlXPathEvalPrimaryExpr(xmlXPathParserContextPtr ctxt) {
    if (CUR == '$') xmlXPathEvalVariableReference(ctxt);
    else if (CUR == '(') {
        NEXT;
        xmlXPathEvalExpr(ctxt);
	if (CUR != ')') {
	    ERROR(XPATH_EXPR_ERROR);
	}
	NEXT;
    } else if (IS_DIGIT(CUR)) {
        xmlXPathEvalNumber(ctxt);
    } else if ((CUR == '\'') || (CUR == '"')) {
        xmlXPathEvalLiteral(ctxt);
    } else {
        xmlXPathEvalFunctionCall(ctxt);
    }
}

/**
 * xmlXPathEvalFilterExpr:
 * @ctxt:  the XPath Parser context
 *
 *  [20]   FilterExpr ::=   PrimaryExpr 
 *               | FilterExpr Predicate 
 *
 * Parse and evaluate a filter expression, then push the result on the stack
 * Square brackets are used to filter expressions in the same way that
 * they are used in location paths. It is an error if the expression to
 * be filtered does not evaluate to a node-set. The context node list
 * used for evaluating the expression in square brackets is the node-set
 * to be filtered listed in document order.
 */

void
xmlXPathEvalFilterExpr(xmlXPathParserContextPtr ctxt) {
    /****
    xmlNodeSetPtr oldset = NULL;
    xmlXPathObjectPtr arg;
     ****/

    xmlXPathEvalPrimaryExpr(ctxt);
    CHECK_ERROR;
    
    if (CUR != '[') return;

    CHECK_TYPE(XPATH_NODESET);

    /******
    TODO:  transition from PathExpr to Expr using paths ...
    arg = valuePop(ctxt);
    oldset = ctxt->context->nodeset;
    ctxt->context->nodeset = arg->nodesetval;
     ******/

    while (CUR == '[') {
	xmlXPathEvalPredicate(ctxt);
    }

    
}

/**
 * xmlXPathEvalPathExpr:
 * @ctxt:  the XPath Parser context
 *
 *  [19]   PathExpr ::=   LocationPath 
 *               | FilterExpr 
 *               | FilterExpr '/' RelativeLocationPath 
 *               | FilterExpr '//' RelativeLocationPath 
 *
 * Parse and evaluate a path expression, then push the result on the stack
 * The / operator and // operators combine an arbitrary expression
 * and a relative location path. It is an error if the expression
 * does not evaluate to a node-set.
 * The / operator does composition in the same way as when / is
 * used in a location path. As in location paths, // is short for
 * /descendant-or-self::node()/.
 */

void
xmlXPathEvalPathExpr(xmlXPathParserContextPtr ctxt) {
    xmlNodeSetPtr newset = NULL;

    /*
     * TODO: FilterExpr => PrimaryExpr => FunctionName is possible too
     *       so we may have to parse a name here, and depending on whether
     *       it's a function name or not parse a FilterExpr or a LocationPath
     *   !!!!!!!!!!!! See NOTE1
     */

    if ((CUR == '$') || (CUR == '(') || (IS_DIGIT(CUR)) ||
        (CUR == '\'') || (CUR == '"')) {
	xmlXPathEvalFilterExpr(ctxt);
	CHECK_ERROR;
	if ((CUR == '/') && (NXT(1) == '/')) {
	    SKIP(2);
	    if (ctxt->context->nodelist == NULL) {
		STRANGE
		xmlXPathRoot(ctxt);
	    }
	    newset = xmlXPathNodeCollectAndTest(ctxt, AXIS_DESCENDANT_OR_SELF,
			     NODE_TEST_TYPE, XML_ELEMENT_NODE, NULL, NULL);
	    if (ctxt->context->nodelist != NULL)
		xmlXPathFreeNodeSet(ctxt->context->nodelist);
	    ctxt->context->nodelist = newset;
	    ctxt->context->node = NULL;
	    xmlXPathEvalRelativeLocationPath(ctxt);
	} else if (CUR == '/') {
	    xmlXPathEvalRelativeLocationPath(ctxt);
	}
    } else {
        xmlXPathEvalLocationPath(ctxt);
    }
}

/**
 * xmlXPathEvalUnionExpr:
 * @ctxt:  the XPath Parser context
 *
 *  [18]   UnionExpr ::=   PathExpr 
 *               | UnionExpr '|' PathExpr 
 *
 * Parse and evaluate an union expression, then push the result on the stack
 */

void
xmlXPathEvalUnionExpr(xmlXPathParserContextPtr ctxt) {
    xmlXPathEvalPathExpr(ctxt);
    CHECK_ERROR;
    if (CUR == '|') {
	xmlNodeSetPtr old = ctxt->context->nodelist;

	xmlXPathEvalPathExpr(ctxt);

	if (ctxt->context->nodelist == NULL)
	    ctxt->context->nodelist = old;
	else {
	    ctxt->context->nodelist = 
	        xmlXPathNodeSetMerge(ctxt->context->nodelist, old);
	    xmlXPathFreeNodeSet(old);
	}
    }
}

/**
 * xmlXPathEvalUnaryExpr:
 * @ctxt:  the XPath Parser context
 *
 *  [27]   UnaryExpr ::=   UnionExpr 
 *                   | '-' UnaryExpr 
 *
 * Parse and evaluate an unary expression, then push the result on the stack
 */

void
xmlXPathEvalUnaryExpr(xmlXPathParserContextPtr ctxt) {
    int minus = 0;

    if (CUR == '-') {
        minus = 1;
	NEXT;
    }
    /* xmlXPathEvalUnionExpr(ctxt); NOTE1 !!! */
    xmlXPathEvalPrimaryExpr(ctxt);
    CHECK_ERROR;
    if (minus) {
        xmlXPathValueFlipSign(ctxt);
    }
}

/**
 * xmlXPathEvalMultiplicativeExpr:
 * @ctxt:  the XPath Parser context
 *
 *  [26]   MultiplicativeExpr ::=   UnaryExpr 
 *                   | MultiplicativeExpr MultiplyOperator UnaryExpr 
 *                   | MultiplicativeExpr 'div' UnaryExpr 
 *                   | MultiplicativeExpr 'mod' UnaryExpr 
 *  [34]   MultiplyOperator ::=   '*'
 *
 * Parse and evaluate an Additive expression, then push the result on the stack
 */

void
xmlXPathEvalMultiplicativeExpr(xmlXPathParserContextPtr ctxt) {
    xmlXPathEvalUnaryExpr(ctxt);
    CHECK_ERROR;
    while ((CUR == '*') || 
           ((CUR == 'd') && (NXT(1) == 'i') && (NXT(2) == 'v')) ||
           ((CUR == 'm') && (NXT(1) == 'o') && (NXT(2) == 'd'))) {
	int op = -1;

        if (CUR == '*') {
	    op = 0;
	    NEXT;
	} else if (CUR == 'd') {
	    op = 1;
	    SKIP(3);
	} else if (CUR == 'm') {
	    op = 2;
	    SKIP(3);
	}
        xmlXPathEvalUnaryExpr(ctxt);
	CHECK_ERROR;
	switch (op) {
	    case 0:
	        xmlXPathMultValues(ctxt);
		break;
	    case 1:
	        xmlXPathDivValues(ctxt);
		break;
	    case 2:
	        xmlXPathModValues(ctxt);
		break;
	}
    }
}

/**
 * xmlXPathEvalAdditiveExpr:
 * @ctxt:  the XPath Parser context
 *
 *  [25]   AdditiveExpr ::=   MultiplicativeExpr 
 *                   | AdditiveExpr '+' MultiplicativeExpr 
 *                   | AdditiveExpr '-' MultiplicativeExpr 
 *
 * Parse and evaluate an Additive expression, then push the result on the stack
 */

void
xmlXPathEvalAdditiveExpr(xmlXPathParserContextPtr ctxt) {
    xmlXPathEvalMultiplicativeExpr(ctxt);
    CHECK_ERROR;
    while ((CUR == '+') || (CUR == '-')) {
	int plus;

        if (CUR == '+') plus = 1;
	else plus = 0;
	NEXT;
        xmlXPathEvalMultiplicativeExpr(ctxt);
	CHECK_ERROR;
	if (plus) xmlXPathAddValues(ctxt);
	else xmlXPathSubValues(ctxt);
    }
}

/**
 * xmlXPathEvalRelationalExpr:
 * @ctxt:  the XPath Parser context
 *
 *  [24]   RelationalExpr ::=   AdditiveExpr 
 *                 | RelationalExpr '<' AdditiveExpr 
 *                 | RelationalExpr '>' AdditiveExpr 
 *                 | RelationalExpr '<=' AdditiveExpr 
 *                 | RelationalExpr '>=' AdditiveExpr 
 *
 *  A <= B > C is allowed ? Answer from James, yes with
 *  (AdditiveExpr <= AdditiveExpr) > AdditiveExpr
 *  which is basically what got implemented.
 *
 * Parse and evaluate a Relational expression, then push the result
 * on the stack
 */

void
xmlXPathEvalRelationalExpr(xmlXPathParserContextPtr ctxt) {
    xmlXPathEvalAdditiveExpr(ctxt);
    CHECK_ERROR;
    while ((CUR == '<') ||
           (CUR == '>') ||
           ((CUR == '<') && (NXT(1) == '=')) ||
           ((CUR == '>') && (NXT(1) == '='))) {
	xmlXPathObjectPtr arg1, arg2, res;
	int inf, strict, equal;

        if (CUR == '<') inf = 1;
	else inf = 0;
	if (NXT(1) == '=') strict = 0;
	else strict = 1;
	NEXT;
	if (!strict) NEXT;
        xmlXPathEvalAdditiveExpr(ctxt);
	CHECK_ERROR;
	arg2 = valuePop(ctxt);
	arg1 = valuePop(ctxt);
	equal = xmlXPathCompareValues(inf, strict, arg1, arg2);
	res = xmlXPathNewBoolean(equal);
	valuePush(ctxt, res);
	xmlXPathFreeObject(arg1);
	xmlXPathFreeObject(arg2);
    }
}

/**
 * xmlXPathEvalEqualityExpr:
 * @ctxt:  the XPath Parser context
 *
 *  [23]   EqualityExpr ::=   RelationalExpr 
 *                 | EqualityExpr '=' RelationalExpr 
 *                 | EqualityExpr '!=' RelationalExpr 
 *
 *  A != B != C is allowed ? Answer from James, yes with
 *  (RelationalExpr = RelationalExpr) = RelationalExpr
 *  (RelationalExpr != RelationalExpr) != RelationalExpr
 *  which is basically what got implemented.
 *
 * Parse and evaluate an Equality expression, then push the result on the stack
 *
 */
void
xmlXPathEvalEqualityExpr(xmlXPathParserContextPtr ctxt) {
    xmlXPathEvalRelationalExpr(ctxt);
    CHECK_ERROR;
    while ((CUR == '=') || ((CUR == '!') && (NXT(1) == '='))) {
	xmlXPathObjectPtr arg1, arg2, res;
	int eq, equal;

        if (CUR == '=') eq = 1;
	else eq = 0;
	NEXT;
	if (!eq) NEXT;
        xmlXPathEvalRelationalExpr(ctxt);
	CHECK_ERROR;
	arg2 = valuePop(ctxt);
	arg1 = valuePop(ctxt);
	equal = xmlXPathEqualValues(arg1, arg2);
	if (eq) res = xmlXPathNewBoolean(equal);
	else res = xmlXPathNewBoolean(!equal);
	valuePush(ctxt, res);
	xmlXPathFreeObject(arg1);
	xmlXPathFreeObject(arg2);
    }
}

/**
 * xmlXPathEvalAndExpr:
 * @ctxt:  the XPath Parser context
 *
 *  [22]   AndExpr ::=   EqualityExpr 
 *                 | AndExpr 'and' EqualityExpr 
 *
 * Parse and evaluate an AND expression, then push the result on the stack
 *
 */
void
xmlXPathEvalAndExpr(xmlXPathParserContextPtr ctxt) {
    xmlXPathEvalEqualityExpr(ctxt);
    CHECK_ERROR;
    while ((CUR == 'a') && (NXT(1) == 'n') && (NXT(2) == 'n')) {
	xmlXPathObjectPtr arg1, arg2;

        SKIP(3);
        xmlXPathEvalEqualityExpr(ctxt);
	CHECK_ERROR;
	arg2 = valuePop(ctxt);
	arg1 = valuePop(ctxt);
	arg1->boolval &= arg2->boolval;
	valuePush(ctxt, arg1);
	xmlXPathFreeObject(arg2);
    }
}

/**
 * xmlXPathEvalExpr:
 * @ctxt:  the XPath Parser context
 *
 *  [14]   Expr ::=   OrExpr 
 *  [21]   OrExpr ::=   AndExpr 
 *                 | OrExpr 'or' AndExpr 
 *
 * Parse and evaluate an expression, then push the result on the stack
 *
 */
void
xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
    xmlXPathEvalAndExpr(ctxt);
    CHECK_ERROR;
    while ((CUR == 'o') && (NXT(1) == 'r')) {
	xmlXPathObjectPtr arg1, arg2;

        SKIP(2);
        xmlXPathEvalAndExpr(ctxt);
	CHECK_ERROR;
	arg2 = valuePop(ctxt);
	arg1 = valuePop(ctxt);
	arg1->boolval |= arg2->boolval;
	valuePush(ctxt, arg1);
	xmlXPathFreeObject(arg2);
    }
}

/**
 * xmlXPathEvaluatePredicateResult:
 * @ctxt:  the XPath Parser context
 * @res:  the Predicate Expression evaluation result
 * @index:  index of the current node in the current list
 *
 * Evaluate a predicate result for the current node.
 * A PredicateExpr is evaluated by evaluating the Expr and converting
 * the result to a boolean. If the result is a number, the result will
 * be converted to true if the number is equal to the position of the
 * context node in the context node list (as returned by the position
 * function) and will be converted to false otherwise; if the result
 * is not a number, then the result will be converted as if by a call
 * to the boolean function. 
 */
int
xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt, 
                                xmlXPathObjectPtr res, int index) {
    if (res == NULL) return(0);
    switch (res->type) {
        case XPATH_BOOLEAN:
	    return(res->boolval);
        case XPATH_NUMBER:
	    return(res->floatval == index);
        case XPATH_NODESET:
	    return(res->nodesetval->nodeNr != 0);
        case XPATH_STRING:
	    return((res->stringval != NULL) &&
	           (xmlStrlen(res->stringval) != 0));
        default:
	    STRANGE
    }
    return(0);
}

/**
 * xmlXPathEvalPredicate:
 * @ctxt:  the XPath Parser context
 *
 *  [8]   Predicate ::=   '[' PredicateExpr ']'
 *  [9]   PredicateExpr ::=   Expr 
 *
 * Parse and evaluate a predicate for all the elements of the
 * current node list. Then refine the list by removing all
 * nodes where the predicate is false.
 */
void
xmlXPathEvalPredicate(xmlXPathParserContextPtr ctxt) {
    const CHAR *cur;
    xmlXPathObjectPtr res;
    xmlNodeSetPtr newset = NULL;
    int i;

    if (CUR != '[') {
	ERROR(XPATH_INVALID_PREDICATE_ERROR);
    }
    NEXT;
    if ((ctxt->context->nodelist == NULL) ||
        (ctxt->context->nodelist->nodeNr == 0)) {
        ctxt->context->node = NULL;
	xmlXPathEvalExpr(ctxt);
	CHECK_ERROR;
	res = valuePop(ctxt);
	if (res != NULL)
	    xmlXPathFreeObject(res);
    } else {
        cur = ctxt->cur;
	newset = xmlXPathNodeSetCreate(NULL);
        for (i = 0; i < ctxt->context->nodelist->nodeNr; i++) {
	    ctxt->cur = cur;
	    ctxt->context->node = ctxt->context->nodelist->nodeTab[i];
	    xmlXPathEvalExpr(ctxt);
	    CHECK_ERROR;
	    res = valuePop(ctxt);
	    if (xmlXPathEvaluatePredicateResult(ctxt, res, i + 1))
	        xmlXPathNodeSetAdd(newset,
		                   ctxt->context->nodelist->nodeTab[i]);
	    if (res != NULL)
	    xmlXPathFreeObject(res);
	}
	if (ctxt->context->nodelist != NULL)
	    xmlXPathFreeNodeSet(ctxt->context->nodelist);
	ctxt->context->nodelist = newset;
	ctxt->context->node = NULL;
    }
    if (CUR != ']') {
	ERROR(XPATH_INVALID_PREDICATE_ERROR);
    }
    NEXT;
#ifdef DEBUG_STEP
    fprintf(xmlXPathDebug, "After predicate : ");
    xmlXPathDebugNodeSet(xmlXPathDebug, ctxt->context->nodelist);
#endif
}

/**
 * xmlXPathEvalBasis:
 * @ctxt:  the XPath Parser context
 *
 *  [5]   Basis ::=   AxisName '::' NodeTest 
 *            | AbbreviatedBasis 
 *  [13]   AbbreviatedBasis ::=   NodeTest 
 *                           | '@' NodeTest 
 *  [7]   NodeTest ::=   WildcardName 
 *              | NodeType '(' ')'
 *              | 'processing-instruction' '(' Literal ')'
 *  [37]   WildcardName ::=   '*'
 *                    | NCName ':' '*'
 *                    | QName 
 *
 * Evaluate one step in a Location Path
 */
void
xmlXPathEvalBasis(xmlXPathParserContextPtr ctxt) {
    CHAR *name = NULL;
    CHAR *prefix = NULL;
    int type = 0;
    int axis = AXIS_CHILD; /* the default on abbreviated syntax */
    int nodetest = NODE_TEST_NONE;
    int nodetype = 0;
    xmlNodeSetPtr newset = NULL;

    if (CUR == '@') {
        TODO /* attributes */
    } else if (CUR == '*') {
        NEXT;
        nodetest = NODE_TEST_ALL;
    } else {
        name = xmlXPathParseNCName(ctxt);
	if (name == NULL) {
	    ERROR(XPATH_EXPR_ERROR);
	}
	type = xmlXPathGetNameType(ctxt, name);
	switch (type) {
	    /*
	     * Simple case: no axis seach all given node types.
	     */
            case NODE_TYPE_COMMENT:
	        if ((CUR != '(') || (NXT(1) != ')')) break;
		SKIP(2);
		nodetest = NODE_TEST_TYPE;
		nodetype = XML_COMMENT_NODE;
		goto search_nodes;
            case NODE_TYPE_TEXT:
	        if ((CUR != '(') || (NXT(1) != ')')) break;
		SKIP(2);
		nodetest = NODE_TEST_TYPE;
		nodetype = XML_TEXT_NODE;
		goto search_nodes;
            case NODE_TYPE_NODE:
	        if ((CUR != '(') || (NXT(1) != ')')) {
		    nodetest = NODE_TEST_NAME;
		    break;
		}
		SKIP(2);
		nodetest = NODE_TEST_TYPE;
		nodetype = XML_ELEMENT_NODE;
		goto search_nodes;
            case NODE_TYPE_PI:
	        if (CUR != '(') break;
		if (NXT(1) != ')') {
		    /*
		     * Specific case: search a PI by name.
		     */
                    SKIP(2);
		    nodetest = NODE_TEST_PI;
		    xmlXPathEvalLiteral(ctxt);
		    CHECK_ERROR;
		    if (CUR != ')')
			ERROR(XPATH_UNCLOSED_ERROR);
		    xmlXPathSearchPI(ctxt, 0);
		    return;
		}
		SKIP(2);
		nodetest = NODE_TEST_TYPE;
		nodetype = XML_PI_NODE;
		goto search_nodes;
	
	    /*
	     * Handling of the compund form: got the axis.
	     */
            case AXIS_ANCESTOR:
            case AXIS_ANCESTOR_OR_SELF:
            case AXIS_ATTRIBUTE:
            case AXIS_CHILD:
            case AXIS_DESCENDANT:
            case AXIS_DESCENDANT_OR_SELF:
            case AXIS_FOLLOWING:
            case AXIS_FOLLOWING_SIBLING:
            case AXIS_NAMESPACE:
            case AXIS_PARENT:
            case AXIS_PRECEDING:
            case AXIS_PRECEDING_SIBLING:
            case AXIS_SELF:
	        if ((CUR != ':') || (NXT(1) != ':')) {
		    nodetest = NODE_TEST_NAME;
		    break;
		}
		SKIP(2);
		axis = type;
		break;
	
	    /*
	     * Default: abbreviated syntax the axis is AXIS_CHILD
	     */
	    default:
	        nodetest = NODE_TEST_NAME;
	}
	if (nodetest == NODE_TEST_NONE) {
	    if (CUR == '*') {
		NEXT;
		nodetest = NODE_TEST_ALL;
	    } else {
		if (name != NULL) 
		    free(name);
		name = xmlXPathParseQName(ctxt, &prefix);
		nodetest = NODE_TEST_NAME;
	    }
	} else if ((CUR == ':') && (nodetest == NODE_TEST_NAME)) {
	    NEXT;
	    prefix = name;
	    if (CUR == '*') {
	        NEXT;
		nodetest = NODE_TEST_ALL;
	    } else 
		name = xmlXPathParseNCName(ctxt);
	} else if (name == NULL)
	    ERROR(XPATH_EXPR_ERROR);
    }

search_nodes:
        
#ifdef DEBUG_STEP
    fprintf(xmlXPathDebug, "Basis : computing new set\n");
#endif
    newset = xmlXPathNodeCollectAndTest(ctxt, axis, nodetest, nodetype,
                                        prefix, name);
    if (ctxt->context->nodelist != NULL)
	xmlXPathFreeNodeSet(ctxt->context->nodelist);
    ctxt->context->nodelist = newset;
    ctxt->context->node = NULL;
#ifdef DEBUG_STEP
    fprintf(xmlXPathDebug, "Basis : ");
    xmlXPathDebugNodeSet(stdout, ctxt->context->nodelist);
#endif
    if (name != NULL) free(name);
    if (prefix != NULL) free(prefix);
}

/**
 * xmlXPathEvalStep:
 * @ctxt:  the XPath Parser context
 *
 *  [4]   Step ::=   Basis Predicate*
 *                     | AbbreviatedStep 
 *  [12]   AbbreviatedStep ::=   '.'
 *                           | '..'
 *
 * Evaluate one step in a Location Path
 * A location step of . is short for self::node(). This is
 * particularly useful in conjunction with //. For example, the
 * location path .//para is short for
 * self::node()/descendant-or-self::node()/child::para
 * and so will select all para descendant elements of the context
 * node.
 * Similarly, a location step of .. is short for parent::node().
 * For example, ../title is short for parent::node()/child::title
 * and so will select the title children of the parent of the context
 * node.
 */
void
xmlXPathEvalStep(xmlXPathParserContextPtr ctxt) {
    xmlNodeSetPtr newset = NULL;

    if ((CUR == '.') && (NXT(1) == '.')) {
	SKIP(2);
	if (ctxt->context->nodelist == NULL) {
	    STRANGE
	    xmlXPathRoot(ctxt);
	}
	newset = xmlXPathNodeCollectAndTest(ctxt, AXIS_PARENT,
			 NODE_TEST_TYPE, XML_ELEMENT_NODE, NULL, NULL);
	if (ctxt->context->nodelist != NULL)
	    xmlXPathFreeNodeSet(ctxt->context->nodelist);
	ctxt->context->nodelist = newset;
	ctxt->context->node = NULL;
    } else if (CUR == '.') {
	NEXT;
    } else {
	xmlXPathEvalBasis(ctxt);
	while (CUR == '[') {
	    xmlXPathEvalPredicate(ctxt);
	}
    }
#ifdef DEBUG_STEP
    fprintf(xmlXPathDebug, "Step : ");
    xmlXPathDebugNodeSet(xmlXPathDebug, ctxt->context->nodelist);
#endif
}

/**
 * xmlXPathEvalRelativeLocationPath:
 * @ctxt:  the XPath Parser context
 *
 *  [3]   RelativeLocationPath ::=   Step 
 *                     | RelativeLocationPath '/' Step 
 *                     | AbbreviatedRelativeLocationPath 
 *  [11]  AbbreviatedRelativeLocationPath ::=   RelativeLocationPath '//' Step 
 *
 */
void
xmlXPathEvalRelativeLocationPath(xmlXPathParserContextPtr ctxt) {
    xmlNodeSetPtr newset = NULL;

    xmlXPathEvalStep(ctxt);
    while (CUR == '/') {
	if ((CUR == '/') && (NXT(1) == '/')) {
	    SKIP(2);
	    if (ctxt->context->nodelist == NULL) {
		STRANGE
		xmlXPathRoot(ctxt);
	    }
	    newset = xmlXPathNodeCollectAndTest(ctxt, AXIS_DESCENDANT_OR_SELF,
			     NODE_TEST_TYPE, XML_ELEMENT_NODE, NULL, NULL);
	    if (ctxt->context->nodelist != NULL)
		xmlXPathFreeNodeSet(ctxt->context->nodelist);
	    ctxt->context->nodelist = newset;
	    ctxt->context->node = NULL;
	    xmlXPathEvalStep(ctxt);
	} else if (CUR == '/') {
	    NEXT;
	    xmlXPathEvalStep(ctxt);
	}
    }
}

/**
 * xmlXPathEvalLocationPath:
 * @ctxt:  the XPath Parser context
 *
 *  [1]   LocationPath ::=   RelativeLocationPath 
 *                     | AbsoluteLocationPath 
 *  [2]   AbsoluteLocationPath ::=   '/' RelativeLocationPath?
 *                     | AbbreviatedAbsoluteLocationPath 
 *  [10]   AbbreviatedAbsoluteLocationPath ::=   
 *                           '//' RelativeLocationPath 
 *
 * // is short for /descendant-or-self::node()/. For example,
 * //para is short for /descendant-or-self::node()/child::para and
 * so will select any para element in the document (even a para element
 * that is a document element will be selected by //para since the
 * document element node is a child of the root node); div//para is
 * short for div/descendant-or-self::node()/child::para and so will
 * select all para descendants of div children.
 */
void
xmlXPathEvalLocationPath(xmlXPathParserContextPtr ctxt) {
    xmlNodeSetPtr newset = NULL;

    while (CUR == '/') {
	if ((CUR == '/') && (NXT(1) == '/')) {
	    SKIP(2);
	    if (ctxt->context->nodelist == NULL)
		xmlXPathRoot(ctxt);
	    newset = xmlXPathNodeCollectAndTest(ctxt, AXIS_DESCENDANT_OR_SELF,
			     NODE_TEST_TYPE, XML_ELEMENT_NODE, NULL, NULL);
	    if (ctxt->context->nodelist != NULL)
		xmlXPathFreeNodeSet(ctxt->context->nodelist);
	    ctxt->context->nodelist = newset;
	    ctxt->context->node = NULL;
	    xmlXPathEvalRelativeLocationPath(ctxt);
	} else if (CUR == '/') {
	    NEXT;
	    xmlXPathRoot(ctxt);
	    xmlXPathEvalRelativeLocationPath(ctxt);
	} else {
	    xmlXPathEvalRelativeLocationPath(ctxt);
	}
    }
}

/*
 * TODO * extra spaces *
 * more tokenization rules ... Not used currently, especially allowing
 * spaces before and after ExprToken !!!!!!!!!!!!!
 *
 *  [32]   Operator ::=   OperatorName 
 *                    | MultiplyOperator 
 *                    | '/' | '//' | '|' | '+' | '-' | '=' | '!='
 *                    | '<'| '<=' | '>' | '>='
 *  [33]   OperatorName ::=   'and' | 'or' | 'mod' | 'div'
 *  [39]   ExprWhitespace ::=   S 
 *
 *  BUG: ExprToken is never referenced.
 *
 *  [28]   ExprToken ::=   '(' | ')' | '[' | ']' | '.' | '..' | '@' | ',' | '::'
 *                    | WildcardName 
 *                    | NodeType 
 *                    | Operator 
 *                    | FunctionName 
 *                    | AxisName 
 *                    | Literal 
 *                    | Number 
 *                    | VariableReference 
 */

/**
 * xmlXPathEval:
 * @str:  the XPath expression
 * @ctxt:  the XPath context
 *
 * Evaluate the XPath Location Path in the given context.
 *
 * Returns the xmlXPathObjectPtr resulting from the eveluation or NULL.
 *         the caller has to free the object.
 */
xmlXPathObjectPtr
xmlXPathEval(const CHAR *str, xmlXPathContextPtr ctxt) {
    xmlXPathParserContextPtr pctxt;
    xmlXPathObjectPtr res;

    xmlXPathInit();

    CHECK_CONTEXT

    if (xmlXPathDebug == NULL)
        xmlXPathDebug = stderr;
    pctxt = xmlXPathNewParserContext(str, ctxt);
    xmlXPathEvalLocationPath(pctxt);

    do {
        res = valuePop(pctxt);
#ifdef DEBUG
#endif
    } while (res != NULL);
    res = xmlXPathNewNodeSetList(pctxt->context->nodelist);
    xmlXPathFreeParserContext(pctxt);
    return(res);
}

/**
 * xmlXPathEvalExpression:
 * @str:  the XPath expression
 * @ctxt:  the XPath context
 *
 * Evaluate the XPath expression in the given context.
 *
 * Returns the xmlXPathObjectPtr resulting from the eveluation or NULL.
 *         the caller has to free the object.
 */
xmlXPathObjectPtr
xmlXPathEvalExpression(const CHAR *str, xmlXPathContextPtr ctxt) {
    xmlXPathParserContextPtr pctxt;
    xmlXPathObjectPtr res, tmp;

    xmlXPathInit();

    CHECK_CONTEXT

    if (xmlXPathDebug == NULL)
        xmlXPathDebug = stderr;
    pctxt = xmlXPathNewParserContext(str, ctxt);
    xmlXPathEvalExpr(pctxt);

    res = valuePop(pctxt);
    do {
        tmp = valuePop(pctxt);
	if (tmp != NULL);
	    xmlXPathFreeObject(tmp);
    } while (tmp != NULL);
    xmlXPathFreeParserContext(pctxt);
    return(res);
}

