quick but apparently working implementation of xi:fallback, should close

* xinclude.c: quick but apparently working implementation of
  xi:fallback, should close bug #89684
* Makefile.am test/XInclude/docs/fallback.xml
  result/XInclude/fallback.xml: added a basic test for fallback,
  and run with --nowarning to avoid a spurious warning
* configure.in: applied patch from Frederic Crozat for python
  bindings on AMD 64bits machines.
Daniel
diff --git a/ChangeLog b/ChangeLog
index ea6126e..fd8b9f8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Wed Aug 14 16:05:37 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: quick but apparently working implementation of
+	  xi:fallback, should close bug #89684
+	* Makefile.am test/XInclude/docs/fallback.xml 
+	  result/XInclude/fallback.xml: added a basic test for fallback,
+	  and run with --nowarning to avoid a spurious warning
+	* configure.in: applied patch from Frederic Crozat for python
+	  bindings on AMD 64bits machines.
+
 Wed Aug 14 10:47:46 CEST 2002 Daniel Veillard <daniel@veillard.com>
 
 	* parser.c: xmlSAXUserParseMemory() really ought to fail if
diff --git a/Makefile.am b/Makefile.am
index 0d3162f..f9d9426 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -399,10 +399,10 @@
 	  if [ ! -d $$i ] ; then \
 	  if [ ! -f $(srcdir)/result/XInclude/$$name ] ; then \
 	      echo New test file $$name ; \
-	      $(CHECKER) $(top_builddir)/xmllint --xinclude $$i > $(srcdir)/result/XInclude/$$name ; \
+	      $(CHECKER) $(top_builddir)/xmllint --nowarning --xinclude $$i > $(srcdir)/result/XInclude/$$name ; \
 	  else \
 	      echo Testing $$name ; \
-	      $(CHECKER) $(top_builddir)/xmllint --xinclude $$i > result.$$name ; \
+	      $(CHECKER) $(top_builddir)/xmllint --nowarning --xinclude $$i > result.$$name ; \
 	      grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0";\
 	      diff $(srcdir)/result/XInclude/$$name result.$$name ; \
 	      rm result.$$name ; \
diff --git a/configure.in b/configure.in
index 28bcada..5498602 100644
--- a/configure.in
+++ b/configure.in
@@ -230,16 +230,20 @@
 	    if test -r $prefix/include/python$PYTHON_VERSION/Python.h
 	    then
 	        PYTHON_INCLUDES='$(prefix)/include/python$(PYTHON_VERSION)'
-		PYTHON_SITE_PACKAGES='$(prefix)/lib/python$(PYTHON_VERSION)/site-packages'
+		PYTHON_SITE_PACKAGES='$(libdir)/python$(PYTHON_VERSION)/site-packages'
 	    else
 		if test -r /usr/include/python$PYTHON_VERSION/Python.h
 		then
 		    PYTHON_INCLUDES=/usr/include/python$PYTHON_VERSION
-		    PYTHON_SITE_PACKAGES='$(prefix)/lib/python$(PYTHON_VERSION)/site-packages'
+		    PYTHON_SITE_PACKAGES='$(libdir)/python$(PYTHON_VERSION)/site-packages'
 		else
 		    echo could not find python$PYTHON_VERSION/Python.h
 		fi
 	    fi
+		if ! test -d "$PYTHON_SITE_PACKAGES"
+		then
+			PYTHON_SITE_PACKAGES=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_python_lib()"`
+		fi
 	fi
     fi
 fi
diff --git a/result/XInclude/fallback.xml b/result/XInclude/fallback.xml
new file mode 100644
index 0000000..d7eed52
--- /dev/null
+++ b/result/XInclude/fallback.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<x xmlns:xinclude="http://www.w3.org/2001/XInclude">
+   <!-- Simple test of a fallback on unavailble URI -->
+   <warning>Inclusion failed</warning>
+</x>
diff --git a/test/XInclude/docs/fallback.xml b/test/XInclude/docs/fallback.xml
new file mode 100644
index 0000000..e80222e
--- /dev/null
+++ b/test/XInclude/docs/fallback.xml
@@ -0,0 +1,6 @@
+<x xmlns:xinclude="http://www.w3.org/2001/XInclude">
+   <!-- Simple test of a fallback on unavailble URI -->
+   <xinclude:include href="something.xml">
+     <xinclude:fallback><warning>Inclusion failed</warning></xinclude:fallback>
+   </xinclude:include>
+</x>
diff --git a/xinclude.c b/xinclude.c
index 1e96fe9..63cb5e9 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -710,8 +710,10 @@
  * @nr:  the xinclude node number
  * 
  * Load the document, and store the result in the XInclude context
+ *
+ * Returns 0 in case of success, -1 in case of failure
  */
-static void
+static int
 xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
     xmlDocPtr doc;
     xmlURIPtr uri;
@@ -725,7 +727,7 @@
     if (uri == NULL) {
 	xmlGenericError(xmlGenericErrorContext,
 		    "XInclude: invalid value URI %s\n", url);
-	return;
+	return(-1);
     }
     if (uri->fragment != NULL) {
 	fragment = (xmlChar *) uri->fragment;
@@ -738,7 +740,7 @@
 		    "XInclude: invalid value URI %s\n", url);
 	if (fragment != NULL)
 	    xmlFree(fragment);
-	return;
+	return(-1);
     }
 
     /*
@@ -764,12 +766,10 @@
      */
     doc = xmlParseFile((const char *)URL);
     if (doc == NULL) {
-	xmlGenericError(xmlGenericErrorContext,
-		    "XInclude: could not load %s\n", URL);
 	xmlFree(URL);
 	if (fragment != NULL)
 	    xmlFree(fragment);
-	return;
+	return(-1);
     }
     xmlXIncludeAddDoc(ctxt, doc, URL);
 
@@ -806,7 +806,7 @@
 			"XInclude: could create XPointer context\n");
 	    xmlFree(URL);
 	    xmlFree(fragment);
-	    return;
+	    return(-1);
 	}
 	xptr = xmlXPtrEval(fragment, xptrctxt);
 	if (xptr == NULL) {
@@ -816,7 +816,7 @@
 	    xmlXPathFreeContext(xptrctxt);
 	    xmlFree(URL);
 	    xmlFree(fragment);
-	    return;
+	    return(-1);
 	}
 	switch (xptr->type) {
 	    case XPATH_UNDEFINED:
@@ -832,7 +832,7 @@
 		xmlXPathFreeContext(xptrctxt);
 		xmlFree(URL);
 		xmlFree(fragment);
-		return;
+		return(-1);
 	    case XPATH_NODESET:
 	    case XPATH_RANGE:
 	    case XPATH_LOCATIONSET:
@@ -893,6 +893,7 @@
 	xmlFree(fragment);
     }
     xmlFree(URL);
+    return(0);
 }
 
 /**
@@ -902,8 +903,10 @@
  * @nr:  the xinclude node number
  * 
  * Load the content, and store the result in the XInclude context
+ *
+ * Returns 0 in case of success, -1 in case of failure
  */
-static void
+static int
 xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
     xmlParserInputBufferPtr buf;
     xmlNodePtr node;
@@ -917,21 +920,21 @@
     if (uri == NULL) {
 	xmlGenericError(xmlGenericErrorContext,
 		    "XInclude: invalid value URI %s\n", url);
-	return;
+	return(-1);
     }
     if (uri->fragment != NULL) {
 	xmlGenericError(xmlGenericErrorContext,
 		"XInclude: fragment identifier forbidden for text: %s\n",
 		uri->fragment);
 	xmlFreeURI(uri);
-	return;
+	return(-1);
     }
     URL = xmlSaveUri(uri);
     xmlFreeURI(uri);
     if (URL == NULL) {
 	xmlGenericError(xmlGenericErrorContext,
 		    "XInclude: invalid value URI %s\n", url);
-	return;
+	return(-1);
     }
 
     /*
@@ -942,7 +945,7 @@
 	xmlGenericError(xmlGenericErrorContext,
 		"XInclude: text serialization of document not available\n");
 	xmlFree(URL);
-	return;
+	return(-1);
     }
 
     /*
@@ -960,10 +963,8 @@
      */
     buf = xmlParserInputBufferCreateFilename((const char *)URL, 0);
     if (buf == NULL) {
-	xmlGenericError(xmlGenericErrorContext,
-		    "XInclude: could not load %s\n", URL);
 	xmlFree(URL);
-	return;
+	return(-1);
     }
     node = xmlNewText(NULL);
 
@@ -998,6 +999,27 @@
      */
     ctxt->repTab[nr] = node;
     xmlFree(URL);
+    return(0);
+}
+
+/**
+ * xmlXIncludeLoadFallback:
+ * @ctxt:  the XInclude context
+ * @fallback:  the fallback node
+ * @nr:  the xinclude node number
+ * 
+ * Load the content of teh fallback node, and store the result
+ * in the XInclude context
+ *
+ * Returns 0 in case of success, -1 in case of failure
+ */
+static int
+xmlXIncludeLoadFallback(xmlXIncludeCtxtPtr ctxt, xmlNodePtr fallback, int nr) {
+    if ((fallback == NULL) || (ctxt == NULL))
+	return(-1);
+
+    ctxt->repTab[nr] = xmlCopyNode(fallback->children, 1);
+    return(0);
 }
 
 /************************************************************************
@@ -1039,6 +1061,7 @@
     xmlChar *base;
     xmlChar *URI;
     int xml = 1; /* default Issue 64 */
+    int ret;
 
     if (ctxt == NULL)
 	return(-1);
@@ -1126,10 +1149,37 @@
      * Cleanup
      */
     if (xml) {
-	xmlXIncludeLoadDoc(ctxt, URI, nr);
+	ret = xmlXIncludeLoadDoc(ctxt, URI, nr);
 	/* xmlXIncludeGetFragment(ctxt, cur, URI); */
     } else {
-	xmlXIncludeLoadTxt(ctxt, URI, nr);
+	ret = xmlXIncludeLoadTxt(ctxt, URI, nr);
+    }
+    if (ret < 0) {
+	xmlNodePtr children;
+
+	/*
+	 * Time to try a fallback if availble
+	 */
+#ifdef DEBUG_XINCLUDE
+	xmlGenericError(xmlGenericErrorContext, "error looking for fallback\n");
+#endif
+	children = cur->children;
+	while (children != NULL) {
+	    if ((children->type == XML_ELEMENT_NODE) &&
+		(children->ns != NULL) &&
+		(xmlStrEqual(children->name, XINCLUDE_FALLBACK)) &&
+		(xmlStrEqual(children->ns->href, XINCLUDE_NS))) {
+		ret = xmlXIncludeLoadFallback(ctxt, children, nr);
+		if (ret == 0)
+		    break;
+	    }
+	    children = children->next;
+	}
+    }
+    if (ret < 0) {
+	xmlGenericError(xmlGenericErrorContext,
+		    "XInclude: could not load %s, and no fallback was found\n",
+		        URI);
     }
 
     /*