- Lots of improvements, too long to list here
- Push mode for the XML parser (HTML to come)
- XML shell like interface for debug
- improvements on XPath and validation
Daniel
diff --git a/xpath.c b/xpath.c
index c5ce36a..4882b04 100644
--- a/xpath.c
+++ b/xpath.c
@@ -47,6 +47,10 @@
 #include "xpath.h"
 #include "parserInternals.h"
 
+/* #define DEBUG */
+/* #define DEBUG_STEP */
+/* #define DEBUG_EXPR */
+
 /*
  * Setup stuff for floating point
  * The lack of portability of this section of the libc is annoying !
@@ -151,10 +155,6 @@
     initialized = 1;
 }
 
-/* #define DEBUG */
-/* #define DEBUG_STEP */
-/* #define DEBUG_EXPR */
-
 FILE *xmlXPathDebug = NULL;
 
 #define TODO 								\
@@ -748,6 +748,22 @@
 }
 
 /**
+ * xmlXPathFreeNodeSetList:
+ * @obj:  an existing NodeSetList object
+ *
+ * Free up the xmlXPathObjectPtr @obj but don't deallocate the objects in
+ * the list contrary to xmlXPathFreeObject().
+ */
+void
+xmlXPathFreeNodeSetList(xmlXPathObjectPtr obj) {
+    if (obj == NULL) return;
+#ifdef DEBUG
+    memset(obj, 0xB , (size_t) sizeof(xmlXPathObject));
+#endif
+    xmlFree(obj);
+}
+
+/**
  * xmlXPathFreeObject:
  * @obj:  the object to free
  *
@@ -791,6 +807,12 @@
     }
     memset(ret, 0 , (size_t) sizeof(xmlXPathContext));
     ret->doc = doc;
+ /***********   
+    ret->node = (xmlNodePtr) doc;
+    ret->nodelist = xmlXPathNodeSetCreate(ret->node);
+  ***********/  
+    ret->node = NULL;
+    ret->nodelist = NULL;
 
     ret->nb_variables = 0;
     ret->max_variables = 0;
@@ -825,6 +847,10 @@
     if (ctxt->namespaces != NULL)
         xmlFree(ctxt->namespaces);
 
+ /***********   
+    if (ctxt->nodelist != NULL) 
+        xmlXPathFreeNodeSet(ctxt->nodelist);
+  ***********/  
 #ifdef DEBUG
     memset(ctxt, 0xB , (size_t) sizeof(xmlXPathContext));
 #endif
@@ -1467,12 +1493,13 @@
 xmlNodePtr
 xmlXPathNextChild(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
     if (cur == NULL) {
-        if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
-	    return(ctxt->context->doc->root);
+	if ((ctxt->context->node->type == XML_DOCUMENT_NODE) ||
+	    (ctxt->context->node->type == XML_HTML_DOCUMENT_NODE))
+	    return(((xmlDocPtr) ctxt->context->node)->root);
         return(ctxt->context->node->childs);
     }
-    if ((ctxt->context->node->type == XML_DOCUMENT_NODE) ||
-        (ctxt->context->node->type == XML_HTML_DOCUMENT_NODE))
+    if ((cur->type == XML_DOCUMENT_NODE) ||
+        (cur->type == XML_HTML_DOCUMENT_NODE))
 	return(NULL);
     return(cur->next);
 }
@@ -1918,23 +1945,23 @@
             ctxt->context->nodelist->nodeNr);
     switch (test) {
 	case NODE_TEST_NONE:
-	    fprintf(xmlXPathDebug, "           seaching for none !!!\n");
+	    fprintf(xmlXPathDebug, "           searching for none !!!\n");
 	    break;
 	case NODE_TEST_TYPE:
-	    fprintf(xmlXPathDebug, "           seaching for type %d\n", type);
+	    fprintf(xmlXPathDebug, "           searching for type %d\n", type);
 	    break;
 	case NODE_TEST_PI:
-	    fprintf(xmlXPathDebug, "           seaching for PI !!!\n");
+	    fprintf(xmlXPathDebug, "           searching for PI !!!\n");
 	    break;
 	case NODE_TEST_ALL:
-	    fprintf(xmlXPathDebug, "           seaching for *\n");
+	    fprintf(xmlXPathDebug, "           searching for *\n");
 	    break;
 	case NODE_TEST_NS:
-	    fprintf(xmlXPathDebug, "           seaching for namespace %s\n",
+	    fprintf(xmlXPathDebug, "           searching for namespace %s\n",
 	            prefix);
 	    break;
 	case NODE_TEST_NAME:
-	    fprintf(xmlXPathDebug, "           seaching for name %s\n", name);
+	    fprintf(xmlXPathDebug, "           searching for name %s\n", name);
 	    if (prefix != NULL)
 		fprintf(xmlXPathDebug, "           with namespace %s\n",
 		        prefix);
@@ -1958,7 +1985,10 @@
 		    STRANGE
 		    return(NULL);
                 case NODE_TEST_TYPE:
-		    if (cur->type == type) {
+		    if ((cur->type == type) ||
+		        ((type == XML_ELEMENT_NODE) && 
+			 ((cur->type == XML_DOCUMENT_NODE) ||
+			  (cur->type == XML_HTML_DOCUMENT_NODE)))) {
 #ifdef DEBUG_STEP
                         n++;
 #endif
@@ -4400,6 +4430,7 @@
 xmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctxt) {
     xmlXPathParserContextPtr pctxt;
     xmlXPathObjectPtr res = NULL, tmp;
+    int stack = 0;
 
     xmlXPathInit();
 
@@ -4408,16 +4439,26 @@
     if (xmlXPathDebug == NULL)
         xmlXPathDebug = stderr;
     pctxt = xmlXPathNewParserContext(str, ctxt);
+    if (str[0] == '/')
+        xmlXPathRoot(pctxt);
     xmlXPathEvalLocationPath(pctxt);
 
     /* TODO: cleanup nodelist, res = valuePop(pctxt); */
     do {
         tmp = valuePop(pctxt);
-	if (tmp != NULL);
+	if (tmp != NULL) {
 	    xmlXPathFreeObject(tmp);
+	    stack++;    
+        }
     } while (tmp != NULL);
-    if (res == NULL)
+    if (stack != 0) {
+	fprintf(xmlXPathDebug, "xmlXPathEval: %d object left on the stack\n",
+	        stack);
+    }
+    if (pctxt->error == XPATH_EXPRESSION_OK)
 	res = xmlXPathNewNodeSetList(pctxt->context->nodelist);
+    else
+        res = NULL;
     xmlXPathFreeParserContext(pctxt);
     return(res);
 }
@@ -4436,6 +4477,7 @@
 xmlXPathEvalExpression(const xmlChar *str, xmlXPathContextPtr ctxt) {
     xmlXPathParserContextPtr pctxt;
     xmlXPathObjectPtr res, tmp;
+    int stack = 0;
 
     xmlXPathInit();
 
@@ -4449,9 +4491,15 @@
     res = valuePop(pctxt);
     do {
         tmp = valuePop(pctxt);
-	if (tmp != NULL);
+	if (tmp != NULL) {
 	    xmlXPathFreeObject(tmp);
+	    stack++;
+	}
     } while (tmp != NULL);
+    if (stack != 0) {
+	fprintf(xmlXPathDebug, "xmlXPathEval: %d object left on the stack\n",
+	        stack);
+    }
     xmlXPathFreeParserContext(pctxt);
     return(res);
 }