integrating Keith Isdale patches for the XSLT debugger interfaces. Some

* include/libxml/debugXML.h debugXML.c tree.c: integrating
  Keith Isdale patches for the XSLT debugger interfaces. Some
  cleanup
Daniel
diff --git a/ChangeLog b/ChangeLog
index c2ab073..60c7746 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Thu Oct 11 11:10:31 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/debugXML.h debugXML.c tree.c: integrating
+	  Keith Isdale patches for the XSLT debugger interfaces. Some
+	  cleanup
+
 Thu Oct 11 08:44:01 CEST 2001 Daniel Veillard <daniel@veillard.com>
 
 	* win32/Makefile.mingw: update from Tobias Peters for 2.4.5
diff --git a/debugXML.c b/debugXML.c
index 83a4d9d..6c7d9a4 100644
--- a/debugXML.c
+++ b/debugXML.c
@@ -1002,7 +1002,7 @@
         fprintf(output, "No entities in external subset\n");
 }
 
-static int xmlLsCountNode(xmlNodePtr node) {
+int xmlLsCountNode(xmlNodePtr node) {
     int ret = 0;
     xmlNodePtr list = NULL;
 
@@ -1052,7 +1052,7 @@
     return(ret);
 }
 
-static void
+void
 xmlLsOneNode(FILE *output, xmlNodePtr node) {
     switch (node->type) {
 	case XML_ELEMENT_NODE:
@@ -1159,12 +1159,57 @@
     fprintf(output, "\n");
 }
 
+/**
+ * xmlBoolToText:
+ * @bool : a bool to turn into text
+ *
+ * Convenient way to turn bool into text 
+*/
+const char *
+xmlBoolToText(int bool)
+{
+    if (bool)
+        return("True");
+    else
+        return("False");
+}
+
+
+/**
+ * xmlGetLineNo:
+ * @node : valid node
+ *
+ * Get line number of node
+ *
+ * Returns the line number if sucessfull, -1 otherwise
+ */
+long
+xmlGetLineNo(xmlNodePtr node)
+{
+    long result = -1;
+
+    if (!node)
+        return result;
+    if (node->type == XML_ELEMENT_NODE)
+        result = (long) node->content;
+    else if ((node->prev != NULL) &&
+             (node->prev->type == XML_ELEMENT_NODE))
+        result = (long) node->prev->content;
+    else if ((node->parent != NULL) &&
+             (node->parent->type == XML_ELEMENT_NODE))
+        result = (long) node->parent->content;
+
+    return result;
+}
+
 /****************************************************************
  *								*
  *	 	The XML shell related functions			*
  *								*
  ****************************************************************/
 
+
+
 /*
  * TODO: Improvement/cleanups for the XML shell
  *     - allow to shell out an editor on a subpart
@@ -1173,6 +1218,139 @@
  */
 
 /**
+ * xmlShellPrintXpathError:
+ * @errorType: valid xpath error id
+ * @arg : the argument that cause xpath to fail
+ *
+ * Print the xpath error to libxml default error channel
+ */
+void
+xmlShellPrintXPathError(int errorType, const char *arg)
+{
+    const char *default_arg = "Result";
+
+    if (!arg)
+        arg = default_arg;
+
+    switch (errorType) {
+        case XPATH_UNDEFINED:
+            xmlGenericError(xmlGenericErrorContext,
+                            "%s: no such node\n", arg);
+            break;
+
+        case XPATH_BOOLEAN:
+            xmlGenericError(xmlGenericErrorContext,
+                            "%s is a Boolean\n", arg);
+            break;
+        case XPATH_NUMBER:
+            xmlGenericError(xmlGenericErrorContext,
+                            "%s is a number\n", arg);
+            break;
+        case XPATH_STRING:
+            xmlGenericError(xmlGenericErrorContext,
+                            "%s is a string\n", arg);
+            break;
+        case XPATH_POINT:
+            xmlGenericError(xmlGenericErrorContext,
+                            "%s is a point\n", arg);
+            break;
+        case XPATH_RANGE:
+            xmlGenericError(xmlGenericErrorContext,
+                            "%s is a range\n", arg);
+            break;
+        case XPATH_LOCATIONSET:
+            xmlGenericError(xmlGenericErrorContext,
+                            "%s is a range\n", arg);
+            break;
+        case XPATH_USERS:
+            xmlGenericError(xmlGenericErrorContext,
+                            "%s is user-defined\n", arg);
+            break;
+        case XPATH_XSLT_TREE:
+            xmlGenericError(xmlGenericErrorContext,
+                            "%s is an XSLT value tree\n", arg);
+            break;
+    }
+    xmlGenericError(xmlGenericErrorContext,
+                    "Try casting the result string function (xpath builtin)\n",
+                    arg);
+}
+
+
+/**
+ * xmlShellPrintNode:
+ * @node : a non-null node to print to stdout
+ *
+ * Print node to stdout
+ */
+void
+xmlShellPrintNode(xmlNodePtr node)
+{
+    if (!node)
+        return;
+
+    if (node->type == XML_DOCUMENT_NODE)
+        xmlDocDump(stdout, (xmlDocPtr) node);
+    else if (node->type == XML_ATTRIBUTE_NODE)
+        xmlDebugDumpAttrList(stdout, (xmlAttrPtr) node, 0);
+    else
+        xmlElemDump(stdout, node->doc, node);
+
+    fprintf(stdout, "\n");
+}
+
+
+/**
+ * xmlShellPrintXPathResult:
+ * list : a valid result generated by an xpath evaluation
+ *
+ * Prints result to stdout
+ */
+void
+xmlShellPrintXPathResult(xmlXPathObjectPtr list)
+{
+    int i = 0;
+
+    if (list != NULL) {
+        switch (list->type) {
+            case XPATH_NODESET:{
+                    int indx;
+
+                    if (list->nodesetval) {
+                        for (indx = 0; indx < list->nodesetval->nodeNr;
+                             indx++) {
+                            if (i > 0)
+                                fprintf(stderr, " -------\n");
+                            xmlShellPrintNode(list->nodesetval->
+                                              nodeTab[indx]);
+                        }
+                    } else {
+                        xmlGenericError(xmlGenericErrorContext,
+                                        "Empty node set\n");
+                    }
+                    break;
+                }
+            case XPATH_BOOLEAN:
+                xmlGenericError(xmlGenericErrorContext,
+                                "Is a Boolean:%s\n",
+                                xmlBoolToText(list->boolval));
+                break;
+            case XPATH_NUMBER:
+                xmlGenericError(xmlGenericErrorContext,
+                                "Is a number:%0g\n", list->floatval);
+                break;
+            case XPATH_STRING:
+                xmlGenericError(xmlGenericErrorContext,
+                                "Is a string:%s\n", list->stringval);
+                break;
+
+            default:
+                xmlShellPrintXPathError(list->type, NULL);
+        }
+    }
+}
+
+/**
  * xmlShellList:
  * @ctxt:  the shell context
  * @arg:  unused
@@ -1184,9 +1362,11 @@
  *
  * Returns 0
  */
-static int
-xmlShellList(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED , char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
-                  xmlNodePtr node2 ATTRIBUTE_UNUSED) {
+int
+xmlShellList(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
+             char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
+             xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
     xmlNodePtr cur;
 
     if ((node->type == XML_DOCUMENT_NODE) ||
@@ -1195,14 +1375,14 @@
     } else if (node->children != NULL) {
         cur = node->children;
     } else {
-	xmlLsOneNode(stdout, node);
-        return(0);
+        xmlLsOneNode(stdout, node);
+        return (0);
     }
     while (cur != NULL) {
-	xmlLsOneNode(stdout, cur);
-	cur = cur->next;
+        xmlLsOneNode(stdout, cur);
+        cur = cur->next;
     }
-    return(0);
+    return (0);
 }
 
 /**
@@ -1217,20 +1397,22 @@
  *
  * Returns 0
  */
-static int
-xmlShellBase(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
-                  xmlNodePtr node2 ATTRIBUTE_UNUSED) {
+int
+xmlShellBase(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
+             char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
+             xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
     xmlChar *base;
 
     base = xmlNodeGetBase(node->doc, node);
 
     if (base == NULL) {
-	printf(" No base found !!!\n");
+        printf(" No base found !!!\n");
     } else {
-	printf("%s\n", base);
-	xmlFree(base);
+        printf("%s\n", base);
+        xmlFree(base);
     }
-    return(0);
+    return (0);
 }
 
 /**
@@ -1245,18 +1427,20 @@
  *
  * Returns 0
  */
-static int
-xmlShellDir(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
-                  xmlNodePtr node2 ATTRIBUTE_UNUSED) {
+int
+xmlShellDir(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
+            char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
+            xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
     if ((node->type == XML_DOCUMENT_NODE) ||
         (node->type == XML_HTML_DOCUMENT_NODE)) {
-	xmlDebugDumpDocumentHead(stdout, (xmlDocPtr) node);
+        xmlDebugDumpDocumentHead(stdout, (xmlDocPtr) node);
     } else if (node->type == XML_ATTRIBUTE_NODE) {
-	xmlDebugDumpAttr(stdout, (xmlAttrPtr) node, 0);
+        xmlDebugDumpAttr(stdout, (xmlAttrPtr) node, 0);
     } else {
-	xmlDebugDumpOneNode(stdout, node, 0);
+        xmlDebugDumpOneNode(stdout, node, 0);
     }
-    return(0);
+    return (0);
 }
 
 /**
@@ -1271,29 +1455,30 @@
  *
  * Returns 0
  */
-static int
-xmlShellCat(xmlShellCtxtPtr ctxt, char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
-                  xmlNodePtr node2 ATTRIBUTE_UNUSED) {
+int
+xmlShellCat(xmlShellCtxtPtr ctxt, char *arg ATTRIBUTE_UNUSED,
+            xmlNodePtr node, xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
     if (ctxt->doc->type == XML_HTML_DOCUMENT_NODE) {
 #ifdef LIBXML_HTML_ENABLED
-	if (node->type == XML_HTML_DOCUMENT_NODE)
-	    htmlDocDump(stdout, (htmlDocPtr) node);
-	else
-	    htmlNodeDumpFile(stdout, ctxt->doc, node);
+        if (node->type == XML_HTML_DOCUMENT_NODE)
+            htmlDocDump(stdout, (htmlDocPtr) node);
+        else
+            htmlNodeDumpFile(stdout, ctxt->doc, node);
 #else
-	if (node->type == XML_DOCUMENT_NODE)
-	    xmlDocDump(stdout, (xmlDocPtr) node);
-	else
-	    xmlElemDump(stdout, ctxt->doc, node);
+        if (node->type == XML_DOCUMENT_NODE)
+            xmlDocDump(stdout, (xmlDocPtr) node);
+        else
+            xmlElemDump(stdout, ctxt->doc, node);
 #endif /* LIBXML_HTML_ENABLED */
     } else {
-	if (node->type == XML_DOCUMENT_NODE)
-	    xmlDocDump(stdout, (xmlDocPtr) node);
-	else
-	    xmlElemDump(stdout, ctxt->doc, node);
+        if (node->type == XML_DOCUMENT_NODE)
+            xmlDocDump(stdout, (xmlDocPtr) node);
+        else
+            xmlElemDump(stdout, ctxt->doc, node);
     }
     printf("\n");
-    return(0);
+    return (0);
 }
 
 /**
@@ -1308,43 +1493,45 @@
  *
  * Returns 0 or -1 if loading failed
  */
-static int
-xmlShellLoad(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node ATTRIBUTE_UNUSED,
-             xmlNodePtr node2 ATTRIBUTE_UNUSED) {
+int
+xmlShellLoad(xmlShellCtxtPtr ctxt, char *filename,
+             xmlNodePtr node ATTRIBUTE_UNUSED,
+             xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
     xmlDocPtr doc;
     int html = 0;
 
     if (ctxt->doc != NULL)
-	html = (ctxt->doc->type == XML_HTML_DOCUMENT_NODE);
+        html = (ctxt->doc->type == XML_HTML_DOCUMENT_NODE);
 
     if (html) {
 #ifdef LIBXML_HTML_ENABLED
-	doc = htmlParseFile(filename, NULL);
-#else	
-	printf("HTML support not compiled in\n");
-	doc = NULL;
+        doc = htmlParseFile(filename, NULL);
+#else
+        printf("HTML support not compiled in\n");
+        doc = NULL;
 #endif /* LIBXML_HTML_ENABLED */
     } else {
-	doc = xmlParseFile(filename);
+        doc = xmlParseFile(filename);
     }
     if (doc != NULL) {
         if (ctxt->loaded == 1) {
-	    xmlFreeDoc(ctxt->doc);
-	}
-	ctxt->loaded = 1;
+            xmlFreeDoc(ctxt->doc);
+        }
+        ctxt->loaded = 1;
 #ifdef LIBXML_XPATH_ENABLED
-	xmlXPathFreeContext(ctxt->pctxt);
+        xmlXPathFreeContext(ctxt->pctxt);
 #endif /* LIBXML_XPATH_ENABLED */
-	xmlFree(ctxt->filename);
-	ctxt->doc = doc;
-	ctxt->node = (xmlNodePtr) doc;	 
+        xmlFree(ctxt->filename);
+        ctxt->doc = doc;
+        ctxt->node = (xmlNodePtr) doc;
 #ifdef LIBXML_XPATH_ENABLED
-	ctxt->pctxt = xmlXPathNewContext(doc);
+        ctxt->pctxt = xmlXPathNewContext(doc);
 #endif /* LIBXML_XPATH_ENABLED */
-	ctxt->filename = (char *) xmlStrdup((xmlChar *) filename);
+        ctxt->filename = (char *) xmlStrdup((xmlChar *) filename);
     } else
-        return(-1);
-    return(0);
+        return (-1);
+    return (0);
 }
 
 /**
@@ -1360,60 +1547,61 @@
  *
  * Returns 0 or -1 in case of error
  */
-static int
+int
 xmlShellWrite(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
-                  xmlNodePtr node2 ATTRIBUTE_UNUSED) {
+              xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
     if (node == NULL)
-        return(-1);
+        return (-1);
     if ((filename == NULL) || (filename[0] == 0)) {
         xmlGenericError(xmlGenericErrorContext,
-		"Write command requires a filename argument\n");
-	return(-1);
+                        "Write command requires a filename argument\n");
+        return (-1);
     }
 #ifdef W_OK
     if (access((char *) filename, W_OK)) {
         xmlGenericError(xmlGenericErrorContext,
-		"Cannot write to %s\n", filename);
-	return(-1);
+                        "Cannot write to %s\n", filename);
+        return (-1);
     }
-#endif    
-    switch(node->type) {
+#endif
+    switch (node->type) {
         case XML_DOCUMENT_NODE:
-	    if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
-		xmlGenericError(xmlGenericErrorContext,
-			"Failed to write to %s\n", filename);
-		return(-1);
-	    }
-	    break;
+            if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
+                xmlGenericError(xmlGenericErrorContext,
+                                "Failed to write to %s\n", filename);
+                return (-1);
+            }
+            break;
         case XML_HTML_DOCUMENT_NODE:
 #ifdef LIBXML_HTML_ENABLED
-	    if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
-		xmlGenericError(xmlGenericErrorContext,
-			"Failed to write to %s\n", filename);
-		return(-1);
-	    }
+            if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
+                xmlGenericError(xmlGenericErrorContext,
+                                "Failed to write to %s\n", filename);
+                return (-1);
+            }
 #else
-	    if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
-		xmlGenericError(xmlGenericErrorContext,
-			"Failed to write to %s\n", filename);
-		return(-1);
-	    }
+            if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
+                xmlGenericError(xmlGenericErrorContext,
+                                "Failed to write to %s\n", filename);
+                return (-1);
+            }
 #endif /* LIBXML_HTML_ENABLED */
-	    break;
-	default: {
-	    FILE *f;
+            break;
+        default:{
+                FILE *f;
 
-	    f = fopen((char *) filename, "w");
-	    if (f == NULL) {
-		xmlGenericError(xmlGenericErrorContext,
-			"Failed to write to %s\n", filename);
-		return(-1);
-	    }
-	    xmlElemDump(f, ctxt->doc, node);
-	    fclose(f);
-	}
+                f = fopen((char *) filename, "w");
+                if (f == NULL) {
+                    xmlGenericError(xmlGenericErrorContext,
+                                    "Failed to write to %s\n", filename);
+                    return (-1);
+                }
+                xmlElemDump(f, ctxt->doc, node);
+                fclose(f);
+            }
     }
-    return(0);
+    return (0);
 }
 
 /**
@@ -1428,47 +1616,49 @@
  *
  * Returns 0 or -1 in case of error
  */
-static int 
-xmlShellSave(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node ATTRIBUTE_UNUSED,
-             xmlNodePtr node2 ATTRIBUTE_UNUSED) {
+int
+xmlShellSave(xmlShellCtxtPtr ctxt, char *filename,
+             xmlNodePtr node ATTRIBUTE_UNUSED,
+             xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
     if (ctxt->doc == NULL)
-	return(-1);
+        return (-1);
     if ((filename == NULL) || (filename[0] == 0))
         filename = ctxt->filename;
 #ifdef W_OK
     if (access((char *) filename, W_OK)) {
         xmlGenericError(xmlGenericErrorContext,
-		"Cannot save to %s\n", filename);
-	return(-1);
+                        "Cannot save to %s\n", filename);
+        return (-1);
     }
 #endif
-    switch(ctxt->doc->type) {
+    switch (ctxt->doc->type) {
         case XML_DOCUMENT_NODE:
-	    if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
-		xmlGenericError(xmlGenericErrorContext,
-			"Failed to save to %s\n", filename);
-	    }
-	    break;
+            if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
+                xmlGenericError(xmlGenericErrorContext,
+                                "Failed to save to %s\n", filename);
+            }
+            break;
         case XML_HTML_DOCUMENT_NODE:
 #ifdef LIBXML_HTML_ENABLED
-	    if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
-		xmlGenericError(xmlGenericErrorContext,
-			"Failed to save to %s\n", filename);
-	    }
+            if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
+                xmlGenericError(xmlGenericErrorContext,
+                                "Failed to save to %s\n", filename);
+            }
 #else
-	    if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
-		xmlGenericError(xmlGenericErrorContext,
-			"Failed to save to %s\n", filename);
-	    }
+            if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
+                xmlGenericError(xmlGenericErrorContext,
+                                "Failed to save to %s\n", filename);
+            }
 #endif /* LIBXML_HTML_ENABLED */
-	    break;
-	default:
-	    xmlGenericError(xmlGenericErrorContext, 
-	      "To save to subparts of a document use the 'write' command\n");
-	    return(-1);
-	    
+            break;
+        default:
+            xmlGenericError(xmlGenericErrorContext,
+	    "To save to subparts of a document use the 'write' command\n");
+            return (-1);
+
     }
-    return(0);
+    return (0);
 }
 
 /**
@@ -1484,9 +1674,11 @@
  *
  * Returns 0 or -1 in case of error
  */
-static int 
-xmlShellValidate(xmlShellCtxtPtr ctxt, char *dtd, xmlNodePtr node ATTRIBUTE_UNUSED,
-                 xmlNodePtr node2 ATTRIBUTE_UNUSED) {
+int
+xmlShellValidate(xmlShellCtxtPtr ctxt, char *dtd,
+                 xmlNodePtr node ATTRIBUTE_UNUSED,
+                 xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
     xmlValidCtxt vctxt;
     int res = -1;
 
@@ -1499,14 +1691,14 @@
     } else {
         xmlDtdPtr subset;
 
-	subset = xmlParseDTD(NULL, (xmlChar *) dtd);
-	if (subset != NULL) {
+        subset = xmlParseDTD(NULL, (xmlChar *) dtd);
+        if (subset != NULL) {
             res = xmlValidateDtd(&vctxt, ctxt->doc, subset);
 
-	    xmlFreeDtd(subset);
-	}
+            xmlFreeDtd(subset);
+        }
     }
-    return(res);
+    return (res);
 }
 
 /**
@@ -1522,66 +1714,70 @@
  *
  * Returns 0 or -1 in case of error
  */
-static int 
-xmlShellDu(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED, xmlNodePtr tree,
-                  xmlNodePtr node2 ATTRIBUTE_UNUSED) {
+int
+xmlShellDu(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
+           char *arg ATTRIBUTE_UNUSED, xmlNodePtr tree,
+           xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
     xmlNodePtr node;
-    int indent = 0,i;
+    int indent = 0, i;
 
-    if (tree == NULL) return(-1);
+    if (tree == NULL)
+        return (-1);
     node = tree;
     while (node != NULL) {
         if ((node->type == XML_DOCUMENT_NODE) ||
             (node->type == XML_HTML_DOCUMENT_NODE)) {
-	    printf("/\n");
-	} else if (node->type == XML_ELEMENT_NODE) {
-	    for (i = 0;i < indent;i++)
-	        printf("  ");
-	    printf("%s\n", node->name);
-	} else {
-	}
+            printf("/\n");
+        } else if (node->type == XML_ELEMENT_NODE) {
+            for (i = 0; i < indent; i++)
+                printf("  ");
+            printf("%s\n", node->name);
+        } else {
+        }
 
-	/*
-	 * Browse the full subtree, deep first
-	 */
+        /*
+         * Browse the full subtree, deep first
+         */
 
         if ((node->type == XML_DOCUMENT_NODE) ||
             (node->type == XML_HTML_DOCUMENT_NODE)) {
-	    node = ((xmlDocPtr) node)->children;
-        } else if ((node->children != NULL) && (node->type != XML_ENTITY_REF_NODE)) {
-	    /* deep first */
-	    node = node->children;
-	    indent++;
-	} else if ((node != tree) && (node->next != NULL)) {
-	    /* then siblings */
-	    node = node->next;
-	} else if (node != tree) {
-	    /* go up to parents->next if needed */
-	    while (node != tree) {
-	        if (node->parent != NULL) {
-		    node = node->parent;
-		    indent--;
-		}
-		if ((node != tree) && (node->next != NULL)) {
-		    node = node->next;
-		    break;
-		}
-		if (node->parent == NULL) {
-		    node = NULL;
-		    break;
-		}
-		if (node == tree) {
-		    node = NULL;
-		    break;
-		}
-	    }
-	    /* exit condition */
-	    if (node == tree) 
-	        node = NULL;
-	} else
-	    node = NULL;
+            node = ((xmlDocPtr) node)->children;
+        } else if ((node->children != NULL)
+                   && (node->type != XML_ENTITY_REF_NODE)) {
+            /* deep first */
+            node = node->children;
+            indent++;
+        } else if ((node != tree) && (node->next != NULL)) {
+            /* then siblings */
+            node = node->next;
+        } else if (node != tree) {
+            /* go up to parents->next if needed */
+            while (node != tree) {
+                if (node->parent != NULL) {
+                    node = node->parent;
+                    indent--;
+                }
+                if ((node != tree) && (node->next != NULL)) {
+                    node = node->next;
+                    break;
+                }
+                if (node->parent == NULL) {
+                    node = NULL;
+                    break;
+                }
+                if (node == tree) {
+                    node = NULL;
+                    break;
+                }
+            }
+            /* exit condition */
+            if (node == tree)
+                node = NULL;
+        } else
+            node = NULL;
     }
-    return(0);
+    return (0);
 }
 
 /**
@@ -1598,62 +1794,71 @@
  *
  * Returns 0 or -1 in case of error
  */
-static int 
-xmlShellPwd(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, char *buffer, xmlNodePtr node,
-                  xmlNodePtr node2 ATTRIBUTE_UNUSED) {
+int
+xmlShellPwd(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, char *buffer,
+            xmlNodePtr node, xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
     xmlNodePtr cur, tmp, next;
     char buf[500];
     char sep;
     const char *name;
+    char nametemp[100];
     int occur = 0;
 
     buffer[0] = 0;
-    if (node == NULL) return(-1);
+    if (node == NULL)
+        return (-1);
     cur = node;
     do {
-	name = "";
-	sep= '?';
-	occur = 0;
-	if ((cur->type == XML_DOCUMENT_NODE) ||
-	    (cur->type == XML_HTML_DOCUMENT_NODE)) {
-	    sep = '/';
-	    next = NULL;
-	} else if (cur->type == XML_ELEMENT_NODE) {
-	    sep = '/';
-	    name = (const char *)cur->name;
-	    next = cur->parent;
+        name = "";
+        sep = '?';
+        occur = 0;
+        if ((cur->type == XML_DOCUMENT_NODE) ||
+            (cur->type == XML_HTML_DOCUMENT_NODE)) {
+            sep = '/';
+            next = NULL;
+        } else if (cur->type == XML_ELEMENT_NODE) {
+            sep = '/';
+            name = (const char *) cur->name;
+            if (cur->ns) {
+                snprintf(nametemp, 99, "%s:%s", cur->ns->prefix,
+                         cur->name);
+                name = nametemp;
+            }
+            next = cur->parent;
 
-	    /*
-	     * Thumbler index computation
-	     */
-	    tmp = cur->prev;
+            /*
+             * Thumbler index computation
+             */
+            tmp = cur->prev;
             while (tmp != NULL) {
-	        if (xmlStrEqual(cur->name, tmp->name))
-		    occur++;
-	        tmp = tmp->prev;
-	    }
-	    if (occur == 0) {
-	        tmp = cur->next;
-		while (tmp != NULL) {
-		    if (xmlStrEqual(cur->name, tmp->name))
-			occur++;
-		    tmp = tmp->next;
-		}
-		if (occur != 0) occur = 1;
-	    } else
-	        occur++;
-	} else if (cur->type == XML_ATTRIBUTE_NODE) {
-	    sep = '@';
-	    name = (const char *) (((xmlAttrPtr) cur)->name);
-	    next = ((xmlAttrPtr) cur)->parent;
-	} else {
-	    next = cur->parent;
-	}
-	if (occur == 0)
-	    snprintf(buf, sizeof(buf), "%c%s%s", sep, name, buffer);
+                if (xmlStrEqual(cur->name, tmp->name))
+                    occur++;
+                tmp = tmp->prev;
+            }
+            if (occur == 0) {
+                tmp = cur->next;
+                while (tmp != NULL) {
+                    if (xmlStrEqual(cur->name, tmp->name))
+                        occur++;
+                    tmp = tmp->next;
+                }
+                if (occur != 0)
+                    occur = 1;
+            } else
+                occur++;
+        } else if (cur->type == XML_ATTRIBUTE_NODE) {
+            sep = '@';
+            name = (const char *) (((xmlAttrPtr) cur)->name);
+            next = ((xmlAttrPtr) cur)->parent;
+        } else {
+            next = cur->parent;
+        }
+        if (occur == 0)
+            snprintf(buf, sizeof(buf), "%c%s%s", sep, name, buffer);
         else
-	    snprintf(buf, sizeof(buf), "%c%s[%d]%s",
-                    sep, name, occur, buffer);
+            snprintf(buf, sizeof(buf), "%c%s[%d]%s",
+                     sep, name, occur, buffer);
         buf[sizeof(buf) - 1] = 0;
         /*
          * This test prevents buffer overflow, because this routine
@@ -1664,11 +1869,11 @@
          * be at least 500 chars long, and could be stripped if too long.
          */
         if (strlen(buffer) + strlen(buf) > 499)
-           break;
-	strcpy(buffer, buf);
+            break;
+        strcpy(buffer, buf);
         cur = next;
     } while (cur != NULL);
-    return(0);
+    return (0);
 }
 
 /**
@@ -1684,7 +1889,8 @@
  */
 void
 xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
-         FILE *output) {
+         FILE * output)
+{
     char prompt[500] = "/ > ";
     char *cmdline = NULL, *cur;
     int nbargs;
@@ -1703,320 +1909,336 @@
     if (output == NULL)
         return;
     ctxt = (xmlShellCtxtPtr) xmlMalloc(sizeof(xmlShellCtxt));
-    if (ctxt == NULL) 
+    if (ctxt == NULL)
         return;
     ctxt->loaded = 0;
     ctxt->doc = doc;
     ctxt->input = input;
     ctxt->output = output;
     ctxt->filename = (char *) xmlStrdup((xmlChar *) filename);
-    ctxt->node = (xmlNodePtr) ctxt->doc;	 
+    ctxt->node = (xmlNodePtr) ctxt->doc;
 
 #ifdef LIBXML_XPATH_ENABLED
     ctxt->pctxt = xmlXPathNewContext(ctxt->doc);
     if (ctxt->pctxt == NULL) {
-	xmlFree(ctxt);
-	return;
+        xmlFree(ctxt);
+        return;
     }
 #endif /* LIBXML_XPATH_ENABLED */
     while (1) {
         if (ctxt->node == (xmlNodePtr) ctxt->doc)
-	    sprintf(prompt, "%s > ", "/");
-	else if (ctxt->node->name)
-	    snprintf(prompt, sizeof(prompt), "%s > ", ctxt->node->name);
+            sprintf(prompt, "%s > ", "/");
+        else if (ctxt->node->name)
+            snprintf(prompt, sizeof(prompt), "%s > ", ctxt->node->name);
         else
-	    sprintf(prompt, "? > ");
+            sprintf(prompt, "? > ");
         prompt[sizeof(prompt) - 1] = 0;
 
-	/*
-	 * Get a new command line
-	 */
+        /*
+         * Get a new command line
+         */
         cmdline = ctxt->input(prompt);
-        if (cmdline == NULL) break;
+        if (cmdline == NULL)
+            break;
 
-	/*
-	 * Parse the command itself
-	 */
-	cur = cmdline;
-	nbargs = 0;
-	while ((*cur == ' ') || (*cur == '\t')) cur++;
-	i = 0;
-	while ((*cur != ' ') && (*cur != '\t') &&
-	       (*cur != '\n') && (*cur != '\r')) {
-	    if (*cur == 0)
-		break;
-	    command[i++] = *cur++;
-	}
-	command[i] = 0;
-	if (i == 0) continue;
-	nbargs++;
+        /*
+         * Parse the command itself
+         */
+        cur = cmdline;
+        nbargs = 0;
+        while ((*cur == ' ') || (*cur == '\t'))
+            cur++;
+        i = 0;
+        while ((*cur != ' ') && (*cur != '\t') &&
+               (*cur != '\n') && (*cur != '\r')) {
+            if (*cur == 0)
+                break;
+            command[i++] = *cur++;
+        }
+        command[i] = 0;
+        if (i == 0)
+            continue;
+        nbargs++;
 
-	/*
-	 * Parse the argument
-	 */
-	while ((*cur == ' ') || (*cur == '\t')) cur++;
-	i = 0;
-	while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) {
-	    if (*cur == 0)
-		break;
-	    arg[i++] = *cur++;
-	}
-	arg[i] = 0;
-	if (i != 0) 
-	    nbargs++;
+        /*
+         * Parse the argument
+         */
+        while ((*cur == ' ') || (*cur == '\t'))
+            cur++;
+        i = 0;
+        while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) {
+            if (*cur == 0)
+                break;
+            arg[i++] = *cur++;
+        }
+        arg[i] = 0;
+        if (i != 0)
+            nbargs++;
 
-	/*
-	 * start interpreting the command
-	 */
+        /*
+         * start interpreting the command
+         */
         if (!strcmp(command, "exit"))
-	    break;
+            break;
         if (!strcmp(command, "quit"))
-	    break;
+            break;
         if (!strcmp(command, "bye"))
-	    break;
-	if (!strcmp(command, "validate")) {
-	    xmlShellValidate(ctxt, arg, NULL, NULL);
-	} else if (!strcmp(command, "load")) {
-	    xmlShellLoad(ctxt, arg, NULL, NULL);
-	} else if (!strcmp(command, "save")) {
-	    xmlShellSave(ctxt, arg, NULL, NULL);
-	} else if (!strcmp(command, "write")) {
-	    xmlShellWrite(ctxt, arg, NULL, NULL);
-	} else if (!strcmp(command, "free")) {
-	    if (arg[0] == 0) {
-		xmlMemShow(stdout, 0);
-	    } else {
-	        int len = 0;
-		sscanf(arg, "%d", &len);
-		xmlMemShow(stdout, len);
-	    }
-	} else if (!strcmp(command, "pwd")) {
-	    char dir[500];
-	    if (!xmlShellPwd(ctxt, dir, ctxt->node, NULL))
-		printf("%s\n", dir);
-	} else  if (!strcmp(command, "du")) {
-	    xmlShellDu(ctxt, NULL, ctxt->node, NULL);
-	} else  if (!strcmp(command, "base")) {
-	    xmlShellBase(ctxt, NULL, ctxt->node, NULL);
-	} else  if ((!strcmp(command, "ls")) ||
-	      (!strcmp(command, "dir"))) {
-	    int dir = (!strcmp(command, "dir"));
-	    if (arg[0] == 0) {
-		if (dir)
-		    xmlShellDir(ctxt, NULL, ctxt->node, NULL);
-		else
-		    xmlShellList(ctxt, NULL, ctxt->node, NULL);
-	    } else {
-	        ctxt->pctxt->node = ctxt->node;
-#ifdef LIBXML_XPATH_ENABLED
-	        ctxt->pctxt->node = ctxt->node;
-		list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
-#else
-		list = NULL;
-#endif /* LIBXML_XPATH_ENABLED */
-		if (list != NULL) {
-		    switch (list->type) {
-			case XPATH_UNDEFINED:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s: no such node\n", arg);
-			    break;
-			case XPATH_NODESET: {
-			    int indx;
+            break;
+        if (!strcmp(command, "validate")) {
+            xmlShellValidate(ctxt, arg, NULL, NULL);
+        } else if (!strcmp(command, "load")) {
+            xmlShellLoad(ctxt, arg, NULL, NULL);
+        } else if (!strcmp(command, "save")) {
+            xmlShellSave(ctxt, arg, NULL, NULL);
+        } else if (!strcmp(command, "write")) {
+            xmlShellWrite(ctxt, arg, NULL, NULL);
+        } else if (!strcmp(command, "free")) {
+            if (arg[0] == 0) {
+                xmlMemShow(stdout, 0);
+            } else {
+                int len = 0;
 
-			    for (indx = 0;indx < list->nodesetval->nodeNr;
-				 indx++) {
-				if (dir)
-				    xmlShellDir(ctxt, NULL,
-				       list->nodesetval->nodeTab[indx], NULL);
-				else
-				    xmlShellList(ctxt, NULL,
-				       list->nodesetval->nodeTab[indx], NULL);
-			    }
-			    break;
-			}
-			case XPATH_BOOLEAN:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is a Boolean\n", arg);
-			    break;
-			case XPATH_NUMBER:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is a number\n", arg);
-			    break;
-			case XPATH_STRING:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is a string\n", arg);
-			    break;
-			case XPATH_POINT:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is a point\n", arg);
-			    break;
-			case XPATH_RANGE:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is a range\n", arg);
-			    break;
-			case XPATH_LOCATIONSET:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is a range\n", arg);
-			    break;
-			case XPATH_USERS:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is user-defined\n", arg);
-			    break;
-			case XPATH_XSLT_TREE:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is an XSLT value tree\n", arg);
-			    break;
-		    }
-#ifdef LIBXML_XPATH_ENABLED
-		    xmlXPathFreeObject(list);
-#endif
-		} else {
-		    xmlGenericError(xmlGenericErrorContext,
-			    "%s: no such node\n", arg);
-		}
-		ctxt->pctxt->node = NULL;
-	    }
-	} else if (!strcmp(command, "cd")) {
-	    if (arg[0] == 0) {
-		ctxt->node = (xmlNodePtr) ctxt->doc;
-	    } else {
-#ifdef LIBXML_XPATH_ENABLED
-	        ctxt->pctxt->node = ctxt->node;
-		list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
-#else
-		list = NULL;
-#endif /* LIBXML_XPATH_ENABLED */
-		if (list != NULL) {
-		    switch (list->type) {
-			case XPATH_UNDEFINED:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s: no such node\n", arg);
-			    break;
-			case XPATH_NODESET:
-			    if (list->nodesetval->nodeNr == 1) {
-				ctxt->node = list->nodesetval->nodeTab[0];
-			    } else 
-				xmlGenericError(xmlGenericErrorContext,
-					"%s is a %d Node Set\n",
-				        arg, list->nodesetval->nodeNr);
-			    break;
-			case XPATH_BOOLEAN:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is a Boolean\n", arg);
-			    break;
-			case XPATH_NUMBER:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is a number\n", arg);
-			    break;
-			case XPATH_STRING:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is a string\n", arg);
-			    break;
-			case XPATH_POINT:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is a point\n", arg);
-			    break;
-			case XPATH_RANGE:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is a range\n", arg);
-			    break;
-			case XPATH_LOCATIONSET:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is a range\n", arg);
-			    break;
-			case XPATH_USERS:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is user-defined\n", arg);
-			    break;
-			case XPATH_XSLT_TREE:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is an XSLT value tree\n", arg);
-			    break;
-		    }
-#ifdef LIBXML_XPATH_ENABLED
-		    xmlXPathFreeObject(list);
-#endif
-		} else {
-		    xmlGenericError(xmlGenericErrorContext,
-			    "%s: no such node\n", arg);
-		}
-		ctxt->pctxt->node = NULL;
-	    }
-	} else if (!strcmp(command, "cat")) {
-	    if (arg[0] == 0) {
-		xmlShellCat(ctxt, NULL, ctxt->node, NULL);
-	    } else {
-	        ctxt->pctxt->node = ctxt->node;
-#ifdef LIBXML_XPATH_ENABLED
-	        ctxt->pctxt->node = ctxt->node;
-		list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
-#else
-		list = NULL;
-#endif /* LIBXML_XPATH_ENABLED */
-		if (list != NULL) {
-		    switch (list->type) {
-			case XPATH_UNDEFINED:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s: no such node\n", arg);
-			    break;
-			case XPATH_NODESET: {
-			    int indx;
+                sscanf(arg, "%d", &len);
+                xmlMemShow(stdout, len);
+            }
+        } else if (!strcmp(command, "pwd")) {
+            char dir[500];
 
-			    for (indx = 0;indx < list->nodesetval->nodeNr;
-				 indx++) {
-			        if (i > 0) printf(" -------\n");
-				xmlShellCat(ctxt, NULL,
-				    list->nodesetval->nodeTab[indx], NULL);
-			    }
-			    break;
-			}
-			case XPATH_BOOLEAN:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is a Boolean\n", arg);
-			    break;
-			case XPATH_NUMBER:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is a number\n", arg);
-			    break;
-			case XPATH_STRING:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is a string\n", arg);
-			    break;
-			case XPATH_POINT:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is a point\n", arg);
-			    break;
-			case XPATH_RANGE:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is a range\n", arg);
-			    break;
-			case XPATH_LOCATIONSET:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is a range\n", arg);
-			    break;
-			case XPATH_USERS:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is user-defined\n", arg);
-			    break;
-			case XPATH_XSLT_TREE:
-			    xmlGenericError(xmlGenericErrorContext,
-				    "%s is an XSLT value tree\n", arg);
-			    break;
-		    }
+            if (!xmlShellPwd(ctxt, dir, ctxt->node, NULL))
+                printf("%s\n", dir);
+        } else if (!strcmp(command, "du")) {
+            xmlShellDu(ctxt, NULL, ctxt->node, NULL);
+        } else if (!strcmp(command, "base")) {
+            xmlShellBase(ctxt, NULL, ctxt->node, NULL);
+        } else if ((!strcmp(command, "ls")) || (!strcmp(command, "dir"))) {
+            int dir = (!strcmp(command, "dir"));
+
+            if (arg[0] == 0) {
+                if (dir)
+                    xmlShellDir(ctxt, NULL, ctxt->node, NULL);
+                else
+                    xmlShellList(ctxt, NULL, ctxt->node, NULL);
+            } else {
+                ctxt->pctxt->node = ctxt->node;
 #ifdef LIBXML_XPATH_ENABLED
-		    xmlXPathFreeObject(list);
+                ctxt->pctxt->node = ctxt->node;
+                list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
+#else
+                list = NULL;
+#endif /* LIBXML_XPATH_ENABLED */
+                if (list != NULL) {
+                    switch (list->type) {
+                        case XPATH_UNDEFINED:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s: no such node\n", arg);
+                            break;
+                        case XPATH_NODESET:{
+                                int indx;
+
+                                for (indx = 0;
+                                     indx < list->nodesetval->nodeNr;
+                                     indx++) {
+                                    if (dir)
+                                        xmlShellDir(ctxt, NULL,
+                                                    list->nodesetval->
+                                                    nodeTab[indx], NULL);
+                                    else
+                                        xmlShellList(ctxt, NULL,
+                                                     list->nodesetval->
+                                                     nodeTab[indx], NULL);
+                                }
+                                break;
+                            }
+                        case XPATH_BOOLEAN:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a Boolean\n", arg);
+                            break;
+                        case XPATH_NUMBER:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a number\n", arg);
+                            break;
+                        case XPATH_STRING:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a string\n", arg);
+                            break;
+                        case XPATH_POINT:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a point\n", arg);
+                            break;
+                        case XPATH_RANGE:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a range\n", arg);
+                            break;
+                        case XPATH_LOCATIONSET:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a range\n", arg);
+                            break;
+                        case XPATH_USERS:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is user-defined\n", arg);
+                            break;
+                        case XPATH_XSLT_TREE:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is an XSLT value tree\n",
+                                            arg);
+                            break;
+                    }
+#ifdef LIBXML_XPATH_ENABLED
+                    xmlXPathFreeObject(list);
 #endif
-		} else {
-		    xmlGenericError(xmlGenericErrorContext,
-			    "%s: no such node\n", arg);
-		}
-		ctxt->pctxt->node = NULL;
-	    }
-	} else {
-	    xmlGenericError(xmlGenericErrorContext,
-		    "Unknown command %s\n", command);
-	}
-	free(cmdline); /* not xmlFree here ! */
+                } else {
+                    xmlGenericError(xmlGenericErrorContext,
+                                    "%s: no such node\n", arg);
+                }
+                ctxt->pctxt->node = NULL;
+            }
+        } else if (!strcmp(command, "cd")) {
+            if (arg[0] == 0) {
+                ctxt->node = (xmlNodePtr) ctxt->doc;
+            } else {
+#ifdef LIBXML_XPATH_ENABLED
+                ctxt->pctxt->node = ctxt->node;
+                list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
+#else
+                list = NULL;
+#endif /* LIBXML_XPATH_ENABLED */
+                if (list != NULL) {
+                    switch (list->type) {
+                        case XPATH_UNDEFINED:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s: no such node\n", arg);
+                            break;
+                        case XPATH_NODESET:
+                            if (list->nodesetval->nodeNr == 1) {
+                                ctxt->node = list->nodesetval->nodeTab[0];
+                            } else
+                                xmlGenericError(xmlGenericErrorContext,
+                                                "%s is a %d Node Set\n",
+                                                arg,
+                                                list->nodesetval->nodeNr);
+                            break;
+                        case XPATH_BOOLEAN:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a Boolean\n", arg);
+                            break;
+                        case XPATH_NUMBER:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a number\n", arg);
+                            break;
+                        case XPATH_STRING:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a string\n", arg);
+                            break;
+                        case XPATH_POINT:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a point\n", arg);
+                            break;
+                        case XPATH_RANGE:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a range\n", arg);
+                            break;
+                        case XPATH_LOCATIONSET:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a range\n", arg);
+                            break;
+                        case XPATH_USERS:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is user-defined\n", arg);
+                            break;
+                        case XPATH_XSLT_TREE:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is an XSLT value tree\n",
+                                            arg);
+                            break;
+                    }
+#ifdef LIBXML_XPATH_ENABLED
+                    xmlXPathFreeObject(list);
+#endif
+                } else {
+                    xmlGenericError(xmlGenericErrorContext,
+                                    "%s: no such node\n", arg);
+                }
+                ctxt->pctxt->node = NULL;
+            }
+        } else if (!strcmp(command, "cat")) {
+            if (arg[0] == 0) {
+                xmlShellCat(ctxt, NULL, ctxt->node, NULL);
+            } else {
+                ctxt->pctxt->node = ctxt->node;
+#ifdef LIBXML_XPATH_ENABLED
+                ctxt->pctxt->node = ctxt->node;
+                list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
+#else
+                list = NULL;
+#endif /* LIBXML_XPATH_ENABLED */
+                if (list != NULL) {
+                    switch (list->type) {
+                        case XPATH_UNDEFINED:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s: no such node\n", arg);
+                            break;
+                        case XPATH_NODESET:{
+                                int indx;
+
+                                for (indx = 0;
+                                     indx < list->nodesetval->nodeNr;
+                                     indx++) {
+                                    if (i > 0)
+                                        printf(" -------\n");
+                                    xmlShellCat(ctxt, NULL,
+                                                list->nodesetval->
+                                                nodeTab[indx], NULL);
+                                }
+                                break;
+                            }
+                        case XPATH_BOOLEAN:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a Boolean\n", arg);
+                            break;
+                        case XPATH_NUMBER:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a number\n", arg);
+                            break;
+                        case XPATH_STRING:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a string\n", arg);
+                            break;
+                        case XPATH_POINT:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a point\n", arg);
+                            break;
+                        case XPATH_RANGE:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a range\n", arg);
+                            break;
+                        case XPATH_LOCATIONSET:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a range\n", arg);
+                            break;
+                        case XPATH_USERS:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is user-defined\n", arg);
+                            break;
+                        case XPATH_XSLT_TREE:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is an XSLT value tree\n",
+                                            arg);
+                            break;
+                    }
+#ifdef LIBXML_XPATH_ENABLED
+                    xmlXPathFreeObject(list);
+#endif
+                } else {
+                    xmlGenericError(xmlGenericErrorContext,
+                                    "%s: no such node\n", arg);
+                }
+                ctxt->pctxt->node = NULL;
+            }
+        } else {
+            xmlGenericError(xmlGenericErrorContext,
+                            "Unknown command %s\n", command);
+        }
+        free(cmdline);          /* not xmlFree here ! */
     }
 #ifdef LIBXML_XPATH_ENABLED
     xmlXPathFreeContext(ctxt->pctxt);
@@ -2025,10 +2247,10 @@
         xmlFreeDoc(ctxt->doc);
     }
     if (ctxt->filename != NULL)
-	xmlFree(ctxt->filename);
+        xmlFree(ctxt->filename);
     xmlFree(ctxt);
     if (cmdline != NULL)
-        free(cmdline); /* not xmlFree here ! */
+        free(cmdline);          /* not xmlFree here ! */
 }
 
 #endif /* LIBXML_DEBUG_ENABLED */
diff --git a/include/libxml/debugXML.h b/include/libxml/debugXML.h
index 36f86a4..bcd8505 100644
--- a/include/libxml/debugXML.h
+++ b/include/libxml/debugXML.h
@@ -47,6 +47,12 @@
 void	xmlDebugDumpEntities	(FILE *output,
 				 xmlDocPtr doc);
 
+void	xmlLsOneNode		(FILE *output, xmlNodePtr node);
+int	xmlLsCountNode		(xmlNodePtr node);
+
+const char *xmlBoolToText	(int bool);
+long	xmlGetLineNo		(xmlNodePtr node);
+
 /****************************************************************
  *								*
  *	 The XML shell related structures and functions		*
@@ -97,13 +103,57 @@
 			     xmlNodePtr node,
 			     xmlNodePtr node2);
 
+void	xmlShellPrintXPathError	(int errorType, const char* arg);
+void	xmlShellPrintNode	(xmlNodePtr node);
+void	xmlShellPrintXPathResult(xmlXPathObjectPtr list);
+int	xmlShellList		(xmlShellCtxtPtr ctxt,
+				 char *arg,
+				 xmlNodePtr node,
+				 xmlNodePtr node2);
+int	xmlShellBase		(xmlShellCtxtPtr ctxt,
+				 char *arg,
+				 xmlNodePtr node,
+				 xmlNodePtr node2);
+int	xmlShellDir		(xmlShellCtxtPtr ctxt,
+				 char *arg,
+				 xmlNodePtr node,
+				 xmlNodePtr node2);
+int	xmlShellCat		(xmlShellCtxtPtr ctxt,
+				 char *arg,
+				 xmlNodePtr node,
+				 xmlNodePtr node2);
+int	xmlShellLoad		(xmlShellCtxtPtr ctxt,
+				 char *filename,
+				 xmlNodePtr node,
+				 xmlNodePtr node2);
+int	xmlShellWrite		(xmlShellCtxtPtr ctxt,
+				 char *filename,
+				 xmlNodePtr node,
+				 xmlNodePtr node2);
+int	xmlShellSave		(xmlShellCtxtPtr ctxt,
+				 char *filename,
+				 xmlNodePtr node,
+				 xmlNodePtr node2);
+int	xmlShellValidate	(xmlShellCtxtPtr ctxt,
+				 char *dtd,
+				 xmlNodePtr node,
+				 xmlNodePtr node2);
+int	xmlShellDu		(xmlShellCtxtPtr ctxt,
+				 char *arg,
+				 xmlNodePtr tree,
+				 xmlNodePtr node2);
+int	xmlShellPwd		(xmlShellCtxtPtr ctxt,
+				 char *buffer,
+				 xmlNodePtr node,
+				 xmlNodePtr node2);
+
 /*
  * The Shell interface.
  */
-void	xmlShell	(xmlDocPtr doc,
-			 char *filename,
-			 xmlShellReadlineFunc input,
-			 FILE *output);
+void	xmlShell		(xmlDocPtr doc,
+				 char *filename,
+				 xmlShellReadlineFunc input,
+				 FILE *output);
 			 
 #ifdef __cplusplus
 }
diff --git a/tree.c b/tree.c
index 836bb03..799d9bf 100644
--- a/tree.c
+++ b/tree.c
@@ -5479,6 +5479,10 @@
         xmlDumpElementDecl(buf, (xmlElementPtr) cur);
 	return;
     }
+    if (cur->type == XML_ATTRIBUTE_NODE){
+      xmlAttrDump(buf, doc, (xmlAttrPtr)cur);
+      return;
+    }
     if (cur->type == XML_ATTRIBUTE_DECL) {
         xmlDumpAttributeDecl(buf, (xmlAttributePtr) cur);
 	return;
@@ -5653,6 +5657,7 @@
 		"xmlElemDump : doc == NULL\n");
     }
 #endif
+      
     buf = xmlBufferCreate();
     if (buf == NULL) return;
     if ((doc != NULL) &&