diff --git a/ChangeLog b/ChangeLog
index edf652d35df17788cb48390bab49e1c62044b2dd_Q2hhbmdlTG9n..563e1383046f52590b15a669684ec4d30b0ec5b8_Q2hhbmdlTG9n 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Wed Jan 17 14:25:25 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* TODO: more stuff
+	* libxslt/transform.c: context position and size in for-each
+	* libxslt/xsltutils[ch] libxslt/makefile.am: added the util module
+	  and put Error and Debug routines
+	* libxslt/xslt.c libxslt/transform.c libxslt/pattern.c: switched
+	  to use the Debug calls, cleanup
+	* libxslt/xsltproc.c: added -v to enable debug printing
+
 Tue Jan 16 17:17:17 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
 	* TODO: started filling it :-(
diff --git a/TODO b/TODO
index edf652d35df17788cb48390bab49e1c62044b2dd_VE9ETw==..563e1383046f52590b15a669684ec4d30b0ec5b8_VE9ETw== 100644
--- a/TODO
+++ b/TODO
@@ -2,6 +2,8 @@
   - should transforms for a given stylesheet be thread clean,
     or can a stylesheet be enriched with document specific
     informations and cleaned up later ?
+  - seems that saving back XSLT stylesheet from a compiled form might
+    be a bit ugly ...
     
 Import:
   -> parse them
@@ -28,3 +30,7 @@
   -> check the version stuff, design a separate module for error interfacing
      and default handling, parsing vs. runtime, fatal / compat / warning,
      and lack of optionnal features.
+
+Support Attribute value templates:
+  -> starts to be urgent. Design it in flexible ways but try to optimize
+     to handle most of it at the stylesheet parse time ...
diff --git a/libxslt/Makefile.am b/libxslt/Makefile.am
index edf652d35df17788cb48390bab49e1c62044b2dd_bGlieHNsdC9NYWtlZmlsZS5hbQ==..563e1383046f52590b15a669684ec4d30b0ec5b8_bGlieHNsdC9NYWtlZmlsZS5hbQ== 100644
--- a/libxslt/Makefile.am
+++ b/libxslt/Makefile.am
@@ -6,6 +6,8 @@
 libxslt_la_SOURCES = 			\
 	xslt.c				\
 	xslt.h				\
+	xsltutils.c			\
+	xsltutils.h			\
 	pattern.c			\
 	pattern.h			\
 	transform.c			\
diff --git a/libxslt/pattern.c b/libxslt/pattern.c
index edf652d35df17788cb48390bab49e1c62044b2dd_bGlieHNsdC9wYXR0ZXJuLmM=..563e1383046f52590b15a669684ec4d30b0ec5b8_bGlieHNsdC9wYXR0ZXJuLmM= 100644
--- a/libxslt/pattern.c
+++ b/libxslt/pattern.c
@@ -21,6 +21,7 @@
 #include <libxml/parserInternals.h>
 #include "xslt.h"
 #include "xsltInternals.h"
+#include "xsltutils.h"
 
 /* #define DEBUG_PARSING */
 
@@ -24,22 +25,6 @@
 
 /* #define DEBUG_PARSING */
 
-#define TODO 								\
-    xsltGenericError(xsltGenericErrorContext,				\
-	    "Unimplemented block at %s:%d\n",				\
-            __FILE__, __LINE__);
-
-/*
- * To cleanup
- */
-xmlChar *xmlSplitQName2(const xmlChar *name, xmlChar **prefix);
-
-/*
- * There is no XSLT specific error reporting module yet
- */
-#define xsltGenericError xmlGenericError
-#define xsltGenericErrorContext xmlGenericErrorContext
-
 /*
  * Types are private:
  */
@@ -901,7 +886,7 @@
     }
 
 #ifdef DEBUG_PARSING
-    xsltGenericError(xsltGenericErrorContext,
+    xsltGenericDebug(xsltGenericDebugContext,
 	    "xsltCompilePattern : parsing '%s'\n", pattern);
 #endif
 
@@ -1057,8 +1042,8 @@
 	    return(-1);
 	}
 #ifdef DEBUG_PARSING
-	xsltGenericError(xsltGenericErrorContext,
+	xsltGenericDebug(xsltGenericDebugContext,
 		"xsltAddTemplate: created template hash\n");
 #endif
 	xmlHashAddEntry(style->templatesHash, name, pat);
 #ifdef DEBUG_PARSING
@@ -1061,8 +1046,8 @@
 		"xsltAddTemplate: created template hash\n");
 #endif
 	xmlHashAddEntry(style->templatesHash, name, pat);
 #ifdef DEBUG_PARSING
-	xsltGenericError(xsltGenericErrorContext,
+	xsltGenericDebug(xsltGenericDebugContext,
 		"xsltAddTemplate: added new hash %s\n", name);
 #endif
     } else {
@@ -1070,7 +1055,7 @@
 	if (list == NULL) {
 	    xmlHashAddEntry(style->templatesHash, name, pat);
 #ifdef DEBUG_PARSING
-	    xsltGenericError(xsltGenericErrorContext,
+	    xsltGenericDebug(xsltGenericDebugContext,
 		    "xsltAddTemplate: added new hash %s\n", name);
 #endif
 	} else {
@@ -1082,7 +1067,7 @@
 		pat->next = list;
 		xmlHashUpdateEntry(style->templatesHash, name, pat, NULL);
 #ifdef DEBUG_PARSING
-		xsltGenericError(xsltGenericErrorContext,
+		xsltGenericDebug(xsltGenericDebugContext,
 			"xsltAddTemplate: added head hash for %s\n", name);
 #endif
 	    } else {
@@ -1161,7 +1146,7 @@
     list = (xsltCompMatchPtr) xmlHashLookup(style->templatesHash, name);
     if (list == NULL) {
 #ifdef DEBUG_MATCHING
-	xsltGenericError(xsltGenericErrorContext,
+	xsltGenericDebug(xsltGenericDebugContext,
 		"xsltGetTemplate: empty set for %s\n", name);
 #endif
 	return(NULL);
diff --git a/libxslt/transform.c b/libxslt/transform.c
index edf652d35df17788cb48390bab49e1c62044b2dd_bGlieHNsdC90cmFuc2Zvcm0uYw==..563e1383046f52590b15a669684ec4d30b0ec5b8_bGlieHNsdC90cmFuc2Zvcm0uYw== 100644
--- a/libxslt/transform.c
+++ b/libxslt/transform.c
@@ -26,9 +26,10 @@
 #include <libxml/HTMLtree.h>
 #include "xslt.h"
 #include "xsltInternals.h"
+#include "xsltutils.h"
 #include "pattern.h"
 #include "transform.h"
 
 #define DEBUG_PROCESS
 
 /*
@@ -29,21 +30,9 @@
 #include "pattern.h"
 #include "transform.h"
 
 #define DEBUG_PROCESS
 
 /*
- * To cleanup
- */
-xmlChar *xmlSplitQName2(const xmlChar *name, xmlChar **prefix);
-void xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs);
-
-/*
- * There is no XSLT specific error reporting module yet
- */
-#define xsltGenericError xmlGenericError
-#define xsltGenericErrorContext xmlGenericErrorContext
-
-/*
  * Useful macros
  */
 
@@ -47,22 +36,6 @@
  * Useful macros
  */
 
-#define TODO 								\
-    xsltGenericError(xsltGenericErrorContext,				\
-	    "Unimplemented block at %s:%d\n",				\
-            __FILE__, __LINE__);
-
-#define STRANGE 							\
-    xsltGenericError(xsltGenericErrorContext,				\
-	    "Internal error at %s:%d\n",				\
-            __FILE__, __LINE__);
-
-#define IS_XSLT_ELEM(n)							\
-    ((n)->ns != NULL) && (xmlStrEqual((n)->ns->href, XSLT_NAMESPACE))
-
-#define IS_XSLT_NAME(n, val)						\
-    (xmlStrEqual((n)->name, (const xmlChar *) (val)))
-
 #define IS_BLANK_NODE(n)						\
     (((n)->type == XML_TEXT_NODE) && (xsltIsBlank((n)->content)))
 
@@ -286,7 +259,7 @@
 	return;
     }
 #ifdef DEBUG_PROCESS
-    xsltGenericError(xsltGenericErrorContext,
+    xsltGenericDebug(xsltGenericDebugContext,
 	 "xsltValueOf: select %s\n", prop);
 #endif
 
@@ -325,7 +298,7 @@
     }
 #ifdef DEBUG_PROCESS
     else
-	xsltGenericError(xsltGenericErrorContext,
+	xsltGenericDebug(xsltGenericDebugContext,
 	     "xsltValueOf: result %s\n", res->stringval);
 #endif
 error:
@@ -469,7 +442,7 @@
 		break;
 	    default:
 #ifdef DEBUG_PROCESS
-		xsltGenericError(xsltGenericErrorContext,
+		xsltGenericDebug(xsltGenericDebugContext,
 		 "xsltDefaultProcessOneNode: skipping node type %d\n",
 		                 node->type);
 #endif
@@ -478,7 +451,7 @@
 	node = node->next;
 	if (delete != NULL) {
 #ifdef DEBUG_PROCESS
-	    xsltGenericError(xsltGenericErrorContext,
+	    xsltGenericDebug(xsltGenericDebugContext,
 		 "xsltDefaultProcessOneNode: removing ignorable blank node\n");
 #endif
 	    xmlUnlinkNode(delete);
@@ -505,7 +478,7 @@
 	return;
 
 #ifdef DEBUG_PROCESS
-    xsltGenericError(xsltGenericErrorContext,
+    xsltGenericDebug(xsltGenericDebugContext,
 	 "xsltApplyTemplates: node: %s\n", node->name);
 #endif
     prop = xmlGetNsProp(inst, (const xmlChar *)"select", XSLT_NAMESPACE);
@@ -541,7 +514,7 @@
 	 */
 	if (insert == NULL) {
 #ifdef DEBUG_PROCESS
-	    xsltGenericError(xsltGenericErrorContext,
+	    xsltGenericDebug(xsltGenericDebugContext,
 		 "xsltApplyOneTemplate: insert == NULL !\n");
 #endif
 	    return;
@@ -552,7 +525,7 @@
 	 */
 	if (delete != NULL) {
 #ifdef DEBUG_PROCESS
-	    xsltGenericError(xsltGenericErrorContext,
+	    xsltGenericDebug(xsltGenericDebugContext,
 		 "xsltApplyOneTemplate: removing ignorable blank node\n");
 #endif
 	    xmlUnlinkNode(delete);
@@ -580,5 +553,9 @@
 		ctxt->insert = insert;
 		xsltAttribute(ctxt, node, cur);
 		ctxt->insert = oldInsert;
+	    } else if (IS_XSLT_NAME(cur, "element")) {
+		ctxt->insert = insert;
+		xsltAttribute(ctxt, node, cur);
+		ctxt->insert = oldInsert;
 	    } else {
 #ifdef DEBUG_PROCESS
@@ -583,6 +560,6 @@
 	    } else {
 #ifdef DEBUG_PROCESS
-		xsltGenericError(xsltGenericErrorContext,
+		xsltGenericDebug(xsltGenericDebugContext,
 		     "xsltApplyOneTemplate: found xslt:%s\n", cur->name);
 #endif
 		TODO
@@ -596,7 +573,7 @@
 	     */
 	    if (!(IS_BLANK_NODE(cur))) {
 #ifdef DEBUG_PROCESS
-		xsltGenericError(xsltGenericErrorContext,
+		xsltGenericDebug(xsltGenericDebugContext,
 		     "xsltApplyOneTemplate: copy text %s\n", cur->content);
 #endif
 		copy = xmlCopyNode(cur, 0);
@@ -611,7 +588,7 @@
 	    }
 	} else if (cur->type == XML_ELEMENT_NODE) {
 #ifdef DEBUG_PROCESS
-	    xsltGenericError(xsltGenericErrorContext,
+	    xsltGenericDebug(xsltGenericDebugContext,
 		 "xsltApplyOneTemplate: copy node %s\n", cur->name);
 #endif
 	    copy = xsltCopyNode(ctxt, cur, insert);
@@ -683,7 +660,7 @@
 	return;
     }
 #ifdef DEBUG_PROCESS
-    xsltGenericError(xsltGenericErrorContext,
+    xsltGenericDebug(xsltGenericDebugContext,
 	 "xsltIf: test %s\n", prop);
 #endif
 
@@ -713,7 +690,7 @@
 	    doit = res->boolval;
 	else {
 #ifdef DEBUG_PROCESS
-	    xsltGenericError(xsltGenericErrorContext,
+	    xsltGenericDebug(xsltGenericDebugContext,
 		"xsltIf: test didn't evaluate to a boolean\n");
 #endif
 	    goto error;
@@ -721,7 +698,7 @@
     }
 
 #ifdef DEBUG_PROCESS
-    xsltGenericError(xsltGenericErrorContext,
+    xsltGenericDebug(xsltGenericDebugContext,
 	"xsltIf: test evaluate to %d\n", doit);
 #endif
     if (doit) {
@@ -753,7 +730,7 @@
     xmlNodePtr replacement;
     xmlNodeSetPtr list = NULL, oldlist;
     xmlXPathParserContextPtr xpathParserCtxt;
-    int i;
+    int i, oldProximityPosition, oldContextSize;
 
     if ((ctxt == NULL) || (node == NULL) || (inst == NULL))
 	return;
@@ -765,7 +742,7 @@
 	return;
     }
 #ifdef DEBUG_PROCESS
-    xsltGenericError(xsltGenericErrorContext,
+    xsltGenericDebug(xsltGenericDebugContext,
 	 "xsltForEach: select %s\n", prop);
 #endif
 
@@ -794,7 +771,7 @@
 	    list = res->nodesetval;
 	else {
 #ifdef DEBUG_PROCESS
-	    xsltGenericError(xsltGenericErrorContext,
+	    xsltGenericDebug(xsltGenericDebugContext,
 		"xsltForEach: select didn't evaluate to a node list\n");
 #endif
 	    goto error;
@@ -802,7 +779,7 @@
     }
 
 #ifdef DEBUG_PROCESS
-    xsltGenericError(xsltGenericErrorContext,
+    xsltGenericDebug(xsltGenericDebugContext,
 	"xsltForEach: select evaluate to %d nodes\n", list->nodeNr);
 #endif
     /* TODO: handle and skip the xsl:sort */
@@ -810,5 +787,8 @@
 
     oldlist = ctxt->nodeList;
     ctxt->nodeList = list;
+    oldContextSize = ctxt->xpathCtxt->contextSize;
+    oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
+    ctxt->xpathCtxt->contextSize = list->nodeNr;
     for (i = 0;i < list->nodeNr;i++) {
 	ctxt->node = list->nodeTab[i];
@@ -813,5 +793,6 @@
     for (i = 0;i < list->nodeNr;i++) {
 	ctxt->node = list->nodeTab[i];
+	ctxt->xpathCtxt->proximityPosition = i + 1;
 	xsltApplyOneTemplate(ctxt, list->nodeTab[i], replacement);
     }
     ctxt->nodeList = oldlist;
@@ -815,6 +796,8 @@
 	xsltApplyOneTemplate(ctxt, list->nodeTab[i], replacement);
     }
     ctxt->nodeList = oldlist;
+    ctxt->xpathCtxt->contextSize = oldContextSize;
+    ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
 
 error:
     if (xpathParserCtxt != NULL)
@@ -843,6 +826,6 @@
     if (template == NULL) {
 #ifdef DEBUG_PROCESS
 	if (node->type == XML_DOCUMENT_NODE)
-	    xsltGenericError(xsltGenericErrorContext,
+	    xsltGenericDebug(xsltGenericDebugContext,
 	     "xsltProcessOneNode: no template found for /\n");
 	else 
@@ -847,6 +830,6 @@
 	     "xsltProcessOneNode: no template found for /\n");
 	else 
-	    xsltGenericError(xsltGenericErrorContext,
+	    xsltGenericDebug(xsltGenericDebugContext,
 	     "xsltProcessOneNode: no template found for %s\n", node->name);
 #endif
 
diff --git a/libxslt/xslt.c b/libxslt/xslt.c
index edf652d35df17788cb48390bab49e1c62044b2dd_bGlieHNsdC94c2x0LmM=..563e1383046f52590b15a669684ec4d30b0ec5b8_bGlieHNsdC94c2x0LmM= 100644
--- a/libxslt/xslt.c
+++ b/libxslt/xslt.c
@@ -22,6 +22,5 @@
 #include "xslt.h"
 #include "xsltInternals.h"
 #include "pattern.h"
-
-/* #define DEBUG_PARSING */
+#include "xsltutils.h"
 
@@ -27,16 +26,7 @@
 
-/*
- * To cleanup
- */
-xmlChar *xmlSplitQName2(const xmlChar *name, xmlChar **prefix);
-
-/*
- * There is no XSLT specific error reporting module yet
- */
-#define xsltGenericError xmlGenericError
-#define xsltGenericErrorContext xmlGenericErrorContext
+#define DEBUG_PARSING
 
 /*
  * Useful macros
  */
 
@@ -38,17 +28,11 @@
 
 /*
  * Useful macros
  */
 
-#define IS_XSLT_ELEM(n)							\
-    ((n)->ns != NULL) && (xmlStrEqual((n)->ns->href, XSLT_NAMESPACE))
-
-#define IS_XSLT_NAME(n, val)						\
-    (xmlStrEqual((n)->name, (const xmlChar *) (val)))
-
 #define IS_BLANK(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xA) ||	\
                      ((c) == 0x0D))
 
 #define IS_BLANK_NODE(n)						\
     (((n)->type == XML_TEXT_NODE) && (xsltIsBlank((n)->content)))
 
@@ -49,18 +33,9 @@
 #define IS_BLANK(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xA) ||	\
                      ((c) == 0x0D))
 
 #define IS_BLANK_NODE(n)						\
     (((n)->type == XML_TEXT_NODE) && (xsltIsBlank((n)->content)))
 
-#define TODO 								\
-    xsltGenericError(xsltGenericErrorContext,				\
-	    "Unimplemented block at %s:%d\n",				\
-            __FILE__, __LINE__);
-
-#define STRANGE 							\
-    xsltGenericError(xsltGenericErrorContext,				\
-	    "Internal error at %s:%d\n",				\
-            __FILE__, __LINE__);
 
 /************************************************************************
  *									*
@@ -354,7 +329,7 @@
 	    element = xmlStrndup(element, end - element);
 	    if (element) {
 #ifdef DEBUG_PARSING
-		xsltGenericError(xsltGenericErrorContext,
+		xsltGenericDebug(xsltGenericDebugContext,
 		    "add cdata section output element %s\n", element);
 #endif
 		xmlHashAddEntry(style->stripSpaces, element, "cdata");
@@ -405,7 +380,7 @@
 	element = xmlStrndup(element, end - element);
 	if (element) {
 #ifdef DEBUG_PARSING
-	    xsltGenericError(xsltGenericErrorContext,
+	    xsltGenericDebug(xsltGenericDebugContext,
 		"add preserved space element %s\n", element);
 #endif
 	    xmlHashAddEntry(style->stripSpaces, element, "preserve");
@@ -455,7 +430,7 @@
 	element = xmlStrndup(element, end - element);
 	if (element) {
 #ifdef DEBUG_PARSING
-	    xsltGenericError(xsltGenericErrorContext,
+	    xsltGenericDebug(xsltGenericDebugContext,
 		"add stripped space element %s\n", element);
 #endif
 	    xmlHashAddEntry(style->stripSpaces, element, "strip");
@@ -491,7 +466,7 @@
     while (cur != NULL) {
 	if (delete != NULL) {
 #ifdef DEBUG_PARSING
-	    xsltGenericError(xsltGenericErrorContext,
+	    xsltGenericDebug(xsltGenericDebugContext,
 	     "xsltParseStylesheetTemplate: removing ignorable blank node\n");
 #endif
 	    xmlUnlinkNode(delete);
@@ -553,7 +528,7 @@
     }
     if (delete != NULL) {
 #ifdef DEBUG_PARSING
-	xsltGenericError(xsltGenericErrorContext,
+	xsltGenericDebug(xsltGenericDebugContext,
 	 "xsltParseStylesheetTemplate: removing ignorable blank node\n");
 #endif
 	xmlUnlinkNode(delete);
@@ -720,7 +695,7 @@
 	}
 	if (!(IS_XSLT_ELEM(cur))) {
 #ifdef DEBUG_PARSING
-	    xsltGenericError(xsltGenericErrorContext,
+	    xsltGenericDebug(xsltGenericDebugContext,
 		    "xsltParseStylesheetTop : found foreign element %s\n",
 		    cur->name);
 #endif
@@ -740,7 +715,7 @@
 	}
 	if (!(IS_XSLT_ELEM(cur))) {
 #ifdef DEBUG_PARSING
-	    xsltGenericError(xsltGenericErrorContext,
+	    xsltGenericDebug(xsltGenericDebugContext,
 		    "xsltParseStylesheetTop : found foreign element %s\n",
 		    cur->name);
 #endif
@@ -783,7 +758,7 @@
 	cur = cur->next;
     }
 #ifdef DEBUG_PARSING
-    xsltGenericError(xsltGenericErrorContext,
+    xsltGenericDebug(xsltGenericDebugContext,
 		    "parsed %d templates\n", templates);
 #endif
 }
@@ -822,5 +797,7 @@
     }
 
     ret->doc = doc;
-    if ((IS_XSLT_ELEM(cur)) && (IS_XSLT_NAME(cur, "stylesheet"))) {
+    if ((IS_XSLT_ELEM(cur)) && 
+	((IS_XSLT_NAME(cur, "stylesheet")) ||
+	 (IS_XSLT_NAME(cur, "transform")))) {
 #ifdef DEBUG_PARSING
@@ -826,5 +803,5 @@
 #ifdef DEBUG_PARSING
-	xsltGenericError(xsltGenericErrorContext,
+	xsltGenericDebug(xsltGenericDebugContext,
 		"xsltParseStylesheetDoc : found stylesheet\n");
 #endif
 
@@ -845,7 +822,7 @@
 	}
 
 #ifdef DEBUG_PARSING
-        xsltGenericError(xsltGenericErrorContext,
+        xsltGenericDebug(xsltGenericDebugContext,
 		"xsltParseStylesheetDoc : document is stylesheet\n");
 #endif
 	
@@ -893,7 +870,7 @@
 	return(NULL);
 
 #ifdef DEBUG_PARSING
-    xsltGenericError(xsltGenericErrorContext,
+    xsltGenericDebug(xsltGenericDebugContext,
 	    "xsltParseStylesheetFile : parse %s\n", filename);
 #endif
 
diff --git a/libxslt/xsltproc.c b/libxslt/xsltproc.c
index edf652d35df17788cb48390bab49e1c62044b2dd_bGlieHNsdC94c2x0cHJvYy5j..563e1383046f52590b15a669684ec4d30b0ec5b8_bGlieHNsdC94c2x0cHJvYy5j 100644
--- a/libxslt/xsltproc.c
+++ b/libxslt/xsltproc.c
@@ -13,6 +13,7 @@
 #include <libxslt/xslt.h>
 #include <libxslt/xsltInternals.h>
 #include <libxslt/transform.h>
+#include <libxslt/xsltutils.h>
 
 static int debug = 0;
 
@@ -24,5 +25,5 @@
 
     LIBXML_TEST_VERSION
     for (i = 1; i < argc ; i++) {
-	if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
+	if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug"))) {
 	    debug++;
@@ -28,4 +29,9 @@
 	    debug++;
+	} else if ((!strcmp(argv[i], "-v")) ||
+		   (!strcmp(argv[i], "-verbose")) ||
+		   (!strcmp(argv[i], "--verbose"))) {
+	    xsltSetGenericDebugFunc(stderr, NULL);
+	}
     }
     xmlSubstituteEntitiesDefault(1);
     for (i = 1; i < argc ; i++) {
diff --git a/libxslt/xsltutils.c b/libxslt/xsltutils.c
new file mode 100644
index 0000000000000000000000000000000000000000..563e1383046f52590b15a669684ec4d30b0ec5b8_bGlieHNsdC94c2x0dXRpbHMuYw==
--- /dev/null
+++ b/libxslt/xsltutils.c
@@ -0,0 +1,120 @@
+/*
+ * xsltutils.c: Utilities for the XSL Transformation 1.0 engine
+ *
+ * Reference:
+ *   http://www.w3.org/TR/1999/REC-xslt-19991116
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel.Veillard@imag.fr
+ */
+
+#include "xsltconfig.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <libxml/xmlmemory.h>
+#include <libxml/tree.h>
+#include <libxml/xmlerror.h>
+#include "xsltutils.h"
+
+
+/************************************************************************
+ * 									*
+ * 		Handling of out of context errors			*
+ * 									*
+ ************************************************************************/
+
+/**
+ * xsltGenericErrorDefaultFunc:
+ * @ctx:  an error context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ * 
+ * Default handler for out of context error messages.
+ */
+void
+xsltGenericErrorDefaultFunc(void *ctx, const char *msg, ...) {
+    va_list args;
+
+    if (xsltGenericErrorContext == NULL)
+	xsltGenericErrorContext = (void *) stderr;
+
+    va_start(args, msg);
+    vfprintf((FILE *)xsltGenericErrorContext, msg, args);
+    va_end(args);
+}
+
+xmlGenericErrorFunc xsltGenericError = xsltGenericErrorDefaultFunc;
+void *xsltGenericErrorContext = NULL;
+
+
+/**
+ * xsltSetGenericErrorFunc:
+ * @ctx:  the new error handling context
+ * @handler:  the new handler function
+ *
+ * Function to reset the handler and the error context for out of
+ * context error messages.
+ * This simply means that @handler will be called for subsequent
+ * error messages while not parsing nor validating. And @ctx will
+ * be passed as first argument to @handler
+ * One can simply force messages to be emitted to another FILE * than
+ * stderr by setting @ctx to this file handle and @handler to NULL.
+ */
+void
+xsltSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) {
+    xsltGenericErrorContext = ctx;
+    if (handler != NULL)
+	xsltGenericError = handler;
+    else
+	xsltGenericError = xsltGenericErrorDefaultFunc;
+}
+
+/**
+ * xsltGenericDebugDefaultFunc:
+ * @ctx:  an error context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ * 
+ * Default handler for out of context error messages.
+ */
+void
+xsltGenericDebugDefaultFunc(void *ctx, const char *msg, ...) {
+    va_list args;
+
+    if (xsltGenericDebugContext == NULL)
+	return;
+
+    va_start(args, msg);
+    vfprintf((FILE *)xsltGenericDebugContext, msg, args);
+    va_end(args);
+}
+
+xmlGenericErrorFunc xsltGenericDebug = xsltGenericDebugDefaultFunc;
+void *xsltGenericDebugContext = NULL;
+
+
+/**
+ * xsltSetGenericDebugFunc:
+ * @ctx:  the new error handling context
+ * @handler:  the new handler function
+ *
+ * Function to reset the handler and the error context for out of
+ * context error messages.
+ * This simply means that @handler will be called for subsequent
+ * error messages while not parsing nor validating. And @ctx will
+ * be passed as first argument to @handler
+ * One can simply force messages to be emitted to another FILE * than
+ * stderr by setting @ctx to this file handle and @handler to NULL.
+ */
+void
+xsltSetGenericDebugFunc(void *ctx, xmlGenericErrorFunc handler) {
+    xsltGenericDebugContext = ctx;
+    if (handler != NULL)
+	xsltGenericDebug = handler;
+    else
+	xsltGenericDebug = xsltGenericDebugDefaultFunc;
+}
+
diff --git a/libxslt/xsltutils.h b/libxslt/xsltutils.h
new file mode 100644
index 0000000000000000000000000000000000000000..563e1383046f52590b15a669684ec4d30b0ec5b8_bGlieHNsdC94c2x0dXRpbHMuaA==
--- /dev/null
+++ b/libxslt/xsltutils.h
@@ -0,0 +1,63 @@
+/*
+ * xsltutils.h: interfaces for the utilities module of the XSLT engine
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel.Veillard@w3.org
+ */
+
+#ifndef __XML_XSLTUTILS_H__
+#define __XML_XSLTUTILS_H__
+
+#include <libxml/xpath.h>
+#include <libxml/xmlerror.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * To cleanup
+ */
+xmlChar *xmlSplitQName2(const xmlChar *name, xmlChar **prefix);
+void xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs);
+
+/*
+ * Useful macros
+ */
+
+#define TODO 								\
+    xsltGenericError(xsltGenericErrorContext,				\
+	    "Unimplemented block at %s:%d\n",				\
+            __FILE__, __LINE__);
+
+#define STRANGE 							\
+    xsltGenericError(xsltGenericErrorContext,				\
+	    "Internal error at %s:%d\n",				\
+            __FILE__, __LINE__);
+
+#define IS_XSLT_ELEM(n)							\
+    ((n)->ns != NULL) && (xmlStrEqual((n)->ns->href, XSLT_NAMESPACE))
+
+#define IS_XSLT_NAME(n, val)						\
+    (xmlStrEqual((n)->name, (const xmlChar *) (val)))
+
+
+/*
+ * XSLT specific error and debug reporting functions
+ */
+extern xmlGenericErrorFunc xsltGenericError;
+extern void *xsltGenericErrorContext;
+extern xmlGenericErrorFunc xsltGenericDebug;
+extern void *xsltGenericDebugContext;
+
+void		xsltSetGenericErrorFunc		(void *ctx,
+						 xmlGenericErrorFunc handler);
+void		xsltSetGenericDebugFunc		(void *ctx,
+						 xmlGenericErrorFunc handler);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_XSLTUTILS_H__ */
+