aboutsummaryrefslogtreecommitdiffstats
path: root/catalog.c
diff options
context:
space:
mode:
authorDaniel Veillard <veillard@src.gnome.org>2001-05-10 14:17:55 +0000
committerDaniel Veillard <veillard@src.gnome.org>2001-05-10 14:17:55 +0000
commita737459bc41f3f4558d814889f0981e2aee4b97f (patch)
tree88a8a03fcb6e462535e7d1f8f8228c7848f3d275 /catalog.c
parentc17337c062d428462b57b8eb25c6867c3ee1d31b (diff)
downloadandroid_external_libxml2-a737459bc41f3f4558d814889f0981e2aee4b97f.tar.gz
android_external_libxml2-a737459bc41f3f4558d814889f0981e2aee4b97f.tar.bz2
android_external_libxml2-a737459bc41f3f4558d814889f0981e2aee4b97f.zip
- Makefile.am xmlversion.h.in configure.in include/Makefile.am:
integrating catalogs - catalog.[ch] testCatalog.c: adding a small catalo API (only SGML catalog support). - parser.c: restaured xmlKeepBlanksDefault(0) API Daniel
Diffstat (limited to 'catalog.c')
-rw-r--r--catalog.c531
1 files changed, 531 insertions, 0 deletions
diff --git a/catalog.c b/catalog.c
new file mode 100644
index 00000000..437474a9
--- /dev/null
+++ b/catalog.c
@@ -0,0 +1,531 @@
+/**
+ * catalog.c: set of generic Catalog related routines
+ *
+ * Reference: SGML Open Technical Resolution TR9401:1997.
+ * http://www.jclark.com/sp/catalog.htm
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel.Veillard@imag.fr
+ */
+
+#include "libxml.h"
+
+#ifdef LIBXML_CATALOG_ENABLED
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include <string.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/hash.h>
+#include <libxml/uri.h>
+#include <libxml/parserInternals.h>
+#include <libxml/catalog.h>
+#include <libxml/xmlerror.h>
+
+/************************************************************************
+ * *
+ * Types, all private *
+ * *
+ ************************************************************************/
+
+typedef enum {
+ XML_CATA_NONE = 0,
+ XML_CATA_SYSTEM,
+ XML_CATA_PUBLIC,
+ XML_CATA_ENTITY,
+ XML_CATA_PENTITY,
+ XML_CATA_DOCTYPE,
+ XML_CATA_LINKTYPE,
+ XML_CATA_NOTATION,
+ XML_CATA_DELEGATE,
+ XML_CATA_BASE,
+ XML_CATA_CATALOG,
+ XML_CATA_DOCUMENT,
+ XML_CATA_SGMLDECL
+} xmlCatalogEntryType;
+
+typedef struct _xmlCatalogEntry xmlCatalogEntry;
+typedef xmlCatalogEntry *xmlCatalogEntryPtr;
+struct _xmlCatalogEntry {
+ xmlCatalogEntryType type;
+ xmlChar *name;
+ xmlChar *value;
+};
+
+static xmlHashTablePtr xmlDefaultCatalog;
+
+/************************************************************************
+ * *
+ * alloc or dealloc *
+ * *
+ ************************************************************************/
+
+static xmlCatalogEntryPtr
+xmlNewCatalogEntry(int type, xmlChar *name, xmlChar *value) {
+ xmlCatalogEntryPtr ret;
+
+ ret = (xmlCatalogEntryPtr) xmlMalloc(sizeof(xmlCatalogEntry));
+ if (ret == NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "malloc of %d byte failed\n", sizeof(xmlCatalogEntry));
+ return(NULL);
+ }
+ ret->type = type;
+ ret->name = name;
+ ret->value = value;
+ return(ret);
+}
+
+static void
+xmlFreeCatalogEntry(xmlCatalogEntryPtr ret) {
+ if (ret == NULL)
+ return;
+ if (ret->name != NULL)
+ xmlFree(ret->name);
+ if (ret->value != NULL)
+ xmlFree(ret->value);
+ xmlFree(ret);
+}
+
+/************************************************************************
+ * *
+ * The parser *
+ * *
+ ************************************************************************/
+
+
+#define RAW *cur
+#define NEXT cur++;
+#define SKIP(x) cur += x;
+
+#define SKIP_BLANKS while (IS_BLANK(*cur)) NEXT;
+
+static const xmlChar *
+xmlParseCatalogComment(const xmlChar *cur) {
+ if ((cur[0] != '-') || (cur[1] != '-'))
+ return(cur);
+ SKIP(2);
+ while ((cur[0] != 0) && ((cur[0] != '-') || ((cur[1] != '-'))))
+ NEXT;
+ if (cur[0] == 0) {
+ return(NULL);
+ }
+ return(cur);
+}
+
+static const xmlChar *
+xmlParseCatalogPubid(const xmlChar *cur, xmlChar **id) {
+ xmlChar *buf = NULL;
+ int len = 0;
+ int size = 50;
+ xmlChar stop;
+ int count = 0;
+
+ *id = NULL;
+
+ if (RAW == '"') {
+ NEXT;
+ stop = '"';
+ } else if (RAW == '\'') {
+ NEXT;
+ stop = '\'';
+ } else {
+ stop = ' ';
+ }
+ buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
+ if (buf == NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "malloc of %d byte failed\n", size);
+ return(NULL);
+ }
+ while (xmlIsPubidChar(*cur)) {
+ if ((*cur == stop) && (stop != ' '))
+ break;
+ if ((stop == ' ') && (IS_BLANK(*cur)))
+ break;
+ if (len + 1 >= size) {
+ size *= 2;
+ buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
+ if (buf == NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "realloc of %d byte failed\n", size);
+ return(NULL);
+ }
+ }
+ buf[len++] = *cur;
+ count++;
+ NEXT;
+ }
+ buf[len] = 0;
+ if (stop == ' ') {
+ if (!IS_BLANK(*cur)) {
+ xmlFree(buf);
+ return(NULL);
+ }
+ } else {
+ if (*cur != stop) {
+ xmlFree(buf);
+ return(NULL);
+ }
+ NEXT;
+ }
+ *id = buf;
+ return(cur);
+}
+
+static const xmlChar *
+xmlParseCatalogName(const xmlChar *cur, xmlChar **name) {
+ xmlChar buf[XML_MAX_NAMELEN + 5];
+ int len = 0;
+ int c;
+
+ *name = NULL;
+
+ /*
+ * Handler for more complex cases
+ */
+ c = *cur;
+ if ((!IS_LETTER(c) && (c != '_') && (c != ':'))) {
+ return(NULL);
+ }
+
+ while (((IS_LETTER(c)) || (IS_DIGIT(c)) ||
+ (c == '.') || (c == '-') ||
+ (c == '_') || (c == ':'))) {
+ buf[len++] = c;
+ cur++;
+ c = *cur;
+ if (len >= XML_MAX_NAMELEN)
+ return(NULL);
+ }
+ *name = xmlStrndup(buf, len);
+ return(cur);
+}
+
+static int
+xmlParseCatalog(const xmlChar *value, const char *file) {
+ const xmlChar *cur = value;
+ xmlChar *base = NULL;
+
+ if ((cur == NULL) || (file == NULL))
+ return(-1);
+ base = xmlStrdup((const xmlChar *) file);
+
+ while ((cur != NULL) && (cur[0] != '0')) {
+ SKIP_BLANKS;
+ if ((cur[0] == '-') && (cur[1] == '-')) {
+ cur = xmlParseCatalogComment(cur);
+ if (cur == NULL) {
+ /* error */
+ break;
+ }
+ } else {
+ xmlChar *sysid = NULL;
+ xmlChar *name = NULL;
+ xmlCatalogEntryType type = XML_CATA_NONE;
+
+ cur = xmlParseCatalogName(cur, &name);
+ if (name == NULL) {
+ /* error */
+ break;
+ }
+ if (!IS_BLANK(*cur)) {
+ /* error */
+ break;
+ }
+ SKIP_BLANKS;
+ if (xmlStrEqual(name, (const xmlChar *) "SYSTEM"))
+ type = XML_CATA_SYSTEM;
+ else if (xmlStrEqual(name, (const xmlChar *) "PUBLIC"))
+ type = XML_CATA_PUBLIC;
+ else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE"))
+ type = XML_CATA_DELEGATE;
+ else if (xmlStrEqual(name, (const xmlChar *) "ENTITY"))
+ type = XML_CATA_ENTITY;
+ else if (xmlStrEqual(name, (const xmlChar *) "DOCTYPE"))
+ type = XML_CATA_DOCTYPE;
+ else if (xmlStrEqual(name, (const xmlChar *) "LINKTYPE"))
+ type = XML_CATA_LINKTYPE;
+ else if (xmlStrEqual(name, (const xmlChar *) "NOTATION"))
+ type = XML_CATA_NOTATION;
+ else if (xmlStrEqual(name, (const xmlChar *) "SGMLDECL"))
+ type = XML_CATA_SGMLDECL;
+ else if (xmlStrEqual(name, (const xmlChar *) "DOCUMENT"))
+ type = XML_CATA_DOCUMENT;
+ else if (xmlStrEqual(name, (const xmlChar *) "CATALOG"))
+ type = XML_CATA_CATALOG;
+ else if (xmlStrEqual(name, (const xmlChar *) "BASE"))
+ type = XML_CATA_BASE;
+ else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE"))
+ type = XML_CATA_DELEGATE;
+ else if (xmlStrEqual(name, (const xmlChar *) "OVERRIDE")) {
+ xmlFree(name);
+ cur = xmlParseCatalogName(cur, &name);
+ if (name == NULL) {
+ /* error */
+ break;
+ }
+ continue;
+ }
+ xmlFree(name);
+
+ switch(type) {
+ case XML_CATA_ENTITY:
+ if (*cur == '%')
+ type = XML_CATA_PENTITY;
+ case XML_CATA_PENTITY:
+ case XML_CATA_DOCTYPE:
+ case XML_CATA_LINKTYPE:
+ case XML_CATA_NOTATION:
+ cur = xmlParseCatalogName(cur, &name);
+ if (cur == NULL) {
+ /* error */
+ break;
+ }
+ if (!IS_BLANK(*cur)) {
+ /* error */
+ break;
+ }
+ SKIP_BLANKS;
+ cur = xmlParseCatalogPubid(cur, &sysid);
+ if (cur == NULL) {
+ /* error */
+ break;
+ }
+ break;
+ case XML_CATA_PUBLIC:
+ case XML_CATA_SYSTEM:
+ case XML_CATA_DELEGATE:
+ cur = xmlParseCatalogPubid(cur, &name);
+ if (cur == NULL) {
+ /* error */
+ break;
+ }
+ if (!IS_BLANK(*cur)) {
+ /* error */
+ break;
+ }
+ SKIP_BLANKS;
+ cur = xmlParseCatalogPubid(cur, &sysid);
+ if (cur == NULL) {
+ /* error */
+ break;
+ }
+ break;
+ case XML_CATA_BASE:
+ case XML_CATA_CATALOG:
+ case XML_CATA_DOCUMENT:
+ case XML_CATA_SGMLDECL:
+ cur = xmlParseCatalogPubid(cur, &sysid);
+ if (cur == NULL) {
+ /* error */
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ if (cur == NULL) {
+ if (name != NULL)
+ xmlFree(name);
+ if (sysid != NULL)
+ xmlFree(sysid);
+ break;
+ } else if (type == XML_CATA_BASE) {
+ if (base != NULL)
+ xmlFree(base);
+ base = sysid;
+ } else if ((type == XML_CATA_PUBLIC) ||
+ (type == XML_CATA_SYSTEM)) {
+ xmlChar *filename;
+
+ filename = xmlBuildURI(sysid, base);
+ if (filename != NULL) {
+
+ xmlHashAddEntry(xmlDefaultCatalog, name,
+ xmlNewCatalogEntry(type, name, filename));
+ }
+ if (sysid != NULL)
+ xmlFree(sysid);
+ } else {
+ /*
+ * drop anything else we won't handle it
+ */
+ if (name != NULL)
+ xmlFree(name);
+ if (sysid != NULL)
+ xmlFree(sysid);
+ }
+ }
+ }
+ if (base != NULL)
+ xmlFree(base);
+ if (cur == NULL)
+ return(-1);
+ return(0);
+}
+
+/************************************************************************
+ * *
+ * Public interfaces *
+ * *
+ ************************************************************************/
+
+/*
+ * xmlLoadCatalog:
+ * @filename: a file path
+ *
+ * Load the catalog and makes its definition effective for the default
+ * external entity loader.
+ *
+ * Returns 0 in case of success -1 in case of error
+ */
+int
+xmlLoadCatalog(const char *filename) {
+ int fd, len, ret;
+ struct stat info;
+ xmlChar *content;
+
+ if (filename == NULL)
+ return(-1);
+ if (xmlDefaultCatalog == NULL)
+ xmlDefaultCatalog = xmlHashCreate(20);
+ if (xmlDefaultCatalog == NULL)
+ return(-1);
+
+ if (stat(filename, &info) < 0)
+ return(-1);
+
+ if ((fd = open(filename, O_RDONLY)) < 0)
+ return(-1);
+
+ content = xmlMalloc(info.st_size + 10);
+ if (content == NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "realloc of %d byte failed\n", info.st_size + 10);
+ }
+ len = read(fd, content, info.st_size);
+ if (len < 0) {
+ xmlFree(content);
+ return(-1);
+ }
+ content[len] = 0;
+ close(fd);
+
+ ret = xmlParseCatalog(content, filename);
+ xmlFree(content);
+ return(ret);
+}
+
+/**
+ * xmlCatalogCleanup:
+ *
+ * Free up all the memory associated with catalogs
+ */
+void
+xmlCatalogCleanup(void) {
+ if (xmlDefaultCatalog != NULL)
+ xmlHashFree(xmlDefaultCatalog,
+ (xmlHashDeallocator) xmlFreeCatalogEntry);
+ xmlDefaultCatalog = NULL;
+}
+
+/**
+ * xmlCatalogDumpEntry:
+ * @entry: the
+ * @out: the file.
+ *
+ * Free up all the memory associated with catalogs
+ */
+static void
+xmlCatalogDumpEntry(xmlCatalogEntryPtr entry, FILE *out) {
+ if ((entry == NULL) || (out == NULL))
+ return;
+ switch (entry->type) {
+ case XML_CATA_ENTITY:
+ fprintf(out, "ENTITY "); break;
+ case XML_CATA_PENTITY:
+ fprintf(out, "ENTITY %%"); break;
+ case XML_CATA_DOCTYPE:
+ fprintf(out, "DOCTYPE "); break;
+ case XML_CATA_LINKTYPE:
+ fprintf(out, "LINKTYPE "); break;
+ case XML_CATA_NOTATION:
+ fprintf(out, "NOTATION "); break;
+ case XML_CATA_PUBLIC:
+ fprintf(out, "PUBLIC "); break;
+ case XML_CATA_SYSTEM:
+ fprintf(out, "SYSTEM "); break;
+ case XML_CATA_DELEGATE:
+ fprintf(out, "DELEGATE "); break;
+ case XML_CATA_BASE:
+ fprintf(out, "BASE "); break;
+ case XML_CATA_CATALOG:
+ fprintf(out, "CATALOG "); break;
+ case XML_CATA_DOCUMENT:
+ fprintf(out, "DOCUMENT "); break;
+ case XML_CATA_SGMLDECL:
+ fprintf(out, "SGMLDECL "); break;
+ default:
+ return;
+ }
+ switch (entry->type) {
+ case XML_CATA_ENTITY:
+ case XML_CATA_PENTITY:
+ case XML_CATA_DOCTYPE:
+ case XML_CATA_LINKTYPE:
+ case XML_CATA_NOTATION:
+ fprintf(out, "%s", entry->name); break;
+ case XML_CATA_PUBLIC:
+ case XML_CATA_SYSTEM:
+ case XML_CATA_SGMLDECL:
+ case XML_CATA_DOCUMENT:
+ case XML_CATA_CATALOG:
+ case XML_CATA_BASE:
+ case XML_CATA_DELEGATE:
+ fprintf(out, "\"%s\"", entry->name); break;
+ default:
+ break;
+ }
+ switch (entry->type) {
+ case XML_CATA_ENTITY:
+ case XML_CATA_PENTITY:
+ case XML_CATA_DOCTYPE:
+ case XML_CATA_LINKTYPE:
+ case XML_CATA_NOTATION:
+ case XML_CATA_PUBLIC:
+ case XML_CATA_SYSTEM:
+ case XML_CATA_DELEGATE:
+ fprintf(out, " \"%s\"", entry->value); break;
+ default:
+ break;
+ }
+ fprintf(out, "\n");
+}
+
+/**
+ * xmlCatalogDump:
+ * @out: the file.
+ *
+ * Free up all the memory associated with catalogs
+ */
+void
+xmlCatalogDump(FILE *out) {
+ if (out == NULL)
+ return;
+ if (xmlDefaultCatalog != NULL) {
+ xmlHashScan(xmlDefaultCatalog,
+ (xmlHashScanner) xmlCatalogDumpEntry, out);
+ }
+}
+#endif /* LIBXML_CATALOG_ENABLED */