Description: Make generate-id() return identifiers in a deterministic way
 generate-id() used to return identifiers based on the memory address of
 the node object. This unfortunately prevents documentation to be built
 reproducily. Instead, we now increment a static counter and store its
 value in the node _private on the first invocation of generate-id().
Author: Jérémy Bobbio <lunar@debian.org>

--- libxslt-1.1.28.orig/libxslt/functions.c
+++ libxslt-1.1.28/libxslt/functions.c
@@ -660,12 +660,11 @@ xsltFormatNumberFunction(xmlXPathParserC
  */
 void
 xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
-    static char base_address;
+    static unsigned long next_id = 1;
     xmlNodePtr cur = NULL;
     xmlXPathObjectPtr obj = NULL;
-    long val;
+    unsigned long val;
     xmlChar str[30];
-    xmlDocPtr doc;
 
     if (nargs == 0) {
 	cur = ctxt->context->node;
@@ -698,31 +697,20 @@ xsltGenerateIdFunction(xmlXPathParserCon
 	ctxt->error = XPATH_INVALID_ARITY;
 	return;
     }
-    /*
-     * Okay this is ugly but should work, use the NodePtr address
-     * to forge the ID
-     */
-    if (cur->type != XML_NAMESPACE_DECL)
-        doc = cur->doc;
-    else {
-        xmlNsPtr ns = (xmlNsPtr) cur;
-
-        if (ns->context != NULL)
-            doc = ns->context;
-        else
-            doc = ctxt->context->doc;
-
-    }
 
     if (obj)
         xmlXPathFreeObject(obj);
 
-    val = (long)((char *)cur - (char *)&base_address);
-    if (val >= 0) {
-      sprintf((char *)str, "idp%ld", val);
-    } else {
-      sprintf((char *)str, "idm%ld", -val);
+    if (cur->_private == NULL) {
+        cur->_private = xmlMalloc(sizeof (unsigned long));
+        if (cur->_private == NULL) {
+            xmlGenericError(xmlGenericErrorContext, "malloc failed !\n");
+        }
+        *((unsigned long *)cur->_private) = next_id++;
     }
+    val = *((unsigned long *)cur->_private);
+
+    sprintf((char *)str, "id%lu", val);
     valuePush(ctxt, xmlXPathNewString(str));
 }
 