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