Fixed SGML catalogs breakage of 2.4.7, added a couple of really needed

* include/libxml/catalog.h catalog.c: Fixed SGML catalogs
  breakage of 2.4.7, added a couple of really needed APIs
  like xmlCatalogIsEmpty() and xmlNewCatalog()
* xmlcatalog.c: updated --sgml --noout to be a suitable replacement
  for install-catalog
* configure.in: preparing 2.4.8
Daniel
diff --git a/ChangeLog b/ChangeLog
index 537c735..c20be18 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Sun Nov  4 20:56:53 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/catalog.h catalog.c: Fixed SGML catalogs
+	  breakage of 2.4.7, added a couple of really needed APIs
+	  like xmlCatalogIsEmpty() and xmlNewCatalog()
+	* xmlcatalog.c: updated --sgml --noout to be a suitable replacement
+	  for install-catalog
+	* configure.in: preparing 2.4.8
+
 Thu Nov  1 15:29:31 CET 2001 Daniel Veillard <daniel@veillard.com>
 
 	* HTMLtree.c tree.c include/libxml/HTMLtree.h
diff --git a/catalog.c b/catalog.c
index a8b9e74..3b6a3e6 100644
--- a/catalog.c
+++ b/catalog.c
@@ -302,7 +302,7 @@
 }
 
 /**
- * xmlNewCatalog:
+ * xmlCreateNewCatalog:
  * @type:  type of catalog
  * @prefer:  the PUBLIC vs. SYSTEM current preference value
  *
@@ -312,7 +312,7 @@
  * Returns the xmlCatalogPtr or NULL in case of error
  */
 static xmlCatalogPtr
-xmlNewCatalog(xmlCatalogType type, xmlCatalogPrefer prefer) {
+xmlCreateNewCatalog(xmlCatalogType type, xmlCatalogPrefer prefer) {
     xmlCatalogPtr ret;
 
     ret = (xmlCatalogPtr) xmlMalloc(sizeof(xmlCatalog));
@@ -326,6 +326,8 @@
     ret->catalNr = 0;
     ret->catalMax = XML_MAX_SGML_CATA_DEPTH;
     ret->prefer = prefer;
+    if (ret->type == XML_SGML_CATALOG_TYPE)
+	ret->sgml = xmlHashCreate(10);
     return(ret);
 }
 
@@ -2353,7 +2355,7 @@
     if (content == NULL)
         return(NULL);
 
-    catal = xmlNewCatalog(XML_SGML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
+    catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
     if (catal == NULL) {
 	xmlFree(content);
 	return(NULL);
@@ -2400,7 +2402,7 @@
 	first++;
 
     if (*first != '<') {
-	catal = xmlNewCatalog(XML_SGML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
+	catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
 	if (catal == NULL) {
 	    xmlFree(content);
 	    return(NULL);
@@ -2412,7 +2414,7 @@
 	    return(NULL);
 	}
     } else {
-	catal = xmlNewCatalog(XML_XML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
+	catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
 	if (catal == NULL) {
 	    xmlFree(content);
 	    return(NULL);
@@ -2630,7 +2632,7 @@
  */
 void
 xmlACatalogDump(xmlCatalogPtr catal, FILE *out) {
-    if (out == NULL)
+    if ((out == NULL) || (catal == NULL))
 	return;
 
     if (catal->type == XML_XML_CATALOG_TYPE) {
@@ -2673,6 +2675,8 @@
 
             entry = xmlNewCatalogEntry(cattype, orig, replace,
                                        XML_CATA_PREFER_NONE);
+	    if (catal->sgml == NULL)
+		catal->sgml = xmlHashCreate(10);
             res = xmlHashAddEntry(catal->sgml, orig, entry);
         }
     }
@@ -2706,6 +2710,65 @@
     return(res);
 }
 
+/**
+ * xmlNewCatalog:
+ * @sgml:  should this create an SGML catalog
+ *
+ * create a new Catalog.
+ *
+ * Returns the xmlCatalogPtr or NULL in case of error
+ */
+xmlCatalogPtr
+xmlNewCatalog(int sgml) {
+    xmlCatalogPtr catal = NULL;
+
+    if (sgml) {
+	catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE,
+		                    xmlCatalogDefaultPrefer);
+        if ((catal != NULL) && (catal->sgml == NULL))
+	    catal->sgml = xmlHashCreate(10);
+    } else
+	catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
+		                    xmlCatalogDefaultPrefer);
+    return(catal);
+}
+
+/**
+ * xmlCatalogIsEmpty:
+ * @catal:  should this create an SGML catalog
+ *
+ * Check is a catalog is empty
+ *
+ * Returns 1 if the catalog is empty, 0 if not, amd -1 in case of error.
+ */
+int
+xmlCatalogIsEmpty(xmlCatalogPtr catal) {
+    if (catal == NULL)
+	return(-1);
+
+    if (catal->type == XML_XML_CATALOG_TYPE) {
+	if (catal->xml == NULL)
+	    return(1);
+	if ((catal->xml->type != XML_CATA_CATALOG) &&
+	    (catal->xml->type != XML_CATA_BROKEN_CATALOG))
+	    return(-1);
+	if (catal->xml->children == NULL)
+	    return(1);
+        return(0);
+    } else {
+	int res;
+
+	if (catal->sgml == NULL)
+	    return(1);
+	res = xmlHashSize(catal->sgml);
+	if (res == 0)
+	    return(1);
+	if (res < 0)
+	    return(-1);
+    } 
+    return(0);
+}
+
 /************************************************************************
  *									*
  *   Public interfaces manipulating the global shared default catalog	*
@@ -2757,7 +2820,7 @@
 	if (catalogs == NULL)
 	    catalogs = XML_XML_DEFAULT_CATALOG;
 
-	catal = xmlNewCatalog(XML_XML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
+	catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
 	if (catal != NULL) {
 
 	    catal->xml = xmlNewCatalogEntry(XML_CATA_CATALOG,
@@ -2996,7 +3059,7 @@
      */
     if ((xmlDefaultCatalog == NULL) &&
 	(xmlStrEqual(type, BAD_CAST "catalog"))) {
-	xmlDefaultCatalog = xmlNewCatalog(XML_XML_CATALOG_TYPE,
+	xmlDefaultCatalog = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
 		                          xmlCatalogDefaultPrefer);
 	xmlDefaultCatalog->xml = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
 				    orig, xmlCatalogDefaultPrefer);
diff --git a/configure.in b/configure.in
index 34b8014..88d4ac1 100644
--- a/configure.in
+++ b/configure.in
@@ -6,7 +6,7 @@
 
 LIBXML_MAJOR_VERSION=2
 LIBXML_MINOR_VERSION=4
-LIBXML_MICRO_VERSION=7
+LIBXML_MICRO_VERSION=8
 LIBXML_VERSION=$LIBXML_MAJOR_VERSION.$LIBXML_MINOR_VERSION.$LIBXML_MICRO_VERSION
 LIBXML_VERSION_INFO=`expr $LIBXML_MAJOR_VERSION + $LIBXML_MINOR_VERSION`:$LIBXML_MICRO_VERSION:$LIBXML_MINOR_VERSION
 
diff --git a/include/libxml/catalog.h b/include/libxml/catalog.h
index a9b2f4b..719e5d6 100644
--- a/include/libxml/catalog.h
+++ b/include/libxml/catalog.h
@@ -60,6 +60,7 @@
 /*
  * Operations on a given catalog
  */
+xmlCatalogPtr	xmlNewCatalog		(int sgml);
 xmlCatalogPtr	xmlLoadACatalog		(const char *filename);
 xmlCatalogPtr	xmlLoadSGMLSuperCatalog	(const char *filename);
 int		xmlConvertSGMLCatalog	(xmlCatalogPtr catal);
@@ -81,6 +82,7 @@
 void		xmlACatalogDump		(xmlCatalogPtr catal,
 					 FILE *out);
 void		xmlFreeCatalog		(xmlCatalogPtr catal);
+int		xmlCatalogIsEmpty	(xmlCatalogPtr catal);
 
 /*
  * Global operations
diff --git a/libxml.spec.in b/libxml.spec.in
index 12c888a..08dbef8 100644
--- a/libxml.spec.in
+++ b/libxml.spec.in
@@ -46,6 +46,10 @@
 
 %changelog
 
+* Sun Nov  4 2001 Daniel Veillard <veillard@redhat.com>
+
+- 2.4.7 broke SGML catalogs badly. this fixes it.
+
 * Thu Apr 26 2001 Toshio Kuratomi <badger@prtr-13.ucsc.edu>
 
 [2.3.7]
diff --git a/xmlcatalog.c b/xmlcatalog.c
index e9238a4..8e45485 100644
--- a/xmlcatalog.c
+++ b/xmlcatalog.c
@@ -15,6 +15,9 @@
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 
 #ifdef HAVE_LIBREADLINE
 #include <readline/readline.h>
@@ -40,6 +43,9 @@
 static char *filename;
 
 #ifdef LIBXML_CATALOG_ENABLED
+
+#define XML_SGML_DEFAULT_CATALOG "/etc/sgml/catalog"
+
 /************************************************************************
  * 									*
  * 			Shell Interface					*
@@ -291,13 +297,14 @@
 static void usage(const char *name) {
     printf("Usage : %s [options] catalogfile entities...\n", name);
     printf("\tParse the catalog file and query it for the entities\n");
-    printf("\t--sgml : handle an SGML Super catalog\n");
+    printf("\t--sgml : handle SGML Super catalogs for --add and --del\n");
     printf("\t--shell : run a shell allowing interactive queries\n");
     printf("\t--create : create a new catalog\n");
     printf("\t--add 'type' 'orig' 'replace' : add an entry\n");
     printf("\t--del 'values' : remove values\n");
     printf("\t--noout: avoid dumping the result on stdout\n");
     printf("\t         used with add or del, it saves the catalog changes\n");
+    printf("\t         and with --sgml it also updates the super catalog\n");
     printf("\t-v --verbose : provide debug informations\n");
 }
 int main(int argc, char **argv) {
@@ -341,7 +348,7 @@
 	} else if ((!strcmp(argv[i], "-add")) ||
 	    (!strcmp(argv[i], "--add"))) {
 	    if (sgml)
-		i += 1;
+		i += 2;
 	    else
 		i += 3;
 	    add++;
@@ -360,7 +367,7 @@
 	if ((!strcmp(argv[i], "-add")) ||
 	    (!strcmp(argv[i], "--add"))) {
 	    if (sgml)
-		i += 1;
+		i += 2;
 	    else
 		i += 3;
 	    continue;
@@ -371,14 +378,11 @@
 	} else if (argv[i][0] == '-')
 	    continue;
 	filename = argv[i];
-	/* !!!!!!!!!!!!!!!!!!  TODO !!!!
-	if (sgml)
-	    ret = xmlLoadSGMLSuperCatalog(argv[i]);
-	else
-	   !!!!!!!!! */
+	if (!sgml) {
 	    ret = xmlLoadCatalog(argv[i]);
-	if ((!sgml) && (ret < 0) && (create)) {
-	    xmlCatalogAdd(BAD_CAST "catalog", BAD_CAST argv[i], NULL);
+	    if ((ret < 0) && (create)) {
+		xmlCatalogAdd(BAD_CAST "catalog", BAD_CAST argv[i], NULL);
+	    }
 	}
 	break;
     }
@@ -393,28 +397,108 @@
 
 	    if (argv[i][0] != '-')
 		continue;
-	    if ((!strcmp(argv[i], "-add")) ||
-		(!strcmp(argv[i], "--add"))) {
-		if (sgml) {
-		    ret = xmlCatalogAdd(BAD_CAST "sgmlcatalog", NULL,
-			                BAD_CAST argv[i + 1]);
-		    i += 1;
+	    if (strcmp(argv[i], "-add") && strcmp(argv[i], "--add") &&
+		strcmp(argv[i], "-del") && strcmp(argv[i], "--del"))
+		continue;
+
+	    if (sgml) {
+		/*
+		 * Maintainance of SGML catalogs.
+		 */
+		xmlCatalogPtr catal = NULL;
+		xmlCatalogPtr super = NULL;
+
+		catal = xmlLoadSGMLSuperCatalog(argv[i + 1]);
+
+		if ((!strcmp(argv[i], "-add")) ||
+		    (!strcmp(argv[i], "--add"))) {
+		    if (catal == NULL)
+			catal = xmlNewCatalog(1);
+		    super = xmlLoadSGMLSuperCatalog(XML_SGML_DEFAULT_CATALOG);
+		    if (super == NULL)
+			super = xmlNewCatalog(1);
+
+		    xmlACatalogAdd(catal, BAD_CAST "CATALOG",
+					 BAD_CAST argv[i + 2], NULL);
+		    xmlACatalogAdd(super, BAD_CAST "CATALOG",
+					 BAD_CAST argv[i + 1], NULL);
 		} else {
-		    if ((argv[i + 3] == NULL) || (argv[i + 3][0] == 0))
-			ret = xmlCatalogAdd(BAD_CAST argv[i + 1], NULL,
-					    BAD_CAST argv[i + 2]);
+		    if (catal != NULL)
+			ret = xmlACatalogRemove(catal, BAD_CAST argv[i + 2]);
 		    else
-			ret = xmlCatalogAdd(BAD_CAST argv[i + 1],
-					    BAD_CAST argv[i + 2],
-					    BAD_CAST argv[i + 3]);
-		    if (ret != 0)
-			printf("add command failed\n");
-		    i += 3;
+			ret = -1;
+		    if (ret < 0)
+			fprintf(stderr, "Failed to removed entry from %s\n",
+				argv[i + 1]);
+		    if ((noout) && (catal != NULL) &&
+			(xmlCatalogIsEmpty(catal))) {
+			super = xmlLoadSGMLSuperCatalog(
+				   XML_SGML_DEFAULT_CATALOG);
+			if (super != NULL) {
+			    ret = xmlACatalogRemove(super,
+				    BAD_CAST argv[i + 1]);
+			    if (ret < 0)
+				fprintf(stderr,
+					"Failed to removed entry from %s\n",
+					XML_SGML_DEFAULT_CATALOG);
+			}
+		    }
 		}
-	    } else if ((!strcmp(argv[i], "-del")) ||
-		(!strcmp(argv[i], "--del"))) {
-		ret = xmlCatalogRemove(BAD_CAST argv[i + 1]);
-		i += 1;
+		if (noout) {
+		    FILE *out;
+
+		    if (xmlCatalogIsEmpty(catal)) {
+			unlink(argv[i + 1]);
+		    } else {
+			out = fopen(argv[i + 1], "w");
+			if (out == NULL) {
+			    fprintf(stderr, "could not open %s for saving\n",
+				    argv[i + 1]);
+			    noout = 0;
+			} else {
+			    xmlACatalogDump(catal, out);
+			    fclose(out);
+			}
+		    }
+		    if (super != NULL) {
+			if (xmlCatalogIsEmpty(super)) {
+			    unlink(XML_SGML_DEFAULT_CATALOG);
+			} else {
+			    out = fopen(XML_SGML_DEFAULT_CATALOG, "w");
+			    if (out == NULL) {
+				fprintf(stderr,
+					"could not open %s for saving\n",
+					XML_SGML_DEFAULT_CATALOG);
+				noout = 0;
+			    } else {
+				
+				xmlACatalogDump(super, out);
+				fclose(out);
+			    }
+			}
+		    }
+		} else {
+		    xmlACatalogDump(catal, stdout);
+		}
+		i += 2;
+	    } else {
+		if ((!strcmp(argv[i], "-add")) ||
+		    (!strcmp(argv[i], "--add"))) {
+			if ((argv[i + 3] == NULL) || (argv[i + 3][0] == 0))
+			    ret = xmlCatalogAdd(BAD_CAST argv[i + 1], NULL,
+						BAD_CAST argv[i + 2]);
+			else
+			    ret = xmlCatalogAdd(BAD_CAST argv[i + 1],
+						BAD_CAST argv[i + 2],
+						BAD_CAST argv[i + 3]);
+			if (ret != 0)
+			    printf("add command failed\n");
+			i += 3;
+		} else if ((!strcmp(argv[i], "-del")) ||
+		    (!strcmp(argv[i], "--del"))) {
+		    ret = xmlCatalogRemove(BAD_CAST argv[i + 1]);
+		    i += 1;
+		}
 	    }
 	}
 	
@@ -446,7 +530,7 @@
 	    }
 	}
     }
-    if ((add) || (del) || (create) || (convert)) {
+    if ((!sgml) && ((add) || (del) || (create) || (convert))) {
 	if (noout) {
 	    FILE *out;