working on better error reporting of validity errors, especially providing

* error.c valid.c: working on better error reporting of validity
  errors, especially providing an accurate context.
* result/valid/xlink.xml.err result/valid/rss.xml.err: better
  error reports in those cases.
Daniel
diff --git a/ChangeLog b/ChangeLog
index 824c70b..5beb6e2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Thu Sep  5 16:19:18 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* error.c valid.c: working on better error reporting of validity
+	  errors, especially providing an accurate context.
+	* result/valid/xlink.xml.err result/valid/rss.xml.err: better
+	  error reports in those cases.
+
 Thu Sep  5 13:29:47 CEST 2002 Daniel Veillard <daniel@veillard.com>
 
 	* DOCBparser.c HTMLparser.c c14n.c entities.c list.c
diff --git a/error.c b/error.c
index 14d91f3..9a80fd5 100644
--- a/error.c
+++ b/error.c
@@ -350,22 +350,34 @@
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
     xmlParserInputPtr input = NULL;
     char * str;
+    int len = xmlStrlen((const xmlChar *) msg);
+    static int had_info = 0;
+    int need_context = 0;
+    int need_info = 0;
 
-    if (ctxt != NULL) {
-	input = ctxt->input;
-	if ((input->filename == NULL) && (ctxt->inputNr > 1))
-	    input = ctxt->inputTab[ctxt->inputNr - 2];
-	    
-	xmlParserPrintFileInfo(input);
+    if ((len > 1) && (msg[len - 2] != ':')) {
+	if (ctxt != NULL) {
+	    input = ctxt->input;
+	    if ((input->filename == NULL) && (ctxt->inputNr > 1))
+		input = ctxt->inputTab[ctxt->inputNr - 2];
+		
+	    if (had_info == 0) {
+		xmlParserPrintFileInfo(input);
+	    }
+	}
+	xmlGenericError(xmlGenericErrorContext, "validity error: ");
+	need_context = 1;
+	had_info = 0;
+    } else {
+	had_info = 1;
     }
 
-    xmlGenericError(xmlGenericErrorContext, "validity error: ");
     XML_GET_VAR_STR(msg, str);
     xmlGenericError(xmlGenericErrorContext, "%s", str);
     if (str != NULL)
 	xmlFree(str);
 
-    if (ctxt != NULL) {
+    if ((ctxt != NULL) && (input != NULL)) {
 	xmlParserPrintFileContext(input);
     }
 }
@@ -385,8 +397,9 @@
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
     xmlParserInputPtr input = NULL;
     char * str;
+    int len = xmlStrlen((const xmlChar *) msg);
 
-    if (ctxt != NULL) {
+    if ((ctxt != NULL) && (len != 0) && (msg[len - 1] != ':')) {
 	input = ctxt->input;
 	if ((input->filename == NULL) && (ctxt->inputNr > 1))
 	    input = ctxt->inputTab[ctxt->inputNr - 2];
diff --git a/result/valid/rss.xml.err b/result/valid/rss.xml.err
index f76367d..1a998f2 100644
--- a/result/valid/rss.xml.err
+++ b/result/valid/rss.xml.err
@@ -1,3 +1,3 @@
-./test/valid/rss.xml:177: validity error: Element rss does not carry attribute version
+./test/valid/rss.xml:172: validity error: Element rss does not carry attribute version
 </rss>
      ^
diff --git a/result/valid/xlink.xml.err b/result/valid/xlink.xml.err
index 27977f7..0394f19 100644
--- a/result/valid/xlink.xml.err
+++ b/result/valid/xlink.xml.err
@@ -1,6 +1,6 @@
 ./test/valid/xlink.xml:450: validity error: ID dt-arc already defined
 	<p><termdef id="dt-arc" term="Arc">An <term>arc</term> is contained within an 
                                    ^
-./test/valid/xlink.xml:530: validity error: IDREF attribute def references an unknown ID "dt-xlg"
+./test/valid/xlink.xml:199: validity error: IDREF attribute def references an unknown ID "dt-xlg"
 
 ^
diff --git a/valid.c b/valid.c
index 1e836d9..ca0d29d 100644
--- a/valid.c
+++ b/valid.c
@@ -311,23 +311,27 @@
 
 #define VECTXT(ctxt, node)					\
    if ((ctxt != NULL) && (ctxt->error != NULL) &&		\
-       (node != NULL) && (node->type == XML_ELEMENT_NODE)) {	\
-       if ((node->doc != NULL) && (node->doc->URL != NULL))	\
-	   ctxt->error(ctxt->userData, "%s:%d:", node->doc->URL,\
+       (node != NULL)) {					\
+       xmlChar *base = xmlNodeGetBase(NULL,node);		\
+       if (base != NULL) {					\
+	   ctxt->error(ctxt->userData, "%s:%d: ", base,		\
 		       (int) node->content);			\
-       else							\
-	   ctxt->error(ctxt->userData, ":%d:", 			\
+	   xmlFree(base);					\
+       } else							\
+	   ctxt->error(ctxt->userData, ":%d: ", 		\
 		       (int) node->content);			\
    }
 
 #define VWCTXT(ctxt, node)					\
    if ((ctxt != NULL) && (ctxt->warning != NULL) &&		\
-       (node != NULL) && (node->type == XML_ELEMENT_NODE)) {	\
-       if ((node->doc != NULL) && (node->doc->URL != NULL))	\
-	   ctxt->warning(ctxt->userData, "%s:%d:", node->doc->URL,\
+       (node != NULL)) {					\
+       xmlChar *base = xmlNodeGetBase(NULL,node);		\
+       if (base != NULL) {					\
+	   ctxt->warning(ctxt->userData, "%s:%d: ", base,	\
 		       (int) node->content);			\
-       else							\
-	   ctxt->warning(ctxt->userData, ":%d:", 		\
+	   xmlFree(base);					\
+       } else							\
+	   ctxt->warning(ctxt->userData, ":%d: ", 		\
 		       (int) node->content);			\
    }
 
@@ -1904,8 +1908,10 @@
 	/*
 	 * The id is already defined in this DTD.
 	 */
-	if (ctxt != NULL)
+	if (ctxt != NULL) {
+	    VECTXT(ctxt, attr->parent);
 	    VERROR(ctxt->userData, "ID %s already defined\n", value);
+	}
 	xmlFreeID(ret);
 	return(NULL);
     }
@@ -4786,6 +4792,7 @@
 	    if ((xmlStrEqual(doc->intSubset->name, BAD_CAST "HTML")) &&
 		(xmlStrEqual(root->name, BAD_CAST "html")))
 		goto name_ok;
+	    VECTXT(ctxt, root);
 	    VERROR(ctxt->userData,
 		   "Not valid: root and DTD name do not match '%s' and '%s'\n",
 		   root->name, doc->intSubset->name);
@@ -4874,6 +4881,7 @@
     if (attr->atype == XML_ATTRIBUTE_IDREF) {
 	id = xmlGetID(ctxt->doc, name);
 	if (id == NULL) {
+	    VECTXT(ctxt, attr->parent);
 	    VERROR(ctxt->userData, 
 	       "IDREF attribute %s references an unknown ID \"%s\"\n",
 		   attr->name, name);
@@ -4895,6 +4903,7 @@
 	    *cur = 0;
 	    id = xmlGetID(ctxt->doc, str);
 	    if (id == NULL) {
+		VECTXT(ctxt, attr->parent);
 		VERROR(ctxt->userData, 
 	       "IDREFS attribute %s references an unknown ID \"%s\"\n",
 		       attr->name, str);