mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-07-29 11:41:22 +03:00
starts to look okay, really plugged the new framework, cleaned a lot of
* catalog.c parser.c xmlIO.c xmlcatalog.c xmllint.c include/libxml/catalog.h: starts to look okay, really plugged the new framework, cleaned a lot of stuff, added some APIs, except the PI's support missing this should be mostly complete * result/catalogs/* test/catalogs/*: added new test, enriched the existing one with URN ID tests Daniel
This commit is contained in:
10
ChangeLog
10
ChangeLog
@ -1,3 +1,13 @@
|
|||||||
|
Wed Aug 22 02:03:31 CEST 2001 Daniel Veillard <daniel@veillard.com>
|
||||||
|
|
||||||
|
* catalog.c parser.c xmlIO.c xmlcatalog.c xmllint.c
|
||||||
|
include/libxml/catalog.h: starts to look okay, really
|
||||||
|
plugged the new framework, cleaned a lot of stuff,
|
||||||
|
added some APIs, except the PI's support missing this
|
||||||
|
should be mostly complete
|
||||||
|
* result/catalogs/* test/catalogs/*: added new test, enriched
|
||||||
|
the existing one with URN ID tests
|
||||||
|
|
||||||
Tue Aug 21 14:56:18 CEST 2001 Daniel Veillard <daniel@veillard.com>
|
Tue Aug 21 14:56:18 CEST 2001 Daniel Veillard <daniel@veillard.com>
|
||||||
|
|
||||||
* catalog.c: fixed nextCatalog
|
* catalog.c: fixed nextCatalog
|
||||||
|
588
catalog.c
588
catalog.c
@ -46,6 +46,8 @@
|
|||||||
__FILE__, __LINE__);
|
__FILE__, __LINE__);
|
||||||
|
|
||||||
#define XML_URN_PUBID "urn:publicid:"
|
#define XML_URN_PUBID "urn:publicid:"
|
||||||
|
#define XML_CATAL_BREAK ((xmlChar *) -1)
|
||||||
|
#define XML_DEFAULT_CATALOG "/etc/xml/catalog"
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* *
|
* *
|
||||||
@ -53,11 +55,6 @@
|
|||||||
* *
|
* *
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
XML_CATA_PREFER_PUBLIC = 1,
|
|
||||||
XML_CATA_PREFER_SYSTEM
|
|
||||||
} xmlCatalogPrefer;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
XML_CATA_NONE = 0,
|
XML_CATA_NONE = 0,
|
||||||
XML_CATA_CATALOG,
|
XML_CATA_CATALOG,
|
||||||
@ -93,11 +90,14 @@ struct _xmlCatalogEntry {
|
|||||||
xmlCatalogEntryType type;
|
xmlCatalogEntryType type;
|
||||||
xmlChar *name;
|
xmlChar *name;
|
||||||
xmlChar *value;
|
xmlChar *value;
|
||||||
/* TODO : 1234 xmlCatalogPrefer prefer */
|
xmlCatalogPrefer prefer;
|
||||||
};
|
};
|
||||||
|
|
||||||
static xmlHashTablePtr xmlDefaultCatalog;
|
static xmlHashTablePtr xmlDefaultCatalog;
|
||||||
static xmlCatalogEntryPtr xmlDefaultXMLCatalogList = NULL;
|
static xmlCatalogEntryPtr xmlDefaultXMLCatalogList = NULL;
|
||||||
|
static int xmlCatalogInitialized = 0;
|
||||||
|
static xmlCatalogPrefer xmlCatalogDefaultPrefer = XML_CATA_PREFER_SYSTEM;
|
||||||
|
|
||||||
|
|
||||||
/* Catalog stack */
|
/* Catalog stack */
|
||||||
static const char * catalTab[10]; /* stack of catals */
|
static const char * catalTab[10]; /* stack of catals */
|
||||||
@ -114,7 +114,7 @@ static int xmlDebugCatalogs = 0; /* used for debugging */
|
|||||||
|
|
||||||
static xmlCatalogEntryPtr
|
static xmlCatalogEntryPtr
|
||||||
xmlNewCatalogEntry(xmlCatalogEntryType type, const xmlChar *name,
|
xmlNewCatalogEntry(xmlCatalogEntryType type, const xmlChar *name,
|
||||||
const xmlChar *value) {
|
const xmlChar *value, xmlCatalogPrefer prefer) {
|
||||||
xmlCatalogEntryPtr ret;
|
xmlCatalogEntryPtr ret;
|
||||||
|
|
||||||
ret = (xmlCatalogEntryPtr) xmlMalloc(sizeof(xmlCatalogEntry));
|
ret = (xmlCatalogEntryPtr) xmlMalloc(sizeof(xmlCatalogEntry));
|
||||||
@ -135,6 +135,7 @@ xmlNewCatalogEntry(xmlCatalogEntryType type, const xmlChar *name,
|
|||||||
ret->value = xmlStrdup(value);
|
ret->value = xmlStrdup(value);
|
||||||
else
|
else
|
||||||
ret->value = NULL;
|
ret->value = NULL;
|
||||||
|
ret->prefer = prefer;
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,6 +239,77 @@ xmlCatalogDumpEntry(xmlCatalogEntryPtr entry, FILE *out) {
|
|||||||
fprintf(out, "\n");
|
fprintf(out, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* *
|
||||||
|
* Helper function *
|
||||||
|
* *
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlCatalogUnWrapURN:
|
||||||
|
* @urn: an "urn:publicid:" to unwrapp
|
||||||
|
*
|
||||||
|
* Expand the URN into the equivalent Public Identifier
|
||||||
|
*
|
||||||
|
* Returns the new identifier or NULL, the string must be deallocated
|
||||||
|
* by the caller.
|
||||||
|
*/
|
||||||
|
static xmlChar *
|
||||||
|
xmlCatalogUnWrapURN(const xmlChar *urn) {
|
||||||
|
xmlChar result[2000];
|
||||||
|
unsigned int i = 0;
|
||||||
|
|
||||||
|
if (xmlStrncmp(urn, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1))
|
||||||
|
return(NULL);
|
||||||
|
urn += sizeof(XML_URN_PUBID) - 1;
|
||||||
|
|
||||||
|
while (*urn != 0) {
|
||||||
|
if (i > sizeof(result) - 3)
|
||||||
|
break;
|
||||||
|
if (*urn == '+') {
|
||||||
|
result[i++] = ' ';
|
||||||
|
urn++;
|
||||||
|
} else if (*urn == ':') {
|
||||||
|
result[i++] = '/';
|
||||||
|
result[i++] = '/';
|
||||||
|
urn++;
|
||||||
|
} else if (*urn == ';') {
|
||||||
|
result[i++] = ':';
|
||||||
|
result[i++] = ':';
|
||||||
|
urn++;
|
||||||
|
} else if (*urn == '%') {
|
||||||
|
if ((urn[1] == '2') && (urn[1] == 'B'))
|
||||||
|
result[i++] = '+';
|
||||||
|
else if ((urn[1] == '3') && (urn[1] == 'A'))
|
||||||
|
result[i++] = ':';
|
||||||
|
else if ((urn[1] == '2') && (urn[1] == 'F'))
|
||||||
|
result[i++] = '/';
|
||||||
|
else if ((urn[1] == '3') && (urn[1] == 'B'))
|
||||||
|
result[i++] = ';';
|
||||||
|
else if ((urn[1] == '2') && (urn[1] == '7'))
|
||||||
|
result[i++] = '\'';
|
||||||
|
else if ((urn[1] == '3') && (urn[1] == 'F'))
|
||||||
|
result[i++] = '?';
|
||||||
|
else if ((urn[1] == '2') && (urn[1] == '3'))
|
||||||
|
result[i++] = '#';
|
||||||
|
else if ((urn[1] == '2') && (urn[1] == '5'))
|
||||||
|
result[i++] = '%';
|
||||||
|
else {
|
||||||
|
result[i++] = *urn;
|
||||||
|
urn++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
urn += 3;
|
||||||
|
} else {
|
||||||
|
result[i++] = *urn;
|
||||||
|
urn++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result[i] = 0;
|
||||||
|
|
||||||
|
return(xmlStrdup(result));
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* *
|
* *
|
||||||
* The XML Catalog parser *
|
* The XML Catalog parser *
|
||||||
@ -286,7 +358,7 @@ xmlGetXMLCatalogEntryType(const xmlChar *name) {
|
|||||||
static xmlCatalogEntryPtr
|
static xmlCatalogEntryPtr
|
||||||
xmlParseXMLCatalogOneNode(xmlNodePtr cur, xmlCatalogEntryType type,
|
xmlParseXMLCatalogOneNode(xmlNodePtr cur, xmlCatalogEntryType type,
|
||||||
const xmlChar *name, const xmlChar *attrName,
|
const xmlChar *name, const xmlChar *attrName,
|
||||||
const xmlChar *uriAttrName) {
|
const xmlChar *uriAttrName, xmlCatalogPrefer prefer) {
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
xmlChar *uriValue;
|
xmlChar *uriValue;
|
||||||
xmlChar *nameValue = NULL;
|
xmlChar *nameValue = NULL;
|
||||||
@ -319,13 +391,15 @@ xmlParseXMLCatalogOneNode(xmlNodePtr cur, xmlCatalogEntryType type,
|
|||||||
base = xmlNodeGetBase(cur->doc, cur);
|
base = xmlNodeGetBase(cur->doc, cur);
|
||||||
URL = xmlBuildURI(uriValue, base);
|
URL = xmlBuildURI(uriValue, base);
|
||||||
if (URL != NULL) {
|
if (URL != NULL) {
|
||||||
if (xmlDebugCatalogs) {
|
if (xmlDebugCatalogs > 1) {
|
||||||
if (nameValue != NULL)
|
if (nameValue != NULL)
|
||||||
printf("Found %s: '%s' '%s'\n", name, nameValue, URL);
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"Found %s: '%s' '%s'\n", name, nameValue, URL);
|
||||||
else
|
else
|
||||||
printf("Found %s: '%s'\n", name, URL);
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"Found %s: '%s'\n", name, URL);
|
||||||
}
|
}
|
||||||
ret = xmlNewCatalogEntry(type, nameValue, URL);
|
ret = xmlNewCatalogEntry(type, nameValue, URL, prefer);
|
||||||
} else {
|
} else {
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
"%s entry '%s' broken ?: %s\n", name, uriAttrName, uriValue);
|
"%s entry '%s' broken ?: %s\n", name, uriAttrName, uriValue);
|
||||||
@ -374,38 +448,38 @@ xmlParseXMLCatalogNode(xmlNodePtr cur, xmlCatalogPrefer prefer,
|
|||||||
xmlParseXMLCatalogNodeList(cur->children, prefer, parent);
|
xmlParseXMLCatalogNodeList(cur->children, prefer, parent);
|
||||||
} else if (xmlStrEqual(cur->name, BAD_CAST "public")) {
|
} else if (xmlStrEqual(cur->name, BAD_CAST "public")) {
|
||||||
entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_PUBLIC,
|
entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_PUBLIC,
|
||||||
BAD_CAST "public", BAD_CAST "publicId", BAD_CAST "uri");
|
BAD_CAST "public", BAD_CAST "publicId", BAD_CAST "uri", prefer);
|
||||||
} else if (xmlStrEqual(cur->name, BAD_CAST "system")) {
|
} else if (xmlStrEqual(cur->name, BAD_CAST "system")) {
|
||||||
entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_SYSTEM,
|
entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_SYSTEM,
|
||||||
BAD_CAST "system", BAD_CAST "systemId", BAD_CAST "uri");
|
BAD_CAST "system", BAD_CAST "systemId", BAD_CAST "uri", prefer);
|
||||||
} else if (xmlStrEqual(cur->name, BAD_CAST "rewriteSystem")) {
|
} else if (xmlStrEqual(cur->name, BAD_CAST "rewriteSystem")) {
|
||||||
entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_SYSTEM,
|
entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_SYSTEM,
|
||||||
BAD_CAST "rewriteSystem", BAD_CAST "systemIdStartString",
|
BAD_CAST "rewriteSystem", BAD_CAST "systemIdStartString",
|
||||||
BAD_CAST "rewritePrefix");
|
BAD_CAST "rewritePrefix", prefer);
|
||||||
} else if (xmlStrEqual(cur->name, BAD_CAST "delegatePublic")) {
|
} else if (xmlStrEqual(cur->name, BAD_CAST "delegatePublic")) {
|
||||||
entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_PUBLIC,
|
entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_PUBLIC,
|
||||||
BAD_CAST "delegatePublic", BAD_CAST "publicIdStartString",
|
BAD_CAST "delegatePublic", BAD_CAST "publicIdStartString",
|
||||||
BAD_CAST "catalog");
|
BAD_CAST "catalog", prefer);
|
||||||
} else if (xmlStrEqual(cur->name, BAD_CAST "delegateSystem")) {
|
} else if (xmlStrEqual(cur->name, BAD_CAST "delegateSystem")) {
|
||||||
entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_SYSTEM,
|
entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_SYSTEM,
|
||||||
BAD_CAST "delegateSystem", BAD_CAST "systemIdStartString",
|
BAD_CAST "delegateSystem", BAD_CAST "systemIdStartString",
|
||||||
BAD_CAST "catalog");
|
BAD_CAST "catalog", prefer);
|
||||||
} else if (xmlStrEqual(cur->name, BAD_CAST "uri")) {
|
} else if (xmlStrEqual(cur->name, BAD_CAST "uri")) {
|
||||||
entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_URI,
|
entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_URI,
|
||||||
BAD_CAST "uri", BAD_CAST "name",
|
BAD_CAST "uri", BAD_CAST "name",
|
||||||
BAD_CAST "uri");
|
BAD_CAST "uri", prefer);
|
||||||
} else if (xmlStrEqual(cur->name, BAD_CAST "rewriteURI")) {
|
} else if (xmlStrEqual(cur->name, BAD_CAST "rewriteURI")) {
|
||||||
entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_URI,
|
entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_URI,
|
||||||
BAD_CAST "rewriteURI", BAD_CAST "uriStartString",
|
BAD_CAST "rewriteURI", BAD_CAST "uriStartString",
|
||||||
BAD_CAST "rewritePrefix");
|
BAD_CAST "rewritePrefix", prefer);
|
||||||
} else if (xmlStrEqual(cur->name, BAD_CAST "delegateURI")) {
|
} else if (xmlStrEqual(cur->name, BAD_CAST "delegateURI")) {
|
||||||
entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_URI,
|
entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_URI,
|
||||||
BAD_CAST "delegateURI", BAD_CAST "uriStartString",
|
BAD_CAST "delegateURI", BAD_CAST "uriStartString",
|
||||||
BAD_CAST "catalog");
|
BAD_CAST "catalog", prefer);
|
||||||
} else if (xmlStrEqual(cur->name, BAD_CAST "nextCatalog")) {
|
} else if (xmlStrEqual(cur->name, BAD_CAST "nextCatalog")) {
|
||||||
entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_NEXT_CATALOG,
|
entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_NEXT_CATALOG,
|
||||||
BAD_CAST "nextCatalog", NULL,
|
BAD_CAST "nextCatalog", NULL,
|
||||||
BAD_CAST "catalog");
|
BAD_CAST "catalog", prefer);
|
||||||
}
|
}
|
||||||
if ((entry != NULL) && (parent != NULL)) {
|
if ((entry != NULL) && (parent != NULL)) {
|
||||||
entry->parent = parent;
|
entry->parent = parent;
|
||||||
@ -452,6 +526,10 @@ xmlParseXMLCatalog(const xmlChar *value, xmlCatalogPrefer prefer,
|
|||||||
if ((value == NULL) || (file == NULL))
|
if ((value == NULL) || (file == NULL))
|
||||||
return(NULL);
|
return(NULL);
|
||||||
|
|
||||||
|
if (xmlDebugCatalogs)
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"Parsing catalog %s's content\n", file);
|
||||||
|
|
||||||
doc = xmlParseDoc((xmlChar *) value);
|
doc = xmlParseDoc((xmlChar *) value);
|
||||||
if (doc == NULL)
|
if (doc == NULL)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
@ -462,13 +540,6 @@ xmlParseXMLCatalog(const xmlChar *value, xmlCatalogPrefer prefer,
|
|||||||
(cur->ns != NULL) && (cur->ns->href != NULL) &&
|
(cur->ns != NULL) && (cur->ns->href != NULL) &&
|
||||||
(xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {
|
(xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {
|
||||||
|
|
||||||
parent = xmlNewCatalogEntry(XML_CATA_CATALOG,
|
|
||||||
(const xmlChar *)file, NULL);
|
|
||||||
if (parent == NULL) {
|
|
||||||
xmlFreeDoc(doc);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
prop = xmlGetProp(cur, BAD_CAST "prefer");
|
prop = xmlGetProp(cur, BAD_CAST "prefer");
|
||||||
if (prop != NULL) {
|
if (prop != NULL) {
|
||||||
if (xmlStrEqual(prop, BAD_CAST "system")) {
|
if (xmlStrEqual(prop, BAD_CAST "system")) {
|
||||||
@ -482,6 +553,13 @@ xmlParseXMLCatalog(const xmlChar *value, xmlCatalogPrefer prefer,
|
|||||||
}
|
}
|
||||||
xmlFree(prop);
|
xmlFree(prop);
|
||||||
}
|
}
|
||||||
|
parent = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
|
||||||
|
(const xmlChar *)file, prefer);
|
||||||
|
if (parent == NULL) {
|
||||||
|
xmlFreeDoc(doc);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
cur = cur->children;
|
cur = cur->children;
|
||||||
xmlParseXMLCatalogNodeList(cur, prefer, parent);
|
xmlParseXMLCatalogNodeList(cur, prefer, parent);
|
||||||
} else {
|
} else {
|
||||||
@ -505,16 +583,24 @@ xmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename) {
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
|
|
||||||
doc = xmlParseFile((const char *) filename);
|
doc = xmlParseFile((const char *) filename);
|
||||||
if (doc == NULL)
|
if (doc == NULL) {
|
||||||
|
if (xmlDebugCatalogs)
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"Failed to parse catalog %s\n", filename);
|
||||||
return(NULL);
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xmlDebugCatalogs)
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"Parsing catalog %s\n", filename);
|
||||||
|
|
||||||
cur = xmlDocGetRootElement(doc);
|
cur = xmlDocGetRootElement(doc);
|
||||||
if ((cur != NULL) && (xmlStrEqual(cur->name, BAD_CAST "catalog")) &&
|
if ((cur != NULL) && (xmlStrEqual(cur->name, BAD_CAST "catalog")) &&
|
||||||
(cur->ns != NULL) && (cur->ns->href != NULL) &&
|
(cur->ns != NULL) && (cur->ns->href != NULL) &&
|
||||||
(xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {
|
(xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {
|
||||||
|
|
||||||
parent = xmlNewCatalogEntry(XML_CATA_CATALOG,
|
parent = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
|
||||||
(const xmlChar *)filename, NULL);
|
(const xmlChar *)filename, prefer);
|
||||||
if (parent == NULL) {
|
if (parent == NULL) {
|
||||||
xmlFreeDoc(doc);
|
xmlFreeDoc(doc);
|
||||||
return(NULL);
|
return(NULL);
|
||||||
@ -569,8 +655,7 @@ xmlFetchXMLCatalogFile(xmlCatalogEntryPtr catal) {
|
|||||||
/*
|
/*
|
||||||
* Fetch and parse
|
* Fetch and parse
|
||||||
*/
|
*/
|
||||||
/* TODO : 1234 s/XML_CATA_PREFER_PUBLIC/catal->prefer */
|
children = xmlParseXMLCatalogFile(catal->prefer, catal->value);
|
||||||
children = xmlParseXMLCatalogFile(XML_CATA_PREFER_PUBLIC, catal->value);
|
|
||||||
if (children == NULL)
|
if (children == NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
|
|
||||||
@ -747,8 +832,12 @@ xmlAddXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *type,
|
|||||||
if ((catal == NULL) || (catal->type != XML_CATA_CATALOG))
|
if ((catal == NULL) || (catal->type != XML_CATA_CATALOG))
|
||||||
return(-1);
|
return(-1);
|
||||||
typ = xmlGetXMLCatalogEntryType(type);
|
typ = xmlGetXMLCatalogEntryType(type);
|
||||||
if (typ == XML_CATA_NONE)
|
if (typ == XML_CATA_NONE) {
|
||||||
|
if (xmlDebugCatalogs)
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"Failed to add unknown element %s to catalog\n", type);
|
||||||
return(-1);
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
cur = catal->children;
|
cur = catal->children;
|
||||||
/*
|
/*
|
||||||
@ -758,6 +847,9 @@ xmlAddXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *type,
|
|||||||
while (cur != NULL) {
|
while (cur != NULL) {
|
||||||
if ((orig != NULL) && (cur->type == typ) &&
|
if ((orig != NULL) && (cur->type == typ) &&
|
||||||
(xmlStrEqual(orig, cur->name))) {
|
(xmlStrEqual(orig, cur->name))) {
|
||||||
|
if (xmlDebugCatalogs)
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"Updating element %s to catalog\n", type);
|
||||||
if (cur->value != NULL)
|
if (cur->value != NULL)
|
||||||
xmlFree(cur->value);
|
xmlFree(cur->value);
|
||||||
cur->value = xmlStrdup(replace);
|
cur->value = xmlStrdup(replace);
|
||||||
@ -768,10 +860,13 @@ xmlAddXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *type,
|
|||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (xmlDebugCatalogs)
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"Adding element %s to catalog\n", type);
|
||||||
if (cur == NULL)
|
if (cur == NULL)
|
||||||
catal->children = xmlNewCatalogEntry(typ, orig, replace);
|
catal->children = xmlNewCatalogEntry(typ, orig, replace, catal->prefer);
|
||||||
else
|
else
|
||||||
cur->next = xmlNewCatalogEntry(typ, orig, replace);
|
cur->next = xmlNewCatalogEntry(typ, orig, replace, catal->prefer);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -803,6 +898,14 @@ xmlDelXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *value) {
|
|||||||
while (cur != NULL) {
|
while (cur != NULL) {
|
||||||
if (((cur->name != NULL) && (xmlStrEqual(value, cur->name))) ||
|
if (((cur->name != NULL) && (xmlStrEqual(value, cur->name))) ||
|
||||||
(xmlStrEqual(value, cur->value))) {
|
(xmlStrEqual(value, cur->value))) {
|
||||||
|
if (xmlDebugCatalogs) {
|
||||||
|
if (cur->name != NULL)
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"Removing element %s from catalog\n", cur->name);
|
||||||
|
else
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"Removing element %s from catalog\n", cur->value);
|
||||||
|
}
|
||||||
ret++;
|
ret++;
|
||||||
tmp = cur;
|
tmp = cur;
|
||||||
cur = tmp->next;
|
cur = tmp->next;
|
||||||
@ -820,69 +923,6 @@ xmlDelXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *value) {
|
|||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* xmlCatalogGetXMLPublic:
|
|
||||||
* @catal: an XML catalog
|
|
||||||
* @pubId: the public ID string
|
|
||||||
*
|
|
||||||
* Try to lookup the system ID associated to a public ID
|
|
||||||
*
|
|
||||||
* Returns the system ID if found or NULL otherwise.
|
|
||||||
*/
|
|
||||||
static const xmlChar *
|
|
||||||
xmlCatalogGetXMLPublic(xmlCatalogEntryPtr catal, const xmlChar *pubID) {
|
|
||||||
const xmlChar *ret;
|
|
||||||
while (catal != NULL) {
|
|
||||||
switch (catal->type) {
|
|
||||||
case XML_CATA_CATALOG:
|
|
||||||
if (catal->children == NULL) {
|
|
||||||
if (xmlFetchXMLCatalogFile(catal))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ret = xmlCatalogGetXMLPublic(catal->children, pubID);
|
|
||||||
if (ret != NULL)
|
|
||||||
return(ret);
|
|
||||||
break;
|
|
||||||
case XML_CATA_NEXT_CATALOG:
|
|
||||||
if (catal->children == NULL) {
|
|
||||||
if (xmlFetchXMLCatalogFile(catal))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case XML_CATA_PUBLIC:
|
|
||||||
if (xmlStrEqual(pubID, catal->name))
|
|
||||||
return(catal->value);
|
|
||||||
break;
|
|
||||||
case XML_CATA_SYSTEM:
|
|
||||||
case XML_CATA_REWRITE_SYSTEM:
|
|
||||||
case XML_CATA_DELEGATE_PUBLIC:
|
|
||||||
case XML_CATA_DELEGATE_SYSTEM:
|
|
||||||
case XML_CATA_URI:
|
|
||||||
case XML_CATA_REWRITE_URI:
|
|
||||||
case XML_CATA_DELEGATE_URI:
|
|
||||||
TODO;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case XML_CATA_NONE:
|
|
||||||
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:
|
|
||||||
/* Ignored entries */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
catal = catal->next;
|
|
||||||
}
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlCatalogXMLResolve:
|
* xmlCatalogXMLResolve:
|
||||||
* @catal: a catalog list
|
* @catal: a catalog list
|
||||||
@ -916,8 +956,12 @@ xmlCatalogXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
|
|||||||
while (cur != NULL) {
|
while (cur != NULL) {
|
||||||
switch (cur->type) {
|
switch (cur->type) {
|
||||||
case XML_CATA_SYSTEM:
|
case XML_CATA_SYSTEM:
|
||||||
if (xmlStrEqual(sysID, cur->name))
|
if (xmlStrEqual(sysID, cur->name)) {
|
||||||
|
if (xmlDebugCatalogs)
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"Found system match %s\n", cur->name);
|
||||||
return(xmlStrdup(cur->value));
|
return(xmlStrdup(cur->value));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case XML_CATA_REWRITE_SYSTEM:
|
case XML_CATA_REWRITE_SYSTEM:
|
||||||
len = xmlStrlen(cur->name);
|
len = xmlStrlen(cur->name);
|
||||||
@ -940,6 +984,9 @@ xmlCatalogXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
|
|||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
if (rewrite != NULL) {
|
if (rewrite != NULL) {
|
||||||
|
if (xmlDebugCatalogs)
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"Using rewriting rule %s\n", rewrite->name);
|
||||||
ret = xmlStrdup(rewrite->value);
|
ret = xmlStrdup(rewrite->value);
|
||||||
if (ret != NULL)
|
if (ret != NULL)
|
||||||
ret = xmlStrcat(ret, &sysID[lenrewrite]);
|
ret = xmlStrcat(ret, &sysID[lenrewrite]);
|
||||||
@ -947,7 +994,7 @@ xmlCatalogXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
|
|||||||
}
|
}
|
||||||
if (haveDelegate) {
|
if (haveDelegate) {
|
||||||
/*
|
/*
|
||||||
* Assume the entries have been sorted by decreasing subscting
|
* Assume the entries have been sorted by decreasing substring
|
||||||
* matches when the list was produced.
|
* matches when the list was produced.
|
||||||
*/
|
*/
|
||||||
cur = catal;
|
cur = catal;
|
||||||
@ -958,11 +1005,21 @@ xmlCatalogXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
|
|||||||
xmlFetchXMLCatalogFile(cur);
|
xmlFetchXMLCatalogFile(cur);
|
||||||
}
|
}
|
||||||
if (cur->children != NULL) {
|
if (cur->children != NULL) {
|
||||||
TODO /* handle a delegate system entry */
|
if (xmlDebugCatalogs)
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"Trying system delegate %s\n", cur->value);
|
||||||
|
ret = xmlCatalogListXMLResolve(cur->children, NULL,
|
||||||
|
sysID);
|
||||||
|
if (ret != NULL)
|
||||||
|
return(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Apply the cut algorithm explained in 4/
|
||||||
|
*/
|
||||||
|
return(XML_CATAL_BREAK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -974,11 +1031,16 @@ xmlCatalogXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
|
|||||||
while (cur != NULL) {
|
while (cur != NULL) {
|
||||||
switch (cur->type) {
|
switch (cur->type) {
|
||||||
case XML_CATA_PUBLIC:
|
case XML_CATA_PUBLIC:
|
||||||
if (xmlStrEqual(pubID, cur->name))
|
if (xmlStrEqual(pubID, cur->name)) {
|
||||||
|
if (xmlDebugCatalogs)
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"Found public match %s\n", cur->name);
|
||||||
return(xmlStrdup(cur->value));
|
return(xmlStrdup(cur->value));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case XML_CATA_DELEGATE_PUBLIC:
|
case XML_CATA_DELEGATE_PUBLIC:
|
||||||
if (!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)))
|
if (!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)) &&
|
||||||
|
(cur->prefer == XML_CATA_PREFER_PUBLIC))
|
||||||
haveDelegate++;
|
haveDelegate++;
|
||||||
break;
|
break;
|
||||||
case XML_CATA_NEXT_CATALOG:
|
case XML_CATA_NEXT_CATALOG:
|
||||||
@ -992,22 +1054,33 @@ xmlCatalogXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
|
|||||||
}
|
}
|
||||||
if (haveDelegate) {
|
if (haveDelegate) {
|
||||||
/*
|
/*
|
||||||
* Assume the entries have been sorted by decreasing subscting
|
* Assume the entries have been sorted by decreasing substring
|
||||||
* matches when the list was produced.
|
* matches when the list was produced.
|
||||||
*/
|
*/
|
||||||
cur = catal;
|
cur = catal;
|
||||||
while (cur != NULL) {
|
while (cur != NULL) {
|
||||||
if ((cur->type == XML_CATA_DELEGATE_PUBLIC) &&
|
if ((cur->type == XML_CATA_DELEGATE_PUBLIC) &&
|
||||||
(!xmlStrncmp(sysID, cur->name, xmlStrlen(cur->name)))) {
|
(cur->prefer == XML_CATA_PREFER_PUBLIC) &&
|
||||||
|
(!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)))) {
|
||||||
if (cur->children == NULL) {
|
if (cur->children == NULL) {
|
||||||
xmlFetchXMLCatalogFile(cur);
|
xmlFetchXMLCatalogFile(cur);
|
||||||
}
|
}
|
||||||
if (cur->children != NULL) {
|
if (cur->children != NULL) {
|
||||||
TODO /* handle a delegate public entry */
|
if (xmlDebugCatalogs)
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"Trying public delegate %s\n", cur->value);
|
||||||
|
ret = xmlCatalogListXMLResolve(cur->children, pubID,
|
||||||
|
NULL);
|
||||||
|
if (ret != NULL)
|
||||||
|
return(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Apply the cut algorithm explained in 4/
|
||||||
|
*/
|
||||||
|
return(XML_CATAL_BREAK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (haveNext) {
|
if (haveNext) {
|
||||||
@ -1048,28 +1121,59 @@ static xmlChar *
|
|||||||
xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
|
xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
|
||||||
const xmlChar *sysID) {
|
const xmlChar *sysID) {
|
||||||
xmlChar *ret = NULL;
|
xmlChar *ret = NULL;
|
||||||
if (!xmlStrncmp(pubID, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID))) {
|
xmlChar *urnID = NULL;
|
||||||
TODO /* convert to PublicId */
|
|
||||||
|
if (catal == NULL)
|
||||||
|
return(NULL);
|
||||||
|
if ((pubID == NULL) && (sysID == NULL))
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
if (!xmlStrncmp(pubID, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
|
||||||
|
urnID = xmlCatalogUnWrapURN(pubID);
|
||||||
|
if (xmlDebugCatalogs) {
|
||||||
|
if (urnID == NULL)
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"Public URN ID %s expanded to NULL\n", pubID);
|
||||||
|
else
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"Public URN ID expanded to %s\n", urnID);
|
||||||
|
}
|
||||||
|
ret = xmlCatalogListXMLResolve(catal, urnID, sysID);
|
||||||
|
if (urnID != NULL)
|
||||||
|
xmlFree(urnID);
|
||||||
|
return(ret);
|
||||||
}
|
}
|
||||||
if (!xmlStrncmp(sysID, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID))) {
|
if (!xmlStrncmp(sysID, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
|
||||||
TODO /* convert to PublicId and check */
|
urnID = xmlCatalogUnWrapURN(sysID);
|
||||||
|
if (xmlDebugCatalogs) {
|
||||||
|
if (urnID == NULL)
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"System URN ID %s expanded to NULL\n", sysID);
|
||||||
|
else
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"System URN ID expanded to %s\n", urnID);
|
||||||
|
}
|
||||||
|
if (pubID == NULL)
|
||||||
|
ret = xmlCatalogListXMLResolve(catal, urnID, NULL);
|
||||||
|
else if (xmlStrEqual(pubID, urnID))
|
||||||
|
ret = xmlCatalogListXMLResolve(catal, pubID, NULL);
|
||||||
|
else {
|
||||||
|
ret = xmlCatalogListXMLResolve(catal, pubID, NULL);
|
||||||
|
}
|
||||||
|
if (urnID != NULL)
|
||||||
|
xmlFree(urnID);
|
||||||
|
return(ret);
|
||||||
}
|
}
|
||||||
while (catal != NULL) {
|
while (catal != NULL) {
|
||||||
if (catal->type == XML_CATA_CATALOG) {
|
if (catal->type == XML_CATA_CATALOG) {
|
||||||
if (catal->children == NULL) {
|
if (catal->children == NULL) {
|
||||||
/*
|
xmlFetchXMLCatalogFile(catal);
|
||||||
* Construct the list on the fly, then double check
|
}
|
||||||
* in case of threaded program that it hasn't already
|
if (catal->children != NULL) {
|
||||||
* being built by a concurrent thread.
|
ret = xmlCatalogXMLResolve(catal->children, pubID, sysID);
|
||||||
xmlCatalogEntryPtr list;
|
if (ret != NULL)
|
||||||
|
return(ret);
|
||||||
list =
|
|
||||||
*/
|
|
||||||
TODO
|
|
||||||
}
|
}
|
||||||
ret = xmlCatalogXMLResolve(catal->children, pubID, sysID);
|
|
||||||
if (ret != NULL)
|
|
||||||
return(ret);
|
|
||||||
}
|
}
|
||||||
catal = catal->next;
|
catal = catal->next;
|
||||||
}
|
}
|
||||||
@ -1365,7 +1469,8 @@ xmlParseSGMLCatalog(const xmlChar *value, const char *file) {
|
|||||||
if (filename != NULL) {
|
if (filename != NULL) {
|
||||||
xmlCatalogEntryPtr entry;
|
xmlCatalogEntryPtr entry;
|
||||||
|
|
||||||
entry = xmlNewCatalogEntry(type, name, filename);
|
entry = xmlNewCatalogEntry(type, name, filename,
|
||||||
|
XML_CATA_PREFER_NONE);
|
||||||
res = xmlHashAddEntry(xmlDefaultCatalog, name, entry);
|
res = xmlHashAddEntry(xmlDefaultCatalog, name, entry);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
xmlFreeCatalogEntry(entry);
|
xmlFreeCatalogEntry(entry);
|
||||||
@ -1422,6 +1527,30 @@ xmlCatalogGetSGMLPublic(xmlHashTablePtr catal, const xmlChar *pubID) {
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlCatalogGetSGMLSystem:
|
||||||
|
* @catal: an SGML catalog hash
|
||||||
|
* @sysId: the public ID string
|
||||||
|
*
|
||||||
|
* Try to lookup the catalog local reference for a system ID
|
||||||
|
*
|
||||||
|
* Returns the system ID if found or NULL otherwise.
|
||||||
|
*/
|
||||||
|
static const xmlChar *
|
||||||
|
xmlCatalogGetSGMLSystem(xmlHashTablePtr catal, const xmlChar *sysID) {
|
||||||
|
xmlCatalogEntryPtr entry;
|
||||||
|
|
||||||
|
if (catal == NULL)
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
entry = (xmlCatalogEntryPtr) xmlHashLookup(catal, sysID);
|
||||||
|
if (entry == NULL)
|
||||||
|
return(NULL);
|
||||||
|
if (entry->type == SGML_CATA_SYSTEM)
|
||||||
|
return(entry->value);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlCatalogSGMLResolve:
|
* xmlCatalogSGMLResolve:
|
||||||
* @pubId: the public ID string
|
* @pubId: the public ID string
|
||||||
@ -1443,6 +1572,33 @@ xmlCatalogSGMLResolve(const xmlChar *pubID, const xmlChar *sysID) {
|
|||||||
* *
|
* *
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlInitializeCatalog:
|
||||||
|
*
|
||||||
|
* Do the catalog initialization.
|
||||||
|
* TODO: this function is not thread safe, catalog initialization should
|
||||||
|
* preferably be done once at startup
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xmlInitializeCatalog(void) {
|
||||||
|
const char *catalogs;
|
||||||
|
|
||||||
|
if (xmlCatalogInitialized != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (getenv("XML_DEBUG_CATALOG"))
|
||||||
|
xmlDebugCatalogs = 1;
|
||||||
|
if ((xmlDefaultXMLCatalogList == NULL) && (xmlDefaultCatalog == NULL)) {
|
||||||
|
catalogs = getenv("XML_CATALOG_FILES");
|
||||||
|
if (catalogs == NULL)
|
||||||
|
catalogs = XML_DEFAULT_CATALOG;
|
||||||
|
xmlDefaultXMLCatalogList = xmlNewCatalogEntry(XML_CATA_CATALOG,
|
||||||
|
NULL, BAD_CAST catalogs, xmlCatalogDefaultPrefer);
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlCatalogInitialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlLoadCatalog:
|
* xmlLoadCatalog:
|
||||||
* @filename: a file path
|
* @filename: a file path
|
||||||
@ -1450,7 +1606,7 @@ xmlCatalogSGMLResolve(const xmlChar *pubID, const xmlChar *sysID) {
|
|||||||
* Load the catalog and makes its definitions effective for the default
|
* Load the catalog and makes its definitions effective for the default
|
||||||
* external entity loader. It will recuse in CATALOG entries.
|
* external entity loader. It will recuse in CATALOG entries.
|
||||||
* TODO: this function is not thread safe, catalog initialization should
|
* TODO: this function is not thread safe, catalog initialization should
|
||||||
* be done once at startup
|
* preferably be done once at startup
|
||||||
*
|
*
|
||||||
* Returns 0 in case of success -1 in case of error
|
* Returns 0 in case of success -1 in case of error
|
||||||
*/
|
*/
|
||||||
@ -1467,9 +1623,17 @@ xmlLoadCatalog(const char *filename) {
|
|||||||
xmlDefaultCatalog = xmlHashCreate(20);
|
xmlDefaultCatalog = xmlHashCreate(20);
|
||||||
if (xmlDefaultCatalog == NULL)
|
if (xmlDefaultCatalog == NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Need to be done after ...
|
||||||
|
*/
|
||||||
|
if (!xmlCatalogInitialized)
|
||||||
|
xmlInitializeCatalog();
|
||||||
|
|
||||||
|
#ifdef HAVE_STAT
|
||||||
if (stat(filename, &info) < 0)
|
if (stat(filename, &info) < 0)
|
||||||
return(-1);
|
return(-1);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prevent loops
|
* Prevent loops
|
||||||
@ -1545,7 +1709,7 @@ xmlLoadCatalog(const char *filename) {
|
|||||||
* Load the catalogs and makes their definitions effective for the default
|
* Load the catalogs and makes their definitions effective for the default
|
||||||
* external entity loader.
|
* external entity loader.
|
||||||
* TODO: this function is not thread safe, catalog initialization should
|
* TODO: this function is not thread safe, catalog initialization should
|
||||||
* be done once at startup
|
* preferably be done once at startup
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
xmlLoadCatalogs(const char *pathss) {
|
xmlLoadCatalogs(const char *pathss) {
|
||||||
@ -1578,33 +1742,93 @@ xmlLoadCatalogs(const char *pathss) {
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
xmlCatalogCleanup(void) {
|
xmlCatalogCleanup(void) {
|
||||||
|
if (xmlDebugCatalogs)
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"Catalogs cleanup\n");
|
||||||
if (xmlDefaultXMLCatalogList != NULL)
|
if (xmlDefaultXMLCatalogList != NULL)
|
||||||
xmlFreeCatalogEntryList(xmlDefaultXMLCatalogList);
|
xmlFreeCatalogEntryList(xmlDefaultXMLCatalogList);
|
||||||
|
xmlDefaultXMLCatalogList = NULL;
|
||||||
if (xmlDefaultCatalog != NULL)
|
if (xmlDefaultCatalog != NULL)
|
||||||
xmlHashFree(xmlDefaultCatalog,
|
xmlHashFree(xmlDefaultCatalog,
|
||||||
(xmlHashDeallocator) xmlFreeCatalogEntry);
|
(xmlHashDeallocator) xmlFreeCatalogEntry);
|
||||||
|
xmlDebugCatalogs = 0;
|
||||||
xmlDefaultCatalog = NULL;
|
xmlDefaultCatalog = NULL;
|
||||||
|
xmlCatalogInitialized = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlCatalogGetSystem:
|
* xmlCatalogGetSystem:
|
||||||
* @sysId: the system ID string
|
* @pubId: the public ID string
|
||||||
*
|
*
|
||||||
* Try to lookup the resource associated to a system ID
|
* Try to lookup the system ID associated to a public ID
|
||||||
|
* DEPRECATED, use xmlCatalogResolveSystem()
|
||||||
*
|
*
|
||||||
* Returns the resource name if found or NULL otherwise.
|
* Returns the system ID if found or NULL otherwise.
|
||||||
*/
|
*/
|
||||||
const xmlChar *
|
const xmlChar *
|
||||||
xmlCatalogGetSystem(const xmlChar *sysID) {
|
xmlCatalogGetSystem(const xmlChar *sysID) {
|
||||||
xmlCatalogEntryPtr entry;
|
xmlChar *ret;
|
||||||
|
static xmlChar result[1000];
|
||||||
|
|
||||||
if ((sysID == NULL) || (xmlDefaultCatalog == NULL))
|
if (sysID == NULL)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
entry = (xmlCatalogEntryPtr) xmlHashLookup(xmlDefaultCatalog, sysID);
|
|
||||||
if (entry == NULL)
|
if (!xmlCatalogInitialized)
|
||||||
|
xmlInitializeCatalog();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check first the XML catalogs
|
||||||
|
*/
|
||||||
|
if (xmlDefaultXMLCatalogList != NULL) {
|
||||||
|
ret = xmlCatalogListXMLResolve(xmlDefaultXMLCatalogList, NULL, sysID);
|
||||||
|
if (ret != NULL) {
|
||||||
|
snprintf((char *) result, sizeof(result) - 1, "%s", (char *) ret);
|
||||||
|
result[sizeof(result) - 1] = 0;
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xmlDefaultCatalog != NULL)
|
||||||
|
return(xmlCatalogGetSGMLSystem(xmlDefaultCatalog, sysID));
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlCatalogResolveSystem:
|
||||||
|
* @sysId: the public ID string
|
||||||
|
*
|
||||||
|
* Try to lookup the catalog resource for a system ID
|
||||||
|
*
|
||||||
|
* Returns the system ID if found or NULL otherwise, the value returned
|
||||||
|
* must be freed by the caller.
|
||||||
|
*/
|
||||||
|
xmlChar *
|
||||||
|
xmlCatalogResolveSystem(const xmlChar *sysID) {
|
||||||
|
xmlCatalogEntryPtr catal;
|
||||||
|
xmlChar *ret;
|
||||||
|
const xmlChar *sgml;
|
||||||
|
|
||||||
|
if (sysID == NULL)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
if (entry->type == SGML_CATA_SYSTEM)
|
|
||||||
return(entry->value);
|
if (!xmlCatalogInitialized)
|
||||||
|
xmlInitializeCatalog();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check first the XML catalogs
|
||||||
|
*/
|
||||||
|
catal = xmlDefaultXMLCatalogList;
|
||||||
|
if (catal != NULL) {
|
||||||
|
ret = xmlCatalogListXMLResolve(xmlDefaultXMLCatalogList, NULL, sysID);
|
||||||
|
if ((ret != NULL) && (ret != XML_CATAL_BREAK))
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xmlDefaultCatalog != NULL) {
|
||||||
|
sgml = xmlCatalogGetSGMLSystem(xmlDefaultCatalog, sysID);
|
||||||
|
if (sgml != NULL)
|
||||||
|
return(xmlStrdup(sgml));
|
||||||
|
}
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1613,29 +1837,74 @@ xmlCatalogGetSystem(const xmlChar *sysID) {
|
|||||||
* @pubId: the public ID string
|
* @pubId: the public ID string
|
||||||
*
|
*
|
||||||
* Try to lookup the system ID associated to a public ID
|
* Try to lookup the system ID associated to a public ID
|
||||||
|
* DEPRECATED, use xmlCatalogResolvePublic()
|
||||||
*
|
*
|
||||||
* Returns the system ID if found or NULL otherwise.
|
* Returns the system ID if found or NULL otherwise.
|
||||||
*/
|
*/
|
||||||
const xmlChar *
|
const xmlChar *
|
||||||
xmlCatalogGetPublic(const xmlChar *pubID) {
|
xmlCatalogGetPublic(const xmlChar *pubID) {
|
||||||
xmlCatalogEntryPtr catal;
|
xmlChar *ret;
|
||||||
const xmlChar *ret;
|
static xmlChar result[1000];
|
||||||
|
|
||||||
if (pubID == NULL)
|
if (pubID == NULL)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
|
|
||||||
|
if (!xmlCatalogInitialized)
|
||||||
|
xmlInitializeCatalog();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check first the XML catalogs
|
||||||
|
*/
|
||||||
|
if (xmlDefaultXMLCatalogList != NULL) {
|
||||||
|
ret = xmlCatalogListXMLResolve(xmlDefaultXMLCatalogList, 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, pubID));
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlCatalogResolvePublic:
|
||||||
|
* @pubId: the public ID string
|
||||||
|
*
|
||||||
|
* Try to lookup the system ID associated to a public ID
|
||||||
|
*
|
||||||
|
* Returns the system ID if found or NULL otherwise, the value returned
|
||||||
|
* must be freed by the caller.
|
||||||
|
*/
|
||||||
|
xmlChar *
|
||||||
|
xmlCatalogResolvePublic(const xmlChar *pubID) {
|
||||||
|
xmlCatalogEntryPtr catal;
|
||||||
|
xmlChar *ret;
|
||||||
|
const xmlChar *sgml;
|
||||||
|
|
||||||
|
if (pubID == NULL)
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
if (!xmlCatalogInitialized)
|
||||||
|
xmlInitializeCatalog();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check first the XML catalogs
|
* Check first the XML catalogs
|
||||||
*/
|
*/
|
||||||
catal = xmlDefaultXMLCatalogList;
|
catal = xmlDefaultXMLCatalogList;
|
||||||
if (catal != NULL) {
|
if (catal != NULL) {
|
||||||
ret = xmlCatalogGetXMLPublic(catal, pubID);
|
ret = xmlCatalogListXMLResolve(xmlDefaultXMLCatalogList, pubID, NULL);
|
||||||
if (ret != NULL)
|
if ((ret != NULL) && (ret != XML_CATAL_BREAK))
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xmlDefaultCatalog != NULL)
|
if (xmlDefaultCatalog != NULL) {
|
||||||
return(xmlCatalogGetSGMLPublic(xmlDefaultCatalog, pubID));
|
sgml = xmlCatalogGetSGMLPublic(xmlDefaultCatalog, pubID);
|
||||||
|
if (sgml != NULL)
|
||||||
|
return(xmlStrdup(sgml));
|
||||||
|
}
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1651,11 +1920,19 @@ xmlCatalogGetPublic(const xmlChar *pubID) {
|
|||||||
*/
|
*/
|
||||||
xmlChar *
|
xmlChar *
|
||||||
xmlCatalogResolve(const xmlChar *pubID, const xmlChar *sysID) {
|
xmlCatalogResolve(const xmlChar *pubID, const xmlChar *sysID) {
|
||||||
|
if (!xmlCatalogInitialized)
|
||||||
|
xmlInitializeCatalog();
|
||||||
|
|
||||||
if (xmlDefaultXMLCatalogList != NULL) {
|
if (xmlDefaultXMLCatalogList != NULL) {
|
||||||
return(xmlCatalogListXMLResolve(xmlDefaultXMLCatalogList, pubID, sysID));
|
return(xmlCatalogListXMLResolve(xmlDefaultXMLCatalogList, pubID, sysID));
|
||||||
} else {
|
} else {
|
||||||
return(xmlCatalogSGMLResolve(pubID, sysID));
|
const xmlChar *ret;
|
||||||
|
|
||||||
|
ret = xmlCatalogSGMLResolve(pubID, sysID);
|
||||||
|
if (ret != NULL)
|
||||||
|
return(xmlStrdup(ret));
|
||||||
}
|
}
|
||||||
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1692,6 +1969,9 @@ int
|
|||||||
xmlCatalogAdd(const xmlChar *type, const xmlChar *orig, const xmlChar *replace) {
|
xmlCatalogAdd(const xmlChar *type, const xmlChar *orig, const xmlChar *replace) {
|
||||||
int res = -1;
|
int res = -1;
|
||||||
|
|
||||||
|
if (!xmlCatalogInitialized)
|
||||||
|
xmlInitializeCatalog();
|
||||||
|
|
||||||
if (xmlDefaultXMLCatalogList != NULL) {
|
if (xmlDefaultXMLCatalogList != NULL) {
|
||||||
res = xmlAddXMLCatalog(xmlDefaultXMLCatalogList, type, orig, replace);
|
res = xmlAddXMLCatalog(xmlDefaultXMLCatalogList, type, orig, replace);
|
||||||
} else if (xmlDefaultCatalog != NULL) {
|
} else if (xmlDefaultCatalog != NULL) {
|
||||||
@ -1700,7 +1980,7 @@ xmlCatalogAdd(const xmlChar *type, const xmlChar *orig, const xmlChar *replace)
|
|||||||
typ = xmlGetSGMLCatalogEntryType(type);
|
typ = xmlGetSGMLCatalogEntryType(type);
|
||||||
if (type != XML_CATA_NONE) {
|
if (type != XML_CATA_NONE) {
|
||||||
xmlCatalogEntryPtr entry;
|
xmlCatalogEntryPtr entry;
|
||||||
entry = xmlNewCatalogEntry(typ, orig, replace);
|
entry = xmlNewCatalogEntry(typ, orig, replace, XML_CATA_PREFER_NONE);
|
||||||
res = xmlHashAddEntry(xmlDefaultCatalog, orig, entry);
|
res = xmlHashAddEntry(xmlDefaultCatalog, orig, entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1719,6 +1999,9 @@ int
|
|||||||
xmlCatalogRemove(const xmlChar *value) {
|
xmlCatalogRemove(const xmlChar *value) {
|
||||||
int res = -1;
|
int res = -1;
|
||||||
|
|
||||||
|
if (!xmlCatalogInitialized)
|
||||||
|
xmlInitializeCatalog();
|
||||||
|
|
||||||
if (xmlDefaultXMLCatalogList != NULL) {
|
if (xmlDefaultXMLCatalogList != NULL) {
|
||||||
res = xmlDelXMLCatalog(xmlDefaultXMLCatalogList, value);
|
res = xmlDelXMLCatalog(xmlDefaultXMLCatalogList, value);
|
||||||
} else if (xmlDefaultCatalog != NULL) {
|
} else if (xmlDefaultCatalog != NULL) {
|
||||||
@ -1727,6 +2010,23 @@ xmlCatalogRemove(const xmlChar *value) {
|
|||||||
return(res);
|
return(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Returns the previous value of the default preference for delegation
|
||||||
|
*/
|
||||||
|
xmlCatalogPrefer
|
||||||
|
xmlCatalogSetDefaultPrefer(xmlCatalogPrefer prefer) {
|
||||||
|
xmlCatalogPrefer ret = xmlCatalogDefaultPrefer;
|
||||||
|
|
||||||
|
xmlCatalogDefaultPrefer = prefer;
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlCatalogSetDebug:
|
* xmlCatalogSetDebug:
|
||||||
* @level: the debug level of catalogs required
|
* @level: the debug level of catalogs required
|
||||||
|
@ -36,19 +36,34 @@ extern "C" {
|
|||||||
#define XML_CATALOGS_NAMESPACE \
|
#define XML_CATALOGS_NAMESPACE \
|
||||||
(const xmlChar *) "urn:oasis:names:tc:entity:xmlns:xml:catalog"
|
(const xmlChar *) "urn:oasis:names:tc:entity:xmlns:xml:catalog"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The API is voluntarily limited to general cataloging
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
XML_CATA_PREFER_NONE = 0,
|
||||||
|
XML_CATA_PREFER_PUBLIC = 1,
|
||||||
|
XML_CATA_PREFER_SYSTEM
|
||||||
|
} xmlCatalogPrefer;
|
||||||
|
|
||||||
|
void xmlInitializeCatalog (void);
|
||||||
int xmlLoadCatalog (const char *filename);
|
int xmlLoadCatalog (const char *filename);
|
||||||
void xmlLoadCatalogs (const char *paths);
|
void xmlLoadCatalogs (const char *paths);
|
||||||
void xmlCatalogCleanup (void);
|
void xmlCatalogCleanup (void);
|
||||||
void xmlCatalogDump (FILE *out);
|
void xmlCatalogDump (FILE *out);
|
||||||
const xmlChar * xmlCatalogGetSystem (const xmlChar *sysID);
|
|
||||||
const xmlChar * xmlCatalogGetPublic (const xmlChar *pubID);
|
|
||||||
xmlChar * xmlCatalogResolve (const xmlChar *pubID,
|
xmlChar * xmlCatalogResolve (const xmlChar *pubID,
|
||||||
const xmlChar *sysID);
|
const xmlChar *sysID);
|
||||||
|
xmlChar * xmlCatalogResolveSystem (const xmlChar *sysID);
|
||||||
|
xmlChar * xmlCatalogResolvePublic (const xmlChar *pubID);
|
||||||
int xmlCatalogAdd (const xmlChar *type,
|
int xmlCatalogAdd (const xmlChar *type,
|
||||||
const xmlChar *orig,
|
const xmlChar *orig,
|
||||||
const xmlChar *replace);
|
const xmlChar *replace);
|
||||||
int xmlCatalogRemove (const xmlChar *value);
|
int xmlCatalogRemove (const xmlChar *value);
|
||||||
int xmlCatalogSetDebug (int level);
|
int xmlCatalogSetDebug (int level);
|
||||||
|
xmlCatalogPrefer xmlCatalogSetDefaultPrefer(xmlCatalogPrefer prefer);
|
||||||
|
|
||||||
|
/* DEPRECATED interfaces */
|
||||||
|
const xmlChar * xmlCatalogGetSystem (const xmlChar *sysID);
|
||||||
|
const xmlChar * xmlCatalogGetPublic (const xmlChar *pubID);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
3
parser.c
3
parser.c
@ -10100,5 +10100,8 @@ xmlCleanupParser(void) {
|
|||||||
xmlParserInitialized = 0;
|
xmlParserInitialized = 0;
|
||||||
xmlCleanupCharEncodingHandlers();
|
xmlCleanupCharEncodingHandlers();
|
||||||
xmlCleanupPredefinedEntities();
|
xmlCleanupPredefinedEntities();
|
||||||
|
#ifdef LIBXML_CATALOG_ENABLED
|
||||||
|
xmlCatalogCleanup();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
> /usr/share/xml/docbook/xml/4.1.2/dbpoolx.mod
|
> /usr/share/xml/docbook/xml/4.1.2/dbpoolx.mod
|
||||||
> http://www.oasis-open.org/docbook/xml/4.1.2/dbcentx.mod
|
> http://www.oasis-open.org/docbook/xml/4.1.2/dbcentx.mod
|
||||||
|
> http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd
|
||||||
|
> http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd
|
||||||
> file:///usr/share/xml/toto/toto.dtd
|
> file:///usr/share/xml/toto/toto.dtd
|
||||||
>
|
>
|
5
result/catalogs/registry
Normal file
5
result/catalogs/registry
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
> /usr/share/xml/docbook/xml/4.1.2/dbpoolx.mod
|
||||||
|
> http://www.oasis-open.org/docbook/xml/4.1.2/dbcentx.mod
|
||||||
|
> /usr/share/xml/docbook/xml/4.1.2/dbpoolx.mod
|
||||||
|
> http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd
|
||||||
|
>
|
@ -1,3 +1,5 @@
|
|||||||
resolve toto http://www.oasis-open.org/docbook/xml/4.1.2/dbpoolx.mod
|
resolve toto http://www.oasis-open.org/docbook/xml/4.1.2/dbpoolx.mod
|
||||||
public "-//OASIS//ENTITIES DocBook XML Character Entities V4.1.2//EN"
|
public "-//OASIS//ENTITIES DocBook XML Character Entities V4.1.2//EN"
|
||||||
|
system urn:publicid:-:OASIS:DTD+DocBook+XML+V4.1.2:EN
|
||||||
|
public urn:publicid:-:OASIS:DTD+DocBook+XML+V4.1.2:EN
|
||||||
resolve toto toto
|
resolve toto toto
|
||||||
|
4
test/catalogs/registry.script
Normal file
4
test/catalogs/registry.script
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
resolve toto http://www.oasis-open.org/docbook/xml/4.1.2/dbpoolx.mod
|
||||||
|
public "-//OASIS//ENTITIES DocBook XML Character Entities V4.1.2//EN"
|
||||||
|
system http://www.oasis-open.org/docbook/xml/4.1.2/dbpoolx.mod
|
||||||
|
system urn:publicid:-:OASIS:DTD+DocBook+XML+V4.1.2:EN
|
23
test/catalogs/registry.xml
Normal file
23
test/catalogs/registry.xml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE catalog PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN" "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
|
||||||
|
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
|
||||||
|
|
||||||
|
<delegatePublic publicIdStartString="-//OASIS//"
|
||||||
|
catalog="oasis.xml"/>
|
||||||
|
<delegateSystem systemIdStartString="http://www.oasis-open.org/"
|
||||||
|
catalog="oasis.xml"/>
|
||||||
|
<delegateURI uriStartString="http://www.oasis-open.org/"
|
||||||
|
catalog="oasis.xml"/>
|
||||||
|
|
||||||
|
<delegatePublic publicIdStartString="-//OASIS//DTD XML Catalog //"
|
||||||
|
catalog="docbook.xml"/>
|
||||||
|
<delegatePublic publicIdStartString="-//OASIS//ENTITIES DocBook XML"
|
||||||
|
catalog="docbook.xml"/>
|
||||||
|
<delegatePublic publicIdStartString="-//OASIS//DTD DocBook XML"
|
||||||
|
catalog="docbook.xml"/>
|
||||||
|
<delegateSystem systemIdStartString="http://www.oasis-open.org/docbook/"
|
||||||
|
catalog="docbook.xml"/>
|
||||||
|
<delegateURI uriStartString="http://www.oasis-open.org/docbook/"
|
||||||
|
catalog="docbook.xml"/>
|
||||||
|
|
||||||
|
</catalog>
|
21
xmlIO.c
21
xmlIO.c
@ -2371,7 +2371,10 @@ xmlParserInputPtr
|
|||||||
xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
|
xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
|
||||||
xmlParserCtxtPtr ctxt) {
|
xmlParserCtxtPtr ctxt) {
|
||||||
xmlParserInputPtr ret = NULL;
|
xmlParserInputPtr ret = NULL;
|
||||||
const xmlChar *resource = NULL;
|
xmlChar *resource = NULL;
|
||||||
|
#ifdef LIBXML_CATALOG_ENABLED
|
||||||
|
struct stat info;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_EXTERNAL_ENTITIES
|
#ifdef DEBUG_EXTERNAL_ENTITIES
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
@ -2379,16 +2382,18 @@ xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
|
|||||||
#endif
|
#endif
|
||||||
#ifdef LIBXML_CATALOG_ENABLED
|
#ifdef LIBXML_CATALOG_ENABLED
|
||||||
/*
|
/*
|
||||||
* Try to load it from the resource pointed in the catalog
|
* If the resource doesn't exists as a file,
|
||||||
|
* try to load it from the resource pointed in the catalog
|
||||||
*/
|
*/
|
||||||
if (ID != NULL)
|
#ifdef HAVE_STAT
|
||||||
resource = xmlCatalogGetPublic((const xmlChar *)ID);
|
if ((URL == NULL) || (stat(URL, &info) < 0))
|
||||||
if ((resource == NULL) && (URL != NULL))
|
#endif
|
||||||
resource = xmlCatalogGetSystem((const xmlChar *)URL);
|
resource = xmlCatalogResolve((const xmlChar *)ID,
|
||||||
|
(const xmlChar *)URL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (resource == NULL)
|
if (resource == NULL)
|
||||||
resource = (const xmlChar *)URL;
|
resource = (xmlChar *) URL;
|
||||||
|
|
||||||
if (resource == NULL) {
|
if (resource == NULL) {
|
||||||
if ((ctxt->validate) && (ctxt->sax != NULL) &&
|
if ((ctxt->validate) && (ctxt->sax != NULL) &&
|
||||||
@ -2410,6 +2415,8 @@ xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
|
|||||||
ctxt->sax->warning(ctxt,
|
ctxt->sax->warning(ctxt,
|
||||||
"failed to load external entity \"%s\"\n", resource);
|
"failed to load external entity \"%s\"\n", resource);
|
||||||
}
|
}
|
||||||
|
if (resource != (xmlChar *) URL)
|
||||||
|
xmlFree(resource);
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
71
xmlcatalog.c
71
xmlcatalog.c
@ -79,7 +79,6 @@ static void usershell(void) {
|
|||||||
char arg[400];
|
char arg[400];
|
||||||
char *argv[20];
|
char *argv[20];
|
||||||
int i, ret;
|
int i, ret;
|
||||||
const xmlChar *answer;
|
|
||||||
xmlChar *ans;
|
xmlChar *ans;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -172,22 +171,24 @@ static void usershell(void) {
|
|||||||
if (nbargs != 1) {
|
if (nbargs != 1) {
|
||||||
printf("public requires 1 arguments\n");
|
printf("public requires 1 arguments\n");
|
||||||
} else {
|
} else {
|
||||||
answer = xmlCatalogGetPublic((const xmlChar *) argv[0]);
|
ans = xmlCatalogResolvePublic((const xmlChar *) argv[0]);
|
||||||
if (answer == NULL) {
|
if (ans == NULL) {
|
||||||
printf("No entry for PUBLIC %s\n", argv[0]);
|
printf("No entry for PUBLIC %s\n", argv[0]);
|
||||||
} else {
|
} else {
|
||||||
printf("%s\n", answer);
|
printf("%s\n", ans);
|
||||||
|
xmlFree(ans);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!strcmp(command, "system")) {
|
} else if (!strcmp(command, "system")) {
|
||||||
if (nbargs != 1) {
|
if (nbargs != 1) {
|
||||||
printf("system requires 1 arguments\n");
|
printf("system requires 1 arguments\n");
|
||||||
} else {
|
} else {
|
||||||
answer = xmlCatalogGetSystem((const xmlChar *) argv[0]);
|
ans = xmlCatalogResolveSystem((const xmlChar *) argv[0]);
|
||||||
if (answer == NULL) {
|
if (ans == NULL) {
|
||||||
printf("No entry for SYSTEM %s\n", argv[0]);
|
printf("No entry for SYSTEM %s\n", argv[0]);
|
||||||
} else {
|
} else {
|
||||||
printf("%s\n", answer);
|
printf("%s\n", ans);
|
||||||
|
xmlFree(ans);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!strcmp(command, "add")) {
|
} else if (!strcmp(command, "add")) {
|
||||||
@ -231,6 +232,21 @@ static void usershell(void) {
|
|||||||
} else {
|
} else {
|
||||||
xmlCatalogDump(stdout);
|
xmlCatalogDump(stdout);
|
||||||
}
|
}
|
||||||
|
} else if (!strcmp(command, "debug")) {
|
||||||
|
if (nbargs != 0) {
|
||||||
|
printf("debug has no arguments\n");
|
||||||
|
} else {
|
||||||
|
verbose++;
|
||||||
|
xmlCatalogSetDebug(verbose);
|
||||||
|
}
|
||||||
|
} else if (!strcmp(command, "quiet")) {
|
||||||
|
if (nbargs != 0) {
|
||||||
|
printf("quiet has no arguments\n");
|
||||||
|
} else {
|
||||||
|
if (verbose > 0)
|
||||||
|
verbose--;
|
||||||
|
xmlCatalogSetDebug(verbose);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (strcmp(command, "help")) {
|
if (strcmp(command, "help")) {
|
||||||
printf("Unrecognized command %s\n", command);
|
printf("Unrecognized command %s\n", command);
|
||||||
@ -242,6 +258,8 @@ static void usershell(void) {
|
|||||||
printf("\tadd 'type' 'orig' 'replace' : add an entry\n");
|
printf("\tadd 'type' 'orig' 'replace' : add an entry\n");
|
||||||
printf("\tdel 'values' : remove values\n");
|
printf("\tdel 'values' : remove values\n");
|
||||||
printf("\tdump: print the current catalog state\n");
|
printf("\tdump: print the current catalog state\n");
|
||||||
|
printf("\tdebug: increase the verbosity level\n");
|
||||||
|
printf("\tquiet: decrease the verbosity level\n");
|
||||||
printf("\texit: quit the shell\n");
|
printf("\texit: quit the shell\n");
|
||||||
}
|
}
|
||||||
free(cmdline); /* not xmlFree here ! */
|
free(cmdline); /* not xmlFree here ! */
|
||||||
@ -254,8 +272,8 @@ static void usershell(void) {
|
|||||||
* *
|
* *
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
static void usage(const char *name) {
|
static void usage(const char *name) {
|
||||||
printf("Usage : %s [options] catalogfile\n", name);
|
printf("Usage : %s [options] catalogfile entities...\n", name);
|
||||||
printf("\tParse the catalog file and output the result of the parsing\n");
|
printf("\tParse the catalog file and query it for the entities\n");
|
||||||
printf("\t--shell : run a shell allowing interactive queries\n");
|
printf("\t--shell : run a shell allowing interactive queries\n");
|
||||||
printf("\t--add 'type' 'orig' 'replace' : add an entry\n");
|
printf("\t--add 'type' 'orig' 'replace' : add an entry\n");
|
||||||
printf("\t--del 'values' : remove values\n");
|
printf("\t--del 'values' : remove values\n");
|
||||||
@ -277,7 +295,7 @@ int main(int argc, char **argv) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (argv[i][0] != '-')
|
if (argv[i][0] != '-')
|
||||||
continue;
|
break;
|
||||||
if ((!strcmp(argv[i], "-verbose")) ||
|
if ((!strcmp(argv[i], "-verbose")) ||
|
||||||
(!strcmp(argv[i], "-v")) ||
|
(!strcmp(argv[i], "-v")) ||
|
||||||
(!strcmp(argv[i], "--verbose"))) {
|
(!strcmp(argv[i], "--verbose"))) {
|
||||||
@ -360,19 +378,38 @@ int main(int argc, char **argv) {
|
|||||||
xmlCatalogDump(out);
|
xmlCatalogDump(out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (shell) {
|
||||||
|
|
||||||
if (shell) {
|
|
||||||
usershell();
|
usershell();
|
||||||
}
|
} else {
|
||||||
if (!noout) {
|
for (i++; i < argc; i++) {
|
||||||
xmlCatalogDump(stdout);
|
xmlURIPtr uri;
|
||||||
|
xmlChar *ans;
|
||||||
|
|
||||||
|
uri = xmlParseURI(argv[i]);
|
||||||
|
if (uri == NULL) {
|
||||||
|
ans = xmlCatalogResolvePublic((const xmlChar *) argv[i]);
|
||||||
|
if (ans == NULL) {
|
||||||
|
printf("No entry for PUBLIC %s\n", argv[i]);
|
||||||
|
} else {
|
||||||
|
printf("%s\n", ans);
|
||||||
|
xmlFree(ans);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
xmlFreeURI(uri);
|
||||||
|
ans = xmlCatalogResolveSystem((const xmlChar *) argv[i]);
|
||||||
|
if (ans == NULL) {
|
||||||
|
printf("No entry for SYSTEM %s\n", argv[i]);
|
||||||
|
} else {
|
||||||
|
printf("%s\n", ans);
|
||||||
|
xmlFree(ans);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cleanup and check for memory leaks
|
* Cleanup and check for memory leaks
|
||||||
*/
|
*/
|
||||||
xmlCatalogCleanup();
|
|
||||||
xmlCleanupParser();
|
xmlCleanupParser();
|
||||||
xmlMemoryDump();
|
xmlMemoryDump();
|
||||||
return(0);
|
return(0);
|
||||||
|
29
xmllint.c
29
xmllint.c
@ -104,6 +104,10 @@ static int progresult = 0;
|
|||||||
static int timing = 0;
|
static int timing = 0;
|
||||||
static int generate = 0;
|
static int generate = 0;
|
||||||
static struct timeval begin, end;
|
static struct timeval begin, end;
|
||||||
|
#ifdef LIBXML_CATALOG_ENABLED
|
||||||
|
static int catalogs = 0;
|
||||||
|
static int nocatalogs = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* *
|
* *
|
||||||
@ -798,6 +802,8 @@ static void usage(const char *name) {
|
|||||||
printf("\t--encode encoding : output in the given encoding\n");
|
printf("\t--encode encoding : output in the given encoding\n");
|
||||||
#ifdef LIBXML_CATALOG_ENABLED
|
#ifdef LIBXML_CATALOG_ENABLED
|
||||||
printf("\t--catalogs : use the catalogs from $SGML_CATALOG_FILES\n");
|
printf("\t--catalogs : use the catalogs from $SGML_CATALOG_FILES\n");
|
||||||
|
printf("\t otherwise /etc/xml/catalog is activated by default\n");
|
||||||
|
printf("\t--nocatalogs: desactivate all catalogs\n");
|
||||||
#endif
|
#endif
|
||||||
printf("\t--auto : generate a small doc on the fly\n");
|
printf("\t--auto : generate a small doc on the fly\n");
|
||||||
#ifdef LIBXML_XINCLUDE_ENABLED
|
#ifdef LIBXML_XINCLUDE_ENABLED
|
||||||
@ -931,14 +937,10 @@ main(int argc, char **argv) {
|
|||||||
#ifdef LIBXML_CATALOG_ENABLED
|
#ifdef LIBXML_CATALOG_ENABLED
|
||||||
else if ((!strcmp(argv[i], "-catalogs")) ||
|
else if ((!strcmp(argv[i], "-catalogs")) ||
|
||||||
(!strcmp(argv[i], "--catalogs"))) {
|
(!strcmp(argv[i], "--catalogs"))) {
|
||||||
const char *catalogs;
|
catalogs++;
|
||||||
|
} else if ((!strcmp(argv[i], "-nocatalogs")) ||
|
||||||
catalogs = getenv("SGML_CATALOG_FILES");
|
(!strcmp(argv[i], "--nocatalogs"))) {
|
||||||
if (catalogs == NULL) {
|
nocatalogs++;
|
||||||
fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
|
|
||||||
} else {
|
|
||||||
xmlLoadCatalogs(catalogs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if ((!strcmp(argv[i], "-encode")) ||
|
else if ((!strcmp(argv[i], "-encode")) ||
|
||||||
@ -966,6 +968,17 @@ main(int argc, char **argv) {
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LIBXML_CATALOG_ENABLED
|
||||||
|
if (nocatalogs == 0) {
|
||||||
|
if (catalogs) {
|
||||||
|
const char *catal;
|
||||||
|
|
||||||
|
catal = getenv("SGML_CATALOG_FILES");
|
||||||
|
xmlLoadCatalogs(catal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
xmlLineNumbersDefault(1);
|
xmlLineNumbersDefault(1);
|
||||||
if (loaddtd != 0)
|
if (loaddtd != 0)
|
||||||
xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
|
xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
|
||||||
|
Reference in New Issue
Block a user