diff options
Diffstat (limited to 'external/libxml2_android/jni/libxml2/catalog.c')
-rw-r--r-- | external/libxml2_android/jni/libxml2/catalog.c | 3825 |
1 files changed, 0 insertions, 3825 deletions
diff --git a/external/libxml2_android/jni/libxml2/catalog.c b/external/libxml2_android/jni/libxml2/catalog.c deleted file mode 100644 index 6dfdfbb8..00000000 --- a/external/libxml2_android/jni/libxml2/catalog.c +++ /dev/null @@ -1,3825 +0,0 @@ -/** - * catalog.c: set of generic Catalog related routines - * - * Reference: SGML Open Technical Resolution TR9401:1997. - * http://www.jclark.com/sp/catalog.htm - * - * XML Catalogs Working Draft 06 August 2001 - * http://www.oasis-open.org/committees/entity/spec-2001-08-06.html - * - * See Copyright for the status of this software. - * - * Daniel.Veillard@imag.fr - */ - -#define IN_LIBXML -#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 -#ifdef HAVE_STDLIB_H -#include <stdlib.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> -#include <libxml/threads.h> -#include <libxml/globals.h> - -#include "buf.h" - -#define MAX_DELEGATE 50 -#define MAX_CATAL_DEPTH 50 - -#ifdef _WIN32 -# define PATH_SEPARATOR ';' -#else -# define PATH_SEPARATOR ':' -#endif - -/** - * TODO: - * - * macro to flag unimplemented blocks - * XML_CATALOG_PREFER user env to select between system/public prefered - * option. C.f. Richard Tobin <richard@cogsci.ed.ac.uk> - *> Just FYI, I am using an environment variable XML_CATALOG_PREFER with - *> values "system" and "public". I have made the default be "system" to - *> match yours. - */ -#define TODO \ - xmlGenericError(xmlGenericErrorContext, \ - "Unimplemented block at %s:%d\n", \ - __FILE__, __LINE__); - -#define XML_URN_PUBID "urn:publicid:" -#define XML_CATAL_BREAK ((xmlChar *) -1) -#ifndef XML_XML_DEFAULT_CATALOG -#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog" -#endif -#ifndef XML_SGML_DEFAULT_CATALOG -#define XML_SGML_DEFAULT_CATALOG "file:///etc/sgml/catalog" -#endif - -#if defined(_WIN32) && defined(_MSC_VER) -#undef XML_XML_DEFAULT_CATALOG -static char XML_XML_DEFAULT_CATALOG[256] = "file:///etc/xml/catalog"; -#if defined(_WIN32_WCE) -/* Windows CE don't have a A variant */ -#define GetModuleHandleA GetModuleHandle -#define GetModuleFileNameA GetModuleFileName -#else -#if !defined(_WINDOWS_) -void* __stdcall GetModuleHandleA(const char*); -unsigned long __stdcall GetModuleFileNameA(void*, char*, unsigned long); -#endif -#endif -#endif - -static xmlChar *xmlCatalogNormalizePublic(const xmlChar *pubID); -static int xmlExpandCatalog(xmlCatalogPtr catal, const char *filename); - -/************************************************************************ - * * - * Types, all private * - * * - ************************************************************************/ - -typedef enum { - XML_CATA_REMOVED = -1, - XML_CATA_NONE = 0, - XML_CATA_CATALOG, - XML_CATA_BROKEN_CATALOG, - XML_CATA_NEXT_CATALOG, - XML_CATA_GROUP, - XML_CATA_PUBLIC, - XML_CATA_SYSTEM, - XML_CATA_REWRITE_SYSTEM, - XML_CATA_DELEGATE_PUBLIC, - XML_CATA_DELEGATE_SYSTEM, - XML_CATA_URI, - XML_CATA_REWRITE_URI, - XML_CATA_DELEGATE_URI, - SGML_CATA_SYSTEM, - SGML_CATA_PUBLIC, - SGML_CATA_ENTITY, - SGML_CATA_PENTITY, - SGML_CATA_DOCTYPE, - SGML_CATA_LINKTYPE, - SGML_CATA_NOTATION, - SGML_CATA_DELEGATE, - SGML_CATA_BASE, - SGML_CATA_CATALOG, - SGML_CATA_DOCUMENT, - SGML_CATA_SGMLDECL -} xmlCatalogEntryType; - -typedef struct _xmlCatalogEntry xmlCatalogEntry; -typedef xmlCatalogEntry *xmlCatalogEntryPtr; -struct _xmlCatalogEntry { - struct _xmlCatalogEntry *next; - struct _xmlCatalogEntry *parent; - struct _xmlCatalogEntry *children; - xmlCatalogEntryType type; - xmlChar *name; - xmlChar *value; - xmlChar *URL; /* The expanded URL using the base */ - xmlCatalogPrefer prefer; - int dealloc; - int depth; - struct _xmlCatalogEntry *group; -}; - -typedef enum { - XML_XML_CATALOG_TYPE = 1, - XML_SGML_CATALOG_TYPE -} xmlCatalogType; - -#define XML_MAX_SGML_CATA_DEPTH 10 -struct _xmlCatalog { - xmlCatalogType type; /* either XML or SGML */ - - /* - * SGML Catalogs are stored as a simple hash table of catalog entries - * Catalog stack to check against overflows when building the - * SGML catalog - */ - char *catalTab[XML_MAX_SGML_CATA_DEPTH]; /* stack of catals */ - int catalNr; /* Number of current catal streams */ - int catalMax; /* Max number of catal streams */ - xmlHashTablePtr sgml; - - /* - * XML Catalogs are stored as a tree of Catalog entries - */ - xmlCatalogPrefer prefer; - xmlCatalogEntryPtr xml; -}; - -/************************************************************************ - * * - * Global variables * - * * - ************************************************************************/ - -/* - * Those are preferences - */ -static int xmlDebugCatalogs = 0; /* used for debugging */ -static xmlCatalogAllow xmlCatalogDefaultAllow = XML_CATA_ALLOW_ALL; -static xmlCatalogPrefer xmlCatalogDefaultPrefer = XML_CATA_PREFER_PUBLIC; - -/* - * Hash table containing all the trees of XML catalogs parsed by - * the application. - */ -static xmlHashTablePtr xmlCatalogXMLFiles = NULL; - -/* - * The default catalog in use by the application - */ -static xmlCatalogPtr xmlDefaultCatalog = NULL; - -/* - * A mutex for modifying the shared global catalog(s) - * xmlDefaultCatalog tree. - * It also protects xmlCatalogXMLFiles - * The core of this readers/writer scheme is in xmlFetchXMLCatalogFile() - */ -static xmlRMutexPtr xmlCatalogMutex = NULL; - -/* - * Whether the catalog support was initialized. - */ -static int xmlCatalogInitialized = 0; - -/************************************************************************ - * * - * Catalog error handlers * - * * - ************************************************************************/ - -/** - * xmlCatalogErrMemory: - * @extra: extra informations - * - * Handle an out of memory condition - */ -static void -xmlCatalogErrMemory(const char *extra) -{ - __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_CATALOG, - XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0, - extra, NULL, NULL, 0, 0, - "Memory allocation failed : %s\n", extra); -} - -/** - * xmlCatalogErr: - * @catal: the Catalog entry - * @node: the context node - * @msg: the error message - * @extra: extra informations - * - * Handle a catalog error - */ -static void LIBXML_ATTR_FORMAT(4,0) -xmlCatalogErr(xmlCatalogEntryPtr catal, xmlNodePtr node, int error, - const char *msg, const xmlChar *str1, const xmlChar *str2, - const xmlChar *str3) -{ - __xmlRaiseError(NULL, NULL, NULL, catal, node, XML_FROM_CATALOG, - error, XML_ERR_ERROR, NULL, 0, - (const char *) str1, (const char *) str2, - (const char *) str3, 0, 0, - msg, str1, str2, str3); -} - - -/************************************************************************ - * * - * Allocation and Freeing * - * * - ************************************************************************/ - -/** - * xmlNewCatalogEntry: - * @type: type of entry - * @name: name of the entry - * @value: value of the entry - * @prefer: the PUBLIC vs. SYSTEM current preference value - * @group: for members of a group, the group entry - * - * create a new Catalog entry, this type is shared both by XML and - * SGML catalogs, but the acceptable types values differs. - * - * Returns the xmlCatalogEntryPtr or NULL in case of error - */ -static xmlCatalogEntryPtr -xmlNewCatalogEntry(xmlCatalogEntryType type, const xmlChar *name, - const xmlChar *value, const xmlChar *URL, xmlCatalogPrefer prefer, - xmlCatalogEntryPtr group) { - xmlCatalogEntryPtr ret; - xmlChar *normid = NULL; - - ret = (xmlCatalogEntryPtr) xmlMalloc(sizeof(xmlCatalogEntry)); - if (ret == NULL) { - xmlCatalogErrMemory("allocating catalog entry"); - return(NULL); - } - ret->next = NULL; - ret->parent = NULL; - ret->children = NULL; - ret->type = type; - if (type == XML_CATA_PUBLIC || type == XML_CATA_DELEGATE_PUBLIC) { - normid = xmlCatalogNormalizePublic(name); - if (normid != NULL) - name = (*normid != 0 ? normid : NULL); - } - if (name != NULL) - ret->name = xmlStrdup(name); - else - ret->name = NULL; - if (normid != NULL) - xmlFree(normid); - if (value != NULL) - ret->value = xmlStrdup(value); - else - ret->value = NULL; - if (URL == NULL) - URL = value; - if (URL != NULL) - ret->URL = xmlStrdup(URL); - else - ret->URL = NULL; - ret->prefer = prefer; - ret->dealloc = 0; - ret->depth = 0; - ret->group = group; - return(ret); -} - -static void -xmlFreeCatalogEntryList(xmlCatalogEntryPtr ret); - -/** - * xmlFreeCatalogEntry: - * @ret: a Catalog entry - * - * Free the memory allocated to a Catalog entry - */ -static void -xmlFreeCatalogEntry(xmlCatalogEntryPtr ret) { - if (ret == NULL) - return; - /* - * Entries stored in the file hash must be deallocated - * only by the file hash cleaner ! - */ - if (ret->dealloc == 1) - return; - - if (xmlDebugCatalogs) { - if (ret->name != NULL) - xmlGenericError(xmlGenericErrorContext, - "Free catalog entry %s\n", ret->name); - else if (ret->value != NULL) - xmlGenericError(xmlGenericErrorContext, - "Free catalog entry %s\n", ret->value); - else - xmlGenericError(xmlGenericErrorContext, - "Free catalog entry\n"); - } - - if (ret->name != NULL) - xmlFree(ret->name); - if (ret->value != NULL) - xmlFree(ret->value); - if (ret->URL != NULL) - xmlFree(ret->URL); - xmlFree(ret); -} - -/** - * xmlFreeCatalogEntryList: - * @ret: a Catalog entry list - * - * Free the memory allocated to a full chained list of Catalog entries - */ -static void -xmlFreeCatalogEntryList(xmlCatalogEntryPtr ret) { - xmlCatalogEntryPtr next; - - while (ret != NULL) { - next = ret->next; - xmlFreeCatalogEntry(ret); - ret = next; - } -} - -/** - * xmlFreeCatalogHashEntryList: - * @ret: a Catalog entry list - * - * Free the memory allocated to list of Catalog entries from the - * catalog file hash. - */ -static void -xmlFreeCatalogHashEntryList(xmlCatalogEntryPtr catal) { - xmlCatalogEntryPtr children, next; - - if (catal == NULL) - return; - - children = catal->children; - while (children != NULL) { - next = children->next; - children->dealloc = 0; - children->children = NULL; - xmlFreeCatalogEntry(children); - children = next; - } - catal->dealloc = 0; - xmlFreeCatalogEntry(catal); -} - -/** - * xmlCreateNewCatalog: - * @type: type of catalog - * @prefer: the PUBLIC vs. SYSTEM current preference value - * - * create a new Catalog, this type is shared both by XML and - * SGML catalogs, but the acceptable types values differs. - * - * Returns the xmlCatalogPtr or NULL in case of error - */ -static xmlCatalogPtr -xmlCreateNewCatalog(xmlCatalogType type, xmlCatalogPrefer prefer) { - xmlCatalogPtr ret; - - ret = (xmlCatalogPtr) xmlMalloc(sizeof(xmlCatalog)); - if (ret == NULL) { - xmlCatalogErrMemory("allocating catalog"); - return(NULL); - } - memset(ret, 0, sizeof(xmlCatalog)); - ret->type = type; - 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); -} - -/** - * xmlFreeCatalog: - * @catal: a Catalog - * - * Free the memory allocated to a Catalog - */ -void -xmlFreeCatalog(xmlCatalogPtr catal) { - if (catal == NULL) - return; - if (catal->xml != NULL) - xmlFreeCatalogEntryList(catal->xml); - if (catal->sgml != NULL) - xmlHashFree(catal->sgml, - (xmlHashDeallocator) xmlFreeCatalogEntry); - xmlFree(catal); -} - -/************************************************************************ - * * - * Serializing Catalogs * - * * - ************************************************************************/ - -#ifdef LIBXML_OUTPUT_ENABLED -/** - * xmlCatalogDumpEntry: - * @entry: the catalog entry - * @out: the file. - * - * Serialize an SGML Catalog entry - */ -static void -xmlCatalogDumpEntry(xmlCatalogEntryPtr entry, FILE *out) { - if ((entry == NULL) || (out == NULL)) - return; - switch (entry->type) { - case SGML_CATA_ENTITY: - fprintf(out, "ENTITY "); break; - case SGML_CATA_PENTITY: - fprintf(out, "ENTITY %%"); break; - case SGML_CATA_DOCTYPE: - fprintf(out, "DOCTYPE "); break; - case SGML_CATA_LINKTYPE: - fprintf(out, "LINKTYPE "); break; - case SGML_CATA_NOTATION: - fprintf(out, "NOTATION "); break; - case SGML_CATA_PUBLIC: - fprintf(out, "PUBLIC "); break; - case SGML_CATA_SYSTEM: - fprintf(out, "SYSTEM "); break; - case SGML_CATA_DELEGATE: - fprintf(out, "DELEGATE "); break; - case SGML_CATA_BASE: - fprintf(out, "BASE "); break; - case SGML_CATA_CATALOG: - fprintf(out, "CATALOG "); break; - case SGML_CATA_DOCUMENT: - fprintf(out, "DOCUMENT "); break; - case SGML_CATA_SGMLDECL: - fprintf(out, "SGMLDECL "); break; - default: - return; - } - switch (entry->type) { - case SGML_CATA_ENTITY: - case SGML_CATA_PENTITY: - case SGML_CATA_DOCTYPE: - case SGML_CATA_LINKTYPE: - case SGML_CATA_NOTATION: - fprintf(out, "%s", (const char *) entry->name); break; - case SGML_CATA_PUBLIC: - case SGML_CATA_SYSTEM: - case SGML_CATA_SGMLDECL: - case SGML_CATA_DOCUMENT: - case SGML_CATA_CATALOG: - case SGML_CATA_BASE: - case SGML_CATA_DELEGATE: - fprintf(out, "\"%s\"", entry->name); break; - default: - break; - } - switch (entry->type) { - case SGML_CATA_ENTITY: - case SGML_CATA_PENTITY: - case SGML_CATA_DOCTYPE: - case SGML_CATA_LINKTYPE: - case SGML_CATA_NOTATION: - case SGML_CATA_PUBLIC: - case SGML_CATA_SYSTEM: - case SGML_CATA_DELEGATE: - fprintf(out, " \"%s\"", entry->value); break; - default: - break; - } - fprintf(out, "\n"); -} - -/** - * xmlDumpXMLCatalogNode: - * @catal: top catalog entry - * @catalog: pointer to the xml tree - * @doc: the containing document - * @ns: the current namespace - * @cgroup: group node for group members - * - * Serializes a Catalog entry, called by xmlDumpXMLCatalog and recursively - * for group entries - */ -static void xmlDumpXMLCatalogNode(xmlCatalogEntryPtr catal, xmlNodePtr catalog, - xmlDocPtr doc, xmlNsPtr ns, xmlCatalogEntryPtr cgroup) { - xmlNodePtr node; - xmlCatalogEntryPtr cur; - /* - * add all the catalog entries - */ - cur = catal; - while (cur != NULL) { - if (cur->group == cgroup) { - switch (cur->type) { - case XML_CATA_REMOVED: - break; - case XML_CATA_BROKEN_CATALOG: - case XML_CATA_CATALOG: - if (cur == catal) { - cur = cur->children; - continue; - } - break; - case XML_CATA_NEXT_CATALOG: - node = xmlNewDocNode(doc, ns, BAD_CAST "nextCatalog", NULL); - xmlSetProp(node, BAD_CAST "catalog", cur->value); - xmlAddChild(catalog, node); - break; - case XML_CATA_NONE: - break; - case XML_CATA_GROUP: - node = xmlNewDocNode(doc, ns, BAD_CAST "group", NULL); - xmlSetProp(node, BAD_CAST "id", cur->name); - if (cur->value != NULL) { - xmlNsPtr xns; - xns = xmlSearchNsByHref(doc, node, XML_XML_NAMESPACE); - if (xns != NULL) - xmlSetNsProp(node, xns, BAD_CAST "base", - cur->value); - } - switch (cur->prefer) { - case XML_CATA_PREFER_NONE: - break; - case XML_CATA_PREFER_PUBLIC: - xmlSetProp(node, BAD_CAST "prefer", BAD_CAST "public"); - break; - case XML_CATA_PREFER_SYSTEM: - xmlSetProp(node, BAD_CAST "prefer", BAD_CAST "system"); - break; - } - xmlDumpXMLCatalogNode(cur->next, node, doc, ns, cur); - xmlAddChild(catalog, node); - break; - case XML_CATA_PUBLIC: - node = xmlNewDocNode(doc, ns, BAD_CAST "public", NULL); - xmlSetProp(node, BAD_CAST "publicId", cur->name); - xmlSetProp(node, BAD_CAST "uri", cur->value); - xmlAddChild(catalog, node); - break; - case XML_CATA_SYSTEM: - node = xmlNewDocNode(doc, ns, BAD_CAST "system", NULL); - xmlSetProp(node, BAD_CAST "systemId", cur->name); - xmlSetProp(node, BAD_CAST "uri", cur->value); - xmlAddChild(catalog, node); - break; - case XML_CATA_REWRITE_SYSTEM: - node = xmlNewDocNode(doc, ns, BAD_CAST "rewriteSystem", NULL); - xmlSetProp(node, BAD_CAST "systemIdStartString", cur->name); - xmlSetProp(node, BAD_CAST "rewritePrefix", cur->value); - xmlAddChild(catalog, node); - break; - case XML_CATA_DELEGATE_PUBLIC: - node = xmlNewDocNode(doc, ns, BAD_CAST "delegatePublic", NULL); - xmlSetProp(node, BAD_CAST "publicIdStartString", cur->name); - xmlSetProp(node, BAD_CAST "catalog", cur->value); - xmlAddChild(catalog, node); - break; - case XML_CATA_DELEGATE_SYSTEM: - node = xmlNewDocNode(doc, ns, BAD_CAST "delegateSystem", NULL); - xmlSetProp(node, BAD_CAST "systemIdStartString", cur->name); - xmlSetProp(node, BAD_CAST "catalog", cur->value); - xmlAddChild(catalog, node); - break; - case XML_CATA_URI: - node = xmlNewDocNode(doc, ns, BAD_CAST "uri", NULL); - xmlSetProp(node, BAD_CAST "name", cur->name); - xmlSetProp(node, BAD_CAST "uri", cur->value); - xmlAddChild(catalog, node); - break; - case XML_CATA_REWRITE_URI: - node = xmlNewDocNode(doc, ns, BAD_CAST "rewriteURI", NULL); - xmlSetProp(node, BAD_CAST "uriStartString", cur->name); - xmlSetProp(node, BAD_CAST "rewritePrefix", cur->value); - xmlAddChild(catalog, node); - break; - case XML_CATA_DELEGATE_URI: - node = xmlNewDocNode(doc, ns, BAD_CAST "delegateURI", NULL); - xmlSetProp(node, BAD_CAST "uriStartString", cur->name); - xmlSetProp(node, BAD_CAST "catalog", cur->value); - xmlAddChild(catalog, node); - break; - case SGML_CATA_SYSTEM: - case SGML_CATA_PUBLIC: - case SGML_CATA_ENTITY: - case SGML_CATA_PENTITY: - case SGML_CATA_DOCTYPE: - case SGML_CATA_LINKTYPE: - case SGML_CATA_NOTATION: - case SGML_CATA_DELEGATE: - case SGML_CATA_BASE: - case SGML_CATA_CATALOG: - case SGML_CATA_DOCUMENT: - case SGML_CATA_SGMLDECL: - break; - } - } - cur = cur->next; - } -} - -static int -xmlDumpXMLCatalog(FILE *out, xmlCatalogEntryPtr catal) { - int ret; - xmlDocPtr doc; - xmlNsPtr ns; - xmlDtdPtr dtd; - xmlNodePtr catalog; - xmlOutputBufferPtr buf; - - /* - * Rebuild a catalog - */ - doc = xmlNewDoc(NULL); - if (doc == NULL) - return(-1); - dtd = xmlNewDtd(doc, BAD_CAST "catalog", - BAD_CAST "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN", -BAD_CAST "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd"); - - xmlAddChild((xmlNodePtr) doc, (xmlNodePtr) dtd); - - ns = xmlNewNs(NULL, XML_CATALOGS_NAMESPACE, NULL); - if (ns == NULL) { - xmlFreeDoc(doc); - return(-1); - } - catalog = xmlNewDocNode(doc, ns, BAD_CAST "catalog", NULL); - if (catalog == NULL) { - xmlFreeNs(ns); - xmlFreeDoc(doc); - return(-1); - } - catalog->nsDef = ns; - xmlAddChild((xmlNodePtr) doc, catalog); - - xmlDumpXMLCatalogNode(catal, catalog, doc, ns, NULL); - - /* - * reserialize it - */ - buf = xmlOutputBufferCreateFile(out, NULL); - if (buf == NULL) { - xmlFreeDoc(doc); - return(-1); - } - ret = xmlSaveFormatFileTo(buf, doc, NULL, 1); - - /* - * Free it - */ - xmlFreeDoc(doc); - - return(ret); -} -#endif /* LIBXML_OUTPUT_ENABLED */ - -/************************************************************************ - * * - * Converting SGML Catalogs to XML * - * * - ************************************************************************/ - -/** - * xmlCatalogConvertEntry: - * @entry: the entry - * @catal: pointer to the catalog being converted - * - * Convert one entry from the catalog - */ -static void -xmlCatalogConvertEntry(xmlCatalogEntryPtr entry, xmlCatalogPtr catal) { - if ((entry == NULL) || (catal == NULL) || (catal->sgml == NULL) || - (catal->xml == NULL)) - return; - switch (entry->type) { - case SGML_CATA_ENTITY: - entry->type = XML_CATA_PUBLIC; - break; - case SGML_CATA_PENTITY: - entry->type = XML_CATA_PUBLIC; - break; - case SGML_CATA_DOCTYPE: - entry->type = XML_CATA_PUBLIC; - break; - case SGML_CATA_LINKTYPE: - entry->type = XML_CATA_PUBLIC; - break; - case SGML_CATA_NOTATION: - entry->type = XML_CATA_PUBLIC; - break; - case SGML_CATA_PUBLIC: - entry->type = XML_CATA_PUBLIC; - break; - case SGML_CATA_SYSTEM: - entry->type = XML_CATA_SYSTEM; - break; - case SGML_CATA_DELEGATE: - entry->type = XML_CATA_DELEGATE_PUBLIC; - break; - case SGML_CATA_CATALOG: - entry->type = XML_CATA_CATALOG; - break; - default: - xmlHashRemoveEntry(catal->sgml, entry->name, - (xmlHashDeallocator) xmlFreeCatalogEntry); - return; - } - /* - * Conversion successful, remove from the SGML catalog - * and add it to the default XML one - */ - xmlHashRemoveEntry(catal->sgml, entry->name, NULL); - entry->parent = catal->xml; - entry->next = NULL; - if (catal->xml->children == NULL) - catal->xml->children = entry; - else { - xmlCatalogEntryPtr prev; - - prev = catal->xml->children; - while (prev->next != NULL) - prev = prev->next; - prev->next = entry; - } -} - -/** - * xmlConvertSGMLCatalog: - * @catal: the catalog - * - * Convert all the SGML catalog entries as XML ones - * - * Returns the number of entries converted if successful, -1 otherwise - */ -int -xmlConvertSGMLCatalog(xmlCatalogPtr catal) { - - if ((catal == NULL) || (catal->type != XML_SGML_CATALOG_TYPE)) - return(-1); - - if (xmlDebugCatalogs) { - xmlGenericError(xmlGenericErrorContext, - "Converting SGML catalog to XML\n"); - } - xmlHashScan(catal->sgml, - (xmlHashScanner) xmlCatalogConvertEntry, - &catal); - return(0); -} - -/************************************************************************ - * * - * Helper function * - * * - ************************************************************************/ - -/** - * xmlCatalogUnWrapURN: - * @urn: an "urn:publicid:" to unwrap - * - * Expand the URN into the equivalent Public Identifier - * - * Returns the new identifier or NULL, the string must be deallocated - * by the caller. - */ -static xmlChar * -xmlCatalogUnWrapURN(const xmlChar *urn) { - xmlChar result[2000]; - unsigned int i = 0; - - if (xmlStrncmp(urn, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) - return(NULL); - urn += sizeof(XML_URN_PUBID) - 1; - - while (*urn != 0) { - if (i > sizeof(result) - 4) - break; - if (*urn == '+') { - result[i++] = ' '; - urn++; - } else if (*urn == ':') { - result[i++] = '/'; - result[i++] = '/'; - urn++; - } else if (*urn == ';') { - result[i++] = ':'; - result[i++] = ':'; - urn++; - } else if (*urn == '%') { - if ((urn[1] == '2') && (urn[2] == 'B')) - result[i++] = '+'; - else if ((urn[1] == '3') && (urn[2] == 'A')) - result[i++] = ':'; - else if ((urn[1] == '2') && (urn[2] == 'F')) - result[i++] = '/'; - else if ((urn[1] == '3') && (urn[2] == 'B')) - result[i++] = ';'; - else if ((urn[1] == '2') && (urn[2] == '7')) - result[i++] = '\''; - else if ((urn[1] == '3') && (urn[2] == 'F')) - result[i++] = '?'; - else if ((urn[1] == '2') && (urn[2] == '3')) - result[i++] = '#'; - else if ((urn[1] == '2') && (urn[2] == '5')) - result[i++] = '%'; - else { - result[i++] = *urn; - urn++; - continue; - } - urn += 3; - } else { - result[i++] = *urn; - urn++; - } - } - result[i] = 0; - - return(xmlStrdup(result)); -} - -/** - * xmlParseCatalogFile: - * @filename: the filename - * - * parse an XML file and build a tree. It's like xmlParseFile() - * except it bypass all catalog lookups. - * - * Returns the resulting document tree or NULL in case of error - */ - -xmlDocPtr -xmlParseCatalogFile(const char *filename) { - xmlDocPtr ret; - xmlParserCtxtPtr ctxt; - char *directory = NULL; - xmlParserInputPtr inputStream; - xmlParserInputBufferPtr buf; - - ctxt = xmlNewParserCtxt(); - if (ctxt == NULL) { -#ifdef LIBXML_SAX1_ENABLED - if (xmlDefaultSAXHandler.error != NULL) { - xmlDefaultSAXHandler.error(NULL, "out of memory\n"); - } -#endif - return(NULL); - } - - buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE); - if (buf == NULL) { - xmlFreeParserCtxt(ctxt); - return(NULL); - } - - inputStream = xmlNewInputStream(ctxt); - if (inputStream == NULL) { - xmlFreeParserCtxt(ctxt); - return(NULL); - } - - inputStream->filename = (char *) xmlCanonicPath((const xmlChar *)filename); - inputStream->buf = buf; - xmlBufResetInput(buf->buffer, inputStream); - - inputPush(ctxt, inputStream); - if ((ctxt->directory == NULL) && (directory == NULL)) - directory = xmlParserGetDirectory(filename); - if ((ctxt->directory == NULL) && (directory != NULL)) - ctxt->directory = directory; - ctxt->valid = 0; - ctxt->validate = 0; - ctxt->loadsubset = 0; - ctxt->pedantic = 0; - ctxt->dictNames = 1; - - xmlParseDocument(ctxt); - - if (ctxt->wellFormed) - ret = ctxt->myDoc; - else { - ret = NULL; - xmlFreeDoc(ctxt->myDoc); - ctxt->myDoc = NULL; - } - xmlFreeParserCtxt(ctxt); - - return(ret); -} - -/** - * xmlLoadFileContent: - * @filename: a file path - * - * Load a file content into memory. - * - * Returns a pointer to the 0 terminated string or NULL in case of error - */ -static xmlChar * -xmlLoadFileContent(const char *filename) -{ -#ifdef HAVE_STAT - int fd; -#else - FILE *fd; -#endif - int len; - long size; - -#ifdef HAVE_STAT - struct stat info; -#endif - xmlChar *content; - - if (filename == NULL) - return (NULL); - -#ifdef HAVE_STAT - if (stat(filename, &info) < 0) - return (NULL); -#endif - -#ifdef HAVE_STAT - if ((fd = open(filename, O_RDONLY)) < 0) -#else - if ((fd = fopen(filename, "rb")) == NULL) -#endif - { - return (NULL); - } -#ifdef HAVE_STAT - size = info.st_size; -#else - if (fseek(fd, 0, SEEK_END) || (size = ftell(fd)) == EOF || fseek(fd, 0, SEEK_SET)) { /* File operations denied? ok, just close and return failure */ - fclose(fd); - return (NULL); - } -#endif - content = (xmlChar*)xmlMallocAtomic(size + 10); - if (content == NULL) { - xmlCatalogErrMemory("allocating catalog data"); -#ifdef HAVE_STAT - close(fd); -#else - fclose(fd); -#endif - return (NULL); - } -#ifdef HAVE_STAT - len = read(fd, content, size); - close(fd); -#else - len = fread(content, 1, size, fd); - fclose(fd); -#endif - if (len < 0) { - xmlFree(content); - return (NULL); - } - content[len] = 0; - - return(content); -} - -/** - * xmlCatalogNormalizePublic: - * @pubID: the public ID string - * - * Normalizes the Public Identifier - * - * Implements 6.2. Public Identifier Normalization - * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html - * - * Returns the new string or NULL, the string must be deallocated - * by the caller. - */ -static xmlChar * -xmlCatalogNormalizePublic(const xmlChar *pubID) -{ - int ok = 1; - int white; - const xmlChar *p; - xmlChar *ret; - xmlChar *q; - - if (pubID == NULL) - return(NULL); - - white = 1; - for (p = pubID;*p != 0 && ok;p++) { - if (!xmlIsBlank_ch(*p)) - white = 0; - else if (*p == 0x20 && !white) - white = 1; - else - ok = 0; - } - if (ok && !white) /* is normalized */ - return(NULL); - - ret = xmlStrdup(pubID); - q = ret; - white = 0; - for (p = pubID;*p != 0;p++) { - if (xmlIsBlank_ch(*p)) { - if (q != ret) - white = 1; - } else { - if (white) { - *(q++) = 0x20; - white = 0; - } - *(q++) = *p; - } - } - *q = 0; - return(ret); -} - -/************************************************************************ - * * - * The XML Catalog parser * - * * - ************************************************************************/ - -static xmlCatalogEntryPtr -xmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename); -static void -xmlParseXMLCatalogNodeList(xmlNodePtr cur, xmlCatalogPrefer prefer, - xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup); -static xmlChar * -xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID, - const xmlChar *sysID); -static xmlChar * -xmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI); - - -/** - * xmlGetXMLCatalogEntryType: - * @name: the name - * - * lookup the internal type associated to an XML catalog entry name - * - * Returns the type associated with that name - */ -static xmlCatalogEntryType -xmlGetXMLCatalogEntryType(const xmlChar *name) { - xmlCatalogEntryType type = XML_CATA_NONE; - 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 *) "rewriteSystem")) - type = XML_CATA_REWRITE_SYSTEM; - else if (xmlStrEqual(name, (const xmlChar *) "delegatePublic")) - type = XML_CATA_DELEGATE_PUBLIC; - else if (xmlStrEqual(name, (const xmlChar *) "delegateSystem")) - type = XML_CATA_DELEGATE_SYSTEM; - else if (xmlStrEqual(name, (const xmlChar *) "uri")) - type = XML_CATA_URI; - else if (xmlStrEqual(name, (const xmlChar *) "rewriteURI")) - type = XML_CATA_REWRITE_URI; - else if (xmlStrEqual(name, (const xmlChar *) "delegateURI")) - type = XML_CATA_DELEGATE_URI; - else if (xmlStrEqual(name, (const xmlChar *) "nextCatalog")) - type = XML_CATA_NEXT_CATALOG; - else if (xmlStrEqual(name, (const xmlChar *) "catalog")) - type = XML_CATA_CATALOG; - return(type); -} - -/** - * xmlParseXMLCatalogOneNode: - * @cur: the XML node - * @type: the type of Catalog entry - * @name: the name of the node - * @attrName: the attribute holding the value - * @uriAttrName: the attribute holding the URI-Reference - * @prefer: the PUBLIC vs. SYSTEM current preference value - * @cgroup: the group which includes this node - * - * Finishes the examination of an XML tree node of a catalog and build - * a Catalog entry from it. - * - * Returns the new Catalog entry node or NULL in case of error. - */ -static xmlCatalogEntryPtr -xmlParseXMLCatalogOneNode(xmlNodePtr cur, xmlCatalogEntryType type, - const xmlChar *name, const xmlChar *attrName, - const xmlChar *uriAttrName, xmlCatalogPrefer prefer, - xmlCatalogEntryPtr cgroup) { - int ok = 1; - xmlChar *uriValue; - xmlChar *nameValue = NULL; - xmlChar *base = NULL; - xmlChar *URL = NULL; - xmlCatalogEntryPtr ret = NULL; - - if (attrName != NULL) { - nameValue = xmlGetProp(cur, attrName); - if (nameValue == NULL) { - xmlCatalogErr(ret, cur, XML_CATALOG_MISSING_ATTR, - "%s entry lacks '%s'\n", name, attrName, NULL); - ok = 0; - } - } - uriValue = xmlGetProp(cur, uriAttrName); - if (uriValue == NULL) { - xmlCatalogErr(ret, cur, XML_CATALOG_MISSING_ATTR, - "%s entry lacks '%s'\n", name, uriAttrName, NULL); - ok = 0; - } - if (!ok) { - if (nameValue != NULL) - xmlFree(nameValue); - if (uriValue != NULL) - xmlFree(uriValue); - return(NULL); - } - - base = xmlNodeGetBase(cur->doc, cur); - URL = xmlBuildURI(uriValue, base); - if (URL != NULL) { - if (xmlDebugCatalogs > 1) { - if (nameValue != NULL) - xmlGenericError(xmlGenericErrorContext, - "Found %s: '%s' '%s'\n", name, nameValue, URL); - else - xmlGenericError(xmlGenericErrorContext, - "Found %s: '%s'\n", name, URL); - } - ret = xmlNewCatalogEntry(type, nameValue, uriValue, URL, prefer, cgroup); - } else { - xmlCatalogErr(ret, cur, XML_CATALOG_ENTRY_BROKEN, - "%s entry '%s' broken ?: %s\n", name, uriAttrName, uriValue); - } - if (nameValue != NULL) - xmlFree(nameValue); - if (uriValue != NULL) - xmlFree(uriValue); - if (base != NULL) - xmlFree(base); - if (URL != NULL) - xmlFree(URL); - return(ret); -} - -/** - * xmlParseXMLCatalogNode: - * @cur: the XML node - * @prefer: the PUBLIC vs. SYSTEM current preference value - * @parent: the parent Catalog entry - * @cgroup: the group which includes this node - * - * Examines an XML tree node of a catalog and build - * a Catalog entry from it adding it to its parent. The examination can - * be recursive. - */ -static void -xmlParseXMLCatalogNode(xmlNodePtr cur, xmlCatalogPrefer prefer, - xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup) -{ - xmlChar *base = NULL; - xmlCatalogEntryPtr entry = NULL; - - if (cur == NULL) - return; - if (xmlStrEqual(cur->name, BAD_CAST "group")) { - xmlChar *prop; - xmlCatalogPrefer pref = XML_CATA_PREFER_NONE; - - prop = xmlGetProp(cur, BAD_CAST "prefer"); - if (prop != NULL) { - if (xmlStrEqual(prop, BAD_CAST "system")) { - prefer = XML_CATA_PREFER_SYSTEM; - } else if (xmlStrEqual(prop, BAD_CAST "public")) { - prefer = XML_CATA_PREFER_PUBLIC; - } else { - xmlCatalogErr(parent, cur, XML_CATALOG_PREFER_VALUE, - "Invalid value for prefer: '%s'\n", - prop, NULL, NULL); - } - xmlFree(prop); - pref = prefer; - } - prop = xmlGetProp(cur, BAD_CAST "id"); - base = xmlGetNsProp(cur, BAD_CAST "base", XML_XML_NAMESPACE); - entry = xmlNewCatalogEntry(XML_CATA_GROUP, prop, base, NULL, pref, cgroup); - xmlFree(prop); - } else if (xmlStrEqual(cur->name, BAD_CAST "public")) { - entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_PUBLIC, - BAD_CAST "public", BAD_CAST "publicId", BAD_CAST "uri", prefer, cgroup); - } else if (xmlStrEqual(cur->name, BAD_CAST "system")) { - entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_SYSTEM, - BAD_CAST "system", BAD_CAST "systemId", BAD_CAST "uri", prefer, cgroup); - } else if (xmlStrEqual(cur->name, BAD_CAST "rewriteSystem")) { - entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_SYSTEM, - BAD_CAST "rewriteSystem", BAD_CAST "systemIdStartString", - BAD_CAST "rewritePrefix", prefer, cgroup); - } else if (xmlStrEqual(cur->name, BAD_CAST "delegatePublic")) { - entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_PUBLIC, - BAD_CAST "delegatePublic", BAD_CAST "publicIdStartString", - BAD_CAST "catalog", prefer, cgroup); - } else if (xmlStrEqual(cur->name, BAD_CAST "delegateSystem")) { - entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_SYSTEM, - BAD_CAST "delegateSystem", BAD_CAST "systemIdStartString", - BAD_CAST "catalog", prefer, cgroup); - } else if (xmlStrEqual(cur->name, BAD_CAST "uri")) { - entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_URI, - BAD_CAST "uri", BAD_CAST "name", - BAD_CAST "uri", prefer, cgroup); - } else if (xmlStrEqual(cur->name, BAD_CAST "rewriteURI")) { - entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_URI, - BAD_CAST "rewriteURI", BAD_CAST "uriStartString", - BAD_CAST "rewritePrefix", prefer, cgroup); - } else if (xmlStrEqual(cur->name, BAD_CAST "delegateURI")) { - entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_URI, - BAD_CAST "delegateURI", BAD_CAST "uriStartString", - BAD_CAST "catalog", prefer, cgroup); - } else if (xmlStrEqual(cur->name, BAD_CAST "nextCatalog")) { - entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_NEXT_CATALOG, - BAD_CAST "nextCatalog", NULL, - BAD_CAST "catalog", prefer, cgroup); - } - if (entry != NULL) { - if (parent != NULL) { - entry->parent = parent; - if (parent->children == NULL) - parent->children = entry; - else { - xmlCatalogEntryPtr prev; - - prev = parent->children; - while (prev->next != NULL) - prev = prev->next; - prev->next = entry; - } - } - if (entry->type == XML_CATA_GROUP) { - /* - * Recurse to propagate prefer to the subtree - * (xml:base handling is automated) - */ - xmlParseXMLCatalogNodeList(cur->children, prefer, parent, entry); - } - } - if (base != NULL) - xmlFree(base); -} - -/** - * xmlParseXMLCatalogNodeList: - * @cur: the XML node list of siblings - * @prefer: the PUBLIC vs. SYSTEM current preference value - * @parent: the parent Catalog entry - * @cgroup: the group which includes this list - * - * Examines a list of XML sibling nodes of a catalog and build - * a list of Catalog entry from it adding it to the parent. - * The examination will recurse to examine node subtrees. - */ -static void -xmlParseXMLCatalogNodeList(xmlNodePtr cur, xmlCatalogPrefer prefer, - xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup) { - while (cur != NULL) { - if ((cur->ns != NULL) && (cur->ns->href != NULL) && - (xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) { - xmlParseXMLCatalogNode(cur, prefer, parent, cgroup); - } - cur = cur->next; - } - /* TODO: sort the list according to REWRITE lengths and prefer value */ -} - -/** - * xmlParseXMLCatalogFile: - * @prefer: the PUBLIC vs. SYSTEM current preference value - * @filename: the filename for the catalog - * - * Parses the catalog file to extract the XML tree and then analyze the - * tree to build a list of Catalog entries corresponding to this catalog - * - * Returns the resulting Catalog entries list - */ -static xmlCatalogEntryPtr -xmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename) { - xmlDocPtr doc; - xmlNodePtr cur; - xmlChar *prop; - xmlCatalogEntryPtr parent = NULL; - - if (filename == NULL) - return(NULL); - - doc = xmlParseCatalogFile((const char *) filename); - if (doc == NULL) { - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "Failed to parse catalog %s\n", filename); - return(NULL); - } - - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "%d Parsing catalog %s\n", xmlGetThreadId(), filename); - - cur = xmlDocGetRootElement(doc); - if ((cur != NULL) && (xmlStrEqual(cur->name, BAD_CAST "catalog")) && - (cur->ns != NULL) && (cur->ns->href != NULL) && - (xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) { - - parent = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL, - (const xmlChar *)filename, NULL, prefer, NULL); - if (parent == NULL) { - xmlFreeDoc(doc); - return(NULL); - } - - prop = xmlGetProp(cur, BAD_CAST "prefer"); - if (prop != NULL) { - if (xmlStrEqual(prop, BAD_CAST "system")) { - prefer = XML_CATA_PREFER_SYSTEM; - } else if (xmlStrEqual(prop, BAD_CAST "public")) { - prefer = XML_CATA_PREFER_PUBLIC; - } else { - xmlCatalogErr(NULL, cur, XML_CATALOG_PREFER_VALUE, - "Invalid value for prefer: '%s'\n", - prop, NULL, NULL); - } - xmlFree(prop); - } - cur = cur->children; - xmlParseXMLCatalogNodeList(cur, prefer, parent, NULL); - } else { - xmlCatalogErr(NULL, (xmlNodePtr) doc, XML_CATALOG_NOT_CATALOG, - "File %s is not an XML Catalog\n", - filename, NULL, NULL); - xmlFreeDoc(doc); - return(NULL); - } - xmlFreeDoc(doc); - return(parent); -} - -/** - * xmlFetchXMLCatalogFile: - * @catal: an existing but incomplete catalog entry - * - * Fetch and parse the subcatalog referenced by an entry - * - * Returns 0 in case of success, -1 otherwise - */ -static int -xmlFetchXMLCatalogFile(xmlCatalogEntryPtr catal) { - xmlCatalogEntryPtr doc; - - if (catal == NULL) - return(-1); - if (catal->URL == NULL) - return(-1); - - /* - * lock the whole catalog for modification - */ - xmlRMutexLock(xmlCatalogMutex); - if (catal->children != NULL) { - /* Okay someone else did it in the meantime */ - xmlRMutexUnlock(xmlCatalogMutex); - return(0); - } - - if (xmlCatalogXMLFiles != NULL) { - doc = (xmlCatalogEntryPtr) - xmlHashLookup(xmlCatalogXMLFiles, catal->URL); - if (doc != NULL) { - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "Found %s in file hash\n", catal->URL); - - if (catal->type == XML_CATA_CATALOG) - catal->children = doc->children; - else - catal->children = doc; - catal->dealloc = 0; - xmlRMutexUnlock(xmlCatalogMutex); - return(0); - } - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "%s not found in file hash\n", catal->URL); - } - - /* - * Fetch and parse. Note that xmlParseXMLCatalogFile does not - * use the existing catalog, there is no recursion allowed at - * that level. - */ - doc = xmlParseXMLCatalogFile(catal->prefer, catal->URL); - if (doc == NULL) { - catal->type = XML_CATA_BROKEN_CATALOG; - xmlRMutexUnlock(xmlCatalogMutex); - return(-1); - } - - if (catal->type == XML_CATA_CATALOG) - catal->children = doc->children; - else - catal->children = doc; - - doc->dealloc = 1; - - if (xmlCatalogXMLFiles == NULL) - xmlCatalogXMLFiles = xmlHashCreate(10); - if (xmlCatalogXMLFiles != NULL) { - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "%s added to file hash\n", catal->URL); - xmlHashAddEntry(xmlCatalogXMLFiles, catal->URL, doc); - } - xmlRMutexUnlock(xmlCatalogMutex); - return(0); -} - -/************************************************************************ - * * - * XML Catalog handling * - * * - ************************************************************************/ - -/** - * xmlAddXMLCatalog: - * @catal: top of an XML catalog - * @type: the type of record to add to the catalog - * @orig: the system, public or prefix to match (or NULL) - * @replace: the replacement value for the match - * - * Add an entry in the XML catalog, it may overwrite existing but - * different entries. - * - * Returns 0 if successful, -1 otherwise - */ -static int -xmlAddXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *type, - const xmlChar *orig, const xmlChar *replace) { - xmlCatalogEntryPtr cur; - xmlCatalogEntryType typ; - int doregister = 0; - - if ((catal == NULL) || - ((catal->type != XML_CATA_CATALOG) && - (catal->type != XML_CATA_BROKEN_CATALOG))) - return(-1); - if (catal->children == NULL) { - xmlFetchXMLCatalogFile(catal); - } - if (catal->children == NULL) - doregister = 1; - - typ = xmlGetXMLCatalogEntryType(type); - if (typ == XML_CATA_NONE) { - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "Failed to add unknown element %s to catalog\n", type); - return(-1); - } - - cur = catal->children; - /* - * Might be a simple "update in place" - */ - if (cur != NULL) { - while (cur != NULL) { - if ((orig != NULL) && (cur->type == typ) && - (xmlStrEqual(orig, cur->name))) { - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "Updating element %s to catalog\n", type); - if (cur->value != NULL) - xmlFree(cur->value); - if (cur->URL != NULL) - xmlFree(cur->URL); - cur->value = xmlStrdup(replace); - cur->URL = xmlStrdup(replace); - return(0); - } - if (cur->next == NULL) - break; - cur = cur->next; - } - } - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "Adding element %s to catalog\n", type); - if (cur == NULL) - catal->children = xmlNewCatalogEntry(typ, orig, replace, - NULL, catal->prefer, NULL); - else - cur->next = xmlNewCatalogEntry(typ, orig, replace, - NULL, catal->prefer, NULL); - if (doregister) { - catal->type = XML_CATA_CATALOG; - cur = (xmlCatalogEntryPtr)xmlHashLookup(xmlCatalogXMLFiles, catal->URL); - if (cur != NULL) - cur->children = catal->children; - } - - return(0); -} - -/** - * xmlDelXMLCatalog: - * @catal: top of an XML catalog - * @value: the value to remove from the catalog - * - * Remove entries in the XML catalog where the value or the URI - * is equal to @value - * - * Returns the number of entries removed if successful, -1 otherwise - */ -static int -xmlDelXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *value) { - xmlCatalogEntryPtr cur; - int ret = 0; - - if ((catal == NULL) || - ((catal->type != XML_CATA_CATALOG) && - (catal->type != XML_CATA_BROKEN_CATALOG))) - return(-1); - if (value == NULL) - return(-1); - if (catal->children == NULL) { - xmlFetchXMLCatalogFile(catal); - } - - /* - * Scan the children - */ - cur = catal->children; - while (cur != NULL) { - if (((cur->name != NULL) && (xmlStrEqual(value, cur->name))) || - (xmlStrEqual(value, cur->value))) { - if (xmlDebugCatalogs) { - if (cur->name != NULL) - xmlGenericError(xmlGenericErrorContext, - "Removing element %s from catalog\n", cur->name); - else - xmlGenericError(xmlGenericErrorContext, - "Removing element %s from catalog\n", cur->value); - } - cur->type = XML_CATA_REMOVED; - } - cur = cur->next; - } - return(ret); -} - -/** - * xmlCatalogXMLResolve: - * @catal: a catalog list - * @pubID: the public ID string - * @sysID: the system ID string - * - * Do a complete resolution lookup of an External Identifier for a - * list of catalog entries. - * - * Implements (or tries to) 7.1. External Identifier Resolution - * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html - * - * Returns the URI of the resource or NULL if not found - */ -static xmlChar * -xmlCatalogXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID, - const xmlChar *sysID) { - xmlChar *ret = NULL; - xmlCatalogEntryPtr cur; - int haveDelegate = 0; - int haveNext = 0; - - /* - * protection against loops - */ - if (catal->depth > MAX_CATAL_DEPTH) { - xmlCatalogErr(catal, NULL, XML_CATALOG_RECURSION, - "Detected recursion in catalog %s\n", - catal->name, NULL, NULL); - return(NULL); - } - catal->depth++; - - /* - * First tries steps 2/ 3/ 4/ if a system ID is provided. - */ - if (sysID != NULL) { - xmlCatalogEntryPtr rewrite = NULL; - int lenrewrite = 0, len; - cur = catal; - haveDelegate = 0; - while (cur != NULL) { - switch (cur->type) { - case XML_CATA_SYSTEM: - if (xmlStrEqual(sysID, cur->name)) { - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "Found system match %s, using %s\n", - cur->name, cur->URL); - catal->depth--; - return(xmlStrdup(cur->URL)); - } - break; - case XML_CATA_REWRITE_SYSTEM: - len = xmlStrlen(cur->name); - if ((len > lenrewrite) && - (!xmlStrncmp(sysID, cur->name, len))) { - lenrewrite = len; - rewrite = cur; - } - break; - case XML_CATA_DELEGATE_SYSTEM: - if (!xmlStrncmp(sysID, cur->name, xmlStrlen(cur->name))) - haveDelegate++; - break; - case XML_CATA_NEXT_CATALOG: - haveNext++; - break; - default: - break; - } - cur = cur->next; - } - if (rewrite != NULL) { - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "Using rewriting rule %s\n", rewrite->name); - ret = xmlStrdup(rewrite->URL); - if (ret != NULL) - ret = xmlStrcat(ret, &sysID[lenrewrite]); - catal->depth--; - return(ret); - } - if (haveDelegate) { - const xmlChar *delegates[MAX_DELEGATE]; - int nbList = 0, i; - - /* - * Assume the entries have been sorted by decreasing substring - * matches when the list was produced. - */ - cur = catal; - while (cur != NULL) { - if ((cur->type == XML_CATA_DELEGATE_SYSTEM) && - (!xmlStrncmp(sysID, cur->name, xmlStrlen(cur->name)))) { - for (i = 0;i < nbList;i++) - if (xmlStrEqual(cur->URL, delegates[i])) - break; - if (i < nbList) { - cur = cur->next; - continue; - } - if (nbList < MAX_DELEGATE) - delegates[nbList++] = cur->URL; - - if (cur->children == NULL) { - xmlFetchXMLCatalogFile(cur); - } - if (cur->children != NULL) { - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "Trying system delegate %s\n", cur->URL); - ret = xmlCatalogListXMLResolve( - cur->children, NULL, sysID); - if (ret != NULL) { - catal->depth--; - return(ret); - } - } - } - cur = cur->next; - } - /* - * Apply the cut algorithm explained in 4/ - */ - catal->depth--; - return(XML_CATAL_BREAK); - } - } - /* - * Then tries 5/ 6/ if a public ID is provided - */ - if (pubID != NULL) { - cur = catal; - haveDelegate = 0; - while (cur != NULL) { - switch (cur->type) { - case XML_CATA_PUBLIC: - if (xmlStrEqual(pubID, cur->name)) { - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "Found public match %s\n", cur->name); - catal->depth--; - return(xmlStrdup(cur->URL)); - } - break; - case XML_CATA_DELEGATE_PUBLIC: - if (!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)) && - (cur->prefer == XML_CATA_PREFER_PUBLIC)) - haveDelegate++; - break; - case XML_CATA_NEXT_CATALOG: - if (sysID == NULL) - haveNext++; - break; - default: - break; - } - cur = cur->next; - } - if (haveDelegate) { - const xmlChar *delegates[MAX_DELEGATE]; - int nbList = 0, i; - - /* - * Assume the entries have been sorted by decreasing substring - * matches when the list was produced. - */ - cur = catal; - while (cur != NULL) { - if ((cur->type == XML_CATA_DELEGATE_PUBLIC) && - (cur->prefer == XML_CATA_PREFER_PUBLIC) && - (!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)))) { - - for (i = 0;i < nbList;i++) - if (xmlStrEqual(cur->URL, delegates[i])) - break; - if (i < nbList) { - cur = cur->next; - continue; - } - if (nbList < MAX_DELEGATE) - delegates[nbList++] = cur->URL; - - if (cur->children == NULL) { - xmlFetchXMLCatalogFile(cur); - } - if (cur->children != NULL) { - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "Trying public delegate %s\n", cur->URL); - ret = xmlCatalogListXMLResolve( - cur->children, pubID, NULL); - if (ret != NULL) { - catal->depth--; - return(ret); - } - } - } - cur = cur->next; - } - /* - * Apply the cut algorithm explained in 4/ - */ - catal->depth--; - return(XML_CATAL_BREAK); - } - } - if (haveNext) { - cur = catal; - while (cur != NULL) { - if (cur->type == XML_CATA_NEXT_CATALOG) { - if (cur->children == NULL) { - xmlFetchXMLCatalogFile(cur); - } - if (cur->children != NULL) { - ret = xmlCatalogListXMLResolve(cur->children, pubID, sysID); - if (ret != NULL) { - catal->depth--; - return(ret); - } else if (catal->depth > MAX_CATAL_DEPTH) { - return(NULL); - } - } - } - cur = cur->next; - } - } - - catal->depth--; - return(NULL); -} - -/** - * xmlCatalogXMLResolveURI: - * @catal: a catalog list - * @URI: the URI - * @sysID: the system ID string - * - * Do a complete resolution lookup of an External Identifier for a - * list of catalog entries. - * - * Implements (or tries to) 7.2.2. URI Resolution - * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html - * - * Returns the URI of the resource or NULL if not found - */ -static xmlChar * -xmlCatalogXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) { - xmlChar *ret = NULL; - xmlCatalogEntryPtr cur; - int haveDelegate = 0; - int haveNext = 0; - xmlCatalogEntryPtr rewrite = NULL; - int lenrewrite = 0, len; - - if (catal == NULL) - return(NULL); - - if (URI == NULL) - return(NULL); - - if (catal->depth > MAX_CATAL_DEPTH) { - xmlCatalogErr(catal, NULL, XML_CATALOG_RECURSION, - "Detected recursion in catalog %s\n", - catal->name, NULL, NULL); - return(NULL); - } - - /* - * First tries steps 2/ 3/ 4/ if a system ID is provided. - */ - cur = catal; - haveDelegate = 0; - while (cur != NULL) { - switch (cur->type) { - case XML_CATA_URI: - if (xmlStrEqual(URI, cur->name)) { - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "Found URI match %s\n", cur->name); - return(xmlStrdup(cur->URL)); - } - break; - case XML_CATA_REWRITE_URI: - len = xmlStrlen(cur->name); - if ((len > lenrewrite) && - (!xmlStrncmp(URI, cur->name, len))) { - lenrewrite = len; - rewrite = cur; - } - break; - case XML_CATA_DELEGATE_URI: - if (!xmlStrncmp(URI, cur->name, xmlStrlen(cur->name))) - haveDelegate++; - break; - case XML_CATA_NEXT_CATALOG: - haveNext++; - break; - default: - break; - } - cur = cur->next; - } - if (rewrite != NULL) { - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "Using rewriting rule %s\n", rewrite->name); - ret = xmlStrdup(rewrite->URL); - if (ret != NULL) - ret = xmlStrcat(ret, &URI[lenrewrite]); - return(ret); - } - if (haveDelegate) { - const xmlChar *delegates[MAX_DELEGATE]; - int nbList = 0, i; - - /* - * Assume the entries have been sorted by decreasing substring - * matches when the list was produced. - */ - cur = catal; - while (cur != NULL) { - if (((cur->type == XML_CATA_DELEGATE_SYSTEM) || - (cur->type == XML_CATA_DELEGATE_URI)) && - (!xmlStrncmp(URI, cur->name, xmlStrlen(cur->name)))) { - for (i = 0;i < nbList;i++) - if (xmlStrEqual(cur->URL, delegates[i])) - break; - if (i < nbList) { - cur = cur->next; - continue; - } - if (nbList < MAX_DELEGATE) - delegates[nbList++] = cur->URL; - - if (cur->children == NULL) { - xmlFetchXMLCatalogFile(cur); - } - if (cur->children != NULL) { - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "Trying URI delegate %s\n", cur->URL); - ret = xmlCatalogListXMLResolveURI( - cur->children, URI); - if (ret != NULL) - return(ret); - } - } - cur = cur->next; - } - /* - * Apply the cut algorithm explained in 4/ - */ - return(XML_CATAL_BREAK); - } - if (haveNext) { - cur = catal; - while (cur != NULL) { - if (cur->type == XML_CATA_NEXT_CATALOG) { - if (cur->children == NULL) { - xmlFetchXMLCatalogFile(cur); - } - if (cur->children != NULL) { - ret = xmlCatalogListXMLResolveURI(cur->children, URI); - if (ret != NULL) - return(ret); - } - } - cur = cur->next; - } - } - - return(NULL); -} - -/** - * xmlCatalogListXMLResolve: - * @catal: a catalog list - * @pubID: the public ID string - * @sysID: the system ID string - * - * Do a complete resolution lookup of an External Identifier for a - * list of catalogs - * - * Implements (or tries to) 7.1. External Identifier Resolution - * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html - * - * Returns the URI of the resource or NULL if not found - */ -static xmlChar * -xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID, - const xmlChar *sysID) { - xmlChar *ret = NULL; - xmlChar *urnID = NULL; - xmlChar *normid; - - if (catal == NULL) - return(NULL); - if ((pubID == NULL) && (sysID == NULL)) - return(NULL); - - normid = xmlCatalogNormalizePublic(pubID); - if (normid != NULL) - pubID = (*normid != 0 ? normid : NULL); - - if (!xmlStrncmp(pubID, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) { - urnID = xmlCatalogUnWrapURN(pubID); - if (xmlDebugCatalogs) { - if (urnID == NULL) - xmlGenericError(xmlGenericErrorContext, - "Public URN ID %s expanded to NULL\n", pubID); - else - xmlGenericError(xmlGenericErrorContext, - "Public URN ID expanded to %s\n", urnID); - } - ret = xmlCatalogListXMLResolve(catal, urnID, sysID); - if (urnID != NULL) - xmlFree(urnID); - if (normid != NULL) - xmlFree(normid); - return(ret); - } - if (!xmlStrncmp(sysID, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) { - urnID = xmlCatalogUnWrapURN(sysID); - if (xmlDebugCatalogs) { - if (urnID == NULL) - xmlGenericError(xmlGenericErrorContext, - "System URN ID %s expanded to NULL\n", sysID); - else - xmlGenericError(xmlGenericErrorContext, - "System URN ID expanded to %s\n", urnID); - } - if (pubID == NULL) - ret = xmlCatalogListXMLResolve(catal, urnID, NULL); - else if (xmlStrEqual(pubID, urnID)) - ret = xmlCatalogListXMLResolve(catal, pubID, NULL); - else { - ret = xmlCatalogListXMLResolve(catal, pubID, urnID); - } - if (urnID != NULL) - xmlFree(urnID); - if (normid != NULL) - xmlFree(normid); - return(ret); - } - while (catal != NULL) { - if (catal->type == XML_CATA_CATALOG) { - if (catal->children == NULL) { - xmlFetchXMLCatalogFile(catal); - } - if (catal->children != NULL) { - ret = xmlCatalogXMLResolve(catal->children, pubID, sysID); - if (ret != NULL) { - break; - } else if ((catal->children != NULL) && - (catal->children->depth > MAX_CATAL_DEPTH)) { - ret = NULL; - break; - } - } - } - catal = catal->next; - } - if (normid != NULL) - xmlFree(normid); - return(ret); -} - -/** - * xmlCatalogListXMLResolveURI: - * @catal: a catalog list - * @URI: the URI - * - * Do a complete resolution lookup of an URI for a list of catalogs - * - * Implements (or tries to) 7.2. URI Resolution - * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html - * - * Returns the URI of the resource or NULL if not found - */ -static xmlChar * -xmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) { - xmlChar *ret = NULL; - xmlChar *urnID = NULL; - - if (catal == NULL) - return(NULL); - if (URI == NULL) - return(NULL); - - if (!xmlStrncmp(URI, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) { - urnID = xmlCatalogUnWrapURN(URI); - if (xmlDebugCatalogs) { - if (urnID == NULL) - xmlGenericError(xmlGenericErrorContext, - "URN ID %s expanded to NULL\n", URI); - else - xmlGenericError(xmlGenericErrorContext, - "URN ID expanded to %s\n", urnID); - } - ret = xmlCatalogListXMLResolve(catal, urnID, NULL); - if (urnID != NULL) - xmlFree(urnID); - return(ret); - } - while (catal != NULL) { - if (catal->type == XML_CATA_CATALOG) { - if (catal->children == NULL) { - xmlFetchXMLCatalogFile(catal); - } - if (catal->children != NULL) { - ret = xmlCatalogXMLResolveURI(catal->children, URI); - if (ret != NULL) - return(ret); - } - } - catal = catal->next; - } - return(ret); -} - -/************************************************************************ - * * - * The SGML Catalog parser * - * * - ************************************************************************/ - - -#define RAW *cur -#define NEXT cur++; -#define SKIP(x) cur += x; - -#define SKIP_BLANKS while (IS_BLANK_CH(*cur)) NEXT; - -/** - * xmlParseSGMLCatalogComment: - * @cur: the current character - * - * Skip a comment in an SGML catalog - * - * Returns new current character - */ -static const xmlChar * -xmlParseSGMLCatalogComment(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 + 2); -} - -/** - * xmlParseSGMLCatalogPubid: - * @cur: the current character - * @id: the return location - * - * Parse an SGML catalog ID - * - * Returns new current character and store the value in @id - */ -static const xmlChar * -xmlParseSGMLCatalogPubid(const xmlChar *cur, xmlChar **id) { - xmlChar *buf = NULL, *tmp; - 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 *) xmlMallocAtomic(size * sizeof(xmlChar)); - if (buf == NULL) { - xmlCatalogErrMemory("allocating public ID"); - return(NULL); - } - while (IS_PUBIDCHAR_CH(*cur) || (*cur == '?')) { - if ((*cur == stop) && (stop != ' ')) - break; - if ((stop == ' ') && (IS_BLANK_CH(*cur))) - break; - if (len + 1 >= size) { - size *= 2; - tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar)); - if (tmp == NULL) { - xmlCatalogErrMemory("allocating public ID"); - xmlFree(buf); - return(NULL); - } - buf = tmp; - } - buf[len++] = *cur; - count++; - NEXT; - } - buf[len] = 0; - if (stop == ' ') { - if (!IS_BLANK_CH(*cur)) { - xmlFree(buf); - return(NULL); - } - } else { - if (*cur != stop) { - xmlFree(buf); - return(NULL); - } - NEXT; - } - *id = buf; - return(cur); -} - -/** - * xmlParseSGMLCatalogName: - * @cur: the current character - * @name: the return location - * - * Parse an SGML catalog name - * - * Returns new current character and store the value in @name - */ -static const xmlChar * -xmlParseSGMLCatalogName(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); -} - -/** - * xmlGetSGMLCatalogEntryType: - * @name: the entry name - * - * Get the Catalog entry type for a given SGML Catalog name - * - * Returns Catalog entry type - */ -static xmlCatalogEntryType -xmlGetSGMLCatalogEntryType(const xmlChar *name) { - xmlCatalogEntryType type = XML_CATA_NONE; - if (xmlStrEqual(name, (const xmlChar *) "SYSTEM")) - type = SGML_CATA_SYSTEM; - else if (xmlStrEqual(name, (const xmlChar *) "PUBLIC")) - type = SGML_CATA_PUBLIC; - else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE")) - type = SGML_CATA_DELEGATE; - else if (xmlStrEqual(name, (const xmlChar *) "ENTITY")) - type = SGML_CATA_ENTITY; - else if (xmlStrEqual(name, (const xmlChar *) "DOCTYPE")) - type = SGML_CATA_DOCTYPE; - else if (xmlStrEqual(name, (const xmlChar *) "LINKTYPE")) - type = SGML_CATA_LINKTYPE; - else if (xmlStrEqual(name, (const xmlChar *) "NOTATION")) - type = SGML_CATA_NOTATION; - else if (xmlStrEqual(name, (const xmlChar *) "SGMLDECL")) - type = SGML_CATA_SGMLDECL; - else if (xmlStrEqual(name, (const xmlChar *) "DOCUMENT")) - type = SGML_CATA_DOCUMENT; - else if (xmlStrEqual(name, (const xmlChar *) "CATALOG")) - type = SGML_CATA_CATALOG; - else if (xmlStrEqual(name, (const xmlChar *) "BASE")) - type = SGML_CATA_BASE; - return(type); -} - -/** - * xmlParseSGMLCatalog: - * @catal: the SGML Catalog - * @value: the content of the SGML Catalog serialization - * @file: the filepath for the catalog - * @super: should this be handled as a Super Catalog in which case - * parsing is not recursive - * - * Parse an SGML catalog content and fill up the @catal hash table with - * the new entries found. - * - * Returns 0 in case of success, -1 in case of error. - */ -static int -xmlParseSGMLCatalog(xmlCatalogPtr catal, const xmlChar *value, - const char *file, int super) { - const xmlChar *cur = value; - xmlChar *base = NULL; - int res; - - if ((cur == NULL) || (file == NULL)) - return(-1); - base = xmlStrdup((const xmlChar *) file); - - while ((cur != NULL) && (cur[0] != 0)) { - SKIP_BLANKS; - if (cur[0] == 0) - break; - if ((cur[0] == '-') && (cur[1] == '-')) { - cur = xmlParseSGMLCatalogComment(cur); - if (cur == NULL) { - /* error */ - break; - } - } else { - xmlChar *sysid = NULL; - xmlChar *name = NULL; - xmlCatalogEntryType type = XML_CATA_NONE; - - cur = xmlParseSGMLCatalogName(cur, &name); - if (name == NULL) { - /* error */ - break; - } - if (!IS_BLANK_CH(*cur)) { - /* error */ - break; - } - SKIP_BLANKS; - if (xmlStrEqual(name, (const xmlChar *) "SYSTEM")) - type = SGML_CATA_SYSTEM; - else if (xmlStrEqual(name, (const xmlChar *) "PUBLIC")) - type = SGML_CATA_PUBLIC; - else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE")) - type = SGML_CATA_DELEGATE; - else if (xmlStrEqual(name, (const xmlChar *) "ENTITY")) - type = SGML_CATA_ENTITY; - else if (xmlStrEqual(name, (const xmlChar *) "DOCTYPE")) - type = SGML_CATA_DOCTYPE; - else if (xmlStrEqual(name, (const xmlChar *) "LINKTYPE")) - type = SGML_CATA_LINKTYPE; - else if (xmlStrEqual(name, (const xmlChar *) "NOTATION")) - type = SGML_CATA_NOTATION; - else if (xmlStrEqual(name, (const xmlChar *) "SGMLDECL")) - type = SGML_CATA_SGMLDECL; - else if (xmlStrEqual(name, (const xmlChar *) "DOCUMENT")) - type = SGML_CATA_DOCUMENT; - else if (xmlStrEqual(name, (const xmlChar *) "CATALOG")) - type = SGML_CATA_CATALOG; - else if (xmlStrEqual(name, (const xmlChar *) "BASE")) - type = SGML_CATA_BASE; - else if (xmlStrEqual(name, (const xmlChar *) "OVERRIDE")) { - xmlFree(name); - cur = xmlParseSGMLCatalogName(cur, &name); - if (name == NULL) { - /* error */ - break; - } - xmlFree(name); - continue; - } - xmlFree(name); - name = NULL; - - switch(type) { - case SGML_CATA_ENTITY: - if (*cur == '%') - type = SGML_CATA_PENTITY; - case SGML_CATA_PENTITY: - case SGML_CATA_DOCTYPE: - case SGML_CATA_LINKTYPE: - case SGML_CATA_NOTATION: - cur = xmlParseSGMLCatalogName(cur, &name); - if (cur == NULL) { - /* error */ - break; - } - if (!IS_BLANK_CH(*cur)) { - /* error */ - break; - } - SKIP_BLANKS; - cur = xmlParseSGMLCatalogPubid(cur, &sysid); - if (cur == NULL) { - /* error */ - break; - } - break; - case SGML_CATA_PUBLIC: - case SGML_CATA_SYSTEM: - case SGML_CATA_DELEGATE: - cur = xmlParseSGMLCatalogPubid(cur, &name); - if (cur == NULL) { - /* error */ - break; - } - if (type != SGML_CATA_SYSTEM) { - xmlChar *normid; - - normid = xmlCatalogNormalizePublic(name); - if (normid != NULL) { - if (name != NULL) - xmlFree(name); - if (*normid != 0) - name = normid; - else { - xmlFree(normid); - name = NULL; - } - } - } - if (!IS_BLANK_CH(*cur)) { - /* error */ - break; - } - SKIP_BLANKS; - cur = xmlParseSGMLCatalogPubid(cur, &sysid); - if (cur == NULL) { - /* error */ - break; - } - break; - case SGML_CATA_BASE: - case SGML_CATA_CATALOG: - case SGML_CATA_DOCUMENT: - case SGML_CATA_SGMLDECL: - cur = xmlParseSGMLCatalogPubid(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 == SGML_CATA_BASE) { - if (base != NULL) - xmlFree(base); - base = xmlStrdup(sysid); - } else if ((type == SGML_CATA_PUBLIC) || - (type == SGML_CATA_SYSTEM)) { - xmlChar *filename; - - filename = xmlBuildURI(sysid, base); - if (filename != NULL) { - xmlCatalogEntryPtr entry; - - entry = xmlNewCatalogEntry(type, name, filename, - NULL, XML_CATA_PREFER_NONE, NULL); - res = xmlHashAddEntry(catal->sgml, name, entry); - if (res < 0) { - xmlFreeCatalogEntry(entry); - } - xmlFree(filename); - } - - } else if (type == SGML_CATA_CATALOG) { - if (super) { - xmlCatalogEntryPtr entry; - - entry = xmlNewCatalogEntry(type, sysid, NULL, NULL, - XML_CATA_PREFER_NONE, NULL); - res = xmlHashAddEntry(catal->sgml, sysid, entry); - if (res < 0) { - xmlFreeCatalogEntry(entry); - } - } else { - xmlChar *filename; - - filename = xmlBuildURI(sysid, base); - if (filename != NULL) { - xmlExpandCatalog(catal, (const char *)filename); - xmlFree(filename); - } - } - } - /* - * 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); -} - -/************************************************************************ - * * - * SGML Catalog handling * - * * - ************************************************************************/ - -/** - * xmlCatalogGetSGMLPublic: - * @catal: an SGML catalog hash - * @pubID: the public ID string - * - * Try to lookup the catalog local reference associated to a public ID - * - * Returns the local resource if found or NULL otherwise. - */ -static const xmlChar * -xmlCatalogGetSGMLPublic(xmlHashTablePtr catal, const xmlChar *pubID) { - xmlCatalogEntryPtr entry; - xmlChar *normid; - - if (catal == NULL) - return(NULL); - - normid = xmlCatalogNormalizePublic(pubID); - if (normid != NULL) - pubID = (*normid != 0 ? normid : NULL); - - entry = (xmlCatalogEntryPtr) xmlHashLookup(catal, pubID); - if (entry == NULL) { - if (normid != NULL) - xmlFree(normid); - return(NULL); - } - if (entry->type == SGML_CATA_PUBLIC) { - if (normid != NULL) - xmlFree(normid); - return(entry->URL); - } - if (normid != NULL) - xmlFree(normid); - return(NULL); -} - -/** - * xmlCatalogGetSGMLSystem: - * @catal: an SGML catalog hash - * @sysID: the system ID string - * - * Try to lookup the catalog local reference for a system ID - * - * Returns the local resource if found or NULL otherwise. - */ -static const xmlChar * -xmlCatalogGetSGMLSystem(xmlHashTablePtr catal, const xmlChar *sysID) { - xmlCatalogEntryPtr entry; - - if (catal == NULL) - return(NULL); - - entry = (xmlCatalogEntryPtr) xmlHashLookup(catal, sysID); - if (entry == NULL) - return(NULL); - if (entry->type == SGML_CATA_SYSTEM) - return(entry->URL); - return(NULL); -} - -/** - * xmlCatalogSGMLResolve: - * @catal: the SGML catalog - * @pubID: the public ID string - * @sysID: the system ID string - * - * Do a complete resolution lookup of an External Identifier - * - * Returns the URI of the resource or NULL if not found - */ -static const xmlChar * -xmlCatalogSGMLResolve(xmlCatalogPtr catal, const xmlChar *pubID, - const xmlChar *sysID) { - const xmlChar *ret = NULL; - - if (catal->sgml == NULL) - return(NULL); - - if (pubID != NULL) - ret = xmlCatalogGetSGMLPublic(catal->sgml, pubID); - if (ret != NULL) - return(ret); - if (sysID != NULL) - ret = xmlCatalogGetSGMLSystem(catal->sgml, sysID); - if (ret != NULL) - return(ret); - return(NULL); -} - -/************************************************************************ - * * - * Specific Public interfaces * - * * - ************************************************************************/ - -/** - * xmlLoadSGMLSuperCatalog: - * @filename: a file path - * - * Load an SGML super catalog. It won't expand CATALOG or DELEGATE - * references. This is only needed for manipulating SGML Super Catalogs - * like adding and removing CATALOG or DELEGATE entries. - * - * Returns the catalog parsed or NULL in case of error - */ -xmlCatalogPtr -xmlLoadSGMLSuperCatalog(const char *filename) -{ - xmlChar *content; - xmlCatalogPtr catal; - int ret; - - content = xmlLoadFileContent(filename); - if (content == NULL) - return(NULL); - - catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE, xmlCatalogDefaultPrefer); - if (catal == NULL) { - xmlFree(content); - return(NULL); - } - - ret = xmlParseSGMLCatalog(catal, content, filename, 1); - xmlFree(content); - if (ret < 0) { - xmlFreeCatalog(catal); - return(NULL); - } - return (catal); -} - -/** - * xmlLoadACatalog: - * @filename: a file path - * - * Load the catalog and build the associated data structures. - * This can be either an XML Catalog or an SGML Catalog - * It will recurse in SGML CATALOG entries. On the other hand XML - * Catalogs are not handled recursively. - * - * Returns the catalog parsed or NULL in case of error - */ -xmlCatalogPtr -xmlLoadACatalog(const char *filename) -{ - xmlChar *content; - xmlChar *first; - xmlCatalogPtr catal; - int ret; - - content = xmlLoadFileContent(filename); - if (content == NULL) - return(NULL); - - - first = content; - - while ((*first != 0) && (*first != '-') && (*first != '<') && - (!(((*first >= 'A') && (*first <= 'Z')) || - ((*first >= 'a') && (*first <= 'z'))))) - first++; - - if (*first != '<') { - catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE, xmlCatalogDefaultPrefer); - if (catal == NULL) { - xmlFree(content); - return(NULL); - } - ret = xmlParseSGMLCatalog(catal, content, filename, 0); - if (ret < 0) { - xmlFreeCatalog(catal); - xmlFree(content); - return(NULL); - } - } else { - catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE, xmlCatalogDefaultPrefer); - if (catal == NULL) { - xmlFree(content); - return(NULL); - } - catal->xml = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL, - NULL, BAD_CAST filename, xmlCatalogDefaultPrefer, NULL); - } - xmlFree(content); - return (catal); -} - -/** - * xmlExpandCatalog: - * @catal: a catalog - * @filename: a file path - * - * Load the catalog and expand the existing catal structure. - * This can be either an XML Catalog or an SGML Catalog - * - * Returns 0 in case of success, -1 in case of error - */ -static int -xmlExpandCatalog(xmlCatalogPtr catal, const char *filename) -{ - int ret; - - if ((catal == NULL) || (filename == NULL)) - return(-1); - - - if (catal->type == XML_SGML_CATALOG_TYPE) { - xmlChar *content; - - content = xmlLoadFileContent(filename); - if (content == NULL) - return(-1); - - ret = xmlParseSGMLCatalog(catal, content, filename, 0); - if (ret < 0) { - xmlFree(content); - return(-1); - } - xmlFree(content); - } else { - xmlCatalogEntryPtr tmp, cur; - tmp = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL, - NULL, BAD_CAST filename, xmlCatalogDefaultPrefer, NULL); - - cur = catal->xml; - if (cur == NULL) { - catal->xml = tmp; - } else { - while (cur->next != NULL) cur = cur->next; - cur->next = tmp; - } - } - return (0); -} - -/** - * xmlACatalogResolveSystem: - * @catal: a Catalog - * @sysID: the system ID string - * - * Try to lookup the catalog resource for a system ID - * - * Returns the resource if found or NULL otherwise, the value returned - * must be freed by the caller. - */ -xmlChar * -xmlACatalogResolveSystem(xmlCatalogPtr catal, const xmlChar *sysID) { - xmlChar *ret = NULL; - - if ((sysID == NULL) || (catal == NULL)) - return(NULL); - - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "Resolve sysID %s\n", sysID); - - if (catal->type == XML_XML_CATALOG_TYPE) { - ret = xmlCatalogListXMLResolve(catal->xml, NULL, sysID); - if (ret == XML_CATAL_BREAK) - ret = NULL; - } else { - const xmlChar *sgml; - - sgml = xmlCatalogGetSGMLSystem(catal->sgml, sysID); - if (sgml != NULL) - ret = xmlStrdup(sgml); - } - return(ret); -} - -/** - * xmlACatalogResolvePublic: - * @catal: a Catalog - * @pubID: the public ID string - * - * Try to lookup the catalog local reference associated to a public ID in that catalog - * - * Returns the local resource if found or NULL otherwise, the value returned - * must be freed by the caller. - */ -xmlChar * -xmlACatalogResolvePublic(xmlCatalogPtr catal, const xmlChar *pubID) { - xmlChar *ret = NULL; - - if ((pubID == NULL) || (catal == NULL)) - return(NULL); - - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "Resolve pubID %s\n", pubID); - - if (catal->type == XML_XML_CATALOG_TYPE) { - ret = xmlCatalogListXMLResolve(catal->xml, pubID, NULL); - if (ret == XML_CATAL_BREAK) - ret = NULL; - } else { - const xmlChar *sgml; - - sgml = xmlCatalogGetSGMLPublic(catal->sgml, pubID); - if (sgml != NULL) - ret = xmlStrdup(sgml); - } - return(ret); -} - -/** - * xmlACatalogResolve: - * @catal: a Catalog - * @pubID: the public ID string - * @sysID: the system ID string - * - * Do a complete resolution lookup of an External Identifier - * - * Returns the URI of the resource or NULL if not found, it must be freed - * by the caller. - */ -xmlChar * -xmlACatalogResolve(xmlCatalogPtr catal, const xmlChar * pubID, - const xmlChar * sysID) -{ - xmlChar *ret = NULL; - - if (((pubID == NULL) && (sysID == NULL)) || (catal == NULL)) - return (NULL); - - if (xmlDebugCatalogs) { - if ((pubID != NULL) && (sysID != NULL)) { - xmlGenericError(xmlGenericErrorContext, - "Resolve: pubID %s sysID %s\n", pubID, sysID); - } else if (pubID != NULL) { - xmlGenericError(xmlGenericErrorContext, - "Resolve: pubID %s\n", pubID); - } else { - xmlGenericError(xmlGenericErrorContext, - "Resolve: sysID %s\n", sysID); - } - } - - if (catal->type == XML_XML_CATALOG_TYPE) { - ret = xmlCatalogListXMLResolve(catal->xml, pubID, sysID); - if (ret == XML_CATAL_BREAK) - ret = NULL; - } else { - const xmlChar *sgml; - - sgml = xmlCatalogSGMLResolve(catal, pubID, sysID); - if (sgml != NULL) - ret = xmlStrdup(sgml); - } - return (ret); -} - -/** - * xmlACatalogResolveURI: - * @catal: a Catalog - * @URI: the URI - * - * Do a complete resolution lookup of an URI - * - * Returns the URI of the resource or NULL if not found, it must be freed - * by the caller. - */ -xmlChar * -xmlACatalogResolveURI(xmlCatalogPtr catal, const xmlChar *URI) { - xmlChar *ret = NULL; - - if ((URI == NULL) || (catal == NULL)) - return(NULL); - - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "Resolve URI %s\n", URI); - - if (catal->type == XML_XML_CATALOG_TYPE) { - ret = xmlCatalogListXMLResolveURI(catal->xml, URI); - if (ret == XML_CATAL_BREAK) - ret = NULL; - } else { - const xmlChar *sgml; - - sgml = xmlCatalogSGMLResolve(catal, NULL, URI); - if (sgml != NULL) - ret = xmlStrdup(sgml); - } - return(ret); -} - -#ifdef LIBXML_OUTPUT_ENABLED -/** - * xmlACatalogDump: - * @catal: a Catalog - * @out: the file. - * - * Dump the given catalog to the given file. - */ -void -xmlACatalogDump(xmlCatalogPtr catal, FILE *out) { - if ((out == NULL) || (catal == NULL)) - return; - - if (catal->type == XML_XML_CATALOG_TYPE) { - xmlDumpXMLCatalog(out, catal->xml); - } else { - xmlHashScan(catal->sgml, - (xmlHashScanner) xmlCatalogDumpEntry, out); - } -} -#endif /* LIBXML_OUTPUT_ENABLED */ - -/** - * xmlACatalogAdd: - * @catal: a Catalog - * @type: the type of record to add to the catalog - * @orig: the system, public or prefix to match - * @replace: the replacement value for the match - * - * Add an entry in the catalog, it may overwrite existing but - * different entries. - * - * Returns 0 if successful, -1 otherwise - */ -int -xmlACatalogAdd(xmlCatalogPtr catal, const xmlChar * type, - const xmlChar * orig, const xmlChar * replace) -{ - int res = -1; - - if (catal == NULL) - return(-1); - - if (catal->type == XML_XML_CATALOG_TYPE) { - res = xmlAddXMLCatalog(catal->xml, type, orig, replace); - } else { - xmlCatalogEntryType cattype; - - cattype = xmlGetSGMLCatalogEntryType(type); - if (cattype != XML_CATA_NONE) { - xmlCatalogEntryPtr entry; - - entry = xmlNewCatalogEntry(cattype, orig, replace, NULL, - XML_CATA_PREFER_NONE, NULL); - if (catal->sgml == NULL) - catal->sgml = xmlHashCreate(10); - res = xmlHashAddEntry(catal->sgml, orig, entry); - } - } - return (res); -} - -/** - * xmlACatalogRemove: - * @catal: a Catalog - * @value: the value to remove - * - * Remove an entry from the catalog - * - * Returns the number of entries removed if successful, -1 otherwise - */ -int -xmlACatalogRemove(xmlCatalogPtr catal, const xmlChar *value) { - int res = -1; - - if ((catal == NULL) || (value == NULL)) - return(-1); - - if (catal->type == XML_XML_CATALOG_TYPE) { - res = xmlDelXMLCatalog(catal->xml, value); - } else { - res = xmlHashRemoveEntry(catal->sgml, value, - (xmlHashDeallocator) xmlFreeCatalogEntry); - if (res == 0) - res = 1; - } - 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 * - * * - ************************************************************************/ - -/** - * xmlInitializeCatalogData: - * - * Do the catalog initialization only of global data, doesn't try to load - * any catalog actually. - * this function is not thread safe, catalog initialization should - * preferably be done once at startup - */ -static void -xmlInitializeCatalogData(void) { - if (xmlCatalogInitialized != 0) - return; - - if (getenv("XML_DEBUG_CATALOG")) - xmlDebugCatalogs = 1; - xmlCatalogMutex = xmlNewRMutex(); - - xmlCatalogInitialized = 1; -} -/** - * xmlInitializeCatalog: - * - * Do the catalog initialization. - * this function is not thread safe, catalog initialization should - * preferably be done once at startup - */ -void -xmlInitializeCatalog(void) { - if (xmlCatalogInitialized != 0) - return; - - xmlInitializeCatalogData(); - xmlRMutexLock(xmlCatalogMutex); - - if (getenv("XML_DEBUG_CATALOG")) - xmlDebugCatalogs = 1; - - if (xmlDefaultCatalog == NULL) { - const char *catalogs; - char *path; - const char *cur, *paths; - xmlCatalogPtr catal; - xmlCatalogEntryPtr *nextent; - - catalogs = (const char *) getenv("XML_CATALOG_FILES"); - if (catalogs == NULL) -#if defined(_WIN32) && defined(_MSC_VER) - { - void* hmodule; - hmodule = GetModuleHandleA("libxml2.dll"); - if (hmodule == NULL) - hmodule = GetModuleHandleA(NULL); - if (hmodule != NULL) { - char buf[256]; - unsigned long len = GetModuleFileNameA(hmodule, buf, 255); - if (len != 0) { - char* p = &(buf[len]); - while (*p != '\\' && p > buf) - p--; - if (p != buf) { - xmlChar* uri; - strncpy(p, "\\..\\etc\\catalog", 255 - (p - buf)); - uri = xmlCanonicPath((const xmlChar*)buf); - if (uri != NULL) { - strncpy(XML_XML_DEFAULT_CATALOG, uri, 255); - xmlFree(uri); - } - } - } - } - catalogs = XML_XML_DEFAULT_CATALOG; - } -#else - catalogs = XML_XML_DEFAULT_CATALOG; -#endif - - catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE, - xmlCatalogDefaultPrefer); - if (catal != NULL) { - /* the XML_CATALOG_FILES envvar is allowed to contain a - space-separated list of entries. */ - cur = catalogs; - nextent = &catal->xml; - while (*cur != '\0') { - while (xmlIsBlank_ch(*cur)) - cur++; - if (*cur != 0) { - paths = cur; - while ((*cur != 0) && (!xmlIsBlank_ch(*cur))) - cur++; - path = (char *) xmlStrndup((const xmlChar *)paths, cur - paths); - if (path != NULL) { - *nextent = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL, - NULL, BAD_CAST path, xmlCatalogDefaultPrefer, NULL); - if (*nextent != NULL) - nextent = &((*nextent)->next); - xmlFree(path); - } - } - } - xmlDefaultCatalog = catal; - } - } - - xmlRMutexUnlock(xmlCatalogMutex); -} - - -/** - * xmlLoadCatalog: - * @filename: a file path - * - * Load the catalog and makes its definitions effective for the default - * external entity loader. It will recurse in SGML CATALOG entries. - * this function is not thread safe, catalog initialization should - * preferably be done once at startup - * - * Returns 0 in case of success -1 in case of error - */ -int -xmlLoadCatalog(const char *filename) -{ - int ret; - xmlCatalogPtr catal; - - if (!xmlCatalogInitialized) - xmlInitializeCatalogData(); - - xmlRMutexLock(xmlCatalogMutex); - - if (xmlDefaultCatalog == NULL) { - catal = xmlLoadACatalog(filename); - if (catal == NULL) { - xmlRMutexUnlock(xmlCatalogMutex); - return(-1); - } - - xmlDefaultCatalog = catal; - xmlRMutexUnlock(xmlCatalogMutex); - return(0); - } - - ret = xmlExpandCatalog(xmlDefaultCatalog, filename); - xmlRMutexUnlock(xmlCatalogMutex); - return(ret); -} - -/** - * xmlLoadCatalogs: - * @pathss: a list of directories separated by a colon or a space. - * - * Load the catalogs and makes their definitions effective for the default - * external entity loader. - * this function is not thread safe, catalog initialization should - * preferably be done once at startup - */ -void -xmlLoadCatalogs(const char *pathss) { - const char *cur; - const char *paths; - xmlChar *path; -#ifdef _WIN32 - int i, iLen; -#endif - - if (pathss == NULL) - return; - - cur = pathss; - while (*cur != 0) { - while (xmlIsBlank_ch(*cur)) cur++; - if (*cur != 0) { - paths = cur; - while ((*cur != 0) && (*cur != PATH_SEPARATOR) && (!xmlIsBlank_ch(*cur))) - cur++; - path = xmlStrndup((const xmlChar *)paths, cur - paths); -#ifdef _WIN32 - iLen = strlen((const char*)path); - for(i = 0; i < iLen; i++) { - if(path[i] == '\\') { - path[i] = '/'; - } - } -#endif - if (path != NULL) { - xmlLoadCatalog((const char *) path); - xmlFree(path); - } - } - while (*cur == PATH_SEPARATOR) - cur++; - } -} - -/** - * xmlCatalogCleanup: - * - * Free up all the memory associated with catalogs - */ -void -xmlCatalogCleanup(void) { - if (xmlCatalogInitialized == 0) - return; - - xmlRMutexLock(xmlCatalogMutex); - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "Catalogs cleanup\n"); - if (xmlCatalogXMLFiles != NULL) - xmlHashFree(xmlCatalogXMLFiles, - (xmlHashDeallocator)xmlFreeCatalogHashEntryList); - xmlCatalogXMLFiles = NULL; - if (xmlDefaultCatalog != NULL) - xmlFreeCatalog(xmlDefaultCatalog); - xmlDefaultCatalog = NULL; - xmlDebugCatalogs = 0; - xmlCatalogInitialized = 0; - xmlRMutexUnlock(xmlCatalogMutex); - xmlFreeRMutex(xmlCatalogMutex); -} - -/** - * xmlCatalogResolveSystem: - * @sysID: the system ID string - * - * Try to lookup the catalog resource for a system ID - * - * Returns the resource if found or NULL otherwise, the value returned - * must be freed by the caller. - */ -xmlChar * -xmlCatalogResolveSystem(const xmlChar *sysID) { - xmlChar *ret; - - if (!xmlCatalogInitialized) - xmlInitializeCatalog(); - - ret = xmlACatalogResolveSystem(xmlDefaultCatalog, sysID); - return(ret); -} - -/** - * xmlCatalogResolvePublic: - * @pubID: the public ID string - * - * Try to lookup the catalog reference associated to a public ID - * - * Returns the resource if found or NULL otherwise, the value returned - * must be freed by the caller. - */ -xmlChar * -xmlCatalogResolvePublic(const xmlChar *pubID) { - xmlChar *ret; - - if (!xmlCatalogInitialized) - xmlInitializeCatalog(); - - ret = xmlACatalogResolvePublic(xmlDefaultCatalog, pubID); - return(ret); -} - -/** - * xmlCatalogResolve: - * @pubID: the public ID string - * @sysID: the system ID string - * - * Do a complete resolution lookup of an External Identifier - * - * Returns the URI of the resource or NULL if not found, it must be freed - * by the caller. - */ -xmlChar * -xmlCatalogResolve(const xmlChar *pubID, const xmlChar *sysID) { - xmlChar *ret; - - if (!xmlCatalogInitialized) - xmlInitializeCatalog(); - - ret = xmlACatalogResolve(xmlDefaultCatalog, pubID, sysID); - return(ret); -} - -/** - * xmlCatalogResolveURI: - * @URI: the URI - * - * Do a complete resolution lookup of an URI - * - * Returns the URI of the resource or NULL if not found, it must be freed - * by the caller. - */ -xmlChar * -xmlCatalogResolveURI(const xmlChar *URI) { - xmlChar *ret; - - if (!xmlCatalogInitialized) - xmlInitializeCatalog(); - - ret = xmlACatalogResolveURI(xmlDefaultCatalog, URI); - return(ret); -} - -#ifdef LIBXML_OUTPUT_ENABLED -/** - * xmlCatalogDump: - * @out: the file. - * - * Dump all the global catalog content to the given file. - */ -void -xmlCatalogDump(FILE *out) { - if (out == NULL) - return; - - if (!xmlCatalogInitialized) - xmlInitializeCatalog(); - - xmlACatalogDump(xmlDefaultCatalog, out); -} -#endif /* LIBXML_OUTPUT_ENABLED */ - -/** - * xmlCatalogAdd: - * @type: the type of record to add to the catalog - * @orig: the system, public or prefix to match - * @replace: the replacement value for the match - * - * Add an entry in the catalog, it may overwrite existing but - * different entries. - * If called before any other catalog routine, allows to override the - * default shared catalog put in place by xmlInitializeCatalog(); - * - * Returns 0 if successful, -1 otherwise - */ -int -xmlCatalogAdd(const xmlChar *type, const xmlChar *orig, const xmlChar *replace) { - int res = -1; - - if (!xmlCatalogInitialized) - xmlInitializeCatalogData(); - - xmlRMutexLock(xmlCatalogMutex); - /* - * Specific case where one want to override the default catalog - * put in place by xmlInitializeCatalog(); - */ - if ((xmlDefaultCatalog == NULL) && - (xmlStrEqual(type, BAD_CAST "catalog"))) { - xmlDefaultCatalog = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE, - xmlCatalogDefaultPrefer); - xmlDefaultCatalog->xml = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL, - orig, NULL, xmlCatalogDefaultPrefer, NULL); - - xmlRMutexUnlock(xmlCatalogMutex); - return(0); - } - - res = xmlACatalogAdd(xmlDefaultCatalog, type, orig, replace); - xmlRMutexUnlock(xmlCatalogMutex); - return(res); -} - -/** - * xmlCatalogRemove: - * @value: the value to remove - * - * Remove an entry from the catalog - * - * Returns the number of entries removed if successful, -1 otherwise - */ -int -xmlCatalogRemove(const xmlChar *value) { - int res; - - if (!xmlCatalogInitialized) - xmlInitializeCatalog(); - - xmlRMutexLock(xmlCatalogMutex); - res = xmlACatalogRemove(xmlDefaultCatalog, value); - xmlRMutexUnlock(xmlCatalogMutex); - return(res); -} - -/** - * xmlCatalogConvert: - * - * Convert all the SGML catalog entries as XML ones - * - * Returns the number of entries converted if successful, -1 otherwise - */ -int -xmlCatalogConvert(void) { - int res = -1; - - if (!xmlCatalogInitialized) - xmlInitializeCatalog(); - - xmlRMutexLock(xmlCatalogMutex); - res = xmlConvertSGMLCatalog(xmlDefaultCatalog); - xmlRMutexUnlock(xmlCatalogMutex); - return(res); -} - -/************************************************************************ - * * - * Public interface manipulating the common preferences * - * * - ************************************************************************/ - -/** - * xmlCatalogGetDefaults: - * - * Used to get the user preference w.r.t. to what catalogs should - * be accepted - * - * Returns the current xmlCatalogAllow value - */ -xmlCatalogAllow -xmlCatalogGetDefaults(void) { - return(xmlCatalogDefaultAllow); -} - -/** - * xmlCatalogSetDefaults: - * @allow: what catalogs should be accepted - * - * Used to set the user preference w.r.t. to what catalogs should - * be accepted - */ -void -xmlCatalogSetDefaults(xmlCatalogAllow allow) { - if (xmlDebugCatalogs) { - switch (allow) { - case XML_CATA_ALLOW_NONE: - xmlGenericError(xmlGenericErrorContext, - "Disabling catalog usage\n"); - break; - case XML_CATA_ALLOW_GLOBAL: - xmlGenericError(xmlGenericErrorContext, - "Allowing only global catalogs\n"); - break; - case XML_CATA_ALLOW_DOCUMENT: - xmlGenericError(xmlGenericErrorContext, - "Allowing only catalogs from the document\n"); - break; - case XML_CATA_ALLOW_ALL: - xmlGenericError(xmlGenericErrorContext, - "Allowing all catalogs\n"); - break; - } - } - xmlCatalogDefaultAllow = allow; -} - -/** - * xmlCatalogSetDefaultPrefer: - * @prefer: the default preference for delegation - * - * Allows to set the preference between public and system for deletion - * in XML Catalog resolution. C.f. section 4.1.1 of the spec - * Values accepted are XML_CATA_PREFER_PUBLIC or XML_CATA_PREFER_SYSTEM - * - * Returns the previous value of the default preference for delegation - */ -xmlCatalogPrefer -xmlCatalogSetDefaultPrefer(xmlCatalogPrefer prefer) { - xmlCatalogPrefer ret = xmlCatalogDefaultPrefer; - - if (prefer == XML_CATA_PREFER_NONE) - return(ret); - - if (xmlDebugCatalogs) { - switch (prefer) { - case XML_CATA_PREFER_PUBLIC: - xmlGenericError(xmlGenericErrorContext, - "Setting catalog preference to PUBLIC\n"); - break; - case XML_CATA_PREFER_SYSTEM: - xmlGenericError(xmlGenericErrorContext, - "Setting catalog preference to SYSTEM\n"); - break; - default: - return(ret); - } - } - xmlCatalogDefaultPrefer = prefer; - return(ret); -} - -/** - * xmlCatalogSetDebug: - * @level: the debug level of catalogs required - * - * Used to set the debug level for catalog operation, 0 disable - * debugging, 1 enable it - * - * Returns the previous value of the catalog debugging level - */ -int -xmlCatalogSetDebug(int level) { - int ret = xmlDebugCatalogs; - - if (level <= 0) - xmlDebugCatalogs = 0; - else - xmlDebugCatalogs = level; - return(ret); -} - -/************************************************************************ - * * - * Minimal interfaces used for per-document catalogs by the parser * - * * - ************************************************************************/ - -/** - * xmlCatalogFreeLocal: - * @catalogs: a document's list of catalogs - * - * Free up the memory associated to the catalog list - */ -void -xmlCatalogFreeLocal(void *catalogs) { - xmlCatalogEntryPtr catal; - - if (!xmlCatalogInitialized) - xmlInitializeCatalog(); - - catal = (xmlCatalogEntryPtr) catalogs; - if (catal != NULL) - xmlFreeCatalogEntryList(catal); -} - - -/** - * xmlCatalogAddLocal: - * @catalogs: a document's list of catalogs - * @URL: the URL to a new local catalog - * - * Add the new entry to the catalog list - * - * Returns the updated list - */ -void * -xmlCatalogAddLocal(void *catalogs, const xmlChar *URL) { - xmlCatalogEntryPtr catal, add; - - if (!xmlCatalogInitialized) - xmlInitializeCatalog(); - - if (URL == NULL) - return(catalogs); - - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "Adding document catalog %s\n", URL); - - add = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL, URL, NULL, - xmlCatalogDefaultPrefer, NULL); - if (add == NULL) - return(catalogs); - - catal = (xmlCatalogEntryPtr) catalogs; - if (catal == NULL) - return((void *) add); - - while (catal->next != NULL) - catal = catal->next; - catal->next = add; - return(catalogs); -} - -/** - * xmlCatalogLocalResolve: - * @catalogs: a document's list of catalogs - * @pubID: the public ID string - * @sysID: the system ID string - * - * Do a complete resolution lookup of an External Identifier using a - * document's private catalog list - * - * Returns the URI of the resource or NULL if not found, it must be freed - * by the caller. - */ -xmlChar * -xmlCatalogLocalResolve(void *catalogs, const xmlChar *pubID, - const xmlChar *sysID) { - xmlCatalogEntryPtr catal; - xmlChar *ret; - - if (!xmlCatalogInitialized) - xmlInitializeCatalog(); - - if ((pubID == NULL) && (sysID == NULL)) - return(NULL); - - if (xmlDebugCatalogs) { - if ((pubID != NULL) && (sysID != NULL)) { - xmlGenericError(xmlGenericErrorContext, - "Local Resolve: pubID %s sysID %s\n", pubID, sysID); - } else if (pubID != NULL) { - xmlGenericError(xmlGenericErrorContext, - "Local Resolve: pubID %s\n", pubID); - } else { - xmlGenericError(xmlGenericErrorContext, - "Local Resolve: sysID %s\n", sysID); - } - } - - catal = (xmlCatalogEntryPtr) catalogs; - if (catal == NULL) - return(NULL); - ret = xmlCatalogListXMLResolve(catal, pubID, sysID); - if ((ret != NULL) && (ret != XML_CATAL_BREAK)) - return(ret); - return(NULL); -} - -/** - * xmlCatalogLocalResolveURI: - * @catalogs: a document's list of catalogs - * @URI: the URI - * - * Do a complete resolution lookup of an URI using a - * document's private catalog list - * - * Returns the URI of the resource or NULL if not found, it must be freed - * by the caller. - */ -xmlChar * -xmlCatalogLocalResolveURI(void *catalogs, const xmlChar *URI) { - xmlCatalogEntryPtr catal; - xmlChar *ret; - - if (!xmlCatalogInitialized) - xmlInitializeCatalog(); - - if (URI == NULL) - return(NULL); - - if (xmlDebugCatalogs) - xmlGenericError(xmlGenericErrorContext, - "Resolve URI %s\n", URI); - - catal = (xmlCatalogEntryPtr) catalogs; - if (catal == NULL) - return(NULL); - ret = xmlCatalogListXMLResolveURI(catal, URI); - if ((ret != NULL) && (ret != XML_CATAL_BREAK)) - return(ret); - return(NULL); -} - -/************************************************************************ - * * - * Deprecated interfaces * - * * - ************************************************************************/ -/** - * xmlCatalogGetSystem: - * @sysID: the system ID string - * - * Try to lookup the catalog reference associated to a system ID - * DEPRECATED, use xmlCatalogResolveSystem() - * - * Returns the resource if found or NULL otherwise. - */ -const xmlChar * -xmlCatalogGetSystem(const xmlChar *sysID) { - xmlChar *ret; - static xmlChar result[1000]; - static int msg = 0; - - if (!xmlCatalogInitialized) - xmlInitializeCatalog(); - - if (msg == 0) { - xmlGenericError(xmlGenericErrorContext, - "Use of deprecated xmlCatalogGetSystem() call\n"); - msg++; - } - - if (sysID == NULL) - return(NULL); - - /* - * Check first the XML catalogs - */ - if (xmlDefaultCatalog != NULL) { - ret = xmlCatalogListXMLResolve(xmlDefaultCatalog->xml, NULL, sysID); - if ((ret != NULL) && (ret != XML_CATAL_BREAK)) { - snprintf((char *) result, sizeof(result) - 1, "%s", (char *) ret); - result[sizeof(result) - 1] = 0; - return(result); - } - } - - if (xmlDefaultCatalog != NULL) - return(xmlCatalogGetSGMLSystem(xmlDefaultCatalog->sgml, sysID)); - return(NULL); -} - -/** - * xmlCatalogGetPublic: - * @pubID: the public ID string - * - * Try to lookup the catalog reference associated to a public ID - * DEPRECATED, use xmlCatalogResolvePublic() - * - * Returns the resource if found or NULL otherwise. - */ -const xmlChar * -xmlCatalogGetPublic(const xmlChar *pubID) { - xmlChar *ret; - static xmlChar result[1000]; - static int msg = 0; - - if (!xmlCatalogInitialized) - xmlInitializeCatalog(); - - if (msg == 0) { - xmlGenericError(xmlGenericErrorContext, - "Use of deprecated xmlCatalogGetPublic() call\n"); - msg++; - } - - if (pubID == NULL) - return(NULL); - - /* - * Check first the XML catalogs - */ - if (xmlDefaultCatalog != NULL) { - ret = xmlCatalogListXMLResolve(xmlDefaultCatalog->xml, pubID, NULL); - if ((ret != NULL) && (ret != XML_CATAL_BREAK)) { - snprintf((char *) result, sizeof(result) - 1, "%s", (char *) ret); - result[sizeof(result) - 1] = 0; - return(result); - } - } - - if (xmlDefaultCatalog != NULL) - return(xmlCatalogGetSGMLPublic(xmlDefaultCatalog->sgml, pubID)); - return(NULL); -} - -#define bottom_catalog -#include "elfgcchack.h" -#endif /* LIBXML_CATALOG_ENABLED */ |