Tiny restructuring of the validation start-up functions. Added cleanup of

* xmlschemas.c: Tiny restructuring of the validation start-up
  functions. Added cleanup of the validation context at the
  end of validation. This takes care of the validation context
  being reused.
diff --git a/xmlschemas.c b/xmlschemas.c
index 82c5087..5166096 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -555,6 +555,8 @@
 static void
 xmlSchemaCheckDefaults(xmlSchemaTypePtr typeDecl,
                        xmlSchemaParserCtxtPtr ctxt, const xmlChar * name);
+static void
+xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
 
 /************************************************************************
  *									*
@@ -12695,9 +12697,11 @@
 static int
 xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
 {
-   if (vctxt->pctxt == NULL) {
-        vctxt->pctxt =xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
-	/* vctxt->pctxt = xmlSchemaNewParserCtxt("*"); */
+    if (vctxt->pctxt == NULL) {
+        if (vctxt->schema != NULL)
+	    vctxt->pctxt = xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
+	else
+	    vctxt->pctxt = xmlSchemaNewParserCtxt("*");
 	if (vctxt->pctxt == NULL) {
 	    xmlSchemaVErr(vctxt, NULL,
 		XML_SCHEMAV_INTERNAL,
@@ -20143,41 +20147,35 @@
 }
 
 /**
- * xmlSchemaValidateElement:
+ * xmlSchemaStartValidation:
  * @ctxt:  a schema validation context
- * @elem:  an element
  *
- * Validate an element in a tree
+ * The starting point of the validation, called by 
+ * xmlSchemaValidateDocument and xmlSchemaValidateOneElement.
  *
  * Returns 0 if the element is schemas valid, a positive error code
  *     number otherwise and -1 in case of internal or API error.
  */
 static int
-xmlSchemaValidateElement(xmlSchemaValidCtxtPtr ctxt)
+xmlSchemaStartValidation(xmlSchemaValidCtxtPtr ctxt)
 {
     xmlSchemaElementPtr elemDecl;    
     int ret = 0;
 
-    /* 
-    * This one is called by xmlSchemaValidateDocument and
-    * xmlSchemaValidateOneElement.
-    */  
+    ctxt->err = 0;
+    ctxt->nberrors = 0;     
     if (ctxt->schema == NULL) {
 	/*
 	* No schema was specified at time of creation of the validation
 	* context. Use xsi:schemaLocation and xsi:noNamespaceSchemaLocation
 	* of the instance to build a schema.
 	*/
-	if (ctxt->pctxt == NULL) 
-	    ctxt->pctxt = xmlSchemaNewParserCtxt("*");
 	if (ctxt->pctxt == NULL)
-	    return (-1);
+	    if (xmlSchemaCreatePCtxtOnVCtxt(ctxt) == -1)
+		return (-1);
 	ctxt->schema = xmlSchemaNewSchema(ctxt->pctxt);
 	if (ctxt->schema == NULL)
 	    return (-1);
-	/* TODO: assign user data. */
-	ctxt->pctxt->error = ctxt->error;
-	ctxt->pctxt->warning = ctxt->warning;	
 	ctxt->xsiAssemble = 1;
     } else
 	ctxt->xsiAssemble = 0;
@@ -20212,7 +20210,6 @@
 		"No matching global declaration available", NULL);
 	    ret = XML_SCHEMAV_CVC_ELT_1;
 	} else { 
-#ifdef IDC_ENABLED
 	    /*
 	    * Augment the IDC definitions.
 	    */
@@ -20220,15 +20217,10 @@
 		xmlHashScan(ctxt->schema->idcDef, 
 		    (xmlHashScanner) xmlSchemaAugmentIDC, ctxt);
 	    }
-#endif
-#ifdef ELEM_INFO_ENABLED
 	    ctxt->depth = -1;
 	    xmlSchemaBeginElement(ctxt);
-#endif
 	    ret = xmlSchemaValidateElementByDeclaration(ctxt, elemDecl);    
-#ifdef ELEM_INFO_ENABLED
 	    xmlSchemaEndElement(ctxt);
-#endif
 	    if (ret < 0) {
 		xmlSchemaVCustomErr(ctxt,
 		    XML_SCHEMAV_INTERNAL, ctxt->node, NULL,
@@ -20237,13 +20229,14 @@
 	    }
 	}
     }
-    /* ctxt->xsiAssemble = 0; */
+
     if (ctxt->xsiAssemble) {
 	if (ctxt->schema != NULL) {
 	    xmlSchemaFree(ctxt->schema);
 	    ctxt->schema = NULL;
 	}
     }
+    xmlSchemaClearValidCtxt(ctxt);
     return (ret);   
 }
 
@@ -20264,7 +20257,7 @@
     if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
 	return (-1);
 
-     if (ctxt->schema == NULL) {
+    if (ctxt->schema == NULL) {
 	xmlSchemaVErr(ctxt, NULL,
 	    XML_SCHEMAV_INTERNAL,
 	    "API error: xmlSchemaValidateOneElement, "
@@ -20273,45 +20266,9 @@
     }
 
     ctxt->doc = elem->doc;
-    ctxt->err = 0;
-    ctxt->nberrors = 0;
     ctxt->node = elem;
     ctxt->validationRoot = elem;
-    return (xmlSchemaValidateElement(ctxt));
-}
-
-/**
- * xmlSchemaValidateDocument:
- * @ctxt:  a schema validation context
- * @doc:  a parsed document tree
- * @xsiAssemble: should schemata be added if requested by the instance?
- *
- * Validate a document tree in memory.
- *
- * Returns 0 if the document is schemas valid, a positive error code
- *     number otherwise and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateDocument(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
-{
-    xmlNodePtr root;
-     
-    root = xmlDocGetRootElement(doc);
-    if (root == NULL) {
-        xmlSchemaVCustomErr(ctxt, 
-	    XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
-	    (xmlNodePtr) doc, NULL,
-	    "The document has no document element", NULL);
-        return (ctxt->err);
-    }    
-    /*
-     * Okay, start the recursive validation
-     */
-    ctxt->node = root;
-    ctxt->validationRoot = root;
-    xmlSchemaValidateElement(ctxt);
-
-    return (ctxt->err);
+    return (xmlSchemaStartValidation(ctxt));
 }
 
 /************************************************************************
@@ -20330,7 +20287,7 @@
  * xmlSchemaNewValidCtxt:
  * @schema:  a precompiled XML Schemas
  *
- * Create an XML Schemas validation context based on the given schema
+ * Create an XML Schemas validation context based on the given schema.
  *
  * Returns the validation context or NULL in case of error
  */
@@ -20346,12 +20303,93 @@
     }
     memset(ret, 0, sizeof(xmlSchemaValidCtxt));
     ret->schema = schema;    
-    ret->attrTop = NULL;
-    ret->attr = NULL;
     return (ret);
 }
 
 /**
+ * xmlSchemaClearValidCtxt:
+ * @ctxt: the schema validation context
+ *
+ * Free the resources associated to the schema validation context;
+ * leaves some fields alive intended for reuse of the context.
+ */
+static void
+xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
+{
+    if (vctxt == NULL)
+        return;
+
+    vctxt->validationRoot = NULL;
+    if (vctxt->attr != NULL) {
+        xmlSchemaFreeAttributeStates(vctxt->attr);
+	vctxt->attr = NULL;
+    }
+    if (vctxt->value != NULL) {
+        xmlSchemaFreeValue(vctxt->value);
+	vctxt->value = NULL;
+    }
+    /*
+    * Augmented IDC information.
+    */
+    if (vctxt->aidcs != NULL) {
+	xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
+	do {
+	    next = cur->next;
+	    xmlFree(cur);
+	    cur = next;
+	} while (cur != NULL);
+	vctxt->aidcs = NULL;
+    }
+    if (vctxt->idcNodes != NULL) {
+	int i;
+	xmlSchemaPSVIIDCNodePtr item;
+
+	for (i = 0; i < vctxt->nbIdcNodes; i++) {
+	    item = vctxt->idcNodes[i];	    
+	    xmlFree(item->keys);
+	    xmlFree(item);
+	}
+	xmlFree(vctxt->idcNodes);
+	vctxt->idcNodes = NULL;
+    }
+    /* 
+    * Note that we won't delete the XPath state pool here.
+    */
+    if (vctxt->xpathStates != NULL) {
+	xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
+	vctxt->xpathStates = NULL;
+    }
+    if (vctxt->attrInfo != NULL) {
+	if (vctxt->attrInfo->value != NULL) {
+	    xmlSchemaFreeValue(vctxt->attrInfo->value);	    
+	}
+	memset(vctxt->attrInfo, 0, sizeof(xmlSchemaNodeInfo));
+    }
+    if (vctxt->elemInfos != NULL) {
+	int i;
+	xmlSchemaNodeInfoPtr info;
+	
+	for (i = 0; i < vctxt->sizeElemInfos; i++) {
+	    info = vctxt->elemInfos[i];
+	    if (info == NULL)
+		break;
+	    if (info->value != NULL) {
+		xmlSchemaFreeValue(info->value);
+		info->value = NULL;
+	    }
+	    if (info->idcMatchers != NULL) {
+		xmlSchemaIDCFreeMatcherList(info->idcMatchers);
+		info->idcMatchers = NULL;
+	    }
+	    if (info->idcTable != NULL) {
+		xmlSchemaIDCFreeIDCTable(info->idcTable);
+		info->idcTable = NULL;
+	    }
+	}
+    }
+}
+
+/**
  * xmlSchemaFreeValidCtxt:
  * @ctxt:  the schema validation context
  *
@@ -20366,11 +20404,8 @@
         xmlSchemaFreeAttributeStates(ctxt->attr);
     if (ctxt->value != NULL)
         xmlSchemaFreeValue(ctxt->value);
-    if (ctxt->pctxt != NULL) {
+    if (ctxt->pctxt != NULL)
 	xmlSchemaFreeParserCtxt(ctxt->pctxt);
-    }
-
-#ifdef IDC_ENABLED
     if (ctxt->idcNodes != NULL) {
 	int i;
 	xmlSchemaPSVIIDCNodePtr item;
@@ -20382,7 +20417,6 @@
 	}
 	xmlFree(ctxt->idcNodes);
     }
-
     if (ctxt->idcKeys != NULL) {
 	int i;
 	for (i = 0; i < ctxt->nbIdcKeys; i++)
@@ -20406,8 +20440,6 @@
 	    cur = next;
 	} while (cur != NULL);
     }
-#endif /* IDC_ENABLED */
-#ifdef ELEM_INFO_ENABLED
     if (ctxt->attrInfo != NULL) {
 	if (ctxt->attrInfo->value != NULL)
 	    xmlSchemaFreeValue(ctxt->attrInfo->value);
@@ -20420,27 +20452,25 @@
 	for (i = 0; i < ctxt->sizeElemInfos; i++) {
 	    info = ctxt->elemInfos[i];
 	    if (info == NULL)
-		continue;
+		break;
 	    if (info->value != NULL)
 		xmlSchemaFreeValue(info->value);
-#ifdef IDC_ENABLED
 	    if (info->idcMatchers != NULL)
 		xmlSchemaIDCFreeMatcherList(info->idcMatchers);
-#endif
+	    if (info->idcTable != NULL)
+		xmlSchemaIDCFreeIDCTable(info->idcTable);
 	    /*
-	    *  TODO: Free the IDC table if still existent.
-	    */
-
-	    /*
-	    xmlFree(info->localName);
-	    if (info->namespaceName != NULL)
-		xmlFree(info->namespaceName);
+	    * TODO: Don't know if those will have to be freed if in streaming
+	    * mode.
+	    *
+	    * xmlFree(info->localName);
+	    * if (info->namespaceName != NULL)
+	    *	xmlFree(info->namespaceName);
 	    */
 	    xmlFree(info);
 	}
 	xmlFree(ctxt->elemInfos);
     }
-#endif
     xmlFree(ctxt);
 }
 
@@ -20565,28 +20595,22 @@
 int
 xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
 {
-    int ret;
-
     if ((ctxt == NULL) || (doc == NULL))
         return (-1);
 
-    ctxt->doc = doc;
-    ctxt->err = 0; 
-    ctxt->nberrors = 0;
-    
-    /*
-    if (ctxt->schema == NULL) {
-	xmlSchemaVErr(ctxt, NULL,
-	    XML_SCHEMAV_INTERNAL,
-	    "API error: xmlSchemaValidateDoc, "
-	    "no schema specified and assembling of schemata "
-	    "using xsi:schemaLocation and xsi:noNamespaceSchemaLocation "
-	    "is not enabled.\n", NULL, NULL);
-	return (-1);
-    }
-    */
-    ret = xmlSchemaValidateDocument(ctxt, doc);
-    return (ret);
+    ctxt->doc = doc;      
+    ctxt->node = xmlDocGetRootElement(doc);
+    if (ctxt->node == NULL) {
+        xmlSchemaVCustomErr(ctxt, 
+	    XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
+	    (xmlNodePtr) doc, NULL,
+	    "The document has no document element", NULL);
+        return (ctxt->err);
+    }    
+    ctxt->validationRoot = ctxt->node;
+    xmlSchemaStartValidation(ctxt);
+
+    return (ctxt->err);
 }
 
 /**