/**
* catalog.c: set of generic Catalog related routines
*
* Reference: SGML Open Technical Resolution TR9401:1997.
*
* XML Catalogs Working Draft 06 August 2001
*
* See Copyright for the status of this software.
*
* Daniel.Veillard@imag.fr
*/
#define IN_LIBXML
#include "libxml.h"
#ifdef LIBXML_CATALOG_ENABLED
#ifdef HAVE_SYS_TYPES_H
#endif
#ifdef HAVE_SYS_STAT_H
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <string.h>
#include <libxml/xmlmemory.h>
#include <libxml/parserInternals.h>
#include <libxml/xmlerror.h>
#ifdef _WIN32
#else
#endif
/**
* TODO:
*
* macro to flag unimplemented blocks
* option. C.f. Richard Tobin <richard@cogsci.ed.ac.uk>
*> Just FYI, I am using an environment variable XML_CATALOG_PREFER with
*> values "system" and "public". I have made the default be "system" to
*> match yours.
*/
#define TODO \
"Unimplemented block at %s:%d\n", \
#ifndef XML_XML_DEFAULT_CATALOG
#endif
#ifndef XML_SGML_DEFAULT_CATALOG
#endif
#if defined(_WIN32_WCE)
/* Windows CE don't have a A variant */
#else
void* __stdcall GetModuleHandleA(const char*);
unsigned long __stdcall GetModuleFileNameA(void*, char*, unsigned long);
#endif
#endif
/************************************************************************
* *
* Types, all private *
* *
************************************************************************/
typedef enum {
XML_CATA_NONE = 0,
struct _xmlCatalogEntry {
int dealloc;
int depth;
};
typedef enum {
struct _xmlCatalog {
/*
* SGML Catalogs are stored as a simple hash table of catalog entries
* Catalog stack to check against overflows when building the
* SGML catalog
*/
/*
* XML Catalogs are stored as a tree of Catalog entries
*/
};
/************************************************************************
* *
* Global variables *
* *
************************************************************************/
/*
* Those are preferences
*/
/*
* Hash table containing all the trees of XML catalogs parsed by
* the application.
*/
/*
* The default catalog in use by the application
*/
/*
* A mutex for modifying the shared global catalog(s)
* xmlDefaultCatalog tree.
* It also protects xmlCatalogXMLFiles
*/
/*
* Whether the catalog support was initialized.
*/
static int xmlCatalogInitialized = 0;
/************************************************************************
* *
* Catalog error handlers *
* *
************************************************************************/
/**
* xmlCatalogErrMemory:
* @extra: extra informations
*
* Handle an out of memory condition
*/
static void
{
"Memory allocation failed : %s\n", extra);
}
/**
* xmlCatalogErr:
* @catal: the Catalog entry
* @node: the context node
* @msg: the error message
* @extra: extra informations
*
* Handle a catalog error
*/
static void
{
(const char *) str3, 0, 0,
}
/************************************************************************
* *
* Allocation and Freeing *
* *
************************************************************************/
/**
* xmlNewCatalogEntry:
* @type: type of entry
* @name: name of the entry
* @value: value of the entry
* @prefer: the PUBLIC vs. SYSTEM current preference value
* @group: for members of a group, the group entry
*
* create a new Catalog entry, this type is shared both by XML and
* SGML catalogs, but the acceptable types values differs.
*
* Returns the xmlCatalogEntryPtr or NULL in case of error
*/
static xmlCatalogEntryPtr
xmlCatalogErrMemory("allocating catalog entry");
return(NULL);
}
}
else
else
else
return(ret);
}
static void
/**
* xmlFreeCatalogEntry:
* @ret: a Catalog entry
*
* Free the memory allocated to a Catalog entry
*/
static void
return;
/*
* Entries stored in the file hash must be deallocated
* only by the file hash cleaner !
*/
return;
if (xmlDebugCatalogs) {
else
"Free catalog entry\n");
}
}
/**
* xmlFreeCatalogEntryList:
* @ret: a Catalog entry list
*
* Free the memory allocated to a full chained list of Catalog entries
*/
static void
}
}
/**
* xmlFreeCatalogHashEntryList:
* @ret: a Catalog entry list
*
* Free the memory allocated to list of Catalog entries from the
* catalog file hash.
*/
static void
return;
}
}
/**
* xmlCreateNewCatalog:
* @type: type of catalog
* @prefer: the PUBLIC vs. SYSTEM current preference value
*
* create a new Catalog, this type is shared both by XML and
* SGML catalogs, but the acceptable types values differs.
*
* Returns the xmlCatalogPtr or NULL in case of error
*/
static xmlCatalogPtr
xmlCatalogErrMemory("allocating catalog");
return(NULL);
}
return(ret);
}
/**
* xmlFreeCatalog:
* @catal: a Catalog
*
* Free the memory allocated to a Catalog
*/
void
return;
}
/************************************************************************
* *
* Serializing Catalogs *
* *
************************************************************************/
#ifdef LIBXML_OUTPUT_ENABLED
/**
* xmlCatalogDumpEntry:
* @entry: the catalog entry
* @out: the file.
*
* Serialize an SGML Catalog entry
*/
static void
return;
case SGML_CATA_ENTITY:
case SGML_CATA_PENTITY:
case SGML_CATA_DOCTYPE:
case SGML_CATA_LINKTYPE:
case SGML_CATA_NOTATION:
case SGML_CATA_PUBLIC:
case SGML_CATA_SYSTEM:
case SGML_CATA_DELEGATE:
case SGML_CATA_BASE:
case SGML_CATA_CATALOG:
case SGML_CATA_DOCUMENT:
case SGML_CATA_SGMLDECL:
default:
return;
}
case SGML_CATA_ENTITY:
case SGML_CATA_PENTITY:
case SGML_CATA_DOCTYPE:
case SGML_CATA_LINKTYPE:
case SGML_CATA_NOTATION:
case SGML_CATA_PUBLIC:
case SGML_CATA_SYSTEM:
case SGML_CATA_SGMLDECL:
case SGML_CATA_DOCUMENT:
case SGML_CATA_CATALOG:
case SGML_CATA_BASE:
case SGML_CATA_DELEGATE:
default:
break;
}
case SGML_CATA_ENTITY:
case SGML_CATA_PENTITY:
case SGML_CATA_DOCTYPE:
case SGML_CATA_LINKTYPE:
case SGML_CATA_NOTATION:
case SGML_CATA_PUBLIC:
case SGML_CATA_SYSTEM:
case SGML_CATA_DELEGATE:
default:
break;
}
}
/**
* xmlDumpXMLCatalogNode:
* @catal: top catalog entry
* @catalog: pointer to the xml tree
* @doc: the containing document
* @ns: the current namespace
* @cgroup: group node for group members
*
* Serializes a Catalog entry, called by xmlDumpXMLCatalog and recursively
* for group entries
*/
/*
* add all the catalog entries
*/
case XML_CATA_REMOVED:
break;
case XML_CATA_BROKEN_CATALOG:
case XML_CATA_CATALOG:
continue;
}
break;
case XML_CATA_NEXT_CATALOG:
break;
case XML_CATA_NONE:
break;
case XML_CATA_GROUP:
}
case XML_CATA_PREFER_NONE:
break;
case XML_CATA_PREFER_PUBLIC:
break;
case XML_CATA_PREFER_SYSTEM:
break;
}
break;
case XML_CATA_PUBLIC:
break;
case XML_CATA_SYSTEM:
break;
case XML_CATA_REWRITE_SYSTEM:
break;
case XML_CATA_DELEGATE_PUBLIC:
break;
case XML_CATA_DELEGATE_SYSTEM:
break;
case XML_CATA_URI:
break;
case XML_CATA_REWRITE_URI:
break;
case XML_CATA_DELEGATE_URI:
break;
case SGML_CATA_SYSTEM:
case SGML_CATA_PUBLIC:
case SGML_CATA_ENTITY:
case SGML_CATA_PENTITY:
case SGML_CATA_DOCTYPE:
case SGML_CATA_LINKTYPE:
case SGML_CATA_NOTATION:
case SGML_CATA_DELEGATE:
case SGML_CATA_BASE:
case SGML_CATA_CATALOG:
case SGML_CATA_DOCUMENT:
case SGML_CATA_SGMLDECL:
break;
}
}
}
}
static int
int ret;
/*
* Rebuild a catalog
*/
return(-1);
BAD_CAST "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN",
return(-1);
}
return(-1);
}
/*
* reserialize it
*/
return(-1);
}
/*
* Free it
*/
return(ret);
}
#endif /* LIBXML_OUTPUT_ENABLED */
/************************************************************************
* *
* Converting SGML Catalogs to XML *
* *
************************************************************************/
/**
* xmlCatalogConvertEntry:
* @entry: the entry
* @catal: pointer to the catalog being converted
*
* Convert one entry from the catalog
*/
static void
return;
case SGML_CATA_ENTITY:
break;
case SGML_CATA_PENTITY:
break;
case SGML_CATA_DOCTYPE:
break;
case SGML_CATA_LINKTYPE:
break;
case SGML_CATA_NOTATION:
break;
case SGML_CATA_PUBLIC:
break;
case SGML_CATA_SYSTEM:
break;
case SGML_CATA_DELEGATE:
break;
case SGML_CATA_CATALOG:
break;
default:
return;
}
/*
* Conversion successful, remove from the SGML catalog
* and add it to the default XML one
*/
else {
}
}
/**
* xmlConvertSGMLCatalog:
* @catal: the catalog
*
* Convert all the SGML catalog entries as XML ones
*
* Returns the number of entries converted if successful, -1 otherwise
*/
int
return(-1);
if (xmlDebugCatalogs) {
"Converting SGML catalog to XML\n");
}
&catal);
return(0);
}
/************************************************************************
* *
* Helper function *
* *
************************************************************************/
/**
* xmlCatalogUnWrapURN:
* @urn: an "urn:publicid:" to unwrap
*
* Expand the URN into the equivalent Public Identifier
*
* Returns the new identifier or NULL, the string must be deallocated
* by the caller.
*/
static xmlChar *
unsigned int i = 0;
return(NULL);
while (*urn != 0) {
if (i > sizeof(result) - 4)
break;
if (*urn == '+') {
result[i++] = ' ';
urn++;
} else if (*urn == ':') {
result[i++] = '/';
result[i++] = '/';
urn++;
} else if (*urn == ';') {
result[i++] = ':';
result[i++] = ':';
urn++;
} else if (*urn == '%') {
result[i++] = '+';
result[i++] = ':';
result[i++] = '/';
result[i++] = ';';
result[i++] = '\'';
result[i++] = '?';
result[i++] = '#';
result[i++] = '%';
else {
urn++;
continue;
}
urn += 3;
} else {
urn++;
}
}
result[i] = 0;
}
/**
* xmlParseCatalogFile:
* @filename: the filename
*
* parse an XML file and build a tree. It's like xmlParseFile()
* except it bypass all catalog lookups.
*
* Returns the resulting document tree or NULL in case of error
*/
ctxt = xmlNewParserCtxt();
#ifdef LIBXML_SAX1_ENABLED
}
#endif
return(NULL);
}
return(NULL);
}
if (inputStream == NULL) {
return(NULL);
}
inputStream->end =
ctxt->loadsubset = 0;
if (ctxt->wellFormed)
else {
}
return(ret);
}
/**
* xmlLoadFileContent:
* @filename: a file path
*
* Load a file content into memory.
*
* Returns a pointer to the 0 terminated string or NULL in case of error
*/
static xmlChar *
{
#ifdef HAVE_STAT
int fd;
#else
#endif
int len;
long size;
#ifdef HAVE_STAT
#endif
return (NULL);
#ifdef HAVE_STAT
return (NULL);
#endif
#ifdef HAVE_STAT
#else
#endif
{
return (NULL);
}
#ifdef HAVE_STAT
#else
if (fseek(fd, 0, SEEK_END) || (size = ftell(fd)) == EOF || fseek(fd, 0, SEEK_SET)) { /* File operations denied? ok, just close and return failure */
return (NULL);
}
#endif
xmlCatalogErrMemory("allocating catalog data");
return (NULL);
}
#ifdef HAVE_STAT
#else
#endif
if (len < 0) {
return (NULL);
}
#ifdef HAVE_STAT
#else
#endif
return(content);
}
/**
* xmlCatalogNormalizePublic:
* @pubID: the public ID string
*
* Normalizes the Public Identifier
*
* Implements 6.2. Public Identifier Normalization
*
* Returns the new string or NULL, the string must be deallocated
* by the caller.
*/
static xmlChar *
{
int white;
const xmlChar *p;
xmlChar *q;
return(NULL);
white = 1;
if (!xmlIsBlank_ch(*p))
white = 0;
else if (*p == 0x20 && !white)
white = 1;
else
ok = 0;
}
return(NULL);
q = ret;
white = 0;
for (p = pubID;*p != 0;p++) {
if (xmlIsBlank_ch(*p)) {
if (q != ret)
white = 1;
} else {
if (white) {
*(q++) = 0x20;
white = 0;
}
*(q++) = *p;
}
}
*q = 0;
return(ret);
}
/************************************************************************
* *
* The XML Catalog parser *
* *
************************************************************************/
static xmlCatalogEntryPtr
static void
static xmlChar *
static xmlChar *
/**
* xmlGetXMLCatalogEntryType:
* @name: the name
*
* lookup the internal type associated to an XML catalog entry name
*
* Returns the type associated with that name
*/
static xmlCatalogEntryType
type = XML_CATA_URI;
return(type);
}
/**
* xmlParseXMLCatalogOneNode:
* @cur: the XML node
* @type: the type of Catalog entry
* @name: the name of the node
* @attrName: the attribute holding the value
* @uriAttrName: the attribute holding the URI-Reference
* @prefer: the PUBLIC vs. SYSTEM current preference value
* @cgroup: the group which includes this node
*
* Finishes the examination of an XML tree node of a catalog and build
* a Catalog entry from it.
*
* Returns the new Catalog entry node or NULL in case of error.
*/
static xmlCatalogEntryPtr
ok = 0;
}
}
ok = 0;
}
if (!ok) {
return(NULL);
}
if (xmlDebugCatalogs > 1) {
else
}
} else {
}
return(ret);
}
/**
* xmlParseXMLCatalogNode:
* @cur: the XML node
* @prefer: the PUBLIC vs. SYSTEM current preference value
* @parent: the parent Catalog entry
* @cgroup: the group which includes this node
*
* Examines an XML tree node of a catalog and build
* a Catalog entry from it adding it to its parent. The examination can
* be recursive.
*/
static void
{
return;
} else {
"Invalid value for prefer: '%s'\n",
}
}
}
else {
}
}
/*
* Recurse to propagate prefer to the subtree
* (xml:base handling is automated)
*/
}
}
}
/**
* xmlParseXMLCatalogNodeList:
* @cur: the XML node list of siblings
* @prefer: the PUBLIC vs. SYSTEM current preference value
* @parent: the parent Catalog entry
* @cgroup: the group which includes this list
*
* Examines a list of XML sibling nodes of a catalog and build
* a list of Catalog entry from it adding it to the parent.
* The examination will recurse to examine node subtrees.
*/
static void
}
}
/* TODO: sort the list according to REWRITE lengths and prefer value */
}
/**
* xmlParseXMLCatalogFile:
* @prefer: the PUBLIC vs. SYSTEM current preference value
* @filename: the filename for the catalog
*
* Parses the catalog file to extract the XML tree and then analyze the
* tree to build a list of Catalog entries corresponding to this catalog
*
* Returns the resulting Catalog entries list
*/
static xmlCatalogEntryPtr
return(NULL);
if (xmlDebugCatalogs)
"Failed to parse catalog %s\n", filename);
return(NULL);
}
if (xmlDebugCatalogs)
return(NULL);
}
} else {
"Invalid value for prefer: '%s'\n",
}
}
} else {
"File %s is not an XML Catalog\n",
return(NULL);
}
return(parent);
}
/**
* xmlFetchXMLCatalogFile:
* @catal: an existing but incomplete catalog entry
*
* Fetch and parse the subcatalog referenced by an entry
*
* Returns 0 in case of success, -1 otherwise
*/
static int
return(-1);
return(-1);
return(-1);
/*
* lock the whole catalog for modification
*/
/* Okay someone else did it in the meantime */
return(0);
}
if (xmlCatalogXMLFiles != NULL) {
if (xmlDebugCatalogs)
else
return(0);
}
if (xmlDebugCatalogs)
}
/*
* Fetch and parse. Note that xmlParseXMLCatalogFile does not
* use the existing catalog, there is no recursion allowed at
* that level.
*/
return(-1);
}
else
if (xmlCatalogXMLFiles == NULL)
if (xmlCatalogXMLFiles != NULL) {
if (xmlDebugCatalogs)
}
return(0);
}
/************************************************************************
* *
* XML Catalog handling *
* *
************************************************************************/
/**
* xmlAddXMLCatalog:
* @catal: top of an XML catalog
* @type: the type of record to add to the catalog
* @orig: the system, public or prefix to match (or NULL)
* @replace: the replacement value for the match
*
* Add an entry in the XML catalog, it may overwrite existing but
* different entries.
*
* Returns 0 if successful, -1 otherwise
*/
static int
int doregister = 0;
return(-1);
}
doregister = 1;
if (typ == XML_CATA_NONE) {
if (xmlDebugCatalogs)
"Failed to add unknown element %s to catalog\n", type);
return(-1);
}
/*
* Might be a simple "update in place"
*/
if (xmlDebugCatalogs)
"Updating element %s to catalog\n", type);
return(0);
}
break;
}
}
if (xmlDebugCatalogs)
"Adding element %s to catalog\n", type);
else
if (doregister) {
}
return(0);
}
/**
* xmlDelXMLCatalog:
* @catal: top of an XML catalog
* @value: the value to remove from the catalog
*
* Remove entries in the XML catalog where the value or the URI
* is equal to @value
*
* Returns the number of entries removed if successful, -1 otherwise
*/
static int
int ret = 0;
return(-1);
return(-1);
}
/*
* Scan the children
*/
if (xmlDebugCatalogs) {
else
}
}
}
return(ret);
}
/**
* xmlCatalogXMLResolve:
* @catal: a catalog list
* @pubID: the public ID string
* @sysID: the system ID string
*
* Do a complete resolution lookup of an External Identifier for a
* list of catalog entries.
*
* Implements (or tries to) 7.1. External Identifier Resolution
*
* Returns the URI of the resource or NULL if not found
*/
static xmlChar *
int haveDelegate = 0;
int haveNext = 0;
/*
* protection against loops
*/
"Detected recursion in catalog %s\n",
return(NULL);
}
/*
* First tries steps 2/ 3/ 4/ if a system ID is provided.
*/
haveDelegate = 0;
case XML_CATA_SYSTEM:
if (xmlDebugCatalogs)
"Found system match %s, using %s\n",
}
break;
case XML_CATA_REWRITE_SYSTEM:
if ((len > lenrewrite) &&
lenrewrite = len;
}
break;
case XML_CATA_DELEGATE_SYSTEM:
haveDelegate++;
break;
case XML_CATA_NEXT_CATALOG:
haveNext++;
break;
default:
break;
}
}
if (xmlDebugCatalogs)
return(ret);
}
if (haveDelegate) {
int nbList = 0, i;
/*
* Assume the entries have been sorted by decreasing substring
* matches when the list was produced.
*/
for (i = 0;i < nbList;i++)
break;
if (i < nbList) {
continue;
}
if (nbList < MAX_DELEGATE)
}
if (xmlDebugCatalogs)
return(ret);
}
}
}
}
/*
* Apply the cut algorithm explained in 4/
*/
return(XML_CATAL_BREAK);
}
}
/*
* Then tries 5/ 6/ if a public ID is provided
*/
haveDelegate = 0;
case XML_CATA_PUBLIC:
if (xmlDebugCatalogs)
}
break;
case XML_CATA_DELEGATE_PUBLIC:
haveDelegate++;
break;
case XML_CATA_NEXT_CATALOG:
haveNext++;
break;
default:
break;
}
}
if (haveDelegate) {
int nbList = 0, i;
/*
* Assume the entries have been sorted by decreasing substring
* matches when the list was produced.
*/
for (i = 0;i < nbList;i++)
break;
if (i < nbList) {
continue;
}
if (nbList < MAX_DELEGATE)
}
if (xmlDebugCatalogs)
return(ret);
}
}
}
}
/*
* Apply the cut algorithm explained in 4/
*/
return(XML_CATAL_BREAK);
}
}
if (haveNext) {
}
return(ret);
return(NULL);
}
}
}
}
}
return(NULL);
}
/**
* xmlCatalogXMLResolveURI:
* @catal: a catalog list
* @URI: the URI
* @sysID: the system ID string
*
* Do a complete resolution lookup of an External Identifier for a
* list of catalog entries.
*
* Implements (or tries to) 7.2.2. URI Resolution
*
* Returns the URI of the resource or NULL if not found
*/
static xmlChar *
int haveDelegate = 0;
int haveNext = 0;
return(NULL);
return(NULL);
"Detected recursion in catalog %s\n",
return(NULL);
}
/*
* First tries steps 2/ 3/ 4/ if a system ID is provided.
*/
haveDelegate = 0;
case XML_CATA_URI:
if (xmlDebugCatalogs)
}
break;
case XML_CATA_REWRITE_URI:
if ((len > lenrewrite) &&
lenrewrite = len;
}
break;
case XML_CATA_DELEGATE_URI:
haveDelegate++;
break;
case XML_CATA_NEXT_CATALOG:
haveNext++;
break;
default:
break;
}
}
if (xmlDebugCatalogs)
return(ret);
}
if (haveDelegate) {
int nbList = 0, i;
/*
* Assume the entries have been sorted by decreasing substring
* matches when the list was produced.
*/
for (i = 0;i < nbList;i++)
break;
if (i < nbList) {
continue;
}
if (nbList < MAX_DELEGATE)
}
if (xmlDebugCatalogs)
return(ret);
}
}
}
/*
* Apply the cut algorithm explained in 4/
*/
return(XML_CATAL_BREAK);
}
if (haveNext) {
}
return(ret);
}
}
}
}
return(NULL);
}
/**
* xmlCatalogListXMLResolve:
* @catal: a catalog list
* @pubID: the public ID string
* @sysID: the system ID string
*
* Do a complete resolution lookup of an External Identifier for a
* list of catalogs
*
* Implements (or tries to) 7.1. External Identifier Resolution
*
* Returns the URI of the resource or NULL if not found
*/
static xmlChar *
return(NULL);
return(NULL);
if (xmlDebugCatalogs) {
"Public URN ID %s expanded to NULL\n", pubID);
else
"Public URN ID expanded to %s\n", urnID);
}
return(ret);
}
if (xmlDebugCatalogs) {
"System URN ID %s expanded to NULL\n", sysID);
else
"System URN ID expanded to %s\n", urnID);
}
else {
}
return(ret);
}
}
break;
break;
}
}
}
}
return(ret);
}
/**
* xmlCatalogListXMLResolveURI:
* @catal: a catalog list
* @URI: the URI
*
* Do a complete resolution lookup of an URI for a list of catalogs
*
* Implements (or tries to) 7.2. URI Resolution
*
* Returns the URI of the resource or NULL if not found
*/
static xmlChar *
return(NULL);
return(NULL);
if (xmlDebugCatalogs) {
"URN ID %s expanded to NULL\n", URI);
else
"URN ID expanded to %s\n", urnID);
}
return(ret);
}
}
return(ret);
}
}
}
return(ret);
}
/************************************************************************
* *
* The SGML Catalog parser *
* *
************************************************************************/
/**
* xmlParseSGMLCatalogComment:
* @cur: the current character
*
* Skip a comment in an SGML catalog
*
* Returns new current character
*/
static const xmlChar *
return(cur);
SKIP(2);
NEXT;
if (cur[0] == 0) {
return(NULL);
}
return(cur + 2);
}
/**
* xmlParseSGMLCatalogPubid:
* @cur: the current character
* @id: the return location
*
* Parse an SGML catalog ID
*
* Returns new current character and store the value in @id
*/
static const xmlChar *
int len = 0;
int count = 0;
if (RAW == '"') {
NEXT;
stop = '"';
} else if (RAW == '\'') {
NEXT;
stop = '\'';
} else {
stop = ' ';
}
xmlCatalogErrMemory("allocating public ID");
return(NULL);
}
break;
break;
size *= 2;
xmlCatalogErrMemory("allocating public ID");
return(NULL);
}
}
count++;
NEXT;
}
if (stop == ' ') {
if (!IS_BLANK_CH(*cur)) {
return(NULL);
}
} else {
return(NULL);
}
NEXT;
}
return(cur);
}
/**
* xmlParseSGMLCatalogName:
* @cur: the current character
* @name: the return location
*
* Parse an SGML catalog name
*
* Returns new current character and store the value in @name
*/
static const xmlChar *
int len = 0;
int c;
/*
* Handler for more complex cases
*/
c = *cur;
return(NULL);
}
(c == '.') || (c == '-') ||
(c == '_') || (c == ':'))) {
cur++;
c = *cur;
if (len >= XML_MAX_NAMELEN)
return(NULL);
}
return(cur);
}
/**
* xmlGetSGMLCatalogEntryType:
* @name: the entry name
*
* Get the Catalog entry type for a given SGML Catalog name
*
* Returns Catalog entry type
*/
static xmlCatalogEntryType
return(type);
}
/**
* xmlParseSGMLCatalog:
* @catal: the SGML Catalog
* @value: the content of the SGML Catalog serialization
* @file: the filepath for the catalog
* @super: should this be handled as a Super Catalog in which case
* parsing is not recursive
*
* Parse an SGML catalog content and fill up the @catal hash table with
* the new entries found.
*
* Returns 0 in case of success, -1 in case of error.
*/
static int
int res;
return(-1);
if (cur[0] == 0)
break;
/* error */
break;
}
} else {
/* error */
break;
}
if (!IS_BLANK_CH(*cur)) {
/* error */
break;
}
/* error */
break;
}
continue;
}
switch(type) {
case SGML_CATA_ENTITY:
if (*cur == '%')
case SGML_CATA_PENTITY:
case SGML_CATA_DOCTYPE:
case SGML_CATA_LINKTYPE:
case SGML_CATA_NOTATION:
/* error */
break;
}
if (!IS_BLANK_CH(*cur)) {
/* error */
break;
}
/* error */
break;
}
break;
case SGML_CATA_PUBLIC:
case SGML_CATA_SYSTEM:
case SGML_CATA_DELEGATE:
/* error */
break;
}
if (type != SGML_CATA_SYSTEM) {
if (*normid != 0)
else {
}
}
}
if (!IS_BLANK_CH(*cur)) {
/* error */
break;
}
/* error */
break;
}
break;
case SGML_CATA_BASE:
case SGML_CATA_CATALOG:
case SGML_CATA_DOCUMENT:
case SGML_CATA_SGMLDECL:
/* error */
break;
}
break;
default:
break;
}
break;
} else if (type == SGML_CATA_BASE) {
} else if ((type == SGML_CATA_PUBLIC) ||
(type == SGML_CATA_SYSTEM)) {
if (res < 0) {
}
}
} else if (type == SGML_CATA_CATALOG) {
if (super) {
if (res < 0) {
}
} else {
}
}
}
/*
* drop anything else we won't handle it
*/
}
}
return(-1);
return(0);
}
/************************************************************************
* *
* SGML Catalog handling *
* *
************************************************************************/
/**
* xmlCatalogGetSGMLPublic:
* @catal: an SGML catalog hash
* @pubID: the public ID string
*
* Try to lookup the catalog local reference associated to a public ID
*
* Returns the local resource if found or NULL otherwise.
*/
static const xmlChar *
return(NULL);
return(NULL);
}
}
return(NULL);
}
/**
* xmlCatalogGetSGMLSystem:
* @catal: an SGML catalog hash
* @sysID: the system ID string
*
* Try to lookup the catalog local reference for a system ID
*
* Returns the local resource if found or NULL otherwise.
*/
static const xmlChar *
return(NULL);
return(NULL);
return(NULL);
}
/**
* xmlCatalogSGMLResolve:
* @catal: the SGML catalog
* @pubID: the public ID string
* @sysID: the system ID string
*
* Do a complete resolution lookup of an External Identifier
*
* Returns the URI of the resource or NULL if not found
*/
static const xmlChar *
return(NULL);
return(ret);
return(NULL);
}
/************************************************************************
* *
* Specific Public interfaces *
* *
************************************************************************/
/**
* xmlLoadSGMLSuperCatalog:
* @filename: a file path
*
* Load an SGML super catalog. It won't expand CATALOG or DELEGATE
* references. This is only needed for manipulating SGML Super Catalogs
* like adding and removing CATALOG or DELEGATE entries.
*
* Returns the catalog parsed or NULL in case of error
*/
{
int ret;
return(NULL);
return(NULL);
}
if (ret < 0) {
return(NULL);
}
return (catal);
}
/**
* xmlLoadACatalog:
* @filename: a file path
*
* Load the catalog and build the associated data structures.
* This can be either an XML Catalog or an SGML Catalog
* It will recurse in SGML CATALOG entries. On the other hand XML
* Catalogs are not handled recursively.
*
* Returns the catalog parsed or NULL in case of error
*/
{
int ret;
return(NULL);
first++;
if (*first != '<') {
return(NULL);
}
if (ret < 0) {
return(NULL);
}
} else {
return(NULL);
}
}
return (catal);
}
/**
* xmlExpandCatalog:
* @catal: a catalog
* @filename: a file path
*
* Load the catalog and expand the existing catal structure.
* This can be either an XML Catalog or an SGML Catalog
*
* Returns 0 in case of success, -1 in case of error
*/
static int
{
int ret;
return(-1);
return(-1);
if (ret < 0) {
return(-1);
}
} else {
} else {
}
}
return (0);
}
/**
* xmlACatalogResolveSystem:
* @catal: a Catalog
* @sysID: the system ID string
*
* Try to lookup the catalog resource for a system ID
*
* Returns the resource if found or NULL otherwise, the value returned
* must be freed by the caller.
*/
xmlChar *
return(NULL);
if (xmlDebugCatalogs)
"Resolve sysID %s\n", sysID);
if (ret == XML_CATAL_BREAK)
} else {
}
return(ret);
}
/**
* xmlACatalogResolvePublic:
* @catal: a Catalog
* @pubID: the public ID string
*
* Try to lookup the catalog local reference associated to a public ID in that catalog
*
* Returns the local resource if found or NULL otherwise, the value returned
* must be freed by the caller.
*/
xmlChar *
return(NULL);
if (xmlDebugCatalogs)
"Resolve pubID %s\n", pubID);
if (ret == XML_CATAL_BREAK)
} else {
}
return(ret);
}
/**
* xmlACatalogResolve:
* @catal: a Catalog
* @pubID: the public ID string
* @sysID: the system ID string
*
* Do a complete resolution lookup of an External Identifier
*
* Returns the URI of the resource or NULL if not found, it must be freed
* by the caller.
*/
xmlChar *
{
return (NULL);
if (xmlDebugCatalogs) {
"Resolve: pubID %s\n", pubID);
} else {
"Resolve: sysID %s\n", sysID);
}
}
if (ret == XML_CATAL_BREAK)
} else {
}
return (ret);
}
/**
* xmlACatalogResolveURI:
* @catal: a Catalog
* @URI: the URI
*
* Do a complete resolution lookup of an URI
*
* Returns the URI of the resource or NULL if not found, it must be freed
* by the caller.
*/
xmlChar *
return(NULL);
if (xmlDebugCatalogs)
"Resolve URI %s\n", URI);
if (ret == XML_CATAL_BREAK)
} else {
}
return(ret);
}
#ifdef LIBXML_OUTPUT_ENABLED
/**
* xmlACatalogDump:
* @catal: a Catalog
* @out: the file.
*
* Dump the given catalog to the given file.
*/
void
return;
} else {
}
}
#endif /* LIBXML_OUTPUT_ENABLED */
/**
* xmlACatalogAdd:
* @catal: a Catalog
* @type: the type of record to add to the catalog
* @orig: the system, public or prefix to match
* @replace: the replacement value for the match
*
* Add an entry in the catalog, it may overwrite existing but
* different entries.
*
* Returns 0 if successful, -1 otherwise
*/
int
{
return(-1);
} else {
if (cattype != XML_CATA_NONE) {
}
}
return (res);
}
/**
* xmlACatalogRemove:
* @catal: a Catalog
* @value: the value to remove
*
* Remove an entry from the catalog
*
* Returns the number of entries removed if successful, -1 otherwise
*/
int
return(-1);
} else {
if (res == 0)
res = 1;
}
return(res);
}
/**
* xmlNewCatalog:
* @sgml: should this create an SGML catalog
*
* create a new Catalog.
*
* Returns the xmlCatalogPtr or NULL in case of error
*/
if (sgml) {
} else
return(catal);
}
/**
* xmlCatalogIsEmpty:
* @catal: should this create an SGML catalog
*
* Check is a catalog is empty
*
* Returns 1 if the catalog is empty, 0 if not, amd -1 in case of error.
*/
int
return(-1);
return(1);
return(-1);
return(1);
return(0);
} else {
int res;
return(1);
if (res == 0)
return(1);
if (res < 0)
return(-1);
}
return(0);
}
/************************************************************************
* *
* Public interfaces manipulating the global shared default catalog *
* *
************************************************************************/
/**
* xmlInitializeCatalogData:
*
* Do the catalog initialization only of global data, doesn't try to load
* any catalog actually.
* this function is not thread safe, catalog initialization should
* preferably be done once at startup
*/
static void
xmlInitializeCatalogData(void) {
if (xmlCatalogInitialized != 0)
return;
if (getenv("XML_DEBUG_CATALOG"))
xmlDebugCatalogs = 1;
}
/**
* xmlInitializeCatalog:
*
* Do the catalog initialization.
* this function is not thread safe, catalog initialization should
* preferably be done once at startup
*/
void
xmlInitializeCatalog(void) {
if (xmlCatalogInitialized != 0)
return;
if (getenv("XML_DEBUG_CATALOG"))
xmlDebugCatalogs = 1;
if (xmlDefaultCatalog == NULL) {
const char *catalogs;
char *path;
{
void* hmodule;
if (len != 0) {
while (*p != '\\' && p > buf)
p--;
if (p != buf) {
}
}
}
}
}
#else
#endif
/* the XML_CATALOG_FILES envvar is allowed to contain a
space-separated list of entries. */
while (*cur != '\0') {
while (xmlIsBlank_ch(*cur))
cur++;
if (*cur != 0) {
cur++;
}
}
}
}
}
}
/**
* xmlLoadCatalog:
* @filename: a file path
*
* Load the catalog and makes its definitions effective for the default
* external entity loader. It will recurse in SGML CATALOG entries.
* this function is not thread safe, catalog initialization should
* preferably be done once at startup
*
* Returns 0 in case of success -1 in case of error
*/
int
{
int ret;
if (!xmlCatalogInitialized)
if (xmlDefaultCatalog == NULL) {
return(-1);
}
return(0);
}
return(ret);
}
/**
* xmlLoadCatalogs:
* @pathss: a list of directories separated by a colon or a space.
*
* Load the catalogs and makes their definitions effective for the default
* external entity loader.
* this function is not thread safe, catalog initialization should
* preferably be done once at startup
*/
void
const char *cur;
const char *paths;
#ifdef _WIN32
int i, iLen;
#endif
return;
while (*cur != 0) {
if (*cur != 0) {
cur++;
#ifdef _WIN32
for(i = 0; i < iLen; i++) {
if(path[i] == '\\') {
path[i] = '/';
}
}
#endif
xmlLoadCatalog((const char *) path);
}
}
while (*cur == PATH_SEAPARATOR)
cur++;
}
}
/**
* xmlCatalogCleanup:
*
* Free up all the memory associated with catalogs
*/
void
xmlCatalogCleanup(void) {
if (xmlCatalogInitialized == 0)
return;
if (xmlDebugCatalogs)
"Catalogs cleanup\n");
if (xmlCatalogXMLFiles != NULL)
if (xmlDefaultCatalog != NULL)
xmlDebugCatalogs = 0;
}
/**
* xmlCatalogResolveSystem:
* @sysID: the system ID string
*
* Try to lookup the catalog resource for a system ID
*
* Returns the resource if found or NULL otherwise, the value returned
* must be freed by the caller.
*/
xmlChar *
if (!xmlCatalogInitialized)
return(ret);
}
/**
* xmlCatalogResolvePublic:
* @pubID: the public ID string
*
* Try to lookup the catalog reference associated to a public ID
*
* Returns the resource if found or NULL otherwise, the value returned
* must be freed by the caller.
*/
xmlChar *
if (!xmlCatalogInitialized)
return(ret);
}
/**
* xmlCatalogResolve:
* @pubID: the public ID string
* @sysID: the system ID string
*
* Do a complete resolution lookup of an External Identifier
*
* Returns the URI of the resource or NULL if not found, it must be freed
* by the caller.
*/
xmlChar *
if (!xmlCatalogInitialized)
return(ret);
}
/**
* xmlCatalogResolveURI:
* @URI: the URI
*
* Do a complete resolution lookup of an URI
*
* Returns the URI of the resource or NULL if not found, it must be freed
* by the caller.
*/
xmlChar *
if (!xmlCatalogInitialized)
return(ret);
}
#ifdef LIBXML_OUTPUT_ENABLED
/**
* xmlCatalogDump:
* @out: the file.
*
* Dump all the global catalog content to the given file.
*/
void
return;
if (!xmlCatalogInitialized)
}
#endif /* LIBXML_OUTPUT_ENABLED */
/**
* xmlCatalogAdd:
* @type: the type of record to add to the catalog
* @orig: the system, public or prefix to match
* @replace: the replacement value for the match
*
* Add an entry in the catalog, it may overwrite existing but
* different entries.
* If called before any other catalog routine, allows to override the
* default shared catalog put in place by xmlInitializeCatalog();
*
* Returns 0 if successful, -1 otherwise
*/
int
if (!xmlCatalogInitialized)
/*
* Specific case where one want to override the default catalog
* put in place by xmlInitializeCatalog();
*/
if ((xmlDefaultCatalog == NULL) &&
return(0);
}
return(res);
}
/**
* xmlCatalogRemove:
* @value: the value to remove
*
* Remove an entry from the catalog
*
* Returns the number of entries removed if successful, -1 otherwise
*/
int
int res;
if (!xmlCatalogInitialized)
return(res);
}
/**
* xmlCatalogConvert:
*
* Convert all the SGML catalog entries as XML ones
*
* Returns the number of entries converted if successful, -1 otherwise
*/
int
xmlCatalogConvert(void) {
if (!xmlCatalogInitialized)
return(res);
}
/************************************************************************
* *
* Public interface manipulating the common preferences *
* *
************************************************************************/
/**
* xmlCatalogGetDefaults:
*
* Used to get the user preference w.r.t. to what catalogs should
* be accepted
*
* Returns the current xmlCatalogAllow value
*/
xmlCatalogGetDefaults(void) {
return(xmlCatalogDefaultAllow);
}
/**
* xmlCatalogSetDefaults:
* @allow: what catalogs should be accepted
*
* Used to set the user preference w.r.t. to what catalogs should
* be accepted
*/
void
if (xmlDebugCatalogs) {
switch (allow) {
case XML_CATA_ALLOW_NONE:
"Disabling catalog usage\n");
break;
case XML_CATA_ALLOW_GLOBAL:
"Allowing only global catalogs\n");
break;
case XML_CATA_ALLOW_DOCUMENT:
"Allowing only catalogs from the document\n");
break;
case XML_CATA_ALLOW_ALL:
"Allowing all catalogs\n");
break;
}
}
}
/**
* xmlCatalogSetDefaultPrefer:
* @prefer: the default preference for delegation
*
* Allows to set the preference between public and system for deletion
* in XML Catalog resolution. C.f. section 4.1.1 of the spec
* Values accepted are XML_CATA_PREFER_PUBLIC or XML_CATA_PREFER_SYSTEM
*
* Returns the previous value of the default preference for delegation
*/
if (prefer == XML_CATA_PREFER_NONE)
return(ret);
if (xmlDebugCatalogs) {
switch (prefer) {
case XML_CATA_PREFER_PUBLIC:
"Setting catalog preference to PUBLIC\n");
break;
case XML_CATA_PREFER_SYSTEM:
"Setting catalog preference to SYSTEM\n");
break;
case XML_CATA_PREFER_NONE:
break;
}
}
return(ret);
}
/**
* xmlCatalogSetDebug:
* @level: the debug level of catalogs required
*
* Used to set the debug level for catalog operation, 0 disable
* debugging, 1 enable it
*
* Returns the previous value of the catalog debugging level
*/
int
if (level <= 0)
xmlDebugCatalogs = 0;
else
return(ret);
}
/************************************************************************
* *
* Minimal interfaces used for per-document catalogs by the parser *
* *
************************************************************************/
/**
* xmlCatalogFreeLocal:
* @catalogs: a document's list of catalogs
*
* Free up the memory associated to the catalog list
*/
void
if (!xmlCatalogInitialized)
}
/**
* xmlCatalogAddLocal:
* @catalogs: a document's list of catalogs
* @URL: the URL to a new local catalog
*
* Add the new entry to the catalog list
*
* Returns the updated list
*/
void *
if (!xmlCatalogInitialized)
return(catalogs);
if (xmlDebugCatalogs)
"Adding document catalog %s\n", URL);
return(catalogs);
return((void *) add);
return(catalogs);
}
/**
* xmlCatalogLocalResolve:
* @catalogs: a document's list of catalogs
* @pubID: the public ID string
* @sysID: the system ID string
*
* Do a complete resolution lookup of an External Identifier using a
* document's private catalog list
*
* Returns the URI of the resource or NULL if not found, it must be freed
* by the caller.
*/
xmlChar *
if (!xmlCatalogInitialized)
return(NULL);
if (xmlDebugCatalogs) {
"Local Resolve: pubID %s\n", pubID);
} else {
"Local Resolve: sysID %s\n", sysID);
}
}
return(NULL);
return(ret);
return(NULL);
}
/**
* xmlCatalogLocalResolveURI:
* @catalogs: a document's list of catalogs
* @URI: the URI
*
* Do a complete resolution lookup of an URI using a
* document's private catalog list
*
* Returns the URI of the resource or NULL if not found, it must be freed
* by the caller.
*/
xmlChar *
if (!xmlCatalogInitialized)
return(NULL);
if (xmlDebugCatalogs)
"Resolve URI %s\n", URI);
return(NULL);
return(ret);
return(NULL);
}
/************************************************************************
* *
* Deprecated interfaces *
* *
************************************************************************/
/**
* xmlCatalogGetSystem:
* @sysID: the system ID string
*
* Try to lookup the catalog reference associated to a system ID
* DEPRECATED, use xmlCatalogResolveSystem()
*
* Returns the resource if found or NULL otherwise.
*/
const xmlChar *
static int msg = 0;
if (!xmlCatalogInitialized)
if (msg == 0) {
"Use of deprecated xmlCatalogGetSystem() call\n");
msg++;
}
return(NULL);
/*
* Check first the XML catalogs
*/
if (xmlDefaultCatalog != NULL) {
return(result);
}
}
if (xmlDefaultCatalog != NULL)
return(NULL);
}
/**
* xmlCatalogGetPublic:
* @pubID: the public ID string
*
* Try to lookup the catalog reference associated to a public ID
* DEPRECATED, use xmlCatalogResolvePublic()
*
* Returns the resource if found or NULL otherwise.
*/
const xmlChar *
static int msg = 0;
if (!xmlCatalogInitialized)
if (msg == 0) {
"Use of deprecated xmlCatalogGetPublic() call\n");
msg++;
}
return(NULL);
/*
* Check first the XML catalogs
*/
if (xmlDefaultCatalog != NULL) {
return(result);
}
}
if (xmlDefaultCatalog != NULL)
return(NULL);
}
#define bottom_catalog
#include "elfgcchack.h"
#endif /* LIBXML_CATALOG_ENABLED */