fixed XML Base computation which was broken added a base function to the

* tree.c: fixed XML Base computation which was broken
* debugXML.c: added a base function to the shell
* Makefile.am result/scripts/* test/scripts/*: added scripts
  based regression tests, and adding 2 XML Base tests
Daniel
diff --git a/ChangeLog b/ChangeLog
index 2339bda..fc453b6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Mon Jul  9 17:59:08 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c: fixed XML Base computation which was broken
+	* debugXML.c: added a base function to the shell
+	* Makefile.am result/scripts/* test/scripts/*: added scripts
+	  based regression tests, and adding 2 XML Base tests
+
 Mon Jul  9 12:31:05 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
 	* tree.c: set properties doc and call xmlSetListDoc for properties
diff --git a/Makefile.am b/Makefile.am
index 5c98219..202b2c9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -89,7 +89,7 @@
 
 testall : tests SVGtests SAXtests
 
-tests: XMLtests XMLenttests HTMLtests Validtests URItests XPathtests XPtrtests XIncludetests
+tests: XMLtests XMLenttests HTMLtests Validtests URItests XPathtests XPtrtests XIncludetests Scripttests
 
 HTMLtests : testHTML
 	@(echo > .memdump)
@@ -365,6 +365,27 @@
 	      rm result.$$name ; \
 	  fi ; fi ; done)
 
+Scripttests : xmllint
+	@(echo > .memdump)
+	@echo "##"
+	@echo "## Scripts regression tests"
+	@echo "## Some of the base computations may be different if srcdir != ."
+	@echo "##"
+	@(for i in $(srcdir)/test/scripts/*.script ; do \
+	  name=`basename $$i .script`; \
+	  xml=$(srcdir)/test/scripts/`basename $$i .script`.xml; \
+	  if [ -f $$xml ] ; then \
+	  if [ ! -f $(srcdir)/result/scripts/$$name ] ; then \
+	      echo New test file $$name ; \
+	      $(top_builddir)/xmllint --shell $$xml < $$i > $(srcdir)/result/scripts/$$name ; \
+	  else \
+	      echo Testing $$name ; \
+	      $(top_builddir)/xmllint --shell $$xml < $$i > result.$$name ; \
+	      grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0";\
+	      diff $(srcdir)/result/scripts/$$name result.$$name ; \
+	      rm result.$$name ; \
+	  fi ; fi ; done)
+
 SVGtests : xmllint
 	@echo "##"
 	@echo "## SVG parsing regression tests"
diff --git a/debugXML.c b/debugXML.c
index 512a366..92d71cb 100644
--- a/debugXML.c
+++ b/debugXML.c
@@ -1092,6 +1092,34 @@
 }
 
 /**
+ * xmlShellBase:
+ * @ctxt:  the shell context
+ * @arg:  unused
+ * @node:  a node
+ * @node2:  unused
+ *
+ * Implements the XML shell function "base"
+ * dumps the current XML base of the node
+ *
+ * Returns 0
+ */
+static 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");
+    } else {
+	printf("%s\n", base);
+	xmlFree(base);
+    }
+    return(0);
+}
+
+/**
  * xmlShellDir:
  * @ctxt:  the shell context
  * @arg:  unused
@@ -1654,6 +1682,8 @@
 		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"));
@@ -1724,7 +1754,7 @@
 			    break;
 		    }
 #ifdef LIBXML_XPATH_ENABLED
-		    xmlXPathFreeNodeSetList(list);
+		    xmlXPathFreeObject(list);
 #endif
 		} else {
 		    xmlGenericError(xmlGenericErrorContext,
@@ -1790,7 +1820,7 @@
 			    break;
 		    }
 #ifdef LIBXML_XPATH_ENABLED
-		    xmlXPathFreeNodeSetList(list);
+		    xmlXPathFreeObject(list);
 #endif
 		} else {
 		    xmlGenericError(xmlGenericErrorContext,
@@ -1860,7 +1890,7 @@
 			    break;
 		    }
 #ifdef LIBXML_XPATH_ENABLED
-		    xmlXPathFreeNodeSetList(list);
+		    xmlXPathFreeObject(list);
 #endif
 		} else {
 		    xmlGenericError(xmlGenericErrorContext,
@@ -1880,6 +1910,8 @@
     if (ctxt->loaded) {
         xmlFreeDoc(ctxt->doc);
     }
+    if (ctxt->filename != NULL)
+	xmlFree(ctxt->filename);
     xmlFree(ctxt);
     if (cmdline != NULL)
         free(cmdline); /* not xmlFree here ! */
diff --git a/result/scripts/base b/result/scripts/base
new file mode 100644
index 0000000..bdfed18
--- /dev/null
+++ b/result/scripts/base
@@ -0,0 +1,9 @@
+/ > base
+./test/scripts/base.xml
+/ > cd //e
+e > base
+http://example.com/base/
+e > cd .//img
+img > base
+http://example.com/base/images/
+img > exit
diff --git a/result/scripts/base2 b/result/scripts/base2
new file mode 100644
index 0000000..ba8bf64
--- /dev/null
+++ b/result/scripts/base2
@@ -0,0 +1,9 @@
+/ > base
+./test/scripts/base2.xml
+/ > cd //e
+e > base
+test/scripts/html/
+e > cd .//img
+img > base
+test/scripts/images/
+img > exit
diff --git a/test/scripts/base.script b/test/scripts/base.script
new file mode 100644
index 0000000..1fc3f57
--- /dev/null
+++ b/test/scripts/base.script
@@ -0,0 +1,7 @@
+base
+cd //e
+base
+cd .//img
+base
+exit
+
diff --git a/test/scripts/base.xml b/test/scripts/base.xml
new file mode 100644
index 0000000..81f71cb
--- /dev/null
+++ b/test/scripts/base.xml
@@ -0,0 +1,7 @@
+<doc>
+    <e xml:base="http://example.com/base/">
+	<images xml:base="images/">
+	    <img href="img1.gif"/>
+	</images>
+    </e>
+</doc>
diff --git a/test/scripts/base2.script b/test/scripts/base2.script
new file mode 100644
index 0000000..1fc3f57
--- /dev/null
+++ b/test/scripts/base2.script
@@ -0,0 +1,7 @@
+base
+cd //e
+base
+cd .//img
+base
+exit
+
diff --git a/test/scripts/base2.xml b/test/scripts/base2.xml
new file mode 100644
index 0000000..0e92a10
--- /dev/null
+++ b/test/scripts/base2.xml
@@ -0,0 +1,7 @@
+<doc>
+    <e xml:base="html/">
+	<images xml:base="../images/">
+	    <img href="img1.gif"/>
+	</images>
+    </e>
+</doc>
diff --git a/tree.c b/tree.c
index 0f78aca..db22591 100644
--- a/tree.c
+++ b/tree.c
@@ -28,6 +28,7 @@
 #include <libxml/xmlmemory.h>
 #include <libxml/tree.h>
 #include <libxml/parser.h>
+#include <libxml/uri.h>
 #include <libxml/entities.h>
 #include <libxml/valid.h>
 #include <libxml/xmlerror.h>
@@ -3317,7 +3318,8 @@
  */
 xmlChar *
 xmlNodeGetBase(xmlDocPtr doc, xmlNodePtr cur) {
-    xmlChar *base;
+    xmlChar *oldbase = NULL;
+    xmlChar *base, *newbase;
 
     if ((cur == NULL) && (doc == NULL)) 
         return(NULL);
@@ -3350,17 +3352,38 @@
 	    return(xmlStrdup(ent->URI));
 	}
 	if (cur->type == XML_ELEMENT_NODE) {
-	    base = xmlGetProp(cur, BAD_CAST "xml:base");
+	    base = xmlGetNsProp(cur, BAD_CAST "base", XML_XML_NAMESPACE);
 	    if (base != NULL) {
-		/* TODO : apply cascade in the base resolution ! */
-		return(base);
+		if (oldbase != NULL) {
+		    newbase = xmlBuildURI(oldbase, base);
+		    if (newbase != NULL) {
+			xmlFree(oldbase);
+			xmlFree(base);
+			oldbase = newbase;
+		    } else {
+			xmlFree(oldbase);
+			xmlFree(base);
+			return(NULL);
+		    }
+		} else {
+		    oldbase = base;
+		}
+		if ((!xmlStrncmp(oldbase, BAD_CAST "http://", 7)) ||
+		    (!xmlStrncmp(oldbase, BAD_CAST "ftp://", 6)) ||
+		    (!xmlStrncmp(oldbase, BAD_CAST "urn:", 4)))
+		    return(oldbase);
 	    }
 	}
 	cur = cur->parent;
     }
-    if ((doc != NULL) && (doc->URL != NULL))
-        return(xmlStrdup(doc->URL));
-    return(NULL);
+    if ((doc != NULL) && (doc->URL != NULL)) {
+	if (oldbase == NULL)
+	    return(xmlStrdup(doc->URL));
+	newbase = xmlBuildURI(oldbase, doc->URL);
+	xmlFree(oldbase);
+	return(newbase);
+    }
+    return(oldbase);
 }
  
 /**