📄 catalog.c
字号:
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);
ret = xmlStrdup(rewrite->URL);
if (ret != NULL)
ret = xmlStrcat(ret, &URI[lenrewrite]);
return(ret);
}
if (haveDelegate) {
const xmlChar *delegates[MAX_DELEGATE];
int nbList = 0, i;
/*
* Assume the entries have been sorted by decreasing substring
* matches when the list was produced.
*/
cur = catal;
while (cur != NULL) {
if (((cur->type == XML_CATA_DELEGATE_SYSTEM) ||
(cur->type == XML_CATA_DELEGATE_URI)) &&
(!xmlStrncmp(URI, cur->name, xmlStrlen(cur->name)))) {
for (i = 0;i < nbList;i++)
if (xmlStrEqual(cur->URL, delegates[i]))
break;
if (i < nbList) {
cur = cur->next;
continue;
}
if (nbList < MAX_DELEGATE)
delegates[nbList++] = cur->URL;
if (cur->children == NULL) {
xmlFetchXMLCatalogFile(cur);
}
if (cur->children != NULL) {
if (xmlDebugCatalogs)
xmlGenericError(xmlGenericErrorContext,
"Trying URI delegate %s\n", cur->URL);
ret = xmlCatalogListXMLResolveURI(
cur->children, URI);
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);
}
/**
* xmlCatalogListXMLResolve:
* @catal: a catalog list
* @pubID: the public ID string
* @sysID: the system ID string
*
* Do a complete resolution lookup of an External Identifier for a
* list of catalogs
*
* Implements (or tries to) 7.1. External Identifier Resolution
* 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;
xmlChar *urnID = NULL;
xmlChar *normid;
if (catal == NULL)
return(NULL);
if ((pubID == NULL) && (sysID == NULL))
return(NULL);
normid = xmlCatalogNormalizePublic(pubID);
if (normid != NULL)
pubID = (*normid != 0 ? normid : 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);
if (normid != NULL)
xmlFree(normid);
return(ret);
}
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 {
ret = xmlCatalogListXMLResolve(catal, pubID, urnID);
}
if (urnID != NULL)
xmlFree(urnID);
if (normid != NULL)
xmlFree(normid);
return(ret);
}
while (catal != NULL) {
if (catal->type == XML_CATA_CATALOG) {
if (catal->children == NULL) {
xmlFetchXMLCatalogFile(catal);
}
if (catal->children != NULL) {
ret = xmlCatalogXMLResolve(catal->children, pubID, sysID);
if (ret != NULL) {
if (normid != NULL)
xmlFree(normid);
return(ret);
}
}
}
catal = catal->next;
}
if (normid != NULL)
xmlFree(normid);
return(ret);
}
/**
* xmlCatalogListXMLResolveURI:
* @catal: a catalog list
* @URI: the URI
*
* Do a complete resolution lookup of an URI for a list of catalogs
*
* Implements (or tries to) 7.2. URI Resolution
* 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;
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);
}
/************************************************************************
* *
* The SGML Catalog parser *
* *
************************************************************************/
#define RAW *cur
#define NEXT cur++;
#define SKIP(x) cur += x;
#define SKIP_BLANKS while (IS_BLANK_CH(*cur)) NEXT;
/**
* xmlParseSGMLCatalogComment:
* @cur: the current character
*
* Skip a comment in an SGML catalog
*
* Returns new current character
*/
static const xmlChar *
xmlParseSGMLCatalogComment(const xmlChar *cur) {
if ((cur[0] != '-') || (cur[1] != '-'))
return(cur);
SKIP(2);
while ((cur[0] != 0) && ((cur[0] != '-') || ((cur[1] != '-'))))
NEXT;
if (cur[0] == 0) {
return(NULL);
}
return(cur + 2);
}
/**
* xmlParseSGMLCatalogPubid:
* @cur: the current character
* @id: the return location
*
* Parse an SGML catalog ID
*
* Returns new current character and store the value in @id
*/
static const xmlChar *
xmlParseSGMLCatalogPubid(const xmlChar *cur, xmlChar **id) {
xmlChar *buf = NULL, *tmp;
int len = 0;
int size = 50;
xmlChar stop;
int count = 0;
*id = NULL;
if (RAW == '"') {
NEXT;
stop = '"';
} else if (RAW == '\'') {
NEXT;
stop = '\'';
} else {
stop = ' ';
}
buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
if (buf == NULL) {
xmlCatalogErrMemory("allocating public ID");
return(NULL);
}
while (IS_PUBIDCHAR_CH(*cur) || (*cur == '?')) {
if ((*cur == stop) && (stop != ' '))
break;
if ((stop == ' ') && (IS_BLANK_CH(*cur)))
break;
if (len + 1 >= size) {
size *= 2;
tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
if (tmp == NULL) {
xmlCatalogErrMemory("allocating public ID");
xmlFree(buf);
return(NULL);
}
buf = tmp;
}
buf[len++] = *cur;
count++;
NEXT;
}
buf[len] = 0;
if (stop == ' ') {
if (!IS_BLANK_CH(*cur)) {
xmlFree(buf);
return(NULL);
}
} else {
if (*cur != stop) {
xmlFree(buf);
return(NULL);
}
NEXT;
}
*id = buf;
return(cur);
}
/**
* xmlParseSGMLCatalogName:
* @cur: the current character
* @name: the return location
*
* Parse an SGML catalog name
*
* Returns new current character and store the value in @name
*/
static const xmlChar *
xmlParseSGMLCatalogName(const xmlChar *cur, xmlChar **name) {
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);
}
/**
* xmlGetSGMLCatalogEntryType:
* @name: the entry name
*
* Get the Catalog entry type for a given SGML Catalog name
*
* Returns Catalog entry type
*/
static xmlCatalogEntryType
xmlGetSGMLCatalogEntryType(const xmlChar *name) {
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);
}
/**
* xmlParseSGMLCatalog:
* @catal: the SGML Catalog
* @value: the content of the SGML Catalog serialization
* @file: the filepath for the catalog
* @super: should this be handled as a Super Catalog in which case
* parsing is not recursive
*
* Parse an SGML catalog content and fill up the @catal hash table with
* the new entries found.
*
* Returns 0 in case of success, -1 in case of error.
*/
static int
xmlParseSGMLCatalog(xmlCatalogPtr catal, const xmlChar *value,
const char *file, int super) {
const xmlChar *cur = value;
xmlChar *base = NULL;
int res;
if ((cur == NULL) || (file == NULL))
return(-1);
base = xmlStrdup((const xmlChar *) file);
while ((cur != NULL) && (cur[0] != 0)) {
SKIP_BLANKS;
if (cur[0] == 0)
break;
if ((cur[0] == '-') && (cur[1] == '-')) {
cur = xmlParseSGMLCatalogComment(cur);
if (cur == NULL) {
/* error */
break;
}
} else {
xmlChar *sysid = NULL;
xmlChar *name = NULL;
xmlCatalogEntryType type = XML_CATA_NONE;
cur = xmlParseSGMLCatalogName(cur, &name);
if (name == NULL) {
/* error */
break;
}
if (!IS_BLANK_CH(*cur)) {
/* error */
break;
}
SKIP_BLANKS;
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_DOCUMEN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -