1a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard/**
2f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * catalog.c: set of generic Catalog related routines
3a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard *
4a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard * Reference:  SGML Open Technical Resolution TR9401:1997.
5a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard *             http://www.jclark.com/sp/catalog.htm
6a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard *
7344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard *             XML Catalogs Working Draft 06 August 2001
8344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard *             http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
9344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard *
10a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard * See Copyright for the status of this software.
11a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard *
12a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard * Daniel.Veillard@imag.fr
13a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard */
14a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
1534ce8bece2f22cc99d25221b77315cd008f4866bDaniel Veillard#define IN_LIBXML
16a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#include "libxml.h"
17a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
18a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#ifdef LIBXML_CATALOG_ENABLED
19a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#ifdef HAVE_SYS_TYPES_H
20a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#include <sys/types.h>
21a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#endif
22a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#ifdef HAVE_SYS_STAT_H
23a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#include <sys/stat.h>
24a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#endif
25a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#ifdef HAVE_UNISTD_H
26a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#include <unistd.h>
27a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#endif
28a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#ifdef HAVE_FCNTL_H
29a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#include <fcntl.h>
30a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#endif
31c0631a608f62902eca453096f0b2fc5b449b0b0aDaniel Veillard#ifdef HAVE_STDLIB_H
32c0631a608f62902eca453096f0b2fc5b449b0b0aDaniel Veillard#include <stdlib.h>
33c0631a608f62902eca453096f0b2fc5b449b0b0aDaniel Veillard#endif
34a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#include <string.h>
35a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#include <libxml/xmlmemory.h>
36a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#include <libxml/hash.h>
37a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#include <libxml/uri.h>
38a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#include <libxml/parserInternals.h>
39a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#include <libxml/catalog.h>
40a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#include <libxml/xmlerror.h>
418146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#include <libxml/threads.h>
423c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard#include <libxml/globals.h>
43a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
442a1d2422a4861efc2fd9f94c19ebfac2d119234aDaniel Veillard#include "buf.h"
452a1d2422a4861efc2fd9f94c19ebfac2d119234aDaniel Veillard
466990bf3c080529493a865a851b753a27d58014eaDaniel Veillard#define MAX_DELEGATE	50
475ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard#define MAX_CATAL_DEPTH	50
486990bf3c080529493a865a851b753a27d58014eaDaniel Veillard
49ed12138b18935276f3815f42a108192cf8b1bf12Daniel Veillard#ifdef _WIN32
509811ce7864a5362492ed0e14a8a6df776d5b8413Jan Pokorný# define PATH_SEPARATOR ';'
51ed12138b18935276f3815f42a108192cf8b1bf12Daniel Veillard#else
529811ce7864a5362492ed0e14a8a6df776d5b8413Jan Pokorný# define PATH_SEPARATOR ':'
53ed12138b18935276f3815f42a108192cf8b1bf12Daniel Veillard#endif
54ed12138b18935276f3815f42a108192cf8b1bf12Daniel Veillard
55344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard/**
56344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * TODO:
57344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard *
58344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * macro to flag unimplemented blocks
593e59fc52d52a7e07a9dbf214893d90c965b53c1cDaniel Veillard * XML_CATALOG_PREFER user env to select between system/public prefered
603e59fc52d52a7e07a9dbf214893d90c965b53c1cDaniel Veillard * option. C.f. Richard Tobin <richard@cogsci.ed.ac.uk>
613e59fc52d52a7e07a9dbf214893d90c965b53c1cDaniel Veillard *> Just FYI, I am using an environment variable XML_CATALOG_PREFER with
623e59fc52d52a7e07a9dbf214893d90c965b53c1cDaniel Veillard *> values "system" and "public".  I have made the default be "system" to
633e59fc52d52a7e07a9dbf214893d90c965b53c1cDaniel Veillard *> match yours.
64344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard */
65f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#define TODO								\
66344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    xmlGenericError(xmlGenericErrorContext,				\
67344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    "Unimplemented block at %s:%d\n",				\
68344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard            __FILE__, __LINE__);
69344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
70cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard#define XML_URN_PUBID "urn:publicid:"
71e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard#define XML_CATAL_BREAK ((xmlChar *) -1)
7275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#ifndef XML_XML_DEFAULT_CATALOG
73f7b094f7ee2a9a7f2f9f05c7390a199c950ec131Daniel Veillard#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
746c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard#endif
7575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#ifndef XML_SGML_DEFAULT_CATALOG
76f7b094f7ee2a9a7f2f9f05c7390a199c950ec131Daniel Veillard#define XML_SGML_DEFAULT_CATALOG "file:///etc/sgml/catalog"
7775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#endif
7875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
79fb382b89905d02caae2e5161a33553b930255915Daniel Veillard#if defined(_WIN32) && defined(_MSC_VER)
80fb382b89905d02caae2e5161a33553b930255915Daniel Veillard#undef XML_XML_DEFAULT_CATALOG
81fb382b89905d02caae2e5161a33553b930255915Daniel Veillardstatic char XML_XML_DEFAULT_CATALOG[256] = "file:///etc/xml/catalog";
8259d3ed8fe0ae9e8f453501d0993f2bc2f3f34ae8Daniel Veillard#if defined(_WIN32_WCE)
8359d3ed8fe0ae9e8f453501d0993f2bc2f3f34ae8Daniel Veillard/* Windows CE don't have a A variant */
8459d3ed8fe0ae9e8f453501d0993f2bc2f3f34ae8Daniel Veillard#define GetModuleHandleA GetModuleHandle
8559d3ed8fe0ae9e8f453501d0993f2bc2f3f34ae8Daniel Veillard#define GetModuleFileNameA GetModuleFileName
8659d3ed8fe0ae9e8f453501d0993f2bc2f3f34ae8Daniel Veillard#else
87e1631e1cfcdf4bd7e7ec4999ec5aae9675390797Denis Pauk#if !defined(_WINDOWS_)
88fb382b89905d02caae2e5161a33553b930255915Daniel Veillardvoid* __stdcall GetModuleHandleA(const char*);
89fb382b89905d02caae2e5161a33553b930255915Daniel Veillardunsigned long __stdcall GetModuleFileNameA(void*, char*, unsigned long);
90fb382b89905d02caae2e5161a33553b930255915Daniel Veillard#endif
9159d3ed8fe0ae9e8f453501d0993f2bc2f3f34ae8Daniel Veillard#endif
92e1631e1cfcdf4bd7e7ec4999ec5aae9675390797Denis Pauk#endif
93fb382b89905d02caae2e5161a33553b930255915Daniel Veillard
94c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillardstatic xmlChar *xmlCatalogNormalizePublic(const xmlChar *pubID);
9585c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillardstatic int xmlExpandCatalog(xmlCatalogPtr catal, const char *filename);
96344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
97a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard/************************************************************************
98a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard *									*
99a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard *			Types, all private				*
100a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard *									*
101a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard ************************************************************************/
102a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
103a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillardtypedef enum {
104c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard    XML_CATA_REMOVED = -1,
105a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    XML_CATA_NONE = 0,
106a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    XML_CATA_CATALOG,
1079f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    XML_CATA_BROKEN_CATALOG,
108344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    XML_CATA_NEXT_CATALOG,
109b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack    XML_CATA_GROUP,
110344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    XML_CATA_PUBLIC,
111344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    XML_CATA_SYSTEM,
112344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    XML_CATA_REWRITE_SYSTEM,
113344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    XML_CATA_DELEGATE_PUBLIC,
114344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    XML_CATA_DELEGATE_SYSTEM,
115344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    XML_CATA_URI,
116344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    XML_CATA_REWRITE_URI,
117344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    XML_CATA_DELEGATE_URI,
118344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    SGML_CATA_SYSTEM,
119344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    SGML_CATA_PUBLIC,
120344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    SGML_CATA_ENTITY,
121344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    SGML_CATA_PENTITY,
122344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    SGML_CATA_DOCTYPE,
123344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    SGML_CATA_LINKTYPE,
124344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    SGML_CATA_NOTATION,
125344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    SGML_CATA_DELEGATE,
126344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    SGML_CATA_BASE,
127344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    SGML_CATA_CATALOG,
128344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    SGML_CATA_DOCUMENT,
129344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    SGML_CATA_SGMLDECL
130a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard} xmlCatalogEntryType;
131a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
132a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillardtypedef struct _xmlCatalogEntry xmlCatalogEntry;
133a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillardtypedef xmlCatalogEntry *xmlCatalogEntryPtr;
134a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillardstruct _xmlCatalogEntry {
135344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    struct _xmlCatalogEntry *next;
136344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    struct _xmlCatalogEntry *parent;
137344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    struct _xmlCatalogEntry *children;
138a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    xmlCatalogEntryType type;
139a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    xmlChar *name;
140a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    xmlChar *value;
141c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard    xmlChar *URL;  /* The expanded URL using the base */
142e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    xmlCatalogPrefer prefer;
1436990bf3c080529493a865a851b753a27d58014eaDaniel Veillard    int dealloc;
1445ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard    int depth;
145b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack    struct _xmlCatalogEntry *group;
146a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard};
147a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
14875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillardtypedef enum {
14975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    XML_XML_CATALOG_TYPE = 1,
15075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    XML_SGML_CATALOG_TYPE
15175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard} xmlCatalogType;
15275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
15375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#define XML_MAX_SGML_CATA_DEPTH 10
15475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillardstruct _xmlCatalog {
15575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlCatalogType type;	/* either XML or SGML */
15675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
15775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    /*
15875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard     * SGML Catalogs are stored as a simple hash table of catalog entries
15975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard     * Catalog stack to check against overflows when building the
16075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard     * SGML catalog
16175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard     */
16275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    char *catalTab[XML_MAX_SGML_CATA_DEPTH];	/* stack of catals */
16375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    int          catalNr;	/* Number of current catal streams */
16475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    int          catalMax;	/* Max number of catal streams */
16575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlHashTablePtr sgml;
16675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
16775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    /*
16875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard     * XML Catalogs are stored as a tree of Catalog entries
16975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard     */
17075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlCatalogPrefer prefer;
17175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlCatalogEntryPtr xml;
17275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard};
17375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
17475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/************************************************************************
17575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
17675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *			Global variables				*
17775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
17875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard ************************************************************************/
17975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
1808146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard/*
1818146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * Those are preferences
1828146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard */
1838146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillardstatic int xmlDebugCatalogs = 0;   /* used for debugging */
1845d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillardstatic xmlCatalogAllow xmlCatalogDefaultAllow = XML_CATA_ALLOW_ALL;
1856990bf3c080529493a865a851b753a27d58014eaDaniel Veillardstatic xmlCatalogPrefer xmlCatalogDefaultPrefer = XML_CATA_PREFER_PUBLIC;
18675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
18775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/*
18875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Hash table containing all the trees of XML catalogs parsed by
18975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * the application.
19075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
1916990bf3c080529493a865a851b753a27d58014eaDaniel Veillardstatic xmlHashTablePtr xmlCatalogXMLFiles = NULL;
192e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
19375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/*
19475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * The default catalog in use by the application
19575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
19675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillardstatic xmlCatalogPtr xmlDefaultCatalog = NULL;
19775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
19875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/*
1998146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * A mutex for modifying the shared global catalog(s)
2008146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * xmlDefaultCatalog tree.
2018146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * It also protects xmlCatalogXMLFiles
2028146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * The core of this readers/writer scheme is in xmlFetchXMLCatalogFile()
2038146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard */
2048146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillardstatic xmlRMutexPtr xmlCatalogMutex = NULL;
2058146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard
2068146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard/*
20775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Whether the catalog support was initialized.
20875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
20975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillardstatic int xmlCatalogInitialized = 0;
210a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
21169d2c171fa5105364168d663467f6834c8216155Daniel Veillard/************************************************************************
21269d2c171fa5105364168d663467f6834c8216155Daniel Veillard *									*
213f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *			Catalog error handlers				*
21469d2c171fa5105364168d663467f6834c8216155Daniel Veillard *									*
21569d2c171fa5105364168d663467f6834c8216155Daniel Veillard ************************************************************************/
21669d2c171fa5105364168d663467f6834c8216155Daniel Veillard
21769d2c171fa5105364168d663467f6834c8216155Daniel Veillard/**
21869d2c171fa5105364168d663467f6834c8216155Daniel Veillard * xmlCatalogErrMemory:
21969d2c171fa5105364168d663467f6834c8216155Daniel Veillard * @extra:  extra informations
22069d2c171fa5105364168d663467f6834c8216155Daniel Veillard *
22169d2c171fa5105364168d663467f6834c8216155Daniel Veillard * Handle an out of memory condition
22269d2c171fa5105364168d663467f6834c8216155Daniel Veillard */
22369d2c171fa5105364168d663467f6834c8216155Daniel Veillardstatic void
22469d2c171fa5105364168d663467f6834c8216155Daniel VeillardxmlCatalogErrMemory(const char *extra)
22569d2c171fa5105364168d663467f6834c8216155Daniel Veillard{
226659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_CATALOG,
22769d2c171fa5105364168d663467f6834c8216155Daniel Veillard                    XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0,
22869d2c171fa5105364168d663467f6834c8216155Daniel Veillard		    extra, NULL, NULL, 0, 0,
22969d2c171fa5105364168d663467f6834c8216155Daniel Veillard		    "Memory allocation failed : %s\n", extra);
23069d2c171fa5105364168d663467f6834c8216155Daniel Veillard}
23169d2c171fa5105364168d663467f6834c8216155Daniel Veillard
23269d2c171fa5105364168d663467f6834c8216155Daniel Veillard/**
23369d2c171fa5105364168d663467f6834c8216155Daniel Veillard * xmlCatalogErr:
23469d2c171fa5105364168d663467f6834c8216155Daniel Veillard * @catal: the Catalog entry
23569d2c171fa5105364168d663467f6834c8216155Daniel Veillard * @node: the context node
23669d2c171fa5105364168d663467f6834c8216155Daniel Veillard * @msg:  the error message
23769d2c171fa5105364168d663467f6834c8216155Daniel Veillard * @extra:  extra informations
23869d2c171fa5105364168d663467f6834c8216155Daniel Veillard *
23969d2c171fa5105364168d663467f6834c8216155Daniel Veillard * Handle a catalog error
24069d2c171fa5105364168d663467f6834c8216155Daniel Veillard */
2414472c3a5a5b516aaf59b89be602fbce52756c3e9David Kilzerstatic void LIBXML_ATTR_FORMAT(4,0)
24269d2c171fa5105364168d663467f6834c8216155Daniel VeillardxmlCatalogErr(xmlCatalogEntryPtr catal, xmlNodePtr node, int error,
24369d2c171fa5105364168d663467f6834c8216155Daniel Veillard               const char *msg, const xmlChar *str1, const xmlChar *str2,
24469d2c171fa5105364168d663467f6834c8216155Daniel Veillard	       const xmlChar *str3)
24569d2c171fa5105364168d663467f6834c8216155Daniel Veillard{
246659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard    __xmlRaiseError(NULL, NULL, NULL, catal, node, XML_FROM_CATALOG,
24769d2c171fa5105364168d663467f6834c8216155Daniel Veillard                    error, XML_ERR_ERROR, NULL, 0,
24869d2c171fa5105364168d663467f6834c8216155Daniel Veillard		    (const char *) str1, (const char *) str2,
24969d2c171fa5105364168d663467f6834c8216155Daniel Veillard		    (const char *) str3, 0, 0,
25069d2c171fa5105364168d663467f6834c8216155Daniel Veillard		    msg, str1, str2, str3);
25169d2c171fa5105364168d663467f6834c8216155Daniel Veillard}
25269d2c171fa5105364168d663467f6834c8216155Daniel Veillard
253af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard
254a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard/************************************************************************
255a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard *									*
25675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *			Allocation and Freeing				*
257a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard *									*
258a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard ************************************************************************/
259a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
26075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
26175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlNewCatalogEntry:
26275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @type:  type of entry
26375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @name:  name of the entry
26475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @value:  value of the entry
26575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @prefer:  the PUBLIC vs. SYSTEM current preference value
266f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @group:  for members of a group, the group entry
26775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
268f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * create a new Catalog entry, this type is shared both by XML and
26975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * SGML catalogs, but the acceptable types values differs.
27075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
27175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Returns the xmlCatalogEntryPtr or NULL in case of error
27275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
273a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillardstatic xmlCatalogEntryPtr
274344cee76a675e83ff159ffc02b009f304569cedaDaniel VeillardxmlNewCatalogEntry(xmlCatalogEntryType type, const xmlChar *name,
275b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	   const xmlChar *value, const xmlChar *URL, xmlCatalogPrefer prefer,
276b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	   xmlCatalogEntryPtr group) {
277a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    xmlCatalogEntryPtr ret;
278c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    xmlChar *normid = NULL;
279a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
280a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    ret = (xmlCatalogEntryPtr) xmlMalloc(sizeof(xmlCatalogEntry));
281a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    if (ret == NULL) {
28269d2c171fa5105364168d663467f6834c8216155Daniel Veillard        xmlCatalogErrMemory("allocating catalog entry");
283a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	return(NULL);
284a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    }
285344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    ret->next = NULL;
286344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    ret->parent = NULL;
287344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    ret->children = NULL;
288a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    ret->type = type;
289c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    if (type == XML_CATA_PUBLIC || type == XML_CATA_DELEGATE_PUBLIC) {
290c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard        normid = xmlCatalogNormalizePublic(name);
291c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard        if (normid != NULL)
292c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard            name = (*normid != 0 ? normid : NULL);
293c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    }
294344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if (name != NULL)
295344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	ret->name = xmlStrdup(name);
296344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else
297344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	ret->name = NULL;
298c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    if (normid != NULL)
299c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard        xmlFree(normid);
300344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if (value != NULL)
301344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	ret->value = xmlStrdup(value);
302344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else
303344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	ret->value = NULL;
304c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard    if (URL == NULL)
305c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard	URL = value;
306c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard    if (URL != NULL)
307c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard	ret->URL = xmlStrdup(URL);
308c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard    else
309c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard	ret->URL = NULL;
310e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    ret->prefer = prefer;
31185c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard    ret->dealloc = 0;
3125ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard    ret->depth = 0;
313b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack    ret->group = group;
314a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    return(ret);
315a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard}
316a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
317a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillardstatic void
318344cee76a675e83ff159ffc02b009f304569cedaDaniel VeillardxmlFreeCatalogEntryList(xmlCatalogEntryPtr ret);
319344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
32075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
32175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlFreeCatalogEntry:
32275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @ret:  a Catalog entry
32375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
32475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Free the memory allocated to a Catalog entry
32575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
326344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillardstatic void
327a737459bc41f3f4558d814889f0981e2aee4b97fDaniel VeillardxmlFreeCatalogEntry(xmlCatalogEntryPtr ret) {
328a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    if (ret == NULL)
329a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	return;
33085c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard    /*
331cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard     * Entries stored in the file hash must be deallocated
33285c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard     * only by the file hash cleaner !
33385c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard     */
33485c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard    if (ret->dealloc == 1)
33585c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	return;
33685c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard
33785c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard    if (xmlDebugCatalogs) {
33885c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	if (ret->name != NULL)
33985c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	    xmlGenericError(xmlGenericErrorContext,
34085c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard		    "Free catalog entry %s\n", ret->name);
34185c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	else if (ret->value != NULL)
34285c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	    xmlGenericError(xmlGenericErrorContext,
34385c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard		    "Free catalog entry %s\n", ret->value);
34485c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	else
34585c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	    xmlGenericError(xmlGenericErrorContext,
34685c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard		    "Free catalog entry\n");
34785c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard    }
34885c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard
349a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    if (ret->name != NULL)
350a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	xmlFree(ret->name);
351a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    if (ret->value != NULL)
352a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	xmlFree(ret->value);
353c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard    if (ret->URL != NULL)
354c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard	xmlFree(ret->URL);
355a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    xmlFree(ret);
356a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard}
357a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
35875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
35975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlFreeCatalogEntryList:
36075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @ret:  a Catalog entry list
36175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
36275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Free the memory allocated to a full chained list of Catalog entries
36375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
364344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillardstatic void
365344cee76a675e83ff159ffc02b009f304569cedaDaniel VeillardxmlFreeCatalogEntryList(xmlCatalogEntryPtr ret) {
366344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    xmlCatalogEntryPtr next;
367344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
368344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    while (ret != NULL) {
369344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	next = ret->next;
370344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	xmlFreeCatalogEntry(ret);
371344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	ret = next;
372344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    }
373344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard}
374344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
3757d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard/**
37685c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard * xmlFreeCatalogHashEntryList:
37785c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard * @ret:  a Catalog entry list
37885c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard *
37985c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard * Free the memory allocated to list of Catalog entries from the
38085c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard * catalog file hash.
38185c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard */
38285c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillardstatic void
38385c11fa20605e0b4fafc680627bd4b66933ac67eDaniel VeillardxmlFreeCatalogHashEntryList(xmlCatalogEntryPtr catal) {
38485c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard    xmlCatalogEntryPtr children, next;
38585c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard
38685c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard    if (catal == NULL)
38785c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	return;
38885c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard
38985c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard    children = catal->children;
39085c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard    while (children != NULL) {
39185c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	next = children->next;
39285c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	children->dealloc = 0;
39385c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	children->children = NULL;
39485c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	xmlFreeCatalogEntry(children);
39585c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	children = next;
39685c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard    }
39785c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard    catal->dealloc = 0;
39885c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard    xmlFreeCatalogEntry(catal);
39985c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard}
40085c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard
40185c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard/**
402cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard * xmlCreateNewCatalog:
40375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @type:  type of catalog
40475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @prefer:  the PUBLIC vs. SYSTEM current preference value
40575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
406f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * create a new Catalog, this type is shared both by XML and
40775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * SGML catalogs, but the acceptable types values differs.
40875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
40975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Returns the xmlCatalogPtr or NULL in case of error
41075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
41175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillardstatic xmlCatalogPtr
412cd21dc784800832cf952061034e52ce9733a4b11Daniel VeillardxmlCreateNewCatalog(xmlCatalogType type, xmlCatalogPrefer prefer) {
41375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlCatalogPtr ret;
41475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
41575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    ret = (xmlCatalogPtr) xmlMalloc(sizeof(xmlCatalog));
41675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (ret == NULL) {
41769d2c171fa5105364168d663467f6834c8216155Daniel Veillard        xmlCatalogErrMemory("allocating catalog");
41875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	return(NULL);
41975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    }
42075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    memset(ret, 0, sizeof(xmlCatalog));
42175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    ret->type = type;
42275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    ret->catalNr = 0;
42375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    ret->catalMax = XML_MAX_SGML_CATA_DEPTH;
42475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    ret->prefer = prefer;
425cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard    if (ret->type == XML_SGML_CATALOG_TYPE)
426cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	ret->sgml = xmlHashCreate(10);
42775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    return(ret);
42875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard}
42975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
43075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
43175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlFreeCatalog:
43206d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * @catal:  a Catalog
43375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
43475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Free the memory allocated to a Catalog
43575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
43675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillardvoid
43775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlFreeCatalog(xmlCatalogPtr catal) {
43875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (catal == NULL)
43975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	return;
44075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (catal->xml != NULL)
44175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlFreeCatalogEntryList(catal->xml);
44275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (catal->sgml != NULL)
44375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlHashFree(catal->sgml,
44475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard		(xmlHashDeallocator) xmlFreeCatalogEntry);
44575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlFree(catal);
44675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard}
44775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
44875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/************************************************************************
44975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
45075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *			Serializing Catalogs				*
45175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
45275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard ************************************************************************/
45375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
454a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#ifdef LIBXML_OUTPUT_ENABLED
45575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
4567d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard * xmlCatalogDumpEntry:
45706d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * @entry:  the catalog entry
4587d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard * @out:  the file.
4597d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard *
46075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Serialize an SGML Catalog entry
4617d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard */
4627d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillardstatic void
4637d6fd219f249e9ce921edd20f34d64944915abffDaniel VeillardxmlCatalogDumpEntry(xmlCatalogEntryPtr entry, FILE *out) {
4647d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard    if ((entry == NULL) || (out == NULL))
4657d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	return;
4667d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard    switch (entry->type) {
467344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_ENTITY:
4687d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	    fprintf(out, "ENTITY "); break;
469344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_PENTITY:
4707d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	    fprintf(out, "ENTITY %%"); break;
471344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_DOCTYPE:
4727d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	    fprintf(out, "DOCTYPE "); break;
473344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_LINKTYPE:
4747d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	    fprintf(out, "LINKTYPE "); break;
475344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_NOTATION:
4767d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	    fprintf(out, "NOTATION "); break;
477344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_PUBLIC:
4787d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	    fprintf(out, "PUBLIC "); break;
479344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_SYSTEM:
4807d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	    fprintf(out, "SYSTEM "); break;
481344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_DELEGATE:
4827d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	    fprintf(out, "DELEGATE "); break;
483344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_BASE:
4847d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	    fprintf(out, "BASE "); break;
485344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_CATALOG:
4867d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	    fprintf(out, "CATALOG "); break;
487344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_DOCUMENT:
4887d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	    fprintf(out, "DOCUMENT "); break;
489344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_SGMLDECL:
4907d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	    fprintf(out, "SGMLDECL "); break;
4917d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	default:
4927d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	    return;
4937d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard    }
4947d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard    switch (entry->type) {
495344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_ENTITY:
496344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_PENTITY:
497344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_DOCTYPE:
498344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_LINKTYPE:
499344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_NOTATION:
500580ced8ee28ecd99374da9383897678e4ba6c358Daniel Veillard	    fprintf(out, "%s", (const char *) entry->name); break;
501344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_PUBLIC:
502344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_SYSTEM:
503344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_SGMLDECL:
504344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_DOCUMENT:
505344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_CATALOG:
506344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_BASE:
507344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_DELEGATE:
5087d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	    fprintf(out, "\"%s\"", entry->name); break;
5097d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	default:
5107d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	    break;
5117d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard    }
5127d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard    switch (entry->type) {
513344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_ENTITY:
514344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_PENTITY:
515344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_DOCTYPE:
516344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_LINKTYPE:
517344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_NOTATION:
518344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_PUBLIC:
519344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_SYSTEM:
520344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	case SGML_CATA_DELEGATE:
5217d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	    fprintf(out, " \"%s\"", entry->value); break;
5227d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	default:
5237d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard	    break;
5247d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard    }
5257d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard    fprintf(out, "\n");
5267d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard}
5277d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard
528b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack/**
529b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack * xmlDumpXMLCatalogNode:
530b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack * @catal:  top catalog entry
531b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack * @catalog: pointer to the xml tree
532b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack * @doc: the containing document
533b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack * @ns: the current namespace
534b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack * @cgroup: group node for group members
535b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack *
536b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack * Serializes a Catalog entry, called by xmlDumpXMLCatalog and recursively
537b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack * for group entries
538b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack */
539b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brackstatic void xmlDumpXMLCatalogNode(xmlCatalogEntryPtr catal, xmlNodePtr catalog,
540b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlDocPtr doc, xmlNsPtr ns, xmlCatalogEntryPtr cgroup) {
541b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack    xmlNodePtr node;
542b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack    xmlCatalogEntryPtr cur;
543b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack    /*
544b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack     * add all the catalog entries
545b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack     */
546b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack    cur = catal;
547b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack    while (cur != NULL) {
548b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack        if (cur->group == cgroup) {
549b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	    switch (cur->type) {
550b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	        case XML_CATA_REMOVED:
551b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    break;
552b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	        case XML_CATA_BROKEN_CATALOG:
553b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	        case XML_CATA_CATALOG:
554b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    if (cur == catal) {
555b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack			cur = cur->children;
556b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		        continue;
557b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    }
558b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    break;
559b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case XML_CATA_NEXT_CATALOG:
560b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    node = xmlNewDocNode(doc, ns, BAD_CAST "nextCatalog", NULL);
561b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlSetProp(node, BAD_CAST "catalog", cur->value);
562b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlAddChild(catalog, node);
563b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack                    break;
564b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case XML_CATA_NONE:
565b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    break;
566b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case XML_CATA_GROUP:
567b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    node = xmlNewDocNode(doc, ns, BAD_CAST "group", NULL);
568b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlSetProp(node, BAD_CAST "id", cur->name);
5696218b31b7fa3da1017c9f6e9f09a6baf11ff2718William M. Brack		    if (cur->value != NULL) {
5706218b31b7fa3da1017c9f6e9f09a6baf11ff2718William M. Brack		        xmlNsPtr xns;
5716218b31b7fa3da1017c9f6e9f09a6baf11ff2718William M. Brack			xns = xmlSearchNsByHref(doc, node, XML_XML_NAMESPACE);
5726218b31b7fa3da1017c9f6e9f09a6baf11ff2718William M. Brack			if (xns != NULL)
5736218b31b7fa3da1017c9f6e9f09a6baf11ff2718William M. Brack			    xmlSetNsProp(node, xns, BAD_CAST "base",
574f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard					 cur->value);
5756218b31b7fa3da1017c9f6e9f09a6baf11ff2718William M. Brack		    }
576b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    switch (cur->prefer) {
577b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack			case XML_CATA_PREFER_NONE:
578b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		            break;
579b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack			case XML_CATA_PREFER_PUBLIC:
580b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		            xmlSetProp(node, BAD_CAST "prefer", BAD_CAST "public");
581b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack			    break;
582b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack			case XML_CATA_PREFER_SYSTEM:
583b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		            xmlSetProp(node, BAD_CAST "prefer", BAD_CAST "system");
584b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack			    break;
585b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    }
586b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlDumpXMLCatalogNode(cur->next, node, doc, ns, cur);
587b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlAddChild(catalog, node);
588b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	            break;
589b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case XML_CATA_PUBLIC:
590b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    node = xmlNewDocNode(doc, ns, BAD_CAST "public", NULL);
591b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlSetProp(node, BAD_CAST "publicId", cur->name);
592b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlSetProp(node, BAD_CAST "uri", cur->value);
593b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlAddChild(catalog, node);
594b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    break;
595b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case XML_CATA_SYSTEM:
596b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    node = xmlNewDocNode(doc, ns, BAD_CAST "system", NULL);
597b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlSetProp(node, BAD_CAST "systemId", cur->name);
598b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlSetProp(node, BAD_CAST "uri", cur->value);
599b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlAddChild(catalog, node);
600b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    break;
601b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case XML_CATA_REWRITE_SYSTEM:
602b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    node = xmlNewDocNode(doc, ns, BAD_CAST "rewriteSystem", NULL);
603b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlSetProp(node, BAD_CAST "systemIdStartString", cur->name);
604b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlSetProp(node, BAD_CAST "rewritePrefix", cur->value);
605b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlAddChild(catalog, node);
606b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    break;
607b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case XML_CATA_DELEGATE_PUBLIC:
608b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    node = xmlNewDocNode(doc, ns, BAD_CAST "delegatePublic", NULL);
609b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlSetProp(node, BAD_CAST "publicIdStartString", cur->name);
610b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlSetProp(node, BAD_CAST "catalog", cur->value);
611b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlAddChild(catalog, node);
612b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    break;
613b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case XML_CATA_DELEGATE_SYSTEM:
614b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    node = xmlNewDocNode(doc, ns, BAD_CAST "delegateSystem", NULL);
615b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlSetProp(node, BAD_CAST "systemIdStartString", cur->name);
616b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlSetProp(node, BAD_CAST "catalog", cur->value);
617b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlAddChild(catalog, node);
618b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    break;
619b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case XML_CATA_URI:
620b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    node = xmlNewDocNode(doc, ns, BAD_CAST "uri", NULL);
621b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlSetProp(node, BAD_CAST "name", cur->name);
622b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlSetProp(node, BAD_CAST "uri", cur->value);
623b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlAddChild(catalog, node);
624b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    break;
625b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case XML_CATA_REWRITE_URI:
626b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    node = xmlNewDocNode(doc, ns, BAD_CAST "rewriteURI", NULL);
627b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlSetProp(node, BAD_CAST "uriStartString", cur->name);
628b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlSetProp(node, BAD_CAST "rewritePrefix", cur->value);
629b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlAddChild(catalog, node);
630b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    break;
631b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case XML_CATA_DELEGATE_URI:
632b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    node = xmlNewDocNode(doc, ns, BAD_CAST "delegateURI", NULL);
633b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlSetProp(node, BAD_CAST "uriStartString", cur->name);
634b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlSetProp(node, BAD_CAST "catalog", cur->value);
635b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    xmlAddChild(catalog, node);
636b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    break;
637b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case SGML_CATA_SYSTEM:
638b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case SGML_CATA_PUBLIC:
639b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case SGML_CATA_ENTITY:
640b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case SGML_CATA_PENTITY:
641b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case SGML_CATA_DOCTYPE:
642b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case SGML_CATA_LINKTYPE:
643b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case SGML_CATA_NOTATION:
644b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case SGML_CATA_DELEGATE:
645b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case SGML_CATA_BASE:
646b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case SGML_CATA_CATALOG:
647b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case SGML_CATA_DOCUMENT:
648b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		case SGML_CATA_SGMLDECL:
649b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		    break;
650b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	    }
651b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack        }
652b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	cur = cur->next;
653b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack    }
654b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack}
655b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack
65675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillardstatic int
65775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlDumpXMLCatalog(FILE *out, xmlCatalogEntryPtr catal) {
65875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    int ret;
65975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlDocPtr doc;
66075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlNsPtr ns;
66175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlDtdPtr dtd;
662b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack    xmlNodePtr catalog;
66375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlOutputBufferPtr buf;
66475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
66575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    /*
66675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard     * Rebuild a catalog
66775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard     */
66875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    doc = xmlNewDoc(NULL);
66975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (doc == NULL)
67075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	return(-1);
67175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    dtd = xmlNewDtd(doc, BAD_CAST "catalog",
67275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	       BAD_CAST "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN",
67375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardBAD_CAST "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd");
67475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
67575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlAddChild((xmlNodePtr) doc, (xmlNodePtr) dtd);
67675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
67775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    ns = xmlNewNs(NULL, XML_CATALOGS_NAMESPACE, NULL);
67875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (ns == NULL) {
67975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlFreeDoc(doc);
68075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	return(-1);
68175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    }
68275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    catalog = xmlNewDocNode(doc, ns, BAD_CAST "catalog", NULL);
68375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (catalog == NULL) {
68475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlFreeNs(ns);
68575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlFreeDoc(doc);
68675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	return(-1);
68775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    }
68875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    catalog->nsDef = ns;
68975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlAddChild((xmlNodePtr) doc, catalog);
69075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
691b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack    xmlDumpXMLCatalogNode(catal, catalog, doc, ns, NULL);
692f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
69375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    /*
69475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard     * reserialize it
69575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard     */
69675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    buf = xmlOutputBufferCreateFile(out, NULL);
69775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (buf == NULL) {
69875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlFreeDoc(doc);
69975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	return(-1);
70075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    }
70175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    ret = xmlSaveFormatFileTo(buf, doc, NULL, 1);
70275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
70375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    /*
70475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard     * Free it
70575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard     */
70675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlFreeDoc(doc);
70775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
70875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    return(ret);
70975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard}
710a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#endif /* LIBXML_OUTPUT_ENABLED */
71175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
71275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/************************************************************************
71375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
71475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *			Converting SGML Catalogs to XML			*
71575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
71675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard ************************************************************************/
71775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
7186c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard/**
7196c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard * xmlCatalogConvertEntry:
7206c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard * @entry:  the entry
72175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @catal:  pointer to the catalog being converted
7226c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard *
72375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Convert one entry from the catalog
7246c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard */
7256c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillardstatic void
72675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlCatalogConvertEntry(xmlCatalogEntryPtr entry, xmlCatalogPtr catal) {
72775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if ((entry == NULL) || (catal == NULL) || (catal->sgml == NULL) ||
72875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	(catal->xml == NULL))
7296c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	return;
7306c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard    switch (entry->type) {
7316c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	case SGML_CATA_ENTITY:
7326c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    entry->type = XML_CATA_PUBLIC;
7336c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    break;
7346c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	case SGML_CATA_PENTITY:
7356c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    entry->type = XML_CATA_PUBLIC;
7366c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    break;
7376c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	case SGML_CATA_DOCTYPE:
7386c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    entry->type = XML_CATA_PUBLIC;
7396c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    break;
7406c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	case SGML_CATA_LINKTYPE:
7416c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    entry->type = XML_CATA_PUBLIC;
7426c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    break;
7436c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	case SGML_CATA_NOTATION:
7446c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    entry->type = XML_CATA_PUBLIC;
7456c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    break;
7466c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	case SGML_CATA_PUBLIC:
7476c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    entry->type = XML_CATA_PUBLIC;
7486c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    break;
7496c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	case SGML_CATA_SYSTEM:
7506c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    entry->type = XML_CATA_SYSTEM;
7516c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    break;
7526c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	case SGML_CATA_DELEGATE:
7536c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    entry->type = XML_CATA_DELEGATE_PUBLIC;
7546c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    break;
7556c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	case SGML_CATA_CATALOG:
7566c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    entry->type = XML_CATA_CATALOG;
7576c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    break;
7586c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	default:
75975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    xmlHashRemoveEntry(catal->sgml, entry->name,
7606c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard		               (xmlHashDeallocator) xmlFreeCatalogEntry);
7616c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    return;
7626c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard    }
7636c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard    /*
7646c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard     * Conversion successful, remove from the SGML catalog
7656c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard     * and add it to the default XML one
7666c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard     */
76775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlHashRemoveEntry(catal->sgml, entry->name, NULL);
76875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    entry->parent = catal->xml;
7696c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard    entry->next = NULL;
77075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (catal->xml->children == NULL)
77175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	catal->xml->children = entry;
7726c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard    else {
7736c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	xmlCatalogEntryPtr prev;
7746c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard
77575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	prev = catal->xml->children;
7766c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	while (prev->next != NULL)
7776c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	    prev = prev->next;
7786c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	prev->next = entry;
7796c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard    }
78075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard}
78175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
78275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
78375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlConvertSGMLCatalog:
78475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @catal: the catalog
78575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
78675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Convert all the SGML catalog entries as XML ones
78775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
78875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Returns the number of entries converted if successful, -1 otherwise
78975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
79075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillardint
79175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlConvertSGMLCatalog(xmlCatalogPtr catal) {
79275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
79375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if ((catal == NULL) || (catal->type != XML_SGML_CATALOG_TYPE))
79475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	return(-1);
79575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
79675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (xmlDebugCatalogs) {
79775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlGenericError(xmlGenericErrorContext,
79875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard		"Converting SGML catalog to XML\n");
79975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    }
80075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlHashScan(catal->sgml,
80175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard		(xmlHashScanner) xmlCatalogConvertEntry,
80275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard		&catal);
80375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    return(0);
8046c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard}
8056c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard
806a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard/************************************************************************
807a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard *									*
808e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard *			Helper function					*
809e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard *									*
810e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard ************************************************************************/
811e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
812e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard/**
813e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard * xmlCatalogUnWrapURN:
814cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @urn:  an "urn:publicid:" to unwrap
815e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard *
816e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard * Expand the URN into the equivalent Public Identifier
817e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard *
818e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard * Returns the new identifier or NULL, the string must be deallocated
819e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard *         by the caller.
820e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard */
821e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillardstatic xmlChar *
822e2940ddb351e0aa2055ec6b74c245685196d532bDaniel VeillardxmlCatalogUnWrapURN(const xmlChar *urn) {
823e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    xmlChar result[2000];
824e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    unsigned int i = 0;
825e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
826e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    if (xmlStrncmp(urn, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1))
827e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	return(NULL);
828e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    urn += sizeof(XML_URN_PUBID) - 1;
829f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
830e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    while (*urn != 0) {
831770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard	if (i > sizeof(result) - 4)
832e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    break;
833e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	if (*urn == '+') {
834e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    result[i++] = ' ';
835e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    urn++;
836e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	} else if (*urn == ':') {
837e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    result[i++] = '/';
838e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    result[i++] = '/';
839e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    urn++;
840e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	} else if (*urn == ';') {
841e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    result[i++] = ':';
842e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    result[i++] = ':';
843e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    urn++;
844e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	} else if (*urn == '%') {
845770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard	    if ((urn[1] == '2') && (urn[2] == 'B'))
846e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		result[i++] = '+';
847770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard	    else if ((urn[1] == '3') && (urn[2] == 'A'))
848e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		result[i++] = ':';
849770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard	    else if ((urn[1] == '2') && (urn[2] == 'F'))
850e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		result[i++] = '/';
851770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard	    else if ((urn[1] == '3') && (urn[2] == 'B'))
852e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		result[i++] = ';';
853770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard	    else if ((urn[1] == '2') && (urn[2] == '7'))
854e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		result[i++] = '\'';
855770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard	    else if ((urn[1] == '3') && (urn[2] == 'F'))
856e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		result[i++] = '?';
857770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard	    else if ((urn[1] == '2') && (urn[2] == '3'))
858e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		result[i++] = '#';
859770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard	    else if ((urn[1] == '2') && (urn[2] == '5'))
860e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		result[i++] = '%';
861e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    else {
862e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		result[i++] = *urn;
863e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		urn++;
864e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		continue;
865e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    }
866e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    urn += 3;
867e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	} else {
868e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    result[i++] = *urn;
869e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    urn++;
870e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	}
871e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    }
872e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    result[i] = 0;
873e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
874e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    return(xmlStrdup(result));
875e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard}
876e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
8779f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard/**
8789f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard * xmlParseCatalogFile:
8799f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard * @filename:  the filename
8809f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard *
8819f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard * parse an XML file and build a tree. It's like xmlParseFile()
8829f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard * except it bypass all catalog lookups.
8839f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard *
8849f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard * Returns the resulting document tree or NULL in case of error
8859f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard */
8869f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard
8879f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel VeillardxmlDocPtr
8889f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel VeillardxmlParseCatalogFile(const char *filename) {
8899f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    xmlDocPtr ret;
8909f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    xmlParserCtxtPtr ctxt;
8919f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    char *directory = NULL;
8929f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    xmlParserInputPtr inputStream;
8939f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    xmlParserInputBufferPtr buf;
8949f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard
8959f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    ctxt = xmlNewParserCtxt();
8969f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    if (ctxt == NULL) {
897d0cf7f6eea7331cc398c232d7879e4239d989e14Daniel Veillard#ifdef LIBXML_SAX1_ENABLED
8989f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard	if (xmlDefaultSAXHandler.error != NULL) {
8999f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard	    xmlDefaultSAXHandler.error(NULL, "out of memory\n");
9009f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard	}
901d0cf7f6eea7331cc398c232d7879e4239d989e14Daniel Veillard#endif
9029f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard	return(NULL);
9039f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    }
9049f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard
9059f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
9069f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    if (buf == NULL) {
9079f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard	xmlFreeParserCtxt(ctxt);
9089f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard	return(NULL);
9099f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    }
9109f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard
9119f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    inputStream = xmlNewInputStream(ctxt);
9129f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    if (inputStream == NULL) {
9139f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard	xmlFreeParserCtxt(ctxt);
9149f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard	return(NULL);
9159f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    }
9169f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard
917c3ca5ba4057ef61012d687c5a48af5ed93e41494Daniel Veillard    inputStream->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
9189f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    inputStream->buf = buf;
91961551a1eb75bacb32e5209635c0f3459595af54aDaniel Veillard    xmlBufResetInput(buf->buffer, inputStream);
9209f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard
9219f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    inputPush(ctxt, inputStream);
9229f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    if ((ctxt->directory == NULL) && (directory == NULL))
9239f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard        directory = xmlParserGetDirectory(filename);
9249f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    if ((ctxt->directory == NULL) && (directory != NULL))
9259f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard        ctxt->directory = directory;
9266990bf3c080529493a865a851b753a27d58014eaDaniel Veillard    ctxt->valid = 0;
9276990bf3c080529493a865a851b753a27d58014eaDaniel Veillard    ctxt->validate = 0;
9286990bf3c080529493a865a851b753a27d58014eaDaniel Veillard    ctxt->loadsubset = 0;
9296990bf3c080529493a865a851b753a27d58014eaDaniel Veillard    ctxt->pedantic = 0;
93003a53c34db279cbe4a305d58969beb1f26ff3d19Daniel Veillard    ctxt->dictNames = 1;
9319f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard
9329f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    xmlParseDocument(ctxt);
9339f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard
9349f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    if (ctxt->wellFormed)
9359f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard	ret = ctxt->myDoc;
9369f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    else {
9379f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard        ret = NULL;
9389f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard        xmlFreeDoc(ctxt->myDoc);
9399f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard        ctxt->myDoc = NULL;
9409f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    }
9419f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    xmlFreeParserCtxt(ctxt);
942f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
9439f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    return(ret);
9449f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard}
9459f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard
94675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
94775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlLoadFileContent:
94875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @filename:  a file path
94975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
95075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Load a file content into memory.
95175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
95275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Returns a pointer to the 0 terminated string or NULL in case of error
95375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
954dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillardstatic xmlChar *
95575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlLoadFileContent(const char *filename)
95675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard{
95775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#ifdef HAVE_STAT
95875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    int fd;
95975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#else
96075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    FILE *fd;
96175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#endif
96275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    int len;
96375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    long size;
964dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard
96575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#ifdef HAVE_STAT
96675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    struct stat info;
96775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#endif
96875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlChar *content;
96975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
97075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (filename == NULL)
97175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        return (NULL);
97275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
97375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#ifdef HAVE_STAT
97475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (stat(filename, &info) < 0)
97575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        return (NULL);
97675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#endif
97775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
97875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#ifdef HAVE_STAT
9795aad832aa34d21fca4696eb5a3bf203521f6a7f2Daniel Veillard    if ((fd = open(filename, O_RDONLY)) < 0)
98075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#else
9815aad832aa34d21fca4696eb5a3bf203521f6a7f2Daniel Veillard    if ((fd = fopen(filename, "rb")) == NULL)
98275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#endif
9835aad832aa34d21fca4696eb5a3bf203521f6a7f2Daniel Veillard    {
98475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        return (NULL);
98575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    }
98675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#ifdef HAVE_STAT
98775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    size = info.st_size;
98875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#else
98975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (fseek(fd, 0, SEEK_END) || (size = ftell(fd)) == EOF || fseek(fd, 0, SEEK_SET)) {        /* File operations denied? ok, just close and return failure */
99075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        fclose(fd);
99175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        return (NULL);
99275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    }
99375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#endif
994e1631e1cfcdf4bd7e7ec4999ec5aae9675390797Denis Pauk    content = (xmlChar*)xmlMallocAtomic(size + 10);
99575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (content == NULL) {
99669d2c171fa5105364168d663467f6834c8216155Daniel Veillard        xmlCatalogErrMemory("allocating catalog data");
99715d12040ff48c5190addd315092c9262fbe54e91Daniel Veillard#ifdef HAVE_STAT
99815d12040ff48c5190addd315092c9262fbe54e91Daniel Veillard	close(fd);
99915d12040ff48c5190addd315092c9262fbe54e91Daniel Veillard#else
100015d12040ff48c5190addd315092c9262fbe54e91Daniel Veillard	fclose(fd);
100115d12040ff48c5190addd315092c9262fbe54e91Daniel Veillard#endif
100275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        return (NULL);
100375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    }
100475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#ifdef HAVE_STAT
100575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    len = read(fd, content, size);
1006c43ac6698818d63e28f3f9691dba8a9cdbc6d469Carlo Bramini    close(fd);
100775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#else
100875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    len = fread(content, 1, size, fd);
1009c43ac6698818d63e28f3f9691dba8a9cdbc6d469Carlo Bramini    fclose(fd);
101075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard#endif
101175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (len < 0) {
101275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        xmlFree(content);
101375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        return (NULL);
101475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    }
101575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    content[len] = 0;
101675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
101775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    return(content);
101875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard}
101975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
1020c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard/**
1021c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard * xmlCatalogNormalizePublic:
1022c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard * @pubID:  the public ID string
1023c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard *
1024c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard *  Normalizes the Public Identifier
1025c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard *
1026c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard * Implements 6.2. Public Identifier Normalization
1027c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
1028c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard *
1029c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard * Returns the new string or NULL, the string must be deallocated
1030c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard *         by the caller.
1031c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard */
1032c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillardstatic xmlChar *
1033c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel VeillardxmlCatalogNormalizePublic(const xmlChar *pubID)
1034c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard{
1035c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    int ok = 1;
1036c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    int white;
1037c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    const xmlChar *p;
1038c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    xmlChar *ret;
1039c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    xmlChar *q;
1040c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard
1041c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    if (pubID == NULL)
1042c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard        return(NULL);
1043c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard
1044c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    white = 1;
1045c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    for (p = pubID;*p != 0 && ok;p++) {
1046c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard        if (!xmlIsBlank_ch(*p))
1047c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard            white = 0;
1048c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard        else if (*p == 0x20 && !white)
1049c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard            white = 1;
1050c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard        else
1051c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard            ok = 0;
1052c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    }
1053c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    if (ok && !white)	/* is normalized */
1054c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard        return(NULL);
1055c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard
1056c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    ret = xmlStrdup(pubID);
1057c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    q = ret;
1058c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    white = 0;
1059c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    for (p = pubID;*p != 0;p++) {
1060c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard        if (xmlIsBlank_ch(*p)) {
1061c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard            if (q != ret)
1062c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard                white = 1;
1063c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard        } else {
1064c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard            if (white) {
1065c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard                *(q++) = 0x20;
1066c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard                white = 0;
1067c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard            }
1068c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard            *(q++) = *p;
1069c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard        }
1070c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    }
1071c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    *q = 0;
1072c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    return(ret);
1073c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard}
1074c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard
107575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/************************************************************************
107675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
107775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *			The XML Catalog parser				*
107875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
107975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard ************************************************************************/
108075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
108175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillardstatic xmlCatalogEntryPtr
108275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename);
108375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillardstatic void
108475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlParseXMLCatalogNodeList(xmlNodePtr cur, xmlCatalogPrefer prefer,
1085b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	                   xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup);
108675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillardstatic xmlChar *
108775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
108875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	              const xmlChar *sysID);
108975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillardstatic xmlChar *
109075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI);
1091344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
109275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
109375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
109475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlGetXMLCatalogEntryType:
109575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @name:  the name
109675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
109775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * lookup the internal type associated to an XML catalog entry name
109875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
109906d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * Returns the type associated with that name
110075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
1101344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillardstatic xmlCatalogEntryType
1102344cee76a675e83ff159ffc02b009f304569cedaDaniel VeillardxmlGetXMLCatalogEntryType(const xmlChar *name) {
1103344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    xmlCatalogEntryType type = XML_CATA_NONE;
1104344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if (xmlStrEqual(name, (const xmlChar *) "system"))
1105344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = XML_CATA_SYSTEM;
1106344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else if (xmlStrEqual(name, (const xmlChar *) "public"))
1107344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = XML_CATA_PUBLIC;
1108344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else if (xmlStrEqual(name, (const xmlChar *) "rewriteSystem"))
1109344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = XML_CATA_REWRITE_SYSTEM;
1110344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else if (xmlStrEqual(name, (const xmlChar *) "delegatePublic"))
1111344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = XML_CATA_DELEGATE_PUBLIC;
1112344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else if (xmlStrEqual(name, (const xmlChar *) "delegateSystem"))
1113344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = XML_CATA_DELEGATE_SYSTEM;
1114344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else if (xmlStrEqual(name, (const xmlChar *) "uri"))
1115344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = XML_CATA_URI;
1116344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else if (xmlStrEqual(name, (const xmlChar *) "rewriteURI"))
1117344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = XML_CATA_REWRITE_URI;
1118344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else if (xmlStrEqual(name, (const xmlChar *) "delegateURI"))
1119344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = XML_CATA_DELEGATE_URI;
1120344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else if (xmlStrEqual(name, (const xmlChar *) "nextCatalog"))
1121344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = XML_CATA_NEXT_CATALOG;
1122344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else if (xmlStrEqual(name, (const xmlChar *) "catalog"))
1123344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = XML_CATA_CATALOG;
1124344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    return(type);
1125344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard}
1126344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
112775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
112875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlParseXMLCatalogOneNode:
112975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @cur:  the XML node
113075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @type:  the type of Catalog entry
113175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @name:  the name of the node
113275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @attrName:  the attribute holding the value
113375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @uriAttrName:  the attribute holding the URI-Reference
113475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @prefer:  the PUBLIC vs. SYSTEM current preference value
1135b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack * @cgroup:  the group which includes this node
113675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
113775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Finishes the examination of an XML tree node of a catalog and build
113875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * a Catalog entry from it.
113975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
114075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Returns the new Catalog entry node or NULL in case of error.
114175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
1142344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillardstatic xmlCatalogEntryPtr
1143344cee76a675e83ff159ffc02b009f304569cedaDaniel VeillardxmlParseXMLCatalogOneNode(xmlNodePtr cur, xmlCatalogEntryType type,
1144344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard			  const xmlChar *name, const xmlChar *attrName,
1145b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack			  const xmlChar *uriAttrName, xmlCatalogPrefer prefer,
1146b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack			  xmlCatalogEntryPtr cgroup) {
1147344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    int ok = 1;
1148344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    xmlChar *uriValue;
1149344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    xmlChar *nameValue = NULL;
1150344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    xmlChar *base = NULL;
1151344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    xmlChar *URL = NULL;
1152344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    xmlCatalogEntryPtr ret = NULL;
1153344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
1154344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if (attrName != NULL) {
1155344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	nameValue = xmlGetProp(cur, attrName);
1156344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	if (nameValue == NULL) {
115769d2c171fa5105364168d663467f6834c8216155Daniel Veillard	    xmlCatalogErr(ret, cur, XML_CATALOG_MISSING_ATTR,
115869d2c171fa5105364168d663467f6834c8216155Daniel Veillard			  "%s entry lacks '%s'\n", name, attrName, NULL);
1159344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    ok = 0;
1160344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	}
1161344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    }
1162344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    uriValue = xmlGetProp(cur, uriAttrName);
1163344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if (uriValue == NULL) {
116469d2c171fa5105364168d663467f6834c8216155Daniel Veillard	xmlCatalogErr(ret, cur, XML_CATALOG_MISSING_ATTR,
116569d2c171fa5105364168d663467f6834c8216155Daniel Veillard		"%s entry lacks '%s'\n", name, uriAttrName, NULL);
1166344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	ok = 0;
1167344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    }
1168344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if (!ok) {
1169344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	if (nameValue != NULL)
1170344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    xmlFree(nameValue);
1171344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	if (uriValue != NULL)
1172344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    xmlFree(uriValue);
1173344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	return(NULL);
1174344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    }
1175344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
1176344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    base = xmlNodeGetBase(cur->doc, cur);
1177344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    URL = xmlBuildURI(uriValue, base);
1178344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if (URL != NULL) {
1179e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	if (xmlDebugCatalogs > 1) {
1180344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    if (nameValue != NULL)
1181e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		xmlGenericError(xmlGenericErrorContext,
1182e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			"Found %s: '%s' '%s'\n", name, nameValue, URL);
1183344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    else
1184e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		xmlGenericError(xmlGenericErrorContext,
1185e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			"Found %s: '%s'\n", name, URL);
1186344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	}
1187b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	ret = xmlNewCatalogEntry(type, nameValue, uriValue, URL, prefer, cgroup);
1188344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    } else {
118969d2c171fa5105364168d663467f6834c8216155Daniel Veillard	xmlCatalogErr(ret, cur, XML_CATALOG_ENTRY_BROKEN,
1190344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		"%s entry '%s' broken ?: %s\n", name, uriAttrName, uriValue);
1191344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    }
1192344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if (nameValue != NULL)
1193344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	xmlFree(nameValue);
1194344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if (uriValue != NULL)
1195344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	xmlFree(uriValue);
1196344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if (base != NULL)
1197344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	xmlFree(base);
1198344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if (URL != NULL)
1199344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	xmlFree(URL);
1200344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    return(ret);
1201344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard}
1202344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
120375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
120475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlParseXMLCatalogNode:
120575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @cur:  the XML node
120675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @prefer:  the PUBLIC vs. SYSTEM current preference value
120775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @parent:  the parent Catalog entry
1208b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack * @cgroup:  the group which includes this node
120975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
121075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Examines an XML tree node of a catalog and build
121175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * a Catalog entry from it adding it to its parent. The examination can
121275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * be recursive.
121375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
1214344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillardstatic void
1215344cee76a675e83ff159ffc02b009f304569cedaDaniel VeillardxmlParseXMLCatalogNode(xmlNodePtr cur, xmlCatalogPrefer prefer,
1216b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	               xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup)
1217344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard{
1218344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    xmlChar *base = NULL;
1219344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    xmlCatalogEntryPtr entry = NULL;
1220344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
1221344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if (cur == NULL)
1222344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard        return;
1223344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if (xmlStrEqual(cur->name, BAD_CAST "group")) {
1224344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard        xmlChar *prop;
1225b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	xmlCatalogPrefer pref = XML_CATA_PREFER_NONE;
1226344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
1227344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard        prop = xmlGetProp(cur, BAD_CAST "prefer");
1228344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard        if (prop != NULL) {
1229344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard            if (xmlStrEqual(prop, BAD_CAST "system")) {
1230344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard                prefer = XML_CATA_PREFER_SYSTEM;
1231344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard            } else if (xmlStrEqual(prop, BAD_CAST "public")) {
1232344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard                prefer = XML_CATA_PREFER_PUBLIC;
1233344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard            } else {
123469d2c171fa5105364168d663467f6834c8216155Daniel Veillard		xmlCatalogErr(parent, cur, XML_CATALOG_PREFER_VALUE,
123569d2c171fa5105364168d663467f6834c8216155Daniel Veillard                              "Invalid value for prefer: '%s'\n",
123669d2c171fa5105364168d663467f6834c8216155Daniel Veillard			      prop, NULL, NULL);
1237344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard            }
1238344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard            xmlFree(prop);
1239b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	    pref = prefer;
1240344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard        }
1241b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	prop = xmlGetProp(cur, BAD_CAST "id");
1242b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	base = xmlGetNsProp(cur, BAD_CAST "base", XML_XML_NAMESPACE);
1243b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	entry = xmlNewCatalogEntry(XML_CATA_GROUP, prop, base, NULL, pref, cgroup);
1244181a1ca01819d347b112aec93174b991b900ce78William M. Brack	xmlFree(prop);
1245344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    } else if (xmlStrEqual(cur->name, BAD_CAST "public")) {
1246344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_PUBLIC,
1247b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		BAD_CAST "public", BAD_CAST "publicId", BAD_CAST "uri", prefer, cgroup);
1248344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    } else if (xmlStrEqual(cur->name, BAD_CAST "system")) {
1249344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_SYSTEM,
1250b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		BAD_CAST "system", BAD_CAST "systemId", BAD_CAST "uri", prefer, cgroup);
1251344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    } else if (xmlStrEqual(cur->name, BAD_CAST "rewriteSystem")) {
1252344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_SYSTEM,
1253344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		BAD_CAST "rewriteSystem", BAD_CAST "systemIdStartString",
1254b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		BAD_CAST "rewritePrefix", prefer, cgroup);
1255344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    } else if (xmlStrEqual(cur->name, BAD_CAST "delegatePublic")) {
1256344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_PUBLIC,
1257344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		BAD_CAST "delegatePublic", BAD_CAST "publicIdStartString",
1258b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		BAD_CAST "catalog", prefer, cgroup);
1259344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    } else if (xmlStrEqual(cur->name, BAD_CAST "delegateSystem")) {
1260344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_SYSTEM,
1261344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		BAD_CAST "delegateSystem", BAD_CAST "systemIdStartString",
1262b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		BAD_CAST "catalog", prefer, cgroup);
1263344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    } else if (xmlStrEqual(cur->name, BAD_CAST "uri")) {
1264344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_URI,
1265344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		BAD_CAST "uri", BAD_CAST "name",
1266b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		BAD_CAST "uri", prefer, cgroup);
1267344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    } else if (xmlStrEqual(cur->name, BAD_CAST "rewriteURI")) {
1268344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_URI,
1269344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		BAD_CAST "rewriteURI", BAD_CAST "uriStartString",
1270b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		BAD_CAST "rewritePrefix", prefer, cgroup);
1271344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    } else if (xmlStrEqual(cur->name, BAD_CAST "delegateURI")) {
1272344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_URI,
1273344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		BAD_CAST "delegateURI", BAD_CAST "uriStartString",
1274b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		BAD_CAST "catalog", prefer, cgroup);
1275344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    } else if (xmlStrEqual(cur->name, BAD_CAST "nextCatalog")) {
1276344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_NEXT_CATALOG,
1277344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		BAD_CAST "nextCatalog", NULL,
1278b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		BAD_CAST "catalog", prefer, cgroup);
1279344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    }
1280b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack    if (entry != NULL) {
1281b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack        if (parent != NULL) {
1282b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack	    entry->parent = parent;
1283b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack	    if (parent->children == NULL)
1284b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack		parent->children = entry;
1285b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack	    else {
1286b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack		xmlCatalogEntryPtr prev;
1287b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack
1288b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack		prev = parent->children;
1289b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack		while (prev->next != NULL)
1290b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack		    prev = prev->next;
1291b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack		prev->next = entry;
1292b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack	    }
1293b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack	}
1294b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack	if (entry->type == XML_CATA_GROUP) {
1295b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack	    /*
1296b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack	     * Recurse to propagate prefer to the subtree
1297b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack	     * (xml:base handling is automated)
1298b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack	     */
1299b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack            xmlParseXMLCatalogNodeList(cur->children, prefer, parent, entry);
1300344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	}
1301b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack    }
1302344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if (base != NULL)
1303344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	xmlFree(base);
1304344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard}
1305344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
130675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
130775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlParseXMLCatalogNodeList:
130875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @cur:  the XML node list of siblings
130975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @prefer:  the PUBLIC vs. SYSTEM current preference value
131075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @parent:  the parent Catalog entry
1311b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack * @cgroup:  the group which includes this list
131275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
131375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Examines a list of XML sibling nodes of a catalog and build
131475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * a list of Catalog entry from it adding it to the parent.
131575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * The examination will recurse to examine node subtrees.
131675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
1317344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillardstatic void
1318344cee76a675e83ff159ffc02b009f304569cedaDaniel VeillardxmlParseXMLCatalogNodeList(xmlNodePtr cur, xmlCatalogPrefer prefer,
1319b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	                   xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup) {
1320344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    while (cur != NULL) {
1321344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	if ((cur->ns != NULL) && (cur->ns->href != NULL) &&
1322344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    (xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {
1323b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	    xmlParseXMLCatalogNode(cur, prefer, parent, cgroup);
1324344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	}
1325344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	cur = cur->next;
1326344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    }
1327344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    /* TODO: sort the list according to REWRITE lengths and prefer value */
1328344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard}
1329344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
133075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
133175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlParseXMLCatalogFile:
133275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @prefer:  the PUBLIC vs. SYSTEM current preference value
133375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @filename:  the filename for the catalog
133475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
133575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Parses the catalog file to extract the XML tree and then analyze the
133675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * tree to build a list of Catalog entries corresponding to this catalog
1337f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *
133875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Returns the resulting Catalog entries list
133975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
1340344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillardstatic xmlCatalogEntryPtr
1341344cee76a675e83ff159ffc02b009f304569cedaDaniel VeillardxmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename) {
1342344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    xmlDocPtr doc;
1343344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    xmlNodePtr cur;
1344344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    xmlChar *prop;
1345344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    xmlCatalogEntryPtr parent = NULL;
1346344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
1347344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if (filename == NULL)
1348344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard        return(NULL);
1349344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
13509f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    doc = xmlParseCatalogFile((const char *) filename);
1351e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    if (doc == NULL) {
1352e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	if (xmlDebugCatalogs)
1353e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    xmlGenericError(xmlGenericErrorContext,
1354e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		    "Failed to parse catalog %s\n", filename);
1355344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	return(NULL);
1356e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    }
1357e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
1358e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    if (xmlDebugCatalogs)
1359e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	xmlGenericError(xmlGenericErrorContext,
13603c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard		"%d Parsing catalog %s\n", xmlGetThreadId(), filename);
1361344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
1362344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    cur = xmlDocGetRootElement(doc);
1363344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if ((cur != NULL) && (xmlStrEqual(cur->name, BAD_CAST "catalog")) &&
1364344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	(cur->ns != NULL) && (cur->ns->href != NULL) &&
1365344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	(xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {
1366344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
1367e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	parent = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
1368b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack				    (const xmlChar *)filename, NULL, prefer, NULL);
1369344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard        if (parent == NULL) {
1370344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    xmlFreeDoc(doc);
1371344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    return(NULL);
1372344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	}
1373344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
1374344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	prop = xmlGetProp(cur, BAD_CAST "prefer");
1375344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	if (prop != NULL) {
1376344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    if (xmlStrEqual(prop, BAD_CAST "system")) {
1377344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		prefer = XML_CATA_PREFER_SYSTEM;
1378344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    } else if (xmlStrEqual(prop, BAD_CAST "public")) {
1379344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		prefer = XML_CATA_PREFER_PUBLIC;
1380344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    } else {
138169d2c171fa5105364168d663467f6834c8216155Daniel Veillard		xmlCatalogErr(NULL, cur, XML_CATALOG_PREFER_VALUE,
138269d2c171fa5105364168d663467f6834c8216155Daniel Veillard			      "Invalid value for prefer: '%s'\n",
138369d2c171fa5105364168d663467f6834c8216155Daniel Veillard			      prop, NULL, NULL);
1384344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    }
1385344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    xmlFree(prop);
1386344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	}
1387344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	cur = cur->children;
1388b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	xmlParseXMLCatalogNodeList(cur, prefer, parent, NULL);
1389344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    } else {
139069d2c171fa5105364168d663467f6834c8216155Daniel Veillard	xmlCatalogErr(NULL, (xmlNodePtr) doc, XML_CATALOG_NOT_CATALOG,
139169d2c171fa5105364168d663467f6834c8216155Daniel Veillard		      "File %s is not an XML Catalog\n",
139269d2c171fa5105364168d663467f6834c8216155Daniel Veillard		      filename, NULL, NULL);
1393344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	xmlFreeDoc(doc);
1394344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	return(NULL);
1395344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    }
1396344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    xmlFreeDoc(doc);
1397344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    return(parent);
1398344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard}
1399344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
1400cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard/**
1401cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * xmlFetchXMLCatalogFile:
1402cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * @catal:  an existing but incomplete catalog entry
1403cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *
1404cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Fetch and parse the subcatalog referenced by an entry
1405f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *
1406cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Returns 0 in case of success, -1 otherwise
1407cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard */
1408cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillardstatic int
1409cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlFetchXMLCatalogFile(xmlCatalogEntryPtr catal) {
141085c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard    xmlCatalogEntryPtr doc;
1411cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
1412f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    if (catal == NULL)
1413cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	return(-1);
1414c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard    if (catal->URL == NULL)
1415cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	return(-1);
1416cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
14178146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    /*
14188146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard     * lock the whole catalog for modification
14198146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard     */
14208146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    xmlRMutexLock(xmlCatalogMutex);
14218146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    if (catal->children != NULL) {
14228146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard	/* Okay someone else did it in the meantime */
14238146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard	xmlRMutexUnlock(xmlCatalogMutex);
14248146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard	return(0);
14258146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    }
14268146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard
142785c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard    if (xmlCatalogXMLFiles != NULL) {
142885c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	doc = (xmlCatalogEntryPtr)
1429c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard	    xmlHashLookup(xmlCatalogXMLFiles, catal->URL);
143085c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	if (doc != NULL) {
143185c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	    if (xmlDebugCatalogs)
143285c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard		xmlGenericError(xmlGenericErrorContext,
1433c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard		    "Found %s in file hash\n", catal->URL);
143485c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard
143585c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	    if (catal->type == XML_CATA_CATALOG)
143685c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard		catal->children = doc->children;
143785c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	    else
143885c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard		catal->children = doc;
143985c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	    catal->dealloc = 0;
144085c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	    xmlRMutexUnlock(xmlCatalogMutex);
144185c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	    return(0);
144285c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	}
144385c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	if (xmlDebugCatalogs)
144485c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	    xmlGenericError(xmlGenericErrorContext,
1445c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard		"%s not found in file hash\n", catal->URL);
14466990bf3c080529493a865a851b753a27d58014eaDaniel Veillard    }
14476990bf3c080529493a865a851b753a27d58014eaDaniel Veillard
1448cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    /*
144975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard     * Fetch and parse. Note that xmlParseXMLCatalogFile does not
1450cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard     * use the existing catalog, there is no recursion allowed at
145175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard     * that level.
1452cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard     */
1453c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard    doc = xmlParseXMLCatalogFile(catal->prefer, catal->URL);
14546990bf3c080529493a865a851b753a27d58014eaDaniel Veillard    if (doc == NULL) {
14559f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard	catal->type = XML_CATA_BROKEN_CATALOG;
14568146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard	xmlRMutexUnlock(xmlCatalogMutex);
1457cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	return(-1);
14589f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard    }
1459cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
146085c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard    if (catal->type == XML_CATA_CATALOG)
146185c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	catal->children = doc->children;
146285c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard    else
146385c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	catal->children = doc;
146485c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard
146585c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard    doc->dealloc = 1;
146685c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard
14678146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    if (xmlCatalogXMLFiles == NULL)
14688146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard	xmlCatalogXMLFiles = xmlHashCreate(10);
14698146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    if (xmlCatalogXMLFiles != NULL) {
147085c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	if (xmlDebugCatalogs)
147185c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	    xmlGenericError(xmlGenericErrorContext,
1472c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard		"%s added to file hash\n", catal->URL);
1473c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard	xmlHashAddEntry(xmlCatalogXMLFiles, catal->URL, doc);
1474cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    }
14758146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    xmlRMutexUnlock(xmlCatalogMutex);
1476cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    return(0);
1477cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard}
1478cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
147975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/************************************************************************
148075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
148175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *			XML Catalog handling				*
148275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
148375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard ************************************************************************/
1484344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
1485344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard/**
1486344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * xmlAddXMLCatalog:
1487344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * @catal:  top of an XML catalog
1488344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * @type:  the type of record to add to the catalog
1489cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * @orig:  the system, public or prefix to match (or NULL)
1490344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * @replace:  the replacement value for the match
1491344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard *
1492344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * Add an entry in the XML catalog, it may overwrite existing but
1493344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * different entries.
1494344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard *
1495344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * Returns 0 if successful, -1 otherwise
1496344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard */
1497344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillardstatic int
1498344cee76a675e83ff159ffc02b009f304569cedaDaniel VeillardxmlAddXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *type,
1499344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	      const xmlChar *orig, const xmlChar *replace) {
1500344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    xmlCatalogEntryPtr cur;
1501344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    xmlCatalogEntryType typ;
1502c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard    int doregister = 0;
1503344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
1504f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    if ((catal == NULL) ||
15059f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard	((catal->type != XML_CATA_CATALOG) &&
15069f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard	 (catal->type != XML_CATA_BROKEN_CATALOG)))
1507344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	return(-1);
1508ffe09c94fd1395c6b7b44eba506716d7fb4b39aaDaniel Veillard    if (catal->children == NULL) {
1509ffe09c94fd1395c6b7b44eba506716d7fb4b39aaDaniel Veillard	xmlFetchXMLCatalogFile(catal);
1510ffe09c94fd1395c6b7b44eba506716d7fb4b39aaDaniel Veillard    }
1511c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard    if (catal->children == NULL)
1512c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard	doregister = 1;
1513c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard
1514344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    typ = xmlGetXMLCatalogEntryType(type);
1515e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    if (typ == XML_CATA_NONE) {
1516e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	if (xmlDebugCatalogs)
1517e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    xmlGenericError(xmlGenericErrorContext,
1518e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		    "Failed to add unknown element %s to catalog\n", type);
1519344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	return(-1);
1520e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    }
1521344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
1522344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    cur = catal->children;
1523344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    /*
1524344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard     * Might be a simple "update in place"
1525344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard     */
1526344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if (cur != NULL) {
1527344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	while (cur != NULL) {
1528cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    if ((orig != NULL) && (cur->type == typ) &&
1529cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		(xmlStrEqual(orig, cur->name))) {
1530e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		if (xmlDebugCatalogs)
1531e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		    xmlGenericError(xmlGenericErrorContext,
1532e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			    "Updating element %s to catalog\n", type);
1533344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		if (cur->value != NULL)
1534344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		    xmlFree(cur->value);
1535c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard		if (cur->URL != NULL)
1536c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard		    xmlFree(cur->URL);
1537344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		cur->value = xmlStrdup(replace);
1538c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard		cur->URL = xmlStrdup(replace);
1539cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		return(0);
1540344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    }
1541344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    if (cur->next == NULL)
1542344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		break;
1543344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    cur = cur->next;
1544344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	}
1545344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    }
1546e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    if (xmlDebugCatalogs)
1547e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	xmlGenericError(xmlGenericErrorContext,
1548e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		"Adding element %s to catalog\n", type);
1549344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if (cur == NULL)
1550c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard	catal->children = xmlNewCatalogEntry(typ, orig, replace,
1551b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		                             NULL, catal->prefer, NULL);
1552344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else
1553c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard	cur->next = xmlNewCatalogEntry(typ, orig, replace,
1554b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		                       NULL, catal->prefer, NULL);
1555c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard    if (doregister) {
155627bec1461b16aa0e9016337723584c62ae179e8aDaniel Veillard        catal->type = XML_CATA_CATALOG;
1557e1631e1cfcdf4bd7e7ec4999ec5aae9675390797Denis Pauk	cur = (xmlCatalogEntryPtr)xmlHashLookup(xmlCatalogXMLFiles, catal->URL);
1558c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard	if (cur != NULL)
1559c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard	    cur->children = catal->children;
1560c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard    }
1561c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard
1562cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    return(0);
1563cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard}
1564cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
1565cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard/**
1566cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * xmlDelXMLCatalog:
1567cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * @catal:  top of an XML catalog
156860087f30f3b4cf21de48f39181736e7d71e7a661Daniel Veillard * @value:  the value to remove from the catalog
1569cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *
1570cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Remove entries in the XML catalog where the value or the URI
1571cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * is equal to @value
1572cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *
1573cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Returns the number of entries removed if successful, -1 otherwise
1574cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard */
1575cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillardstatic int
1576cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlDelXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *value) {
1577c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard    xmlCatalogEntryPtr cur;
1578cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    int ret = 0;
1579cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
1580f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    if ((catal == NULL) ||
15819f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard	((catal->type != XML_CATA_CATALOG) &&
15829f7b84bb07ab4f748ba981a38c7566cd48af60faDaniel Veillard	 (catal->type != XML_CATA_BROKEN_CATALOG)))
1583cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	return(-1);
1584cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    if (value == NULL)
1585cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	return(-1);
1586ffe09c94fd1395c6b7b44eba506716d7fb4b39aaDaniel Veillard    if (catal->children == NULL) {
1587ffe09c94fd1395c6b7b44eba506716d7fb4b39aaDaniel Veillard	xmlFetchXMLCatalogFile(catal);
1588ffe09c94fd1395c6b7b44eba506716d7fb4b39aaDaniel Veillard    }
1589cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
1590cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    /*
1591cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard     * Scan the children
1592cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard     */
1593cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    cur = catal->children;
1594cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    while (cur != NULL) {
1595cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	if (((cur->name != NULL) && (xmlStrEqual(value, cur->name))) ||
1596cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    (xmlStrEqual(value, cur->value))) {
1597e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    if (xmlDebugCatalogs) {
1598e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		if (cur->name != NULL)
1599e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		    xmlGenericError(xmlGenericErrorContext,
1600e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			    "Removing element %s from catalog\n", cur->name);
1601e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		else
1602e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		    xmlGenericError(xmlGenericErrorContext,
1603e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			    "Removing element %s from catalog\n", cur->value);
1604e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    }
1605c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard	    cur->type = XML_CATA_REMOVED;
1606cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	}
1607cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	cur = cur->next;
1608cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    }
1609cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    return(ret);
1610cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard}
1611cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
1612cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard/**
1613cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * xmlCatalogXMLResolve:
1614cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * @catal:  a catalog list
161506d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * @pubID:  the public ID string
161606d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * @sysID:  the system ID string
1617cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *
1618cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Do a complete resolution lookup of an External Identifier for a
1619cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * list of catalog entries.
1620cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *
1621cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Implements (or tries to) 7.1. External Identifier Resolution
1622cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
1623cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *
1624cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Returns the URI of the resource or NULL if not found
1625cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard */
1626cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillardstatic xmlChar *
1627cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlCatalogXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
1628cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	              const xmlChar *sysID) {
1629cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    xmlChar *ret = NULL;
1630cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    xmlCatalogEntryPtr cur;
1631cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    int haveDelegate = 0;
1632cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    int haveNext = 0;
1633cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
1634cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    /*
16355ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard     * protection against loops
16365ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard     */
16375ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard    if (catal->depth > MAX_CATAL_DEPTH) {
163869d2c171fa5105364168d663467f6834c8216155Daniel Veillard	xmlCatalogErr(catal, NULL, XML_CATALOG_RECURSION,
163969d2c171fa5105364168d663467f6834c8216155Daniel Veillard		      "Detected recursion in catalog %s\n",
164069d2c171fa5105364168d663467f6834c8216155Daniel Veillard		      catal->name, NULL, NULL);
16415ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard	return(NULL);
16425ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard    }
16435ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard    catal->depth++;
16445ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard
16455ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard    /*
1646cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard     * First tries steps 2/ 3/ 4/ if a system ID is provided.
1647cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard     */
1648cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    if (sysID != NULL) {
1649cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	xmlCatalogEntryPtr rewrite = NULL;
1650cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	int lenrewrite = 0, len;
1651cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	cur = catal;
1652cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	haveDelegate = 0;
1653cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	while (cur != NULL) {
1654cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    switch (cur->type) {
1655cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		case XML_CATA_SYSTEM:
1656e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		    if (xmlStrEqual(sysID, cur->name)) {
1657e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			if (xmlDebugCatalogs)
1658e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			    xmlGenericError(xmlGenericErrorContext,
1659890b5492c62427dbbda5025725fab9b96f375512Daniel Veillard				    "Found system match %s, using %s\n",
1660890b5492c62427dbbda5025725fab9b96f375512Daniel Veillard				            cur->name, cur->URL);
16615ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard			catal->depth--;
1662c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard			return(xmlStrdup(cur->URL));
1663e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		    }
1664cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    break;
1665cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		case XML_CATA_REWRITE_SYSTEM:
1666cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    len = xmlStrlen(cur->name);
1667cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    if ((len > lenrewrite) &&
1668cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard			(!xmlStrncmp(sysID, cur->name, len))) {
1669cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard			lenrewrite = len;
1670cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard			rewrite = cur;
1671cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    }
1672cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    break;
1673cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		case XML_CATA_DELEGATE_SYSTEM:
1674cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    if (!xmlStrncmp(sysID, cur->name, xmlStrlen(cur->name)))
1675cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard			haveDelegate++;
1676cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    break;
1677cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		case XML_CATA_NEXT_CATALOG:
1678cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    haveNext++;
1679cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    break;
1680cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		default:
1681cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    break;
1682cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    }
1683cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    cur = cur->next;
1684cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	}
1685cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	if (rewrite != NULL) {
1686e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    if (xmlDebugCatalogs)
1687e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		xmlGenericError(xmlGenericErrorContext,
1688e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			"Using rewriting rule %s\n", rewrite->name);
1689c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard	    ret = xmlStrdup(rewrite->URL);
1690cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    if (ret != NULL)
1691cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		ret = xmlStrcat(ret, &sysID[lenrewrite]);
16925ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard	    catal->depth--;
1693cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    return(ret);
1694cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	}
1695cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	if (haveDelegate) {
16966990bf3c080529493a865a851b753a27d58014eaDaniel Veillard	    const xmlChar *delegates[MAX_DELEGATE];
16976990bf3c080529493a865a851b753a27d58014eaDaniel Veillard	    int nbList = 0, i;
16986990bf3c080529493a865a851b753a27d58014eaDaniel Veillard
1699cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    /*
1700e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	     * Assume the entries have been sorted by decreasing substring
1701cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	     * matches when the list was produced.
1702cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	     */
1703cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    cur = catal;
1704cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    while (cur != NULL) {
1705cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		if ((cur->type == XML_CATA_DELEGATE_SYSTEM) &&
1706cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    (!xmlStrncmp(sysID, cur->name, xmlStrlen(cur->name)))) {
17076990bf3c080529493a865a851b753a27d58014eaDaniel Veillard		    for (i = 0;i < nbList;i++)
1708c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard			if (xmlStrEqual(cur->URL, delegates[i]))
17096990bf3c080529493a865a851b753a27d58014eaDaniel Veillard			    break;
17106990bf3c080529493a865a851b753a27d58014eaDaniel Veillard		    if (i < nbList) {
17116990bf3c080529493a865a851b753a27d58014eaDaniel Veillard			cur = cur->next;
17126990bf3c080529493a865a851b753a27d58014eaDaniel Veillard			continue;
17136990bf3c080529493a865a851b753a27d58014eaDaniel Veillard		    }
17146990bf3c080529493a865a851b753a27d58014eaDaniel Veillard		    if (nbList < MAX_DELEGATE)
1715c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard			delegates[nbList++] = cur->URL;
17166990bf3c080529493a865a851b753a27d58014eaDaniel Veillard
1717cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    if (cur->children == NULL) {
1718cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard			xmlFetchXMLCatalogFile(cur);
1719cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    }
1720cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    if (cur->children != NULL) {
1721e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			if (xmlDebugCatalogs)
1722e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			    xmlGenericError(xmlGenericErrorContext,
1723c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard				    "Trying system delegate %s\n", cur->URL);
172485c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard			ret = xmlCatalogListXMLResolve(
172585c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard				cur->children, NULL, sysID);
17265ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard			if (ret != NULL) {
17275ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard			    catal->depth--;
1728e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			    return(ret);
17295ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard			}
1730cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    }
1731cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		}
1732cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		cur = cur->next;
1733cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    }
1734e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    /*
1735e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	     * Apply the cut algorithm explained in 4/
1736e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	     */
17375ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard	    catal->depth--;
1738e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    return(XML_CATAL_BREAK);
1739cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	}
1740cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    }
1741cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    /*
1742cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard     * Then tries 5/ 6/ if a public ID is provided
1743cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard     */
1744cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    if (pubID != NULL) {
1745cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	cur = catal;
1746cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	haveDelegate = 0;
1747cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	while (cur != NULL) {
1748cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    switch (cur->type) {
1749cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		case XML_CATA_PUBLIC:
1750e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		    if (xmlStrEqual(pubID, cur->name)) {
1751e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			if (xmlDebugCatalogs)
1752e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			    xmlGenericError(xmlGenericErrorContext,
1753e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard				    "Found public match %s\n", cur->name);
17545ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard			catal->depth--;
1755c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard			return(xmlStrdup(cur->URL));
1756e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		    }
1757cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    break;
1758cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		case XML_CATA_DELEGATE_PUBLIC:
1759e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		    if (!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)) &&
1760e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			(cur->prefer == XML_CATA_PREFER_PUBLIC))
1761cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard			haveDelegate++;
1762cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    break;
1763cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		case XML_CATA_NEXT_CATALOG:
1764cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    if (sysID == NULL)
1765cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard			haveNext++;
1766cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    break;
1767cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		default:
1768cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    break;
1769cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    }
1770cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    cur = cur->next;
1771cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	}
1772cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	if (haveDelegate) {
17736990bf3c080529493a865a851b753a27d58014eaDaniel Veillard	    const xmlChar *delegates[MAX_DELEGATE];
17746990bf3c080529493a865a851b753a27d58014eaDaniel Veillard	    int nbList = 0, i;
17756990bf3c080529493a865a851b753a27d58014eaDaniel Veillard
1776cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    /*
1777e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	     * Assume the entries have been sorted by decreasing substring
1778cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	     * matches when the list was produced.
1779cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	     */
1780cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    cur = catal;
1781cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    while (cur != NULL) {
1782cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		if ((cur->type == XML_CATA_DELEGATE_PUBLIC) &&
1783e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		    (cur->prefer == XML_CATA_PREFER_PUBLIC) &&
1784e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		    (!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)))) {
17856990bf3c080529493a865a851b753a27d58014eaDaniel Veillard
17866990bf3c080529493a865a851b753a27d58014eaDaniel Veillard		    for (i = 0;i < nbList;i++)
1787c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard			if (xmlStrEqual(cur->URL, delegates[i]))
17886990bf3c080529493a865a851b753a27d58014eaDaniel Veillard			    break;
17896990bf3c080529493a865a851b753a27d58014eaDaniel Veillard		    if (i < nbList) {
17906990bf3c080529493a865a851b753a27d58014eaDaniel Veillard			cur = cur->next;
17916990bf3c080529493a865a851b753a27d58014eaDaniel Veillard			continue;
17926990bf3c080529493a865a851b753a27d58014eaDaniel Veillard		    }
17936990bf3c080529493a865a851b753a27d58014eaDaniel Veillard		    if (nbList < MAX_DELEGATE)
1794c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard			delegates[nbList++] = cur->URL;
1795f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
1796cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    if (cur->children == NULL) {
1797cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard			xmlFetchXMLCatalogFile(cur);
1798cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    }
1799cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    if (cur->children != NULL) {
1800e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			if (xmlDebugCatalogs)
1801e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			    xmlGenericError(xmlGenericErrorContext,
1802c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard				    "Trying public delegate %s\n", cur->URL);
180385c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard			ret = xmlCatalogListXMLResolve(
180485c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard				cur->children, pubID, NULL);
18055ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard			if (ret != NULL) {
18065ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard			    catal->depth--;
1807e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			    return(ret);
18085ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard			}
1809cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    }
1810cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		}
1811cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		cur = cur->next;
1812cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    }
1813e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    /*
1814e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	     * Apply the cut algorithm explained in 4/
1815e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	     */
18165ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard	    catal->depth--;
1817e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    return(XML_CATAL_BREAK);
1818cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	}
1819cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    }
1820cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    if (haveNext) {
1821cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	cur = catal;
1822cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	while (cur != NULL) {
1823cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    if (cur->type == XML_CATA_NEXT_CATALOG) {
1824cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		if (cur->children == NULL) {
1825cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    xmlFetchXMLCatalogFile(cur);
1826cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		}
1827cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		if (cur->children != NULL) {
18286433954692abb5620ed4e554a2979ef4ecdc6871Daniel Veillard		    ret = xmlCatalogListXMLResolve(cur->children, pubID, sysID);
18295ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard		    if (ret != NULL) {
18305ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard			catal->depth--;
18316433954692abb5620ed4e554a2979ef4ecdc6871Daniel Veillard			return(ret);
1832be8d9d33eb9d8fc39ebc8c03ee9bbc790a812b59Daniel Veillard		    } else if (catal->depth > MAX_CATAL_DEPTH) {
1833be8d9d33eb9d8fc39ebc8c03ee9bbc790a812b59Daniel Veillard		        return(NULL);
18345ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard		    }
1835cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		}
1836cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    }
1837cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    cur = cur->next;
1838cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	}
1839cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    }
1840cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
18415ee43b06000bf42aea1955260aa867c6e466e0a4Daniel Veillard    catal->depth--;
1842cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    return(NULL);
1843cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard}
1844cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
1845cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard/**
1846dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * xmlCatalogXMLResolveURI:
1847dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * @catal:  a catalog list
1848dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * @URI:  the URI
184906d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * @sysID:  the system ID string
1850dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard *
1851dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * Do a complete resolution lookup of an External Identifier for a
1852dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * list of catalog entries.
1853dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard *
1854dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * Implements (or tries to) 7.2.2. URI Resolution
1855dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
1856dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard *
1857dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * Returns the URI of the resource or NULL if not found
1858dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard */
1859dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillardstatic xmlChar *
1860dc2cee29d094958139f409e30209f68953c9cb67Daniel VeillardxmlCatalogXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) {
1861dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    xmlChar *ret = NULL;
1862dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    xmlCatalogEntryPtr cur;
1863dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    int haveDelegate = 0;
1864dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    int haveNext = 0;
1865dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    xmlCatalogEntryPtr rewrite = NULL;
1866dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    int lenrewrite = 0, len;
1867dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard
1868dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    if (catal == NULL)
1869dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	return(NULL);
1870dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard
1871dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    if (URI == NULL)
1872dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	return(NULL);
1873dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard
1874be8d9d33eb9d8fc39ebc8c03ee9bbc790a812b59Daniel Veillard    if (catal->depth > MAX_CATAL_DEPTH) {
1875be8d9d33eb9d8fc39ebc8c03ee9bbc790a812b59Daniel Veillard	xmlCatalogErr(catal, NULL, XML_CATALOG_RECURSION,
1876be8d9d33eb9d8fc39ebc8c03ee9bbc790a812b59Daniel Veillard		      "Detected recursion in catalog %s\n",
1877be8d9d33eb9d8fc39ebc8c03ee9bbc790a812b59Daniel Veillard		      catal->name, NULL, NULL);
1878be8d9d33eb9d8fc39ebc8c03ee9bbc790a812b59Daniel Veillard	return(NULL);
1879be8d9d33eb9d8fc39ebc8c03ee9bbc790a812b59Daniel Veillard    }
1880be8d9d33eb9d8fc39ebc8c03ee9bbc790a812b59Daniel Veillard
1881dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    /*
1882dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard     * First tries steps 2/ 3/ 4/ if a system ID is provided.
1883dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard     */
1884dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    cur = catal;
1885dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    haveDelegate = 0;
1886dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    while (cur != NULL) {
1887dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	switch (cur->type) {
1888dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	    case XML_CATA_URI:
1889dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		if (xmlStrEqual(URI, cur->name)) {
1890dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		    if (xmlDebugCatalogs)
1891dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard			xmlGenericError(xmlGenericErrorContext,
1892dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard				"Found URI match %s\n", cur->name);
1893c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard		    return(xmlStrdup(cur->URL));
1894dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		}
1895dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		break;
1896dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	    case XML_CATA_REWRITE_URI:
1897dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		len = xmlStrlen(cur->name);
1898dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		if ((len > lenrewrite) &&
1899dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		    (!xmlStrncmp(URI, cur->name, len))) {
1900dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		    lenrewrite = len;
1901dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		    rewrite = cur;
1902dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		}
1903dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		break;
1904dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	    case XML_CATA_DELEGATE_URI:
1905dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		if (!xmlStrncmp(URI, cur->name, xmlStrlen(cur->name)))
1906dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		    haveDelegate++;
1907dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		break;
1908dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	    case XML_CATA_NEXT_CATALOG:
1909dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		haveNext++;
1910dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		break;
1911dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	    default:
1912dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		break;
1913dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	}
1914dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	cur = cur->next;
1915dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    }
1916dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    if (rewrite != NULL) {
1917dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	if (xmlDebugCatalogs)
1918dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
1919dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		    "Using rewriting rule %s\n", rewrite->name);
1920c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard	ret = xmlStrdup(rewrite->URL);
1921dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	if (ret != NULL)
1922dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	    ret = xmlStrcat(ret, &URI[lenrewrite]);
1923dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	return(ret);
1924dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    }
1925dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    if (haveDelegate) {
19266990bf3c080529493a865a851b753a27d58014eaDaniel Veillard	const xmlChar *delegates[MAX_DELEGATE];
19276990bf3c080529493a865a851b753a27d58014eaDaniel Veillard	int nbList = 0, i;
19286990bf3c080529493a865a851b753a27d58014eaDaniel Veillard
1929dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	/*
1930dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	 * Assume the entries have been sorted by decreasing substring
1931dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	 * matches when the list was produced.
1932dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	 */
1933dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	cur = catal;
1934dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	while (cur != NULL) {
1935652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard	    if (((cur->type == XML_CATA_DELEGATE_SYSTEM) ||
1936652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard	         (cur->type == XML_CATA_DELEGATE_URI)) &&
1937dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		(!xmlStrncmp(URI, cur->name, xmlStrlen(cur->name)))) {
19386990bf3c080529493a865a851b753a27d58014eaDaniel Veillard		for (i = 0;i < nbList;i++)
1939c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard		    if (xmlStrEqual(cur->URL, delegates[i]))
19406990bf3c080529493a865a851b753a27d58014eaDaniel Veillard			break;
19416990bf3c080529493a865a851b753a27d58014eaDaniel Veillard		if (i < nbList) {
19426990bf3c080529493a865a851b753a27d58014eaDaniel Veillard		    cur = cur->next;
19436990bf3c080529493a865a851b753a27d58014eaDaniel Veillard		    continue;
19446990bf3c080529493a865a851b753a27d58014eaDaniel Veillard		}
19456990bf3c080529493a865a851b753a27d58014eaDaniel Veillard		if (nbList < MAX_DELEGATE)
1946c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard		    delegates[nbList++] = cur->URL;
19476990bf3c080529493a865a851b753a27d58014eaDaniel Veillard
1948dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		if (cur->children == NULL) {
1949dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		    xmlFetchXMLCatalogFile(cur);
1950dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		}
1951dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		if (cur->children != NULL) {
1952dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		    if (xmlDebugCatalogs)
1953dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard			xmlGenericError(xmlGenericErrorContext,
1954c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard				"Trying URI delegate %s\n", cur->URL);
195585c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard		    ret = xmlCatalogListXMLResolveURI(
195685c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard			    cur->children, URI);
1957dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		    if (ret != NULL)
1958dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard			return(ret);
1959dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		}
1960dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	    }
1961dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	    cur = cur->next;
1962dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	}
1963dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	/*
1964dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	 * Apply the cut algorithm explained in 4/
1965dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	 */
1966dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	return(XML_CATAL_BREAK);
1967dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    }
1968dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    if (haveNext) {
1969dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	cur = catal;
1970dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	while (cur != NULL) {
1971dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	    if (cur->type == XML_CATA_NEXT_CATALOG) {
1972dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		if (cur->children == NULL) {
1973dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		    xmlFetchXMLCatalogFile(cur);
1974dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		}
1975dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		if (cur->children != NULL) {
1976dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		    ret = xmlCatalogListXMLResolveURI(cur->children, URI);
1977dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		    if (ret != NULL)
1978dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard			return(ret);
1979dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		}
1980dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	    }
1981dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	    cur = cur->next;
1982dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	}
1983dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    }
1984dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard
1985dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    return(NULL);
1986dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard}
1987dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard
1988dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard/**
1989cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * xmlCatalogListXMLResolve:
1990cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * @catal:  a catalog list
199106d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * @pubID:  the public ID string
199206d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * @sysID:  the system ID string
1993cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *
1994cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Do a complete resolution lookup of an External Identifier for a
1995cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * list of catalogs
1996cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *
1997cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Implements (or tries to) 7.1. External Identifier Resolution
1998cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
1999cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *
2000cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Returns the URI of the resource or NULL if not found
2001cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard */
2002cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillardstatic xmlChar *
2003cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
2004cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	              const xmlChar *sysID) {
2005cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    xmlChar *ret = NULL;
2006e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    xmlChar *urnID = NULL;
2007c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    xmlChar *normid;
2008f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
2009e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    if (catal == NULL)
2010e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard        return(NULL);
2011e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    if ((pubID == NULL) && (sysID == NULL))
2012e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	return(NULL);
2013e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
2014c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    normid = xmlCatalogNormalizePublic(pubID);
2015c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    if (normid != NULL)
2016c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard        pubID = (*normid != 0 ? normid : NULL);
2017f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
2018e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    if (!xmlStrncmp(pubID, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
2019e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	urnID = xmlCatalogUnWrapURN(pubID);
2020e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	if (xmlDebugCatalogs) {
2021e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    if (urnID == NULL)
2022e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		xmlGenericError(xmlGenericErrorContext,
2023e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			"Public URN ID %s expanded to NULL\n", pubID);
2024e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    else
2025e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		xmlGenericError(xmlGenericErrorContext,
2026e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			"Public URN ID expanded to %s\n", urnID);
2027e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	}
2028e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	ret = xmlCatalogListXMLResolve(catal, urnID, sysID);
2029e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	if (urnID != NULL)
2030e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    xmlFree(urnID);
2031c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard	if (normid != NULL)
2032c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard	    xmlFree(normid);
2033e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	return(ret);
2034cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    }
2035e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    if (!xmlStrncmp(sysID, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
2036e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	urnID = xmlCatalogUnWrapURN(sysID);
2037e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	if (xmlDebugCatalogs) {
2038e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    if (urnID == NULL)
2039e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		xmlGenericError(xmlGenericErrorContext,
2040e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			"System URN ID %s expanded to NULL\n", sysID);
2041e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    else
2042e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		xmlGenericError(xmlGenericErrorContext,
2043e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard			"System URN ID expanded to %s\n", urnID);
2044e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	}
2045e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	if (pubID == NULL)
2046e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    ret = xmlCatalogListXMLResolve(catal, urnID, NULL);
2047e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	else if (xmlStrEqual(pubID, urnID))
2048e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    ret = xmlCatalogListXMLResolve(catal, pubID, NULL);
2049e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	else {
2050770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard	    ret = xmlCatalogListXMLResolve(catal, pubID, urnID);
2051e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	}
2052e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	if (urnID != NULL)
2053e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    xmlFree(urnID);
2054c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard	if (normid != NULL)
2055c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard	    xmlFree(normid);
2056e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	return(ret);
2057cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    }
2058cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    while (catal != NULL) {
2059cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	if (catal->type == XML_CATA_CATALOG) {
2060cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    if (catal->children == NULL) {
2061e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		xmlFetchXMLCatalogFile(catal);
2062e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    }
2063e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	    if (catal->children != NULL) {
2064e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		ret = xmlCatalogXMLResolve(catal->children, pubID, sysID);
2065c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard		if (ret != NULL) {
2066be8d9d33eb9d8fc39ebc8c03ee9bbc790a812b59Daniel Veillard		    break;
2067be8d9d33eb9d8fc39ebc8c03ee9bbc790a812b59Daniel Veillard                } else if ((catal->children != NULL) &&
2068be8d9d33eb9d8fc39ebc8c03ee9bbc790a812b59Daniel Veillard		           (catal->children->depth > MAX_CATAL_DEPTH)) {
2069be8d9d33eb9d8fc39ebc8c03ee9bbc790a812b59Daniel Veillard	            ret = NULL;
2070be8d9d33eb9d8fc39ebc8c03ee9bbc790a812b59Daniel Veillard		    break;
2071be8d9d33eb9d8fc39ebc8c03ee9bbc790a812b59Daniel Veillard	        }
2072cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    }
2073cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	}
2074cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	catal = catal->next;
2075cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    }
2076be8d9d33eb9d8fc39ebc8c03ee9bbc790a812b59Daniel Veillard    if (normid != NULL)
2077be8d9d33eb9d8fc39ebc8c03ee9bbc790a812b59Daniel Veillard	xmlFree(normid);
2078cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    return(ret);
2079344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard}
2080344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
2081dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard/**
2082dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * xmlCatalogListXMLResolveURI:
2083dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * @catal:  a catalog list
2084dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * @URI:  the URI
2085dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard *
2086dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * Do a complete resolution lookup of an URI for a list of catalogs
2087dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard *
2088dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * Implements (or tries to) 7.2. URI Resolution
2089dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
2090dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard *
2091dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * Returns the URI of the resource or NULL if not found
2092dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard */
2093dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillardstatic xmlChar *
2094dc2cee29d094958139f409e30209f68953c9cb67Daniel VeillardxmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) {
2095dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    xmlChar *ret = NULL;
2096dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    xmlChar *urnID = NULL;
2097f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
2098dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    if (catal == NULL)
2099dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard        return(NULL);
2100dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    if (URI == NULL)
2101dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	return(NULL);
2102dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard
2103dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    if (!xmlStrncmp(URI, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
2104dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	urnID = xmlCatalogUnWrapURN(URI);
2105dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	if (xmlDebugCatalogs) {
2106dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	    if (urnID == NULL)
2107dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		xmlGenericError(xmlGenericErrorContext,
2108dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard			"URN ID %s expanded to NULL\n", URI);
2109dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	    else
2110dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		xmlGenericError(xmlGenericErrorContext,
2111dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard			"URN ID expanded to %s\n", urnID);
2112dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	}
2113dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	ret = xmlCatalogListXMLResolve(catal, urnID, NULL);
2114dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	if (urnID != NULL)
2115dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	    xmlFree(urnID);
2116dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	return(ret);
2117dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    }
2118dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    while (catal != NULL) {
2119dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	if (catal->type == XML_CATA_CATALOG) {
2120dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	    if (catal->children == NULL) {
2121dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		xmlFetchXMLCatalogFile(catal);
2122dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	    }
2123dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	    if (catal->children != NULL) {
2124dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		ret = xmlCatalogXMLResolveURI(catal->children, URI);
2125dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		if (ret != NULL)
2126dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard		    return(ret);
2127dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	    }
2128dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	}
2129dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	catal = catal->next;
2130dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    }
2131dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    return(ret);
2132dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard}
2133dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard
2134344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard/************************************************************************
2135344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard *									*
2136344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard *			The SGML Catalog parser				*
2137a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard *									*
2138a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard ************************************************************************/
2139a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
2140a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
2141a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#define RAW *cur
2142a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#define NEXT cur++;
2143a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#define SKIP(x) cur += x;
2144a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
2145272693c7e127a43dbcd5bc39c1cec4bfcdabcd2aWilliam M. Brack#define SKIP_BLANKS while (IS_BLANK_CH(*cur)) NEXT;
2146a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
214775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
214875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlParseSGMLCatalogComment:
214975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @cur:  the current character
215075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
215175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Skip a comment in an SGML catalog
215275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
215375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Returns new current character
215475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
2155a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillardstatic const xmlChar *
2156cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlParseSGMLCatalogComment(const xmlChar *cur) {
2157f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    if ((cur[0] != '-') || (cur[1] != '-'))
2158a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	return(cur);
2159a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    SKIP(2);
2160a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    while ((cur[0] != 0) && ((cur[0] != '-') || ((cur[1] != '-'))))
2161a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	NEXT;
2162a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    if (cur[0] == 0) {
2163a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	return(NULL);
2164a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    }
2165af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard    return(cur + 2);
2166a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard}
2167a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
216875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
216975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlParseSGMLCatalogPubid:
217075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @cur:  the current character
217175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @id:  the return location
217275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
217375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Parse an SGML catalog ID
217475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
217575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Returns new current character and store the value in @id
217675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
2177a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillardstatic const xmlChar *
2178cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlParseSGMLCatalogPubid(const xmlChar *cur, xmlChar **id) {
217969d2c171fa5105364168d663467f6834c8216155Daniel Veillard    xmlChar *buf = NULL, *tmp;
2180a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    int len = 0;
2181a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    int size = 50;
2182a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    xmlChar stop;
2183a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    int count = 0;
2184a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
2185a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    *id = NULL;
2186a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
2187a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    if (RAW == '"') {
2188a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard        NEXT;
2189a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	stop = '"';
2190a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    } else if (RAW == '\'') {
2191a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard        NEXT;
2192a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	stop = '\'';
2193a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    } else {
2194a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	stop = ' ';
2195a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    }
21963c908dca479ed50dca24b8593bca90e40dbde6b8Daniel Veillard    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
2197a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    if (buf == NULL) {
219869d2c171fa5105364168d663467f6834c8216155Daniel Veillard        xmlCatalogErrMemory("allocating public ID");
2199a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	return(NULL);
2200a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    }
220176e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack    while (IS_PUBIDCHAR_CH(*cur) || (*cur == '?')) {
2202a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	if ((*cur == stop) && (stop != ' '))
2203a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    break;
220476e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	if ((stop == ' ') && (IS_BLANK_CH(*cur)))
2205a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    break;
2206a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	if (len + 1 >= size) {
2207a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    size *= 2;
220869d2c171fa5105364168d663467f6834c8216155Daniel Veillard	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
220969d2c171fa5105364168d663467f6834c8216155Daniel Veillard	    if (tmp == NULL) {
221069d2c171fa5105364168d663467f6834c8216155Daniel Veillard		xmlCatalogErrMemory("allocating public ID");
221169d2c171fa5105364168d663467f6834c8216155Daniel Veillard		xmlFree(buf);
2212a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		return(NULL);
2213a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    }
221469d2c171fa5105364168d663467f6834c8216155Daniel Veillard	    buf = tmp;
2215a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	}
2216a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	buf[len++] = *cur;
2217a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	count++;
2218a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	NEXT;
2219a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    }
2220a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    buf[len] = 0;
2221a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    if (stop == ' ') {
222276e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	if (!IS_BLANK_CH(*cur)) {
2223a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    xmlFree(buf);
2224a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    return(NULL);
2225a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	}
2226a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    } else {
2227a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	if (*cur != stop) {
2228a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    xmlFree(buf);
2229a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    return(NULL);
2230a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	}
2231a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	NEXT;
2232a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    }
2233a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    *id = buf;
2234a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    return(cur);
2235a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard}
2236a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
223775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
223875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlParseSGMLCatalogName:
223975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @cur:  the current character
224075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @name:  the return location
224175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
224275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Parse an SGML catalog name
224375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
224475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Returns new current character and store the value in @name
224575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
2246a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillardstatic const xmlChar *
2247cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlParseSGMLCatalogName(const xmlChar *cur, xmlChar **name) {
2248a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    xmlChar buf[XML_MAX_NAMELEN + 5];
2249a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    int len = 0;
2250a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    int c;
2251a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
2252a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    *name = NULL;
2253a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
2254a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    /*
2255a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard     * Handler for more complex cases
2256a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard     */
2257a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    c = *cur;
2258a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    if ((!IS_LETTER(c) && (c != '_') && (c != ':'))) {
2259a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	return(NULL);
2260a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    }
2261a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
2262a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    while (((IS_LETTER(c)) || (IS_DIGIT(c)) ||
2263a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard            (c == '.') || (c == '-') ||
2264a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    (c == '_') || (c == ':'))) {
2265a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	buf[len++] = c;
2266a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	cur++;
2267a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	c = *cur;
2268a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	if (len >= XML_MAX_NAMELEN)
2269a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    return(NULL);
2270a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    }
2271a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    *name = xmlStrndup(buf, len);
2272a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    return(cur);
2273a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard}
2274a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
227575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
227675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlGetSGMLCatalogEntryType:
227775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @name:  the entry name
227875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
227975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Get the Catalog entry type for a given SGML Catalog name
228075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
228175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Returns Catalog entry type
228275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
2283344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillardstatic xmlCatalogEntryType
2284cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlGetSGMLCatalogEntryType(const xmlChar *name) {
2285344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    xmlCatalogEntryType type = XML_CATA_NONE;
2286344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if (xmlStrEqual(name, (const xmlChar *) "SYSTEM"))
2287344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = SGML_CATA_SYSTEM;
2288344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else if (xmlStrEqual(name, (const xmlChar *) "PUBLIC"))
2289344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = SGML_CATA_PUBLIC;
2290344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE"))
2291344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = SGML_CATA_DELEGATE;
2292344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else if (xmlStrEqual(name, (const xmlChar *) "ENTITY"))
2293344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = SGML_CATA_ENTITY;
2294344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else if (xmlStrEqual(name, (const xmlChar *) "DOCTYPE"))
2295344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = SGML_CATA_DOCTYPE;
2296344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else if (xmlStrEqual(name, (const xmlChar *) "LINKTYPE"))
2297344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = SGML_CATA_LINKTYPE;
2298344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else if (xmlStrEqual(name, (const xmlChar *) "NOTATION"))
2299344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = SGML_CATA_NOTATION;
2300344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else if (xmlStrEqual(name, (const xmlChar *) "SGMLDECL"))
2301344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = SGML_CATA_SGMLDECL;
2302344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else if (xmlStrEqual(name, (const xmlChar *) "DOCUMENT"))
2303344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = SGML_CATA_DOCUMENT;
2304344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else if (xmlStrEqual(name, (const xmlChar *) "CATALOG"))
2305344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = SGML_CATA_CATALOG;
2306344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else if (xmlStrEqual(name, (const xmlChar *) "BASE"))
2307344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	type = SGML_CATA_BASE;
2308344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    return(type);
2309344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard}
2310344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
231175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
231275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlParseSGMLCatalog:
231375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @catal:  the SGML Catalog
231475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @value:  the content of the SGML Catalog serialization
231575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @file:  the filepath for the catalog
231675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @super:  should this be handled as a Super Catalog in which case
231775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *          parsing is not recursive
231875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
231975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Parse an SGML catalog content and fill up the @catal hash table with
232075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * the new entries found.
232175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
232275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Returns 0 in case of success, -1 in case of error.
232375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
2324a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillardstatic int
232575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlParseSGMLCatalog(xmlCatalogPtr catal, const xmlChar *value,
232675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	            const char *file, int super) {
2327a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    const xmlChar *cur = value;
2328a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    xmlChar *base = NULL;
2329af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard    int res;
2330a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
2331a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    if ((cur == NULL) || (file == NULL))
2332a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard        return(-1);
2333a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    base = xmlStrdup((const xmlChar *) file);
2334a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
2335bc2ddbe7c3cc496c843667b157a68d4fee4def90Daniel Veillard    while ((cur != NULL) && (cur[0] != 0)) {
2336a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	SKIP_BLANKS;
2337bc2ddbe7c3cc496c843667b157a68d4fee4def90Daniel Veillard	if (cur[0] == 0)
2338bc2ddbe7c3cc496c843667b157a68d4fee4def90Daniel Veillard	    break;
2339a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	if ((cur[0] == '-') && (cur[1] == '-')) {
2340cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    cur = xmlParseSGMLCatalogComment(cur);
2341a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    if (cur == NULL) {
2342a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		/* error */
2343a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		break;
2344a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    }
2345a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	} else {
2346a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    xmlChar *sysid = NULL;
2347a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    xmlChar *name = NULL;
2348a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    xmlCatalogEntryType type = XML_CATA_NONE;
2349a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
2350cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    cur = xmlParseSGMLCatalogName(cur, &name);
2351a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    if (name == NULL) {
2352a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		/* error */
2353a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		break;
2354a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    }
235576e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	    if (!IS_BLANK_CH(*cur)) {
2356a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		/* error */
2357a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		break;
2358a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    }
2359a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    SKIP_BLANKS;
2360a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    if (xmlStrEqual(name, (const xmlChar *) "SYSTEM"))
2361344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard                type = SGML_CATA_SYSTEM;
2362a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    else if (xmlStrEqual(name, (const xmlChar *) "PUBLIC"))
2363344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard                type = SGML_CATA_PUBLIC;
2364a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE"))
2365344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard                type = SGML_CATA_DELEGATE;
2366a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    else if (xmlStrEqual(name, (const xmlChar *) "ENTITY"))
2367344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard                type = SGML_CATA_ENTITY;
2368a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    else if (xmlStrEqual(name, (const xmlChar *) "DOCTYPE"))
2369344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard                type = SGML_CATA_DOCTYPE;
2370a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    else if (xmlStrEqual(name, (const xmlChar *) "LINKTYPE"))
2371344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard                type = SGML_CATA_LINKTYPE;
2372a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    else if (xmlStrEqual(name, (const xmlChar *) "NOTATION"))
2373344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard                type = SGML_CATA_NOTATION;
2374a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    else if (xmlStrEqual(name, (const xmlChar *) "SGMLDECL"))
2375344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard                type = SGML_CATA_SGMLDECL;
2376a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    else if (xmlStrEqual(name, (const xmlChar *) "DOCUMENT"))
2377344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard                type = SGML_CATA_DOCUMENT;
2378a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    else if (xmlStrEqual(name, (const xmlChar *) "CATALOG"))
2379344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard                type = SGML_CATA_CATALOG;
2380a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    else if (xmlStrEqual(name, (const xmlChar *) "BASE"))
2381344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard                type = SGML_CATA_BASE;
2382a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    else if (xmlStrEqual(name, (const xmlChar *) "OVERRIDE")) {
2383a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		xmlFree(name);
2384cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		cur = xmlParseSGMLCatalogName(cur, &name);
2385a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		if (name == NULL) {
2386a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    /* error */
2387a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    break;
2388a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		}
2389af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard		xmlFree(name);
2390a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		continue;
2391a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    }
2392a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    xmlFree(name);
2393af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard	    name = NULL;
2394a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
2395a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    switch(type) {
2396344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		case SGML_CATA_ENTITY:
2397a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    if (*cur == '%')
2398344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard			type = SGML_CATA_PENTITY;
2399344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		case SGML_CATA_PENTITY:
2400344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		case SGML_CATA_DOCTYPE:
2401344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		case SGML_CATA_LINKTYPE:
2402344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		case SGML_CATA_NOTATION:
2403cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    cur = xmlParseSGMLCatalogName(cur, &name);
2404a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    if (cur == NULL) {
2405a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard			/* error */
2406a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard			break;
2407a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    }
240876e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack		    if (!IS_BLANK_CH(*cur)) {
2409a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard			/* error */
2410a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard			break;
2411a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    }
2412a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    SKIP_BLANKS;
2413cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    cur = xmlParseSGMLCatalogPubid(cur, &sysid);
2414a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    if (cur == NULL) {
2415a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard			/* error */
2416a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard			break;
2417a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    }
2418a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    break;
2419344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		case SGML_CATA_PUBLIC:
2420344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		case SGML_CATA_SYSTEM:
2421344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		case SGML_CATA_DELEGATE:
2422cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    cur = xmlParseSGMLCatalogPubid(cur, &name);
2423a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    if (cur == NULL) {
2424a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard			/* error */
2425a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard			break;
2426a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    }
2427c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard		    if (type != SGML_CATA_SYSTEM) {
2428c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard		        xmlChar *normid;
2429c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard
2430c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard		        normid = xmlCatalogNormalizePublic(name);
2431c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard		        if (normid != NULL) {
2432c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard		            if (name != NULL)
2433c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard		                xmlFree(name);
2434c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard		            if (*normid != 0)
2435c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard		                name = normid;
2436c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard		            else {
2437c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard		                xmlFree(normid);
2438c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard		                name = NULL;
2439c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard		            }
2440c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard		        }
2441c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard		    }
244276e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack		    if (!IS_BLANK_CH(*cur)) {
2443a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard			/* error */
2444a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard			break;
2445a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    }
2446a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    SKIP_BLANKS;
2447cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    cur = xmlParseSGMLCatalogPubid(cur, &sysid);
2448a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    if (cur == NULL) {
2449a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard			/* error */
2450a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard			break;
2451a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    }
2452a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    break;
2453344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		case SGML_CATA_BASE:
2454344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		case SGML_CATA_CATALOG:
2455344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		case SGML_CATA_DOCUMENT:
2456344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		case SGML_CATA_SGMLDECL:
2457cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		    cur = xmlParseSGMLCatalogPubid(cur, &sysid);
2458a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    if (cur == NULL) {
2459a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard			/* error */
2460a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard			break;
2461a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    }
2462a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    break;
2463a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		default:
2464a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    break;
2465a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    }
2466a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    if (cur == NULL) {
2467a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		if (name != NULL)
2468a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    xmlFree(name);
2469a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		if (sysid != NULL)
2470a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    xmlFree(sysid);
2471a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		break;
2472344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    } else if (type == SGML_CATA_BASE) {
2473a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		if (base != NULL)
2474a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		    xmlFree(base);
2475af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard		base = xmlStrdup(sysid);
2476344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    } else if ((type == SGML_CATA_PUBLIC) ||
2477344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard		       (type == SGML_CATA_SYSTEM)) {
2478a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		xmlChar *filename;
2479a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
2480a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		filename = xmlBuildURI(sysid, base);
2481a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		if (filename != NULL) {
2482af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard		    xmlCatalogEntryPtr entry;
2483a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
2484e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		    entry = xmlNewCatalogEntry(type, name, filename,
2485b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack			                       NULL, XML_CATA_PREFER_NONE, NULL);
248675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard		    res = xmlHashAddEntry(catal->sgml, name, entry);
2487af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard		    if (res < 0) {
2488af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard			xmlFreeCatalogEntry(entry);
2489af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard		    }
2490af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard		    xmlFree(filename);
2491af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard		}
2492af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard
2493344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	    } else if (type == SGML_CATA_CATALOG) {
249482d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard		if (super) {
249582d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard		    xmlCatalogEntryPtr entry;
2496af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard
2497c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard		    entry = xmlNewCatalogEntry(type, sysid, NULL, NULL,
2498b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack			                       XML_CATA_PREFER_NONE, NULL);
249975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard		    res = xmlHashAddEntry(catal->sgml, sysid, entry);
250082d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard		    if (res < 0) {
250182d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard			xmlFreeCatalogEntry(entry);
250282d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard		    }
250382d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard		} else {
250482d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard		    xmlChar *filename;
250582d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard
250682d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard		    filename = xmlBuildURI(sysid, base);
250782d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard		    if (filename != NULL) {
250875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard			xmlExpandCatalog(catal, (const char *)filename);
250982d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard			xmlFree(filename);
251082d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard		    }
2511a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard		}
2512a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	    }
2513af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard	    /*
2514af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard	     * drop anything else we won't handle it
2515af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard	     */
2516af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard	    if (name != NULL)
2517af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard		xmlFree(name);
2518af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard	    if (sysid != NULL)
2519af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard		xmlFree(sysid);
2520a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	}
2521a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    }
2522a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    if (base != NULL)
2523a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	xmlFree(base);
2524a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    if (cur == NULL)
2525a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	return(-1);
2526a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    return(0);
2527a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard}
2528a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
252975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/************************************************************************
253075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
253175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *			SGML Catalog handling				*
253275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
253375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard ************************************************************************/
253475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
2535cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard/**
2536cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * xmlCatalogGetSGMLPublic:
2537cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * @catal:  an SGML catalog hash
253806d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * @pubID:  the public ID string
2539cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *
254006d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * Try to lookup the catalog local reference associated to a public ID
2541cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *
254206d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * Returns the local resource if found or NULL otherwise.
2543cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard */
2544cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillardstatic const xmlChar *
2545cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlCatalogGetSGMLPublic(xmlHashTablePtr catal, const xmlChar *pubID) {
2546cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    xmlCatalogEntryPtr entry;
2547c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    xmlChar *normid;
2548cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
2549cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    if (catal == NULL)
2550cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	return(NULL);
2551cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
2552c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    normid = xmlCatalogNormalizePublic(pubID);
2553c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    if (normid != NULL)
2554c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard        pubID = (*normid != 0 ? normid : NULL);
2555c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard
2556cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    entry = (xmlCatalogEntryPtr) xmlHashLookup(catal, pubID);
2557c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    if (entry == NULL) {
2558c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard	if (normid != NULL)
2559c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard	    xmlFree(normid);
2560cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	return(NULL);
2561c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    }
2562c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    if (entry->type == SGML_CATA_PUBLIC) {
2563c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard	if (normid != NULL)
2564c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard	    xmlFree(normid);
2565c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard	return(entry->URL);
2566c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    }
2567c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard    if (normid != NULL)
2568c815505f7d7a09a834d33aa6fefe10b48be2bfc9Daniel Veillard        xmlFree(normid);
2569cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    return(NULL);
2570cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard}
2571cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
2572cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard/**
2573e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard * xmlCatalogGetSGMLSystem:
2574e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard * @catal:  an SGML catalog hash
257506d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * @sysID:  the system ID string
2576e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard *
2577e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard * Try to lookup the catalog local reference for a system ID
2578e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard *
2579770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard * Returns the local resource if found or NULL otherwise.
2580e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard */
2581e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillardstatic const xmlChar *
2582e2940ddb351e0aa2055ec6b74c245685196d532bDaniel VeillardxmlCatalogGetSGMLSystem(xmlHashTablePtr catal, const xmlChar *sysID) {
2583e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    xmlCatalogEntryPtr entry;
2584e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
2585e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    if (catal == NULL)
2586e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	return(NULL);
2587e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
2588e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    entry = (xmlCatalogEntryPtr) xmlHashLookup(catal, sysID);
2589e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    if (entry == NULL)
2590e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	return(NULL);
2591e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    if (entry->type == SGML_CATA_SYSTEM)
2592c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard	return(entry->URL);
2593e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    return(NULL);
2594e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard}
2595e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
2596e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard/**
2597cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * xmlCatalogSGMLResolve:
259875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @catal:  the SGML catalog
259906d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * @pubID:  the public ID string
260006d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * @sysID:  the system ID string
2601cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *
2602cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Do a complete resolution lookup of an External Identifier
2603cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *
2604cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Returns the URI of the resource or NULL if not found
2605cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard */
2606cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillardstatic const xmlChar *
260775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlCatalogSGMLResolve(xmlCatalogPtr catal, const xmlChar *pubID,
260875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	              const xmlChar *sysID) {
26095d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    const xmlChar *ret = NULL;
26105d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard
261175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (catal->sgml == NULL)
26125d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	return(NULL);
26135d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard
26145d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    if (pubID != NULL)
261575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	ret = xmlCatalogGetSGMLPublic(catal->sgml, pubID);
26165d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    if (ret != NULL)
26175d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	return(ret);
26185d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    if (sysID != NULL)
261975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	ret = xmlCatalogGetSGMLSystem(catal->sgml, sysID);
262063806b5373806c8a0dd9c43bce066a414815b293Daniel Veillard    if (ret != NULL)
262163806b5373806c8a0dd9c43bce066a414815b293Daniel Veillard	return(ret);
2622cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    return(NULL);
2623cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard}
2624cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
2625a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard/************************************************************************
2626a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard *									*
262775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *			Specific Public interfaces			*
2628a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard *									*
2629a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard ************************************************************************/
2630a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
26315e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/**
263275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlLoadSGMLSuperCatalog:
263375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @filename:  a file path
2634e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard *
263575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Load an SGML super catalog. It won't expand CATALOG or DELEGATE
263675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * references. This is only needed for manipulating SGML Super Catalogs
263775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * like adding and removing CATALOG or DELEGATE entries.
263875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
263975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Returns the catalog parsed or NULL in case of error
2640e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard */
264175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlCatalogPtr
264275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlLoadSGMLSuperCatalog(const char *filename)
264375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard{
264475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlChar *content;
264575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlCatalogPtr catal;
264675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    int ret;
2647e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
264875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    content = xmlLoadFileContent(filename);
264975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (content == NULL)
265075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        return(NULL);
2651e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
2652cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard    catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
265375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (catal == NULL) {
265475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlFree(content);
265575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	return(NULL);
2656e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    }
2657e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
265875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    ret = xmlParseSGMLCatalog(catal, content, filename, 1);
265975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlFree(content);
266075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (ret < 0) {
266175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlFreeCatalog(catal);
266275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	return(NULL);
266375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    }
266475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    return (catal);
2665e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard}
2666e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
2667e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard/**
266875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlLoadACatalog:
266982d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard * @filename:  a file path
267082d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard *
267175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Load the catalog and build the associated data structures.
267275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * This can be either an XML Catalog or an SGML Catalog
267375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * It will recurse in SGML CATALOG entries. On the other hand XML
267475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Catalogs are not handled recursively.
267582d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard *
267675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Returns the catalog parsed or NULL in case of error
267782d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard */
267875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlCatalogPtr
267975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlLoadACatalog(const char *filename)
268082d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard{
268182d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard    xmlChar *content;
268275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlChar *first;
268375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlCatalogPtr catal;
268475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    int ret;
268582d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard
268675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    content = xmlLoadFileContent(filename);
268775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (content == NULL)
268875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        return(NULL);
268982d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard
269082d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard
269175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    first = content;
2692f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
269375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    while ((*first != 0) && (*first != '-') && (*first != '<') &&
269475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	   (!(((*first >= 'A') && (*first <= 'Z')) ||
269575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	      ((*first >= 'a') && (*first <= 'z')))))
269675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	first++;
269782d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard
269875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (*first != '<') {
2699cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
270075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	if (catal == NULL) {
270175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    xmlFree(content);
270275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    return(NULL);
270375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	}
270475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        ret = xmlParseSGMLCatalog(catal, content, filename, 0);
270575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	if (ret < 0) {
270675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    xmlFreeCatalog(catal);
270775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    xmlFree(content);
270875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    return(NULL);
270975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	}
271075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    } else {
2711cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
271275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	if (catal == NULL) {
271375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    xmlFree(content);
271475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    return(NULL);
271575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	}
2716c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard        catal->xml = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
2717b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		       NULL, BAD_CAST filename, xmlCatalogDefaultPrefer, NULL);
271882d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard    }
271982d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard    xmlFree(content);
272075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    return (catal);
272182d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard}
272282d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard
272382d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard/**
272475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlExpandCatalog:
272575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @catal:  a catalog
2726a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard * @filename:  a file path
2727a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard *
272875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Load the catalog and expand the existing catal structure.
272975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * This can be either an XML Catalog or an SGML Catalog
2730a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard *
273175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Returns 0 in case of success, -1 in case of error
2732a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard */
273385c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillardstatic int
273475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlExpandCatalog(xmlCatalogPtr catal, const char *filename)
273516756b627bc32956dcecf43b2c1781b1d0657f8fDaniel Veillard{
273675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    int ret;
2737a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
273875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if ((catal == NULL) || (filename == NULL))
273975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	return(-1);
2740af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard
2741e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
274275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (catal->type == XML_SGML_CATALOG_TYPE) {
274385c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	xmlChar *content;
274485c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard
274585c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	content = xmlLoadFileContent(filename);
274685c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	if (content == NULL)
274785c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	    return(-1);
274885c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard
274975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        ret = xmlParseSGMLCatalog(catal, content, filename, 0);
275075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	if (ret < 0) {
275175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    xmlFree(content);
275275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    return(-1);
275375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	}
275485c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	xmlFree(content);
275575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    } else {
275675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlCatalogEntryPtr tmp, cur;
2757c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard	tmp = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
2758b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack		       NULL, BAD_CAST filename, xmlCatalogDefaultPrefer, NULL);
2759a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
276075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	cur = catal->xml;
276175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	if (cur == NULL) {
276275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    catal->xml = tmp;
276375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	} else {
276475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    while (cur->next != NULL) cur = cur->next;
276575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    cur->next = tmp;
276675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	}
276775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    }
276875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    return (0);
276975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard}
277075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
277175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
277275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlACatalogResolveSystem:
277375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @catal:  a Catalog
277406d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * @sysID:  the system ID string
277575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
277675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Try to lookup the catalog resource for a system ID
277775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
277806d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * Returns the resource if found or NULL otherwise, the value returned
277975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *      must be freed by the caller.
278075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
278175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlChar *
278275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlACatalogResolveSystem(xmlCatalogPtr catal, const xmlChar *sysID) {
278375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlChar *ret = NULL;
278475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
278575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if ((sysID == NULL) || (catal == NULL))
278675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	return(NULL);
2787f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
278875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (xmlDebugCatalogs)
278975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlGenericError(xmlGenericErrorContext,
279075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard		"Resolve sysID %s\n", sysID);
279175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
279275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (catal->type == XML_XML_CATALOG_TYPE) {
279375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	ret = xmlCatalogListXMLResolve(catal->xml, NULL, sysID);
279475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	if (ret == XML_CATAL_BREAK)
279575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    ret = NULL;
279675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    } else {
279775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	const xmlChar *sgml;
279875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
279975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	sgml = xmlCatalogGetSGMLSystem(catal->sgml, sysID);
280075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	if (sgml != NULL)
280175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    ret = xmlStrdup(sgml);
280275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    }
280375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    return(ret);
280475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard}
280575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
280675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
280775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlACatalogResolvePublic:
280875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @catal:  a Catalog
28095aad832aa34d21fca4696eb5a3bf203521f6a7f2Daniel Veillard * @pubID:  the public ID string
281075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
281106d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * Try to lookup the catalog local reference associated to a public ID in that catalog
281275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
281306d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * Returns the local resource if found or NULL otherwise, the value returned
281475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *      must be freed by the caller.
281575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
281675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlChar *
281775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlACatalogResolvePublic(xmlCatalogPtr catal, const xmlChar *pubID) {
281875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlChar *ret = NULL;
281975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
282075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if ((pubID == NULL) || (catal == NULL))
282175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	return(NULL);
2822f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
282375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (xmlDebugCatalogs)
282475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlGenericError(xmlGenericErrorContext,
282575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard		"Resolve pubID %s\n", pubID);
282675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
282775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (catal->type == XML_XML_CATALOG_TYPE) {
282875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	ret = xmlCatalogListXMLResolve(catal->xml, pubID, NULL);
282975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	if (ret == XML_CATAL_BREAK)
283075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    ret = NULL;
283175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    } else {
283275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	const xmlChar *sgml;
283375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
283475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	sgml = xmlCatalogGetSGMLPublic(catal->sgml, pubID);
283575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	if (sgml != NULL)
283675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    ret = xmlStrdup(sgml);
283775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    }
283875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    return(ret);
283975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard}
284075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
284175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
284275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlACatalogResolve:
284375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @catal:  a Catalog
28445aad832aa34d21fca4696eb5a3bf203521f6a7f2Daniel Veillard * @pubID:  the public ID string
28455aad832aa34d21fca4696eb5a3bf203521f6a7f2Daniel Veillard * @sysID:  the system ID string
284675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
284775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Do a complete resolution lookup of an External Identifier
284875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
284975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Returns the URI of the resource or NULL if not found, it must be freed
285075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *      by the caller.
285175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
285275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlChar *
285375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlACatalogResolve(xmlCatalogPtr catal, const xmlChar * pubID,
285475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard                   const xmlChar * sysID)
285575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard{
285675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlChar *ret = NULL;
285775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
285875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (((pubID == NULL) && (sysID == NULL)) || (catal == NULL))
285975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        return (NULL);
286075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
286175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (xmlDebugCatalogs) {
2862770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard         if ((pubID != NULL) && (sysID != NULL)) {
2863770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard             xmlGenericError(xmlGenericErrorContext,
2864770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard                             "Resolve: pubID %s sysID %s\n", pubID, sysID);
2865770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard         } else if (pubID != NULL) {
2866770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard             xmlGenericError(xmlGenericErrorContext,
2867770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard                             "Resolve: pubID %s\n", pubID);
2868770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard         } else {
2869770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard             xmlGenericError(xmlGenericErrorContext,
2870770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard                             "Resolve: sysID %s\n", sysID);
2871770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard         }
2872af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard    }
2873af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard
287475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (catal->type == XML_XML_CATALOG_TYPE) {
287575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        ret = xmlCatalogListXMLResolve(catal->xml, pubID, sysID);
287675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	if (ret == XML_CATAL_BREAK)
287775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    ret = NULL;
287875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    } else {
287975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        const xmlChar *sgml;
288075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
288175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        sgml = xmlCatalogSGMLResolve(catal, pubID, sysID);
288275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        if (sgml != NULL)
288375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard            ret = xmlStrdup(sgml);
2884af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard    }
288575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    return (ret);
288675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard}
288775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
288875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
288975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlACatalogResolveURI:
289075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @catal:  a Catalog
2891cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @URI:  the URI
289275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
289375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Do a complete resolution lookup of an URI
289475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
289575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Returns the URI of the resource or NULL if not found, it must be freed
289675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *      by the caller.
289775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
289875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlChar *
289975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlACatalogResolveURI(xmlCatalogPtr catal, const xmlChar *URI) {
290075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlChar *ret = NULL;
290175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
290275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if ((URI == NULL) || (catal == NULL))
290375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	return(NULL);
290475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
2905b44025c72b7472971a061b022cfe422adc42715dDaniel Veillard    if (xmlDebugCatalogs)
290675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlGenericError(xmlGenericErrorContext,
290775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard		"Resolve URI %s\n", URI);
290875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
290975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (catal->type == XML_XML_CATALOG_TYPE) {
291075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	ret = xmlCatalogListXMLResolveURI(catal->xml, URI);
291175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	if (ret == XML_CATAL_BREAK)
291275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    ret = NULL;
291375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    } else {
291475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	const xmlChar *sgml;
291575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
291675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	sgml = xmlCatalogSGMLResolve(catal, NULL, URI);
291775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	if (sgml != NULL)
291863806b5373806c8a0dd9c43bce066a414815b293Daniel Veillard            ret = xmlStrdup(sgml);
291916756b627bc32956dcecf43b2c1781b1d0657f8fDaniel Veillard    }
292075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    return(ret);
292175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard}
292275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
2923a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#ifdef LIBXML_OUTPUT_ENABLED
292475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
292575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlACatalogDump:
292675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @catal:  a Catalog
292775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @out:  the file.
292875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
2929a8dc2886f4578e04c03ab6a7cbf5bc52b0a72d02Daniel Veillard * Dump the given catalog to the given file.
293075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
293175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillardvoid
293275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlACatalogDump(xmlCatalogPtr catal, FILE *out) {
2933cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard    if ((out == NULL) || (catal == NULL))
293475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	return;
293575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
293675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (catal->type == XML_XML_CATALOG_TYPE) {
293775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlDumpXMLCatalog(out, catal->xml);
293875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    } else {
293975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlHashScan(catal->sgml,
294075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard		    (xmlHashScanner) xmlCatalogDumpEntry, out);
2941f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    }
294275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard}
2943a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#endif /* LIBXML_OUTPUT_ENABLED */
294475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
294575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
294675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlACatalogAdd:
294775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @catal:  a Catalog
294875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @type:  the type of record to add to the catalog
2949f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @orig:  the system, public or prefix to match
295075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @replace:  the replacement value for the match
295175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
295275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Add an entry in the catalog, it may overwrite existing but
295375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * different entries.
295475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
295575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Returns 0 if successful, -1 otherwise
295675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
295775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillardint
295875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlACatalogAdd(xmlCatalogPtr catal, const xmlChar * type,
295975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard              const xmlChar * orig, const xmlChar * replace)
296075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard{
296175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    int res = -1;
296275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
296375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (catal == NULL)
296475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	return(-1);
296575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
296675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (catal->type == XML_XML_CATALOG_TYPE) {
296775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        res = xmlAddXMLCatalog(catal->xml, type, orig, replace);
296875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    } else {
296975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        xmlCatalogEntryType cattype;
297075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
297175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        cattype = xmlGetSGMLCatalogEntryType(type);
297275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        if (cattype != XML_CATA_NONE) {
297375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard            xmlCatalogEntryPtr entry;
297475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
2975c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard            entry = xmlNewCatalogEntry(cattype, orig, replace, NULL,
2976b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack                                       XML_CATA_PREFER_NONE, NULL);
2977cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	    if (catal->sgml == NULL)
2978cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard		catal->sgml = xmlHashCreate(10);
297975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard            res = xmlHashAddEntry(catal->sgml, orig, entry);
298075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard        }
2981a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    }
298275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    return (res);
298375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard}
298475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
298575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
298675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlACatalogRemove:
298775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @catal:  a Catalog
298875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @value:  the value to remove
298975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
299075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Remove an entry from the catalog
299175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
299275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Returns the number of entries removed if successful, -1 otherwise
299375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
299475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillardint
299575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlACatalogRemove(xmlCatalogPtr catal, const xmlChar *value) {
299675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    int res = -1;
299775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
299875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if ((catal == NULL) || (value == NULL))
299975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	return(-1);
300075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
300175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (catal->type == XML_XML_CATALOG_TYPE) {
300275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	res = xmlDelXMLCatalog(catal->xml, value);
300375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    } else {
300475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	res = xmlHashRemoveEntry(catal->sgml, value,
300575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard		(xmlHashDeallocator) xmlFreeCatalogEntry);
300675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	if (res == 0)
300775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    res = 1;
3008f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    }
300975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    return(res);
301075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard}
301175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
3012cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard/**
3013cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard * xmlNewCatalog:
3014cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard * @sgml:  should this create an SGML catalog
3015cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard *
3016cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard * create a new Catalog.
3017cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard *
3018cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard * Returns the xmlCatalogPtr or NULL in case of error
3019cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard */
3020cd21dc784800832cf952061034e52ce9733a4b11Daniel VeillardxmlCatalogPtr
3021cd21dc784800832cf952061034e52ce9733a4b11Daniel VeillardxmlNewCatalog(int sgml) {
3022cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard    xmlCatalogPtr catal = NULL;
3023cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard
3024cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard    if (sgml) {
3025cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE,
3026cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard		                    xmlCatalogDefaultPrefer);
3027cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard        if ((catal != NULL) && (catal->sgml == NULL))
3028cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	    catal->sgml = xmlHashCreate(10);
3029cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard    } else
3030cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
3031cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard		                    xmlCatalogDefaultPrefer);
3032cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard    return(catal);
3033cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard}
3034cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard
3035cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard/**
3036cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard * xmlCatalogIsEmpty:
3037cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard * @catal:  should this create an SGML catalog
3038cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard *
3039cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard * Check is a catalog is empty
3040cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard *
3041cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard * Returns 1 if the catalog is empty, 0 if not, amd -1 in case of error.
3042cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard */
3043cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillardint
3044cd21dc784800832cf952061034e52ce9733a4b11Daniel VeillardxmlCatalogIsEmpty(xmlCatalogPtr catal) {
3045cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard    if (catal == NULL)
3046cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	return(-1);
3047cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard
3048cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard    if (catal->type == XML_XML_CATALOG_TYPE) {
3049cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	if (catal->xml == NULL)
3050cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	    return(1);
3051cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	if ((catal->xml->type != XML_CATA_CATALOG) &&
3052cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	    (catal->xml->type != XML_CATA_BROKEN_CATALOG))
3053cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	    return(-1);
3054cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	if (catal->xml->children == NULL)
3055cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	    return(1);
3056cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard        return(0);
3057cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard    } else {
3058cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	int res;
3059cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard
3060cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	if (catal->sgml == NULL)
3061cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	    return(1);
3062cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	res = xmlHashSize(catal->sgml);
3063cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	if (res == 0)
3064cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	    return(1);
3065cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	if (res < 0)
3066cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	    return(-1);
3067f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    }
3068cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard    return(0);
3069cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard}
3070cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard
307175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/************************************************************************
307275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
307375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *   Public interfaces manipulating the global shared default catalog	*
307475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
307575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard ************************************************************************/
307675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
307775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
30788146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * xmlInitializeCatalogData:
30798146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard *
30808146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * Do the catalog initialization only of global data, doesn't try to load
30818146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * any catalog actually.
30828146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * this function is not thread safe, catalog initialization should
30838146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * preferably be done once at startup
30848146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard */
30858146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillardstatic void
30868146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel VeillardxmlInitializeCatalogData(void) {
30878146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    if (xmlCatalogInitialized != 0)
30888146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard	return;
30898146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard
3090f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    if (getenv("XML_DEBUG_CATALOG"))
30918146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard	xmlDebugCatalogs = 1;
30928146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    xmlCatalogMutex = xmlNewRMutex();
30938146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard
30948146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    xmlCatalogInitialized = 1;
30958146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard}
30968146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard/**
309775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlInitializeCatalog:
309875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
309975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Do the catalog initialization.
31008146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * this function is not thread safe, catalog initialization should
31018146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * preferably be done once at startup
310275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
310375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillardvoid
310475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlInitializeCatalog(void) {
310575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (xmlCatalogInitialized != 0)
310675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	return;
310775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
31088146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    xmlInitializeCatalogData();
31098146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    xmlRMutexLock(xmlCatalogMutex);
31108146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard
3111f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    if (getenv("XML_DEBUG_CATALOG"))
311275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlDebugCatalogs = 1;
31138146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard
311475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (xmlDefaultCatalog == NULL) {
311575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	const char *catalogs;
3116124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic	char *path;
3117124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic	const char *cur, *paths;
311875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlCatalogPtr catal;
3119124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic	xmlCatalogEntryPtr *nextent;
312075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
3121b44025c72b7472971a061b022cfe422adc42715dDaniel Veillard	catalogs = (const char *) getenv("XML_CATALOG_FILES");
312275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	if (catalogs == NULL)
3123fb382b89905d02caae2e5161a33553b930255915Daniel Veillard#if defined(_WIN32) && defined(_MSC_VER)
3124fb382b89905d02caae2e5161a33553b930255915Daniel Veillard    {
3125fb382b89905d02caae2e5161a33553b930255915Daniel Veillard		void* hmodule;
3126fb382b89905d02caae2e5161a33553b930255915Daniel Veillard		hmodule = GetModuleHandleA("libxml2.dll");
3127fb382b89905d02caae2e5161a33553b930255915Daniel Veillard		if (hmodule == NULL)
3128fb382b89905d02caae2e5161a33553b930255915Daniel Veillard			hmodule = GetModuleHandleA(NULL);
3129fb382b89905d02caae2e5161a33553b930255915Daniel Veillard		if (hmodule != NULL) {
3130fb382b89905d02caae2e5161a33553b930255915Daniel Veillard			char buf[256];
3131fb382b89905d02caae2e5161a33553b930255915Daniel Veillard			unsigned long len = GetModuleFileNameA(hmodule, buf, 255);
3132fb382b89905d02caae2e5161a33553b930255915Daniel Veillard			if (len != 0) {
3133fb382b89905d02caae2e5161a33553b930255915Daniel Veillard				char* p = &(buf[len]);
3134f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard				while (*p != '\\' && p > buf)
3135fb382b89905d02caae2e5161a33553b930255915Daniel Veillard					p--;
3136fb382b89905d02caae2e5161a33553b930255915Daniel Veillard				if (p != buf) {
3137fb382b89905d02caae2e5161a33553b930255915Daniel Veillard					xmlChar* uri;
3138fb382b89905d02caae2e5161a33553b930255915Daniel Veillard					strncpy(p, "\\..\\etc\\catalog", 255 - (p - buf));
3139e1631e1cfcdf4bd7e7ec4999ec5aae9675390797Denis Pauk					uri = xmlCanonicPath((const xmlChar*)buf);
3140fb382b89905d02caae2e5161a33553b930255915Daniel Veillard					if (uri != NULL) {
3141fb382b89905d02caae2e5161a33553b930255915Daniel Veillard						strncpy(XML_XML_DEFAULT_CATALOG, uri, 255);
3142fb382b89905d02caae2e5161a33553b930255915Daniel Veillard						xmlFree(uri);
3143fb382b89905d02caae2e5161a33553b930255915Daniel Veillard					}
3144fb382b89905d02caae2e5161a33553b930255915Daniel Veillard				}
3145fb382b89905d02caae2e5161a33553b930255915Daniel Veillard			}
3146fb382b89905d02caae2e5161a33553b930255915Daniel Veillard		}
3147fb382b89905d02caae2e5161a33553b930255915Daniel Veillard		catalogs = XML_XML_DEFAULT_CATALOG;
3148fb382b89905d02caae2e5161a33553b930255915Daniel Veillard    }
3149fb382b89905d02caae2e5161a33553b930255915Daniel Veillard#else
315075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    catalogs = XML_XML_DEFAULT_CATALOG;
3151fb382b89905d02caae2e5161a33553b930255915Daniel Veillard#endif
315275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
3153f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
3154124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic		xmlCatalogDefaultPrefer);
315585c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	if (catal != NULL) {
3156f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	    /* the XML_CATALOG_FILES envvar is allowed to contain a
3157124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic	       space-separated list of entries. */
3158124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic	    cur = catalogs;
3159124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic	    nextent = &catal->xml;
3160124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic	    while (*cur != '\0') {
3161f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard		while (xmlIsBlank_ch(*cur))
3162124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic		    cur++;
3163124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic		if (*cur != 0) {
3164124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic		    paths = cur;
316568aca051a61608e6cbbd2d36263e4470008e64f5William M. Brack		    while ((*cur != 0) && (!xmlIsBlank_ch(*cur)))
3166124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic			cur++;
3167e645e8c1414b53d96b6cca3c7691005b75b2e647Daniel Veillard		    path = (char *) xmlStrndup((const xmlChar *)paths, cur - paths);
3168124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic		    if (path != NULL) {
3169124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic			*nextent = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
3170b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack				NULL, BAD_CAST path, xmlCatalogDefaultPrefer, NULL);
3171124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic			if (*nextent != NULL)
3172124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic			    nextent = &((*nextent)->next);
3173124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic			xmlFree(path);
3174124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic		    }
3175124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic		}
3176124ec318f86384f3fb1c8bf05c212c12ebbbe323Igor Zlatkovic	    }
317785c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	    xmlDefaultCatalog = catal;
317885c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard	}
3179a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    }
3180a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
31818146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    xmlRMutexUnlock(xmlCatalogMutex);
318275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard}
318316756b627bc32956dcecf43b2c1781b1d0657f8fDaniel Veillard
318475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
318575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
318675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlLoadCatalog:
318775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * @filename:  a file path
318875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
318975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Load the catalog and makes its definitions effective for the default
319075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * external entity loader. It will recurse in SGML CATALOG entries.
31918146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * this function is not thread safe, catalog initialization should
31928146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * preferably be done once at startup
319375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
319475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * Returns 0 in case of success -1 in case of error
319575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
319675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillardint
319775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlLoadCatalog(const char *filename)
319875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard{
319975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    int ret;
320075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlCatalogPtr catal;
320175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
32028146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    if (!xmlCatalogInitialized)
32038146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard	xmlInitializeCatalogData();
32048146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard
32058146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    xmlRMutexLock(xmlCatalogMutex);
32068146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard
320775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (xmlDefaultCatalog == NULL) {
320875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	catal = xmlLoadACatalog(filename);
320959002e7bea266c024fa343524c58c6a2fea5895cWilliam M. Brack	if (catal == NULL) {
321059002e7bea266c024fa343524c58c6a2fea5895cWilliam M. Brack	    xmlRMutexUnlock(xmlCatalogMutex);
321175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	    return(-1);
321259002e7bea266c024fa343524c58c6a2fea5895cWilliam M. Brack	}
321375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
321475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlDefaultCatalog = catal;
32158146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard	xmlRMutexUnlock(xmlCatalogMutex);
321675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	return(0);
3217344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    }
321875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
321975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    ret = xmlExpandCatalog(xmlDefaultCatalog, filename);
32208146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    xmlRMutexUnlock(xmlCatalogMutex);
322175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    return(ret);
3222a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard}
3223a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
32245e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/**
322581418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard * xmlLoadCatalogs:
32265aad832aa34d21fca4696eb5a3bf203521f6a7f2Daniel Veillard * @pathss:  a list of directories separated by a colon or a space.
322781418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard *
322881418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard * Load the catalogs and makes their definitions effective for the default
322981418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard * external entity loader.
32308146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * this function is not thread safe, catalog initialization should
32318146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * preferably be done once at startup
323281418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard */
323381418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillardvoid
323481418e38c80cf1ddac6fe1426d8037a3da39853fDaniel VeillardxmlLoadCatalogs(const char *pathss) {
323581418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard    const char *cur;
323681418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard    const char *paths;
323781418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard    xmlChar *path;
3238ed12138b18935276f3815f42a108192cf8b1bf12Daniel Veillard#ifdef _WIN32
3239ed12138b18935276f3815f42a108192cf8b1bf12Daniel Veillard    int i, iLen;
3240ed12138b18935276f3815f42a108192cf8b1bf12Daniel Veillard#endif
324181418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard
32426c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard    if (pathss == NULL)
32436c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	return;
32446c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard
324581418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard    cur = pathss;
32462728f845c5581af9213057ace8b3f664d64c15a9Daniel Veillard    while (*cur != 0) {
324768aca051a61608e6cbbd2d36263e4470008e64f5William M. Brack	while (xmlIsBlank_ch(*cur)) cur++;
324881418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard	if (*cur != 0) {
324981418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard	    paths = cur;
32509811ce7864a5362492ed0e14a8a6df776d5b8413Jan Pokorný	    while ((*cur != 0) && (*cur != PATH_SEPARATOR) && (!xmlIsBlank_ch(*cur)))
325181418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard		cur++;
325281418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard	    path = xmlStrndup((const xmlChar *)paths, cur - paths);
3253ed12138b18935276f3815f42a108192cf8b1bf12Daniel Veillard#ifdef _WIN32
3254e1631e1cfcdf4bd7e7ec4999ec5aae9675390797Denis Pauk        iLen = strlen((const char*)path);
3255ed12138b18935276f3815f42a108192cf8b1bf12Daniel Veillard        for(i = 0; i < iLen; i++) {
3256ed12138b18935276f3815f42a108192cf8b1bf12Daniel Veillard            if(path[i] == '\\') {
3257ed12138b18935276f3815f42a108192cf8b1bf12Daniel Veillard                path[i] = '/';
3258ed12138b18935276f3815f42a108192cf8b1bf12Daniel Veillard            }
3259ed12138b18935276f3815f42a108192cf8b1bf12Daniel Veillard        }
3260ed12138b18935276f3815f42a108192cf8b1bf12Daniel Veillard#endif
326181418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard	    if (path != NULL) {
326281418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard		xmlLoadCatalog((const char *) path);
326381418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard		xmlFree(path);
326481418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard	    }
326581418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard	}
32669811ce7864a5362492ed0e14a8a6df776d5b8413Jan Pokorný	while (*cur == PATH_SEPARATOR)
3267130e5791b65fe8c584e7a3ee1f0b443055d029d6Igor Zlatkovic	    cur++;
326881418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard    }
326981418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard}
327081418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard
3271a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard/**
3272a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard * xmlCatalogCleanup:
3273a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard *
3274a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard * Free up all the memory associated with catalogs
3275a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard */
3276a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillardvoid
3277a737459bc41f3f4558d814889f0981e2aee4b97fDaniel VeillardxmlCatalogCleanup(void) {
3278364789a6dc0e74d3f4852a99ceb745139698ebe6Daniel Veillard    if (xmlCatalogInitialized == 0)
3279364789a6dc0e74d3f4852a99ceb745139698ebe6Daniel Veillard        return;
3280364789a6dc0e74d3f4852a99ceb745139698ebe6Daniel Veillard
32818146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    xmlRMutexLock(xmlCatalogMutex);
3282e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    if (xmlDebugCatalogs)
3283e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	xmlGenericError(xmlGenericErrorContext,
3284e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard		"Catalogs cleanup\n");
32856990bf3c080529493a865a851b753a27d58014eaDaniel Veillard    if (xmlCatalogXMLFiles != NULL)
3286f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	xmlHashFree(xmlCatalogXMLFiles,
328785c11fa20605e0b4fafc680627bd4b66933ac67eDaniel Veillard		    (xmlHashDeallocator)xmlFreeCatalogHashEntryList);
32886990bf3c080529493a865a851b753a27d58014eaDaniel Veillard    xmlCatalogXMLFiles = NULL;
3289a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    if (xmlDefaultCatalog != NULL)
329075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlFreeCatalog(xmlDefaultCatalog);
32916990bf3c080529493a865a851b753a27d58014eaDaniel Veillard    xmlDefaultCatalog = NULL;
3292e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    xmlDebugCatalogs = 0;
3293e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    xmlCatalogInitialized = 0;
32948146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    xmlRMutexUnlock(xmlCatalogMutex);
32958146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    xmlFreeRMutex(xmlCatalogMutex);
3296a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard}
3297a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard
3298a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard/**
3299e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard * xmlCatalogResolveSystem:
330006d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * @sysID:  the system ID string
3301e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard *
3302e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard * Try to lookup the catalog resource for a system ID
3303e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard *
330406d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * Returns the resource if found or NULL otherwise, the value returned
3305e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard *      must be freed by the caller.
3306e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard */
3307e2940ddb351e0aa2055ec6b74c245685196d532bDaniel VeillardxmlChar *
3308e2940ddb351e0aa2055ec6b74c245685196d532bDaniel VeillardxmlCatalogResolveSystem(const xmlChar *sysID) {
3309e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    xmlChar *ret;
3310e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
3311e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    if (!xmlCatalogInitialized)
3312e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	xmlInitializeCatalog();
3313e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
331475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    ret = xmlACatalogResolveSystem(xmlDefaultCatalog, sysID);
331575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    return(ret);
3316e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard}
3317e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
3318e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard/**
3319e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard * xmlCatalogResolvePublic:
33205aad832aa34d21fca4696eb5a3bf203521f6a7f2Daniel Veillard * @pubID:  the public ID string
3321e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard *
332206d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * Try to lookup the catalog reference associated to a public ID
3323e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard *
332406d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * Returns the resource if found or NULL otherwise, the value returned
3325e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard *      must be freed by the caller.
3326e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard */
3327e2940ddb351e0aa2055ec6b74c245685196d532bDaniel VeillardxmlChar *
3328e2940ddb351e0aa2055ec6b74c245685196d532bDaniel VeillardxmlCatalogResolvePublic(const xmlChar *pubID) {
3329e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    xmlChar *ret;
3330344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
3331e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    if (!xmlCatalogInitialized)
3332e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	xmlInitializeCatalog();
3333e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
333475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    ret = xmlACatalogResolvePublic(xmlDefaultCatalog, pubID);
333575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    return(ret);
3336344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard}
3337344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
33387d6fd219f249e9ce921edd20f34d64944915abffDaniel Veillard/**
3339cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * xmlCatalogResolve:
33405aad832aa34d21fca4696eb5a3bf203521f6a7f2Daniel Veillard * @pubID:  the public ID string
33415aad832aa34d21fca4696eb5a3bf203521f6a7f2Daniel Veillard * @sysID:  the system ID string
3342cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *
3343cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Do a complete resolution lookup of an External Identifier
3344cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *
3345cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Returns the URI of the resource or NULL if not found, it must be freed
3346cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *      by the caller.
3347cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard */
3348cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlChar *
3349cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlCatalogResolve(const xmlChar *pubID, const xmlChar *sysID) {
335075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlChar *ret;
33516990bf3c080529493a865a851b753a27d58014eaDaniel Veillard
3352e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    if (!xmlCatalogInitialized)
3353e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	xmlInitializeCatalog();
3354e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
335575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    ret = xmlACatalogResolve(xmlDefaultCatalog, pubID, sysID);
335675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    return(ret);
3357cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard}
3358cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
3359cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard/**
3360dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * xmlCatalogResolveURI:
3361cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @URI:  the URI
3362dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard *
3363dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * Do a complete resolution lookup of an URI
3364dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard *
3365dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * Returns the URI of the resource or NULL if not found, it must be freed
3366dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard *      by the caller.
3367dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard */
3368dc2cee29d094958139f409e30209f68953c9cb67Daniel VeillardxmlChar *
3369dc2cee29d094958139f409e30209f68953c9cb67Daniel VeillardxmlCatalogResolveURI(const xmlChar *URI) {
337075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlChar *ret;
337175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
3372dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    if (!xmlCatalogInitialized)
3373dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	xmlInitializeCatalog();
3374dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard
337575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    ret = xmlACatalogResolveURI(xmlDefaultCatalog, URI);
337675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    return(ret);
3377dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard}
3378dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard
3379a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#ifdef LIBXML_OUTPUT_ENABLED
3380dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard/**
3381a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard * xmlCatalogDump:
3382a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard * @out:  the file.
3383a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard *
3384a8dc2886f4578e04c03ab6a7cbf5bc52b0a72d02Daniel Veillard * Dump all the global catalog content to the given file.
3385a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard */
3386a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillardvoid
3387a737459bc41f3f4558d814889f0981e2aee4b97fDaniel VeillardxmlCatalogDump(FILE *out) {
3388a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard    if (out == NULL)
3389a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard	return;
3390344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
339175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if (!xmlCatalogInitialized)
339275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlInitializeCatalog();
339375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
339475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    xmlACatalogDump(xmlDefaultCatalog, out);
3395344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard}
3396a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#endif /* LIBXML_OUTPUT_ENABLED */
3397344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
3398344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard/**
3399344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * xmlCatalogAdd:
3400344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * @type:  the type of record to add to the catalog
3401f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @orig:  the system, public or prefix to match
3402344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * @replace:  the replacement value for the match
3403344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard *
3404344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * Add an entry in the catalog, it may overwrite existing but
3405344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * different entries.
3406cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * If called before any other catalog routine, allows to override the
340775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * default shared catalog put in place by xmlInitializeCatalog();
3408344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard *
3409344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * Returns 0 if successful, -1 otherwise
3410344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard */
3411344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillardint
3412344cee76a675e83ff159ffc02b009f304569cedaDaniel VeillardxmlCatalogAdd(const xmlChar *type, const xmlChar *orig, const xmlChar *replace) {
3413344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    int res = -1;
3414344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
34158146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    if (!xmlCatalogInitialized)
34168146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard	xmlInitializeCatalogData();
34178146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard
34188146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    xmlRMutexLock(xmlCatalogMutex);
341975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    /*
342075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard     * Specific case where one want to override the default catalog
342175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard     * put in place by xmlInitializeCatalog();
342275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard     */
342375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    if ((xmlDefaultCatalog == NULL) &&
3424e7ead2d2379fa933b064e4a138a267313d40988eDaniel Veillard	(xmlStrEqual(type, BAD_CAST "catalog"))) {
3425cd21dc784800832cf952061034e52ce9733a4b11Daniel Veillard	xmlDefaultCatalog = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
342675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard		                          xmlCatalogDefaultPrefer);
342775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard	xmlDefaultCatalog->xml = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
3428b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack				    orig, NULL,  xmlCatalogDefaultPrefer, NULL);
342975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
34308146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard	xmlRMutexUnlock(xmlCatalogMutex);
3431e7ead2d2379fa933b064e4a138a267313d40988eDaniel Veillard	return(0);
3432f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    }
3433e7ead2d2379fa933b064e4a138a267313d40988eDaniel Veillard
343475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    res = xmlACatalogAdd(xmlDefaultCatalog, type, orig, replace);
34358146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    xmlRMutexUnlock(xmlCatalogMutex);
3436344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    return(res);
3437344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard}
3438344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
3439344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard/**
3440344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * xmlCatalogRemove:
3441344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * @value:  the value to remove
3442344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard *
3443344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * Remove an entry from the catalog
3444344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard *
344582d753388039e0677a9ac13ca0fda19abc5e8f66Daniel Veillard * Returns the number of entries removed if successful, -1 otherwise
3446344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard */
3447344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillardint
3448344cee76a675e83ff159ffc02b009f304569cedaDaniel VeillardxmlCatalogRemove(const xmlChar *value) {
344975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    int res;
3450cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
3451e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    if (!xmlCatalogInitialized)
3452e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard	xmlInitializeCatalog();
3453e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
34548146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    xmlRMutexLock(xmlCatalogMutex);
345575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    res = xmlACatalogRemove(xmlDefaultCatalog, value);
34568146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    xmlRMutexUnlock(xmlCatalogMutex);
3457cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    return(res);
3458344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard}
3459344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
3460344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard/**
34616c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard * xmlCatalogConvert:
34626c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard *
34636c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard * Convert all the SGML catalog entries as XML ones
34646c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard *
34656c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard * Returns the number of entries converted if successful, -1 otherwise
34666c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard */
34676c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillardint
34686c5f9d14cc2bdf602b57499d001626176e409d1bDaniel VeillardxmlCatalogConvert(void) {
34696c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard    int res = -1;
34706c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard
34716c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard    if (!xmlCatalogInitialized)
34726c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard	xmlInitializeCatalog();
34736c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard
34748146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    xmlRMutexLock(xmlCatalogMutex);
347575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard    res = xmlConvertSGMLCatalog(xmlDefaultCatalog);
34768146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    xmlRMutexUnlock(xmlCatalogMutex);
34776c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard    return(res);
34786c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard}
34796c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard
348075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/************************************************************************
348175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
348275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *	Public interface manipulating the common preferences		*
348375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
348475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard ************************************************************************/
34858146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard
34866c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard/**
34875d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * xmlCatalogGetDefaults:
34885d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard *
34895d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * Used to get the user preference w.r.t. to what catalogs should
34905d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * be accepted
34915d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard *
34925d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * Returns the current xmlCatalogAllow value
34935d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard */
34945d90b6c983185e09dd514aa48d7df51b8a236466Daniel VeillardxmlCatalogAllow
34955d90b6c983185e09dd514aa48d7df51b8a236466Daniel VeillardxmlCatalogGetDefaults(void) {
34965d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    return(xmlCatalogDefaultAllow);
34975d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard}
34985d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard
34995d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard/**
35005d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * xmlCatalogSetDefaults:
3501cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @allow:  what catalogs should be accepted
35025d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard *
35035d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * Used to set the user preference w.r.t. to what catalogs should
35045d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * be accepted
35055d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard */
35065d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillardvoid
35075d90b6c983185e09dd514aa48d7df51b8a236466Daniel VeillardxmlCatalogSetDefaults(xmlCatalogAllow allow) {
35085d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    if (xmlDebugCatalogs) {
35095d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	switch (allow) {
35105d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	    case XML_CATA_ALLOW_NONE:
35115d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard		xmlGenericError(xmlGenericErrorContext,
35125d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard			"Disabling catalog usage\n");
35135d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard		break;
35145d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	    case XML_CATA_ALLOW_GLOBAL:
35155d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard		xmlGenericError(xmlGenericErrorContext,
35165d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard			"Allowing only global catalogs\n");
35175d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard		break;
35185d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	    case XML_CATA_ALLOW_DOCUMENT:
35195d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard		xmlGenericError(xmlGenericErrorContext,
35205d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard			"Allowing only catalogs from the document\n");
35215d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard		break;
35225d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	    case XML_CATA_ALLOW_ALL:
35235d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard		xmlGenericError(xmlGenericErrorContext,
35245d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard			"Allowing all catalogs\n");
35255d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard		break;
35265d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	}
35275d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    }
35285d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    xmlCatalogDefaultAllow = allow;
35295d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard}
35305d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard
35315d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard/**
3532e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard * xmlCatalogSetDefaultPrefer:
3533e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard * @prefer:  the default preference for delegation
3534e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard *
3535e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard * Allows to set the preference between public and system for deletion
3536e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard * in XML Catalog resolution. C.f. section 4.1.1 of the spec
35375d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * Values accepted are XML_CATA_PREFER_PUBLIC or XML_CATA_PREFER_SYSTEM
3538e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard *
3539e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard * Returns the previous value of the default preference for delegation
3540e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard */
3541e2940ddb351e0aa2055ec6b74c245685196d532bDaniel VeillardxmlCatalogPrefer
3542e2940ddb351e0aa2055ec6b74c245685196d532bDaniel VeillardxmlCatalogSetDefaultPrefer(xmlCatalogPrefer prefer) {
3543e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    xmlCatalogPrefer ret = xmlCatalogDefaultPrefer;
3544e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
35455d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    if (prefer == XML_CATA_PREFER_NONE)
35465d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	return(ret);
35475d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard
35485d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    if (xmlDebugCatalogs) {
35495d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	switch (prefer) {
35505d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	    case XML_CATA_PREFER_PUBLIC:
35515d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard		xmlGenericError(xmlGenericErrorContext,
35525d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard			"Setting catalog preference to PUBLIC\n");
35535d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard		break;
35545d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	    case XML_CATA_PREFER_SYSTEM:
35555d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard		xmlGenericError(xmlGenericErrorContext,
35565d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard			"Setting catalog preference to SYSTEM\n");
35575d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard		break;
3558b8bdc258dec460c0d07b50223792e26bc78b2f2dDaniel Veillard	    default:
3559b8bdc258dec460c0d07b50223792e26bc78b2f2dDaniel Veillard		return(ret);
35605d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	}
35615d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    }
3562e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    xmlCatalogDefaultPrefer = prefer;
3563e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard    return(ret);
3564e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard}
3565e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard
3566e2940ddb351e0aa2055ec6b74c245685196d532bDaniel Veillard/**
3567344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * xmlCatalogSetDebug:
3568344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * @level:  the debug level of catalogs required
3569344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard *
3570344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * Used to set the debug level for catalog operation, 0 disable
3571344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * debugging, 1 enable it
3572344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard *
3573344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard * Returns the previous value of the catalog debugging level
3574344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard */
3575344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillardint
3576344cee76a675e83ff159ffc02b009f304569cedaDaniel VeillardxmlCatalogSetDebug(int level) {
3577344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    int ret = xmlDebugCatalogs;
3578344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard
3579344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    if (level <= 0)
3580344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard        xmlDebugCatalogs = 0;
3581344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    else
3582344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard	xmlDebugCatalogs = level;
3583344cee76a675e83ff159ffc02b009f304569cedaDaniel Veillard    return(ret);
3584a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard}
35855d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard
358675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/************************************************************************
358775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
358875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *   Minimal interfaces used for per-document catalogs by the parser	*
358975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
359075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard ************************************************************************/
359175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
35925d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard/**
35935d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * xmlCatalogFreeLocal:
35945d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * @catalogs:  a document's list of catalogs
35955d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard *
35965d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * Free up the memory associated to the catalog list
35975d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard */
35985d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillardvoid
35995d90b6c983185e09dd514aa48d7df51b8a236466Daniel VeillardxmlCatalogFreeLocal(void *catalogs) {
36005d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    xmlCatalogEntryPtr catal;
36015d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard
36028146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    if (!xmlCatalogInitialized)
36038146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard	xmlInitializeCatalog();
36048146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard
36055d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    catal = (xmlCatalogEntryPtr) catalogs;
36065d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    if (catal != NULL)
36075d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	xmlFreeCatalogEntryList(catal);
36085d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard}
36095d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard
36105d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard
36115d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard/**
36125d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * xmlCatalogAddLocal:
36135d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * @catalogs:  a document's list of catalogs
36145d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * @URL:  the URL to a new local catalog
36155d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard *
36165d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * Add the new entry to the catalog list
36175d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard *
36185d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * Returns the updated list
36195d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard */
3620f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardvoid *
36215d90b6c983185e09dd514aa48d7df51b8a236466Daniel VeillardxmlCatalogAddLocal(void *catalogs, const xmlChar *URL) {
36225d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    xmlCatalogEntryPtr catal, add;
36235d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard
36245d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    if (!xmlCatalogInitialized)
36255d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	xmlInitializeCatalog();
36268146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard
36275d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    if (URL == NULL)
36285d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	return(catalogs);
36295d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard
36305d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    if (xmlDebugCatalogs)
36315d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	xmlGenericError(xmlGenericErrorContext,
36325d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard		"Adding document catalog %s\n", URL);
36335d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard
3634c853b32f9d51c8ee842c04ffd73af3e36aa58714Daniel Veillard    add = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL, URL, NULL,
3635b7b54de6c69074c9f5a81ad71cfa12f7005f2505William M. Brack	                     xmlCatalogDefaultPrefer, NULL);
36365d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    if (add == NULL)
36375d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	return(catalogs);
36385d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard
36395d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    catal = (xmlCatalogEntryPtr) catalogs;
3640f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    if (catal == NULL)
36415d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	return((void *) add);
36425d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard
36435d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    while (catal->next != NULL)
36445d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	catal = catal->next;
36455d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    catal->next = add;
36465d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    return(catalogs);
36475d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard}
36485d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard
36495d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard/**
36505d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * xmlCatalogLocalResolve:
36515d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * @catalogs:  a document's list of catalogs
36525aad832aa34d21fca4696eb5a3bf203521f6a7f2Daniel Veillard * @pubID:  the public ID string
36535aad832aa34d21fca4696eb5a3bf203521f6a7f2Daniel Veillard * @sysID:  the system ID string
36545d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard *
3655f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * Do a complete resolution lookup of an External Identifier using a
36565d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * document's private catalog list
36575d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard *
36585d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard * Returns the URI of the resource or NULL if not found, it must be freed
36595d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard *      by the caller.
36605d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard */
36615d90b6c983185e09dd514aa48d7df51b8a236466Daniel VeillardxmlChar *
36625d90b6c983185e09dd514aa48d7df51b8a236466Daniel VeillardxmlCatalogLocalResolve(void *catalogs, const xmlChar *pubID,
36635d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	               const xmlChar *sysID) {
36645d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    xmlCatalogEntryPtr catal;
36656990bf3c080529493a865a851b753a27d58014eaDaniel Veillard    xmlChar *ret;
36666990bf3c080529493a865a851b753a27d58014eaDaniel Veillard
36675d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    if (!xmlCatalogInitialized)
36685d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	xmlInitializeCatalog();
36696990bf3c080529493a865a851b753a27d58014eaDaniel Veillard
36708146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    if ((pubID == NULL) && (sysID == NULL))
36718146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard	return(NULL);
36728146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard
36736c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard    if (xmlDebugCatalogs) {
3674770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard        if ((pubID != NULL) && (sysID != NULL)) {
3675770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
3676770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard                            "Local Resolve: pubID %s sysID %s\n", pubID, sysID);
3677770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard        } else if (pubID != NULL) {
3678770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
3679770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard                            "Local Resolve: pubID %s\n", pubID);
3680770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard        } else {
3681770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
3682770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard                            "Local Resolve: sysID %s\n", sysID);
3683770075b500b153cdedc7cc00f085fd78dbe489c7Daniel Veillard        }
36846c5f9d14cc2bdf602b57499d001626176e409d1bDaniel Veillard    }
36856990bf3c080529493a865a851b753a27d58014eaDaniel Veillard
36865d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    catal = (xmlCatalogEntryPtr) catalogs;
36875d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard    if (catal == NULL)
36885d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard	return(NULL);
36896990bf3c080529493a865a851b753a27d58014eaDaniel Veillard    ret = xmlCatalogListXMLResolve(catal, pubID, sysID);
36906990bf3c080529493a865a851b753a27d58014eaDaniel Veillard    if ((ret != NULL) && (ret != XML_CATAL_BREAK))
36916990bf3c080529493a865a851b753a27d58014eaDaniel Veillard	return(ret);
36926990bf3c080529493a865a851b753a27d58014eaDaniel Veillard    return(NULL);
36935d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard}
36945d90b6c983185e09dd514aa48d7df51b8a236466Daniel Veillard
3695dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard/**
3696dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * xmlCatalogLocalResolveURI:
3697dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * @catalogs:  a document's list of catalogs
3698cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @URI:  the URI
3699dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard *
3700f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * Do a complete resolution lookup of an URI using a
3701dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * document's private catalog list
3702dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard *
3703dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard * Returns the URI of the resource or NULL if not found, it must be freed
3704dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard *      by the caller.
3705dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard */
3706dc2cee29d094958139f409e30209f68953c9cb67Daniel VeillardxmlChar *
3707dc2cee29d094958139f409e30209f68953c9cb67Daniel VeillardxmlCatalogLocalResolveURI(void *catalogs, const xmlChar *URI) {
3708dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    xmlCatalogEntryPtr catal;
37096990bf3c080529493a865a851b753a27d58014eaDaniel Veillard    xmlChar *ret;
37106990bf3c080529493a865a851b753a27d58014eaDaniel Veillard
3711dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    if (!xmlCatalogInitialized)
3712dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	xmlInitializeCatalog();
37136990bf3c080529493a865a851b753a27d58014eaDaniel Veillard
37148146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    if (URI == NULL)
37158146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard	return(NULL);
37168146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard
37176990bf3c080529493a865a851b753a27d58014eaDaniel Veillard    if (xmlDebugCatalogs)
37186990bf3c080529493a865a851b753a27d58014eaDaniel Veillard	xmlGenericError(xmlGenericErrorContext,
37196990bf3c080529493a865a851b753a27d58014eaDaniel Veillard		"Resolve URI %s\n", URI);
37206990bf3c080529493a865a851b753a27d58014eaDaniel Veillard
3721dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    catal = (xmlCatalogEntryPtr) catalogs;
3722dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard    if (catal == NULL)
3723dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard	return(NULL);
37246990bf3c080529493a865a851b753a27d58014eaDaniel Veillard    ret = xmlCatalogListXMLResolveURI(catal, URI);
37256990bf3c080529493a865a851b753a27d58014eaDaniel Veillard    if ((ret != NULL) && (ret != XML_CATAL_BREAK))
37266990bf3c080529493a865a851b753a27d58014eaDaniel Veillard	return(ret);
37276990bf3c080529493a865a851b753a27d58014eaDaniel Veillard    return(NULL);
3728dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard}
3729dc2cee29d094958139f409e30209f68953c9cb67Daniel Veillard
373075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/************************************************************************
373175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
373275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *			Deprecated interfaces				*
373375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *									*
373475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard ************************************************************************/
373575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
373675b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlCatalogGetSystem:
37375aad832aa34d21fca4696eb5a3bf203521f6a7f2Daniel Veillard * @sysID:  the system ID string
373875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
373906d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * Try to lookup the catalog reference associated to a system ID
374075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * DEPRECATED, use xmlCatalogResolveSystem()
374175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
374206d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * Returns the resource if found or NULL otherwise.
374375b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
374475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillardconst xmlChar *
374575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlCatalogGetSystem(const xmlChar *sysID) {
3746ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    xmlChar *ret;
3747ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    static xmlChar result[1000];
3748ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    static int msg = 0;
3749ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard
3750ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    if (!xmlCatalogInitialized)
3751ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	xmlInitializeCatalog();
3752ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard
3753ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    if (msg == 0) {
3754ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	xmlGenericError(xmlGenericErrorContext,
3755ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard		"Use of deprecated xmlCatalogGetSystem() call\n");
3756ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	msg++;
3757ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    }
3758ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard
3759ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    if (sysID == NULL)
3760ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	return(NULL);
3761f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
3762ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    /*
3763ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard     * Check first the XML catalogs
3764ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard     */
3765ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    if (xmlDefaultCatalog != NULL) {
3766ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	ret = xmlCatalogListXMLResolve(xmlDefaultCatalog->xml, NULL, sysID);
3767ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	if ((ret != NULL) && (ret != XML_CATAL_BREAK)) {
3768ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	    snprintf((char *) result, sizeof(result) - 1, "%s", (char *) ret);
3769ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	    result[sizeof(result) - 1] = 0;
3770ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	    return(result);
3771ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	}
3772ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    }
3773ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard
3774ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    if (xmlDefaultCatalog != NULL)
3775ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	return(xmlCatalogGetSGMLSystem(xmlDefaultCatalog->sgml, sysID));
3776ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    return(NULL);
377775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard}
377875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
377975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard/**
378075b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * xmlCatalogGetPublic:
37815aad832aa34d21fca4696eb5a3bf203521f6a7f2Daniel Veillard * @pubID:  the public ID string
378275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
378306d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * Try to lookup the catalog reference associated to a public ID
378475b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard * DEPRECATED, use xmlCatalogResolvePublic()
378575b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard *
378606d2524e8069c7ab0626d03910ac29484741f811Daniel Veillard * Returns the resource if found or NULL otherwise.
378775b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard */
378875b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillardconst xmlChar *
378975b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel VeillardxmlCatalogGetPublic(const xmlChar *pubID) {
3790ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    xmlChar *ret;
3791ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    static xmlChar result[1000];
3792ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    static int msg = 0;
3793ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard
3794ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    if (!xmlCatalogInitialized)
3795ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	xmlInitializeCatalog();
3796ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard
3797ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    if (msg == 0) {
3798ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	xmlGenericError(xmlGenericErrorContext,
3799ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard		"Use of deprecated xmlCatalogGetPublic() call\n");
3800ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	msg++;
3801ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    }
3802ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard
3803ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    if (pubID == NULL)
3804ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	return(NULL);
3805f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
3806ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    /*
3807ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard     * Check first the XML catalogs
3808ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard     */
3809ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    if (xmlDefaultCatalog != NULL) {
3810ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	ret = xmlCatalogListXMLResolve(xmlDefaultCatalog->xml, pubID, NULL);
3811ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	if ((ret != NULL) && (ret != XML_CATAL_BREAK)) {
3812ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	    snprintf((char *) result, sizeof(result) - 1, "%s", (char *) ret);
3813ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	    result[sizeof(result) - 1] = 0;
3814ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	    return(result);
3815ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	}
3816ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    }
3817ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard
3818ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    if (xmlDefaultCatalog != NULL)
3819ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard	return(xmlCatalogGetSGMLPublic(xmlDefaultCatalog->sgml, pubID));
3820ab690c5e9e36bd964297d2ffe757941b7359aaa1Daniel Veillard    return(NULL);
382175b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard}
382275b96824bccaeadd9e71eba9be7fab1bd88ac814Daniel Veillard
38235d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#define bottom_catalog
38245d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#include "elfgcchack.h"
3825a737459bc41f3f4558d814889f0981e2aee4b97fDaniel Veillard#endif /* LIBXML_CATALOG_ENABLED */
3826