📄 catalog.c.svn-base
字号:
* @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 xmlCatalogEntryTypexmlGetSGMLCatalogEntryType(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; else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE")) type = SGML_CATA_DELEGATE; 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 intxmlParseSGMLCatalog(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_DOCUMENT; else if (xmlStrEqual(name, (const xmlChar *) "CATALOG")) type = SGML_CATA_CATALOG; else if (xmlStrEqual(name, (const xmlChar *) "BASE")) type = SGML_CATA_BASE; else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE")) type = SGML_CATA_DELEGATE; else if (xmlStrEqual(name, (const xmlChar *) "OVERRIDE")) { xmlFree(name); cur = xmlParseSGMLCatalogName(cur, &name); if (name == NULL) { /* error */ break; } xmlFree(name); continue; } xmlFree(name); name = NULL; switch(type) { case SGML_CATA_ENTITY: if (*cur == '%') type = SGML_CATA_PENTITY; case SGML_CATA_PENTITY: case SGML_CATA_DOCTYPE: case SGML_CATA_LINKTYPE: case SGML_CATA_NOTATION: cur = xmlParseSGMLCatalogName(cur, &name); if (cur == NULL) { /* error */ break; } if (!IS_BLANK_CH(*cur)) { /* error */ break; } SKIP_BLANKS; cur = xmlParseSGMLCatalogPubid(cur, &sysid); if (cur == NULL) { /* error */ break; } break; case SGML_CATA_PUBLIC: case SGML_CATA_SYSTEM: case SGML_CATA_DELEGATE: cur = xmlParseSGMLCatalogPubid(cur, &name); if (cur == NULL) { /* error */ break; } if (!IS_BLANK_CH(*cur)) { /* error */ break; } SKIP_BLANKS; cur = xmlParseSGMLCatalogPubid(cur, &sysid); if (cur == NULL) { /* error */ break; } break; case SGML_CATA_BASE: case SGML_CATA_CATALOG: case SGML_CATA_DOCUMENT: case SGML_CATA_SGMLDECL: cur = xmlParseSGMLCatalogPubid(cur, &sysid); if (cur == NULL) { /* error */ break; } break; default: break; } if (cur == NULL) { if (name != NULL) xmlFree(name); if (sysid != NULL) xmlFree(sysid); break; } else if (type == SGML_CATA_BASE) { if (base != NULL) xmlFree(base); base = xmlStrdup(sysid); } else if ((type == SGML_CATA_PUBLIC) || (type == SGML_CATA_SYSTEM)) { xmlChar *filename; filename = xmlBuildURI(sysid, base); if (filename != NULL) { xmlCatalogEntryPtr entry; entry = xmlNewCatalogEntry(type, name, filename, NULL, XML_CATA_PREFER_NONE); res = xmlHashAddEntry(catal->sgml, name, entry); if (res < 0) { xmlFreeCatalogEntry(entry); } xmlFree(filename); } } else if (type == SGML_CATA_CATALOG) { if (super) { xmlCatalogEntryPtr entry; entry = xmlNewCatalogEntry(type, sysid, NULL, NULL, XML_CATA_PREFER_NONE); res = xmlHashAddEntry(catal->sgml, sysid, entry); if (res < 0) { xmlFreeCatalogEntry(entry); } } else { xmlChar *filename; filename = xmlBuildURI(sysid, base); if (filename != NULL) { xmlExpandCatalog(catal, (const char *)filename); xmlFree(filename); } } } /* * drop anything else we won't handle it */ if (name != NULL) xmlFree(name); if (sysid != NULL) xmlFree(sysid); } } if (base != NULL) xmlFree(base); if (cur == NULL) return(-1); return(0);}/************************************************************************ * * * SGML Catalog handling * * * ************************************************************************//** * xmlCatalogGetSGMLPublic: * @catal: an SGML catalog hash * @pubID: the public ID string * * Try to lookup the catalog local reference associated to a public ID * * Returns the local resource if found or NULL otherwise. */static const xmlChar *xmlCatalogGetSGMLPublic(xmlHashTablePtr catal, const xmlChar *pubID) { xmlCatalogEntryPtr entry; if (catal == NULL) return(NULL); entry = (xmlCatalogEntryPtr) xmlHashLookup(catal, pubID); if (entry == NULL) return(NULL); if (entry->type == SGML_CATA_PUBLIC) return(entry->URL); return(NULL);}/** * xmlCatalogGetSGMLSystem: * @catal: an SGML catalog hash * @sysID: the system ID string * * Try to lookup the catalog local reference for a system ID * * Returns the local resource if found or NULL otherwise. */static const xmlChar *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->URL); return(NULL);}/** * xmlCatalogSGMLResolve: * @catal: the SGML catalog * @pubID: the public ID string * @sysID: the system ID string * * Do a complete resolution lookup of an External Identifier * * Returns the URI of the resource or NULL if not found */static const xmlChar *xmlCatalogSGMLResolve(xmlCatalogPtr catal, const xmlChar *pubID, const xmlChar *sysID) { const xmlChar *ret = NULL; if (catal->sgml == NULL) return(NULL); if (pubID != NULL) ret = xmlCatalogGetSGMLPublic(catal->sgml, pubID); if (ret != NULL) return(ret); if (sysID != NULL) ret = xmlCatalogGetSGMLSystem(catal->sgml, sysID); return(NULL);}/************************************************************************ * * * Specific Public interfaces * * * ************************************************************************//** * xmlLoadSGMLSuperCatalog: * @filename: a file path * * Load an SGML super catalog. It won't expand CATALOG or DELEGATE * references. This is only needed for manipulating SGML Super Catalogs * like adding and removing CATALOG or DELEGATE entries. * * Returns the catalog parsed or NULL in case of error */xmlCatalogPtrxmlLoadSGMLSuperCatalog(const char *filename){ xmlChar *content; xmlCatalogPtr catal; int ret; content = xmlLoadFileContent(filename); if (content == NULL) return(NULL); catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE, xmlCatalogDefaultPrefer); if (catal == NULL) { xmlFree(content); return(NULL); } ret = xmlParseSGMLCatalog(catal, content, filename, 1); xmlFree(content); if (ret < 0) { xmlFreeCatalog(catal); return(NULL); } return (catal);}/** * xmlLoadACatalog: * @filename: a file path * * Load the catalog and build the associated data structures. * This can be either an XML Catalog or an SGML Catalog * It will recurse in SGML CATALOG entries. On the other hand XML * Catalogs are not handled recursively. * * Returns the catalog parsed or NULL in case of error */xmlCatalogPtrxmlLoadACatalog(const char *filename){ xmlChar *content; xmlChar *first; xmlCatalogPtr catal; int ret; content = xmlLoadFileContent(filename); if (content == NULL) return(NULL); first = content; while (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -