Makefile.am: updated c14n tests suite
c14n.c: performance improvement for previous c14n patch
diff --git a/c14n.c b/c14n.c
index d8e42e0..3ab4a2f 100644
--- a/c14n.c
+++ b/c14n.c
@@ -41,6 +41,7 @@
 typedef struct _xmlC14NNamespaces {
     int nsNr;		/* number of nodes in the set */
     int nsMax;		/* size of the array as allocated */
+    int nsPos;		/* the begginning of the stack for this node */
     xmlNsPtr *nsTab;	/* array of nodes in no particular order */	      
 } xmlC14NNamespaces, *xmlC14NNamespacesPtr;
 
@@ -212,25 +213,28 @@
 xmlExcC14NIsRendered(xmlC14NCtxPtr ctx, xmlNsPtr ns)
 {
     int i;
-
+    int emptyNs;
+    
     if ((ctx == NULL) || (ctx->ns_rendered == NULL) || (ns == NULL)) {
         return (0);
     }
 
+    /*
+     * if the default namespace xmlns="" is not defined yet then 
+     * we do not want to print it out
+     */
+    emptyNs = ((xmlStrlen(ns->prefix) == 0) && (xmlStrlen(ns->href) == 0));
     if (ctx->ns_rendered->nsTab != NULL) {
-        for (i = ctx->ns_rendered->nsNr - 1; i >= 0; --i) {
-            xmlNsPtr ns1 = (xmlNsPtr) ctx->ns_rendered->nsTab[i];
+	int pos = (emptyNs) ? 0 : ctx->ns_rendered->nsPos;
+        for (i = ctx->ns_rendered->nsNr - 1; i >= pos; --i) {
+            xmlNsPtr ns1 = ctx->ns_rendered->nsTab[i];
 
             if (xmlStrEqual(ns1->prefix, ns->prefix)) {
                 return (xmlStrEqual(ns1->href, ns->href));
             }
         }
     }
-    /*
-     * if the default namespace xmlns="" is not defined yet then 
-     * we do not want to print it out
-     */
-    return ((xmlStrlen(ns->prefix) == 0) && (xmlStrlen(ns->href) == 0));
+    return(emptyNs);
 }
 
 /**
@@ -333,7 +337,6 @@
 {
     xmlNsPtr ns;
     xmlListPtr list;
-    xmlNodePtr visible_parent;
     
     if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
 #ifdef DEBUG_C14N
@@ -356,30 +359,19 @@
         return (-1);
     }
 
-    /* find nearest visible parent */
-    visible_parent = cur->parent;
-    while ((visible_parent != NULL) && (!xmlC14NIsVisible(ctx, visible_parent))) {
-        visible_parent = visible_parent->parent;
-    }
-
     if(ctx->visible_nodes == NULL) {
-	xmlNodePtr node;
-	
-	/* 
-         * the libxml does not create nodes for all namespaces known 
-	 * to the node (i.e. for namespaces defined in node parents). 
-	 * By this we need to now walk thru all namespace in current 
-	 * node and all invisible ancesstors
-         */
-	node = cur;
-	while (cur != visible_parent) {
-    	    for (ns = cur->nsDef; ns != NULL; ns = ns->next) {
-		if(!xmlC14NIsXmlNs(ns) && !xmlExcC14NIsRendered(ctx, ns)) {
-                    xmlListInsert(list, ns);
-                    xmlC14NNamespacesAdd(ctx->ns_rendered, ns);
-                }
-    	    }
-    	    cur = cur->parent;
+	xmlNsPtr tmp;
+
+	for (ns = cur->nsDef; ns != NULL; ns = ns->next) {
+	    if(!xmlC14NIsXmlNs(ns)) {
+	        tmp = (cur->parent != NULL) ?
+			xmlSearchNs(ctx->doc, cur->parent, ns->prefix) :
+			NULL;
+		if(((tmp == NULL) && (xmlStrlen(ns->href) > 0)) || 
+		    ((tmp != NULL) && !xmlStrEqual(ns->href, tmp->href))) {
+		    xmlListInsert(list, ns); 
+		}
+	    }
 	}
     } else {
 	int i;
@@ -391,9 +383,10 @@
 	    if(ctx->visible_nodes->nodeTab[i]->type == XML_NAMESPACE_DECL) {
 		ns = (xmlNsPtr) ctx->visible_nodes->nodeTab[i];
 		
-		if((ns != NULL) && (ns->next == (xmlNsPtr)cur) &&
-		   !xmlC14NIsXmlNs(ns) && !xmlExcC14NIsRendered(ctx, ns)) {
-                    xmlListInsert(list, ns);
+		if((ns != NULL) && (ns->next == (xmlNsPtr)cur) && !xmlC14NIsXmlNs(ns)) {
+		    if(!xmlExcC14NIsRendered(ctx, ns)) {
+                	xmlListInsert(list, ns);
+		    }
                     xmlC14NNamespacesAdd(ctx->ns_rendered, ns);
                 }
             }
@@ -488,10 +481,11 @@
      * todo: shouldn't we check for namespaces "visibility"?
      */
     ns = (cur->ns != NULL) ? cur->ns : xmlSearchNs(ctx->doc, cur, NULL);
-    if ((ns != NULL) && (!xmlC14NIsXmlNs(ns)) &&
-	(xmlListSearch(list, ns) == NULL) && !xmlExcC14NIsRendered(ctx, ns)) {
+    if ((ns != NULL) && (!xmlC14NIsXmlNs(ns)) && (xmlListSearch(list, ns) == NULL)) {
+	 if(!xmlExcC14NIsRendered(ctx, ns)) {
             xmlListInsert(list, ns);
-            xmlC14NNamespacesAdd(ctx->ns_rendered, ns);
+	}
+        xmlC14NNamespacesAdd(ctx->ns_rendered, ns);
     }
     attr = cur->properties;
     while (attr != NULL) {
@@ -501,9 +495,10 @@
 	   * do not apply directly to attributes")	 
          */
         if ((attr->ns != NULL) && xmlC14NIsVisible(ctx, attr) && 
-	    (!xmlC14NIsXmlNs(attr->ns)) && 
-            (xmlListSearch(list, attr->ns) == NULL) && (!xmlExcC14NIsRendered(ctx, attr->ns))) {
-        	xmlListInsert(list, attr->ns);
+	    (!xmlC14NIsXmlNs(attr->ns)) && (xmlListSearch(list, attr->ns) == NULL)) {
+		if(!xmlExcC14NIsRendered(ctx, attr->ns)) {
+        	    xmlListInsert(list, attr->ns);
+		}
         	xmlC14NNamespacesAdd(ctx->ns_rendered, attr->ns);
         }
         attr = attr->next;
@@ -527,9 +522,10 @@
             }
             ns = xmlSearchNs(ctx->doc, cur, prefix);
             if ((ns != NULL) && (!xmlC14NIsXmlNs(ns))) {
-                if (xmlListSearch(list, ns) == NULL &&
-                    !xmlExcC14NIsRendered(ctx, ns)) {
-                    xmlListInsert(list, ns);
+                if (xmlListSearch(list, ns) == NULL) {
+                    if(!xmlExcC14NIsRendered(ctx, ns)) {
+                	xmlListInsert(list, ns);
+		    }
                     xmlC14NNamespacesAdd(ctx->ns_rendered, ns);
                 }
             }
@@ -841,6 +837,7 @@
 {
     int ret;
     int ns_rendered_pos = 0;
+    int ns_rendered_nr = 0;
     int parent_is_doc = 0;
 
     if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
@@ -869,8 +866,9 @@
      * Save ns_rendered stack position for exclusive 
      * processing
      */
-    if (ctx->ns_rendered != NULL) {
-        ns_rendered_pos = ctx->ns_rendered->nsNr;
+    if (ctx->ns_rendered != NULL) {    
+        ns_rendered_pos = ctx->ns_rendered->nsPos;
+        ns_rendered_nr = ctx->ns_rendered->nsNr;
     }
 
     if (visible) {	
@@ -901,6 +899,9 @@
 #endif
             return (-1);
         }
+	if (ctx->ns_rendered != NULL) { 
+	    ctx->ns_rendered->nsPos = ns_rendered_nr; 
+	}
 
         ret = xmlC14NProcessAttrsAxis(ctx, cur);
         if (ret < 0) {
@@ -944,7 +945,8 @@
      * processing
      */
     if (ctx->ns_rendered != NULL) {
-        ctx->ns_rendered->nsNr = ns_rendered_pos;
+        ctx->ns_rendered->nsPos = ns_rendered_pos;
+        ctx->ns_rendered->nsNr = ns_rendered_nr;
     }
     return (0);
 }