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