📄 catalog.c
字号:
xmlRMutexUnlock(xmlCatalogMutex); return(0);}/************************************************************************ * * * XML Catalog handling * * * ************************************************************************//** * xmlAddXMLCatalog: * @catal: top of an XML catalog * @type: the type of record to add to the catalog * @orig: the system, public or prefix to match (or NULL) * @replace: the replacement value for the match * * Add an entry in the XML catalog, it may overwrite existing but * different entries. * * Returns 0 if successful, -1 otherwise */static intxmlAddXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *type, const xmlChar *orig, const xmlChar *replace) { xmlCatalogEntryPtr cur; xmlCatalogEntryType typ; int doregister = 0; if ((catal == NULL) || ((catal->type != XML_CATA_CATALOG) && (catal->type != XML_CATA_BROKEN_CATALOG))) return(-1); if (catal->children == NULL) { xmlFetchXMLCatalogFile(catal); } if (catal->children == NULL) doregister = 1; typ = xmlGetXMLCatalogEntryType(type); if (typ == XML_CATA_NONE) { if (xmlDebugCatalogs) xmlGenericError(xmlGenericErrorContext, "Failed to add unknown element %s to catalog\n", type); return(-1); } cur = catal->children; /* * Might be a simple "update in place" */ if (cur != NULL) { while (cur != NULL) { if ((orig != NULL) && (cur->type == typ) && (xmlStrEqual(orig, cur->name))) { if (xmlDebugCatalogs) xmlGenericError(xmlGenericErrorContext, "Updating element %s to catalog\n", type); if (cur->value != NULL) xmlFree(cur->value); if (cur->URL != NULL) xmlFree(cur->URL); cur->value = xmlStrdup(replace); cur->URL = xmlStrdup(replace); return(0); } if (cur->next == NULL) break; cur = cur->next; } } if (xmlDebugCatalogs) xmlGenericError(xmlGenericErrorContext, "Adding element %s to catalog\n", type); if (cur == NULL) catal->children = xmlNewCatalogEntry(typ, orig, replace, NULL, catal->prefer, NULL); else cur->next = xmlNewCatalogEntry(typ, orig, replace, NULL, catal->prefer, NULL); if (doregister) { catal->type = XML_CATA_CATALOG; cur = xmlHashLookup(xmlCatalogXMLFiles, catal->URL); if (cur != NULL) cur->children = catal->children; } return(0);}/** * xmlDelXMLCatalog: * @catal: top of an XML catalog * @value: the value to remove from the catalog * * Remove entries in the XML catalog where the value or the URI * is equal to @value * * Returns the number of entries removed if successful, -1 otherwise */static intxmlDelXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *value) { xmlCatalogEntryPtr cur; int ret = 0; if ((catal == NULL) || ((catal->type != XML_CATA_CATALOG) && (catal->type != XML_CATA_BROKEN_CATALOG))) return(-1); if (value == NULL) return(-1); if (catal->children == NULL) { xmlFetchXMLCatalogFile(catal); } /* * Scan the children */ cur = catal->children; while (cur != NULL) { if (((cur->name != NULL) && (xmlStrEqual(value, cur->name))) || (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); } cur->type = XML_CATA_REMOVED; } cur = cur->next; } return(ret);}/** * xmlCatalogXMLResolve: * @catal: a catalog list * @pubID: the public ID string * @sysID: the system ID string * * Do a complete resolution lookup of an External Identifier for a * list of catalog entries. * * Implements (or tries to) 7.1. External Identifier Resolution * 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; /* * protection against loops */ if (catal->depth > MAX_CATAL_DEPTH) { xmlCatalogErr(catal, NULL, XML_CATALOG_RECURSION, "Detected recursion in catalog %s\n", catal->name, NULL, NULL); return(NULL); } catal->depth++; /* * 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: if (xmlStrEqual(sysID, cur->name)) { if (xmlDebugCatalogs) xmlGenericError(xmlGenericErrorContext, "Found system match %s, using %s\n", cur->name, cur->URL); catal->depth--; return(xmlStrdup(cur->URL)); } 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) { if (xmlDebugCatalogs) xmlGenericError(xmlGenericErrorContext, "Using rewriting rule %s\n", rewrite->name); ret = xmlStrdup(rewrite->URL); if (ret != NULL) ret = xmlStrcat(ret, &sysID[lenrewrite]); catal->depth--; 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) && (!xmlStrncmp(sysID, 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 system delegate %s\n", cur->URL); ret = xmlCatalogListXMLResolve( cur->children, NULL, sysID); if (ret != NULL) { catal->depth--; return(ret); } } } cur = cur->next; } /* * Apply the cut algorithm explained in 4/ */ catal->depth--; return(XML_CATAL_BREAK); } } /* * 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: if (xmlStrEqual(pubID, cur->name)) { if (xmlDebugCatalogs) xmlGenericError(xmlGenericErrorContext, "Found public match %s\n", cur->name); catal->depth--; return(xmlStrdup(cur->URL)); } break; case XML_CATA_DELEGATE_PUBLIC: if (!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)) && (cur->prefer == XML_CATA_PREFER_PUBLIC)) haveDelegate++; break; case XML_CATA_NEXT_CATALOG: if (sysID == NULL) haveNext++; break; default: break; } cur = cur->next; } 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_PUBLIC) && (cur->prefer == XML_CATA_PREFER_PUBLIC) && (!xmlStrncmp(pubID, 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 public delegate %s\n", cur->URL); ret = xmlCatalogListXMLResolve( cur->children, pubID, NULL); if (ret != NULL) { catal->depth--; return(ret); } } } cur = cur->next; } /* * Apply the cut algorithm explained in 4/ */ catal->depth--; 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 = xmlCatalogListXMLResolve(cur->children, pubID, sysID); if (ret != NULL) { catal->depth--; return(ret); } else if (catal->depth > MAX_CATAL_DEPTH) { return(NULL); } } } cur = cur->next; } } catal->depth--; return(NULL);}/** * xmlCatalogXMLResolveURI: * @catal: a catalog list * @URI: the URI * @sysID: the system ID string * * Do a complete resolution lookup of an External Identifier for a * list of catalog entries. * * Implements (or tries to) 7.2.2. URI Resolution * 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); if (catal->depth > MAX_CATAL_DEPTH) { xmlCatalogErr(catal, NULL, XML_CATALOG_RECURSION, "Detected recursion in catalog %s\n", catal->name, NULL, NULL); return(NULL); } /* * 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); return(xmlStrdup(cur->URL)); } 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); 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/ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -