1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-01-27 14:03:36 +03:00

- Makefile.am xmlversion.h.in configure.in include/Makefile.am:

integrating catalogs
- catalog.[ch] testCatalog.c: adding a small catalo API
  (only SGML catalog support).
- parser.c: restaured xmlKeepBlanksDefault(0) API
Daniel
This commit is contained in:
Daniel Veillard 2001-05-10 14:17:55 +00:00
parent c17337c062
commit a737459bc4
11 changed files with 688 additions and 9 deletions

View File

@ -1,3 +1,11 @@
Thu May 10 16:14:36 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* Makefile.am xmlversion.h.in configure.in include/Makefile.am:
integrating catalogs
* catalog.[ch] testCatalog.c: adding a small catalo API
(only SGML catalog support).
* parser.c: restaured xmlKeepBlanksDefault(0) API
Wed May 9 12:50:15 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* tree.c: zb@bisp.com reported an error in xmlNodeGetLang()

View File

@ -4,7 +4,7 @@ SUBDIRS = . include doc example
INCLUDES = -I@srcdir@/include -I./include @Z_CFLAGS@ @CORBA_CFLAGS@
noinst_PROGRAMS=testSAX testHTML testXPath testURI testDocbook
noinst_PROGRAMS=testSAX testHTML testXPath testURI testDocbook testCatalog
bin_PROGRAMS = xmllint
@ -20,13 +20,14 @@ libxml2_la_SOURCES = SAX.c entities.c encoding.c error.c parserInternals.c \
parser.c tree.c hash.c list.c xmlIO.c xmlmemory.c uri.c \
valid.c xlink.c HTMLparser.c HTMLtree.c debugXML.c xpath.c \
xpointer.c xinclude.c nanohttp.c nanoftp.c DOCBparser.c \
strio.c trio.c
catalog.c strio.c trio.c
else
libxml2_la_SOURCES = SAX.c entities.c encoding.c error.c parserInternals.c \
parser.c tree.c hash.c list.c xmlIO.c xmlmemory.c uri.c \
valid.c xlink.c HTMLparser.c HTMLtree.c debugXML.c xpath.c \
xpointer.c xinclude.c nanohttp.c nanoftp.c DOCBparser.c
xpointer.c xinclude.c nanohttp.c nanoftp.c DOCBparser.c \
catalog.c
endif
@ -58,6 +59,11 @@ testDocbook_LDFLAGS =
testDocbook_DEPENDENCIES = $(DEPS)
testDocbook_LDADD= $(LDADDS)
testCatalog_SOURCES=testCatalog.c
testCatalog_LDFLAGS =
testCatalog_DEPENDENCIES = $(DEPS)
testCatalog_LDADD= $(LDADDS)
testXPath_SOURCES=testXPath.c
testXPath_LDFLAGS =
testXPath_DEPENDENCIES = $(DEPS)

531
catalog.c Normal file
View File

@ -0,0 +1,531 @@
/**
* catalog.c: set of generic Catalog related routines
*
* Reference: SGML Open Technical Resolution TR9401:1997.
* http://www.jclark.com/sp/catalog.htm
*
* See Copyright for the status of this software.
*
* Daniel.Veillard@imag.fr
*/
#include "libxml.h"
#ifdef LIBXML_CATALOG_ENABLED
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include <string.h>
#include <libxml/xmlmemory.h>
#include <libxml/hash.h>
#include <libxml/uri.h>
#include <libxml/parserInternals.h>
#include <libxml/catalog.h>
#include <libxml/xmlerror.h>
/************************************************************************
* *
* Types, all private *
* *
************************************************************************/
typedef enum {
XML_CATA_NONE = 0,
XML_CATA_SYSTEM,
XML_CATA_PUBLIC,
XML_CATA_ENTITY,
XML_CATA_PENTITY,
XML_CATA_DOCTYPE,
XML_CATA_LINKTYPE,
XML_CATA_NOTATION,
XML_CATA_DELEGATE,
XML_CATA_BASE,
XML_CATA_CATALOG,
XML_CATA_DOCUMENT,
XML_CATA_SGMLDECL
} xmlCatalogEntryType;
typedef struct _xmlCatalogEntry xmlCatalogEntry;
typedef xmlCatalogEntry *xmlCatalogEntryPtr;
struct _xmlCatalogEntry {
xmlCatalogEntryType type;
xmlChar *name;
xmlChar *value;
};
static xmlHashTablePtr xmlDefaultCatalog;
/************************************************************************
* *
* alloc or dealloc *
* *
************************************************************************/
static xmlCatalogEntryPtr
xmlNewCatalogEntry(int type, xmlChar *name, xmlChar *value) {
xmlCatalogEntryPtr ret;
ret = (xmlCatalogEntryPtr) xmlMalloc(sizeof(xmlCatalogEntry));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext,
"malloc of %d byte failed\n", sizeof(xmlCatalogEntry));
return(NULL);
}
ret->type = type;
ret->name = name;
ret->value = value;
return(ret);
}
static void
xmlFreeCatalogEntry(xmlCatalogEntryPtr ret) {
if (ret == NULL)
return;
if (ret->name != NULL)
xmlFree(ret->name);
if (ret->value != NULL)
xmlFree(ret->value);
xmlFree(ret);
}
/************************************************************************
* *
* The parser *
* *
************************************************************************/
#define RAW *cur
#define NEXT cur++;
#define SKIP(x) cur += x;
#define SKIP_BLANKS while (IS_BLANK(*cur)) NEXT;
static const xmlChar *
xmlParseCatalogComment(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);
}
static const xmlChar *
xmlParseCatalogPubid(const xmlChar *cur, xmlChar **id) {
xmlChar *buf = NULL;
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 *) xmlMalloc(size * sizeof(xmlChar));
if (buf == NULL) {
xmlGenericError(xmlGenericErrorContext,
"malloc of %d byte failed\n", size);
return(NULL);
}
while (xmlIsPubidChar(*cur)) {
if ((*cur == stop) && (stop != ' '))
break;
if ((stop == ' ') && (IS_BLANK(*cur)))
break;
if (len + 1 >= size) {
size *= 2;
buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
if (buf == NULL) {
xmlGenericError(xmlGenericErrorContext,
"realloc of %d byte failed\n", size);
return(NULL);
}
}
buf[len++] = *cur;
count++;
NEXT;
}
buf[len] = 0;
if (stop == ' ') {
if (!IS_BLANK(*cur)) {
xmlFree(buf);
return(NULL);
}
} else {
if (*cur != stop) {
xmlFree(buf);
return(NULL);
}
NEXT;
}
*id = buf;
return(cur);
}
static const xmlChar *
xmlParseCatalogName(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);
}
static int
xmlParseCatalog(const xmlChar *value, const char *file) {
const xmlChar *cur = value;
xmlChar *base = NULL;
if ((cur == NULL) || (file == NULL))
return(-1);
base = xmlStrdup((const xmlChar *) file);
while ((cur != NULL) && (cur[0] != '0')) {
SKIP_BLANKS;
if ((cur[0] == '-') && (cur[1] == '-')) {
cur = xmlParseCatalogComment(cur);
if (cur == NULL) {
/* error */
break;
}
} else {
xmlChar *sysid = NULL;
xmlChar *name = NULL;
xmlCatalogEntryType type = XML_CATA_NONE;
cur = xmlParseCatalogName(cur, &name);
if (name == NULL) {
/* error */
break;
}
if (!IS_BLANK(*cur)) {
/* error */
break;
}
SKIP_BLANKS;
if (xmlStrEqual(name, (const xmlChar *) "SYSTEM"))
type = XML_CATA_SYSTEM;
else if (xmlStrEqual(name, (const xmlChar *) "PUBLIC"))
type = XML_CATA_PUBLIC;
else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE"))
type = XML_CATA_DELEGATE;
else if (xmlStrEqual(name, (const xmlChar *) "ENTITY"))
type = XML_CATA_ENTITY;
else if (xmlStrEqual(name, (const xmlChar *) "DOCTYPE"))
type = XML_CATA_DOCTYPE;
else if (xmlStrEqual(name, (const xmlChar *) "LINKTYPE"))
type = XML_CATA_LINKTYPE;
else if (xmlStrEqual(name, (const xmlChar *) "NOTATION"))
type = XML_CATA_NOTATION;
else if (xmlStrEqual(name, (const xmlChar *) "SGMLDECL"))
type = XML_CATA_SGMLDECL;
else if (xmlStrEqual(name, (const xmlChar *) "DOCUMENT"))
type = XML_CATA_DOCUMENT;
else if (xmlStrEqual(name, (const xmlChar *) "CATALOG"))
type = XML_CATA_CATALOG;
else if (xmlStrEqual(name, (const xmlChar *) "BASE"))
type = XML_CATA_BASE;
else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE"))
type = XML_CATA_DELEGATE;
else if (xmlStrEqual(name, (const xmlChar *) "OVERRIDE")) {
xmlFree(name);
cur = xmlParseCatalogName(cur, &name);
if (name == NULL) {
/* error */
break;
}
continue;
}
xmlFree(name);
switch(type) {
case XML_CATA_ENTITY:
if (*cur == '%')
type = XML_CATA_PENTITY;
case XML_CATA_PENTITY:
case XML_CATA_DOCTYPE:
case XML_CATA_LINKTYPE:
case XML_CATA_NOTATION:
cur = xmlParseCatalogName(cur, &name);
if (cur == NULL) {
/* error */
break;
}
if (!IS_BLANK(*cur)) {
/* error */
break;
}
SKIP_BLANKS;
cur = xmlParseCatalogPubid(cur, &sysid);
if (cur == NULL) {
/* error */
break;
}
break;
case XML_CATA_PUBLIC:
case XML_CATA_SYSTEM:
case XML_CATA_DELEGATE:
cur = xmlParseCatalogPubid(cur, &name);
if (cur == NULL) {
/* error */
break;
}
if (!IS_BLANK(*cur)) {
/* error */
break;
}
SKIP_BLANKS;
cur = xmlParseCatalogPubid(cur, &sysid);
if (cur == NULL) {
/* error */
break;
}
break;
case XML_CATA_BASE:
case XML_CATA_CATALOG:
case XML_CATA_DOCUMENT:
case XML_CATA_SGMLDECL:
cur = xmlParseCatalogPubid(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 == XML_CATA_BASE) {
if (base != NULL)
xmlFree(base);
base = sysid;
} else if ((type == XML_CATA_PUBLIC) ||
(type == XML_CATA_SYSTEM)) {
xmlChar *filename;
filename = xmlBuildURI(sysid, base);
if (filename != NULL) {
xmlHashAddEntry(xmlDefaultCatalog, name,
xmlNewCatalogEntry(type, name, filename));
}
if (sysid != NULL)
xmlFree(sysid);
} else {
/*
* 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);
}
/************************************************************************
* *
* Public interfaces *
* *
************************************************************************/
/*
* xmlLoadCatalog:
* @filename: a file path
*
* Load the catalog and makes its definition effective for the default
* external entity loader.
*
* Returns 0 in case of success -1 in case of error
*/
int
xmlLoadCatalog(const char *filename) {
int fd, len, ret;
struct stat info;
xmlChar *content;
if (filename == NULL)
return(-1);
if (xmlDefaultCatalog == NULL)
xmlDefaultCatalog = xmlHashCreate(20);
if (xmlDefaultCatalog == NULL)
return(-1);
if (stat(filename, &info) < 0)
return(-1);
if ((fd = open(filename, O_RDONLY)) < 0)
return(-1);
content = xmlMalloc(info.st_size + 10);
if (content == NULL) {
xmlGenericError(xmlGenericErrorContext,
"realloc of %d byte failed\n", info.st_size + 10);
}
len = read(fd, content, info.st_size);
if (len < 0) {
xmlFree(content);
return(-1);
}
content[len] = 0;
close(fd);
ret = xmlParseCatalog(content, filename);
xmlFree(content);
return(ret);
}
/**
* xmlCatalogCleanup:
*
* Free up all the memory associated with catalogs
*/
void
xmlCatalogCleanup(void) {
if (xmlDefaultCatalog != NULL)
xmlHashFree(xmlDefaultCatalog,
(xmlHashDeallocator) xmlFreeCatalogEntry);
xmlDefaultCatalog = NULL;
}
/**
* xmlCatalogDumpEntry:
* @entry: the
* @out: the file.
*
* Free up all the memory associated with catalogs
*/
static void
xmlCatalogDumpEntry(xmlCatalogEntryPtr entry, FILE *out) {
if ((entry == NULL) || (out == NULL))
return;
switch (entry->type) {
case XML_CATA_ENTITY:
fprintf(out, "ENTITY "); break;
case XML_CATA_PENTITY:
fprintf(out, "ENTITY %%"); break;
case XML_CATA_DOCTYPE:
fprintf(out, "DOCTYPE "); break;
case XML_CATA_LINKTYPE:
fprintf(out, "LINKTYPE "); break;
case XML_CATA_NOTATION:
fprintf(out, "NOTATION "); break;
case XML_CATA_PUBLIC:
fprintf(out, "PUBLIC "); break;
case XML_CATA_SYSTEM:
fprintf(out, "SYSTEM "); break;
case XML_CATA_DELEGATE:
fprintf(out, "DELEGATE "); break;
case XML_CATA_BASE:
fprintf(out, "BASE "); break;
case XML_CATA_CATALOG:
fprintf(out, "CATALOG "); break;
case XML_CATA_DOCUMENT:
fprintf(out, "DOCUMENT "); break;
case XML_CATA_SGMLDECL:
fprintf(out, "SGMLDECL "); break;
default:
return;
}
switch (entry->type) {
case XML_CATA_ENTITY:
case XML_CATA_PENTITY:
case XML_CATA_DOCTYPE:
case XML_CATA_LINKTYPE:
case XML_CATA_NOTATION:
fprintf(out, "%s", entry->name); break;
case XML_CATA_PUBLIC:
case XML_CATA_SYSTEM:
case XML_CATA_SGMLDECL:
case XML_CATA_DOCUMENT:
case XML_CATA_CATALOG:
case XML_CATA_BASE:
case XML_CATA_DELEGATE:
fprintf(out, "\"%s\"", entry->name); break;
default:
break;
}
switch (entry->type) {
case XML_CATA_ENTITY:
case XML_CATA_PENTITY:
case XML_CATA_DOCTYPE:
case XML_CATA_LINKTYPE:
case XML_CATA_NOTATION:
case XML_CATA_PUBLIC:
case XML_CATA_SYSTEM:
case XML_CATA_DELEGATE:
fprintf(out, " \"%s\"", entry->value); break;
default:
break;
}
fprintf(out, "\n");
}
/**
* xmlCatalogDump:
* @out: the file.
*
* Free up all the memory associated with catalogs
*/
void
xmlCatalogDump(FILE *out) {
if (out == NULL)
return;
if (xmlDefaultCatalog != NULL) {
xmlHashScan(xmlDefaultCatalog,
(xmlHashScanner) xmlCatalogDumpEntry, out);
}
}
#endif /* LIBXML_CATALOG_ENABLED */

32
catalog.h Normal file
View File

@ -0,0 +1,32 @@
/**
* uri.c: interfaces of the Catalog handling system
*
* Reference: SGML Open Technical Resolution TR9401:1997.
* http://www.jclark.com/sp/catalog.htm
*
* See Copyright for the status of this software.
*
* Daniel.Veillard@w3.org
*/
#ifndef __XML_CATALOG_H__
#define __XML_CATALOG_H__
#include <stdio.h>
#include <libxml/xmlversion.h>
#ifdef LIBXML_CATALOG_ENABLED
#ifdef __cplusplus
extern "C" {
#endif
int xmlLoadCatalog (const char *URL);
void xmlCatalogCleanup (void);
void xmlCatalogDump (FILE *out);
#ifdef __cplusplus
}
#endif
#endif /* LIBXML_CATALOG_ENABLED */
#endif /* __XML_CATALOG_H__ */

View File

@ -301,6 +301,18 @@ fi
AC_SUBST(WITH_HTML)
AC_SUBST(HTML_OBJ)
AC_ARG_WITH(catalog, [ --with-catalog Add the Catalog support (on)])
if test "$with_catalog" = "no" ; then
echo Disabling Catalog support
WITH_CATALOG=0
CATALOG_OBJ=
else
WITH_CATALOG=1
CATALOG_OBJ="catalog.o"
fi
AC_SUBST(WITH_CATALOG)
AC_SUBST(CATALOG_OBJ)
AC_ARG_WITH(docbook, [ --with-docbook Add Docbook SGML support (on)])
if test "$with_docbook" = "no" ; then
echo Disabling Docbook support

View File

@ -27,7 +27,8 @@ xmlinc_HEADERS = \
libxml/valid.h \
libxml/xlink.h \
libxml/xmlversion.h \
libxml/DOCBparser.h
libxml/DOCBparser.h \
libxml/catalog.h
install-exec-hook:
$(mkinstalldirs) $(DESTDIR)$(xmlincdir) $(DESTDIR)$(xmlincdir)/libxml

32
include/libxml/catalog.h Normal file
View File

@ -0,0 +1,32 @@
/**
* uri.c: interfaces of the Catalog handling system
*
* Reference: SGML Open Technical Resolution TR9401:1997.
* http://www.jclark.com/sp/catalog.htm
*
* See Copyright for the status of this software.
*
* Daniel.Veillard@w3.org
*/
#ifndef __XML_CATALOG_H__
#define __XML_CATALOG_H__
#include <stdio.h>
#include <libxml/xmlversion.h>
#ifdef LIBXML_CATALOG_ENABLED
#ifdef __cplusplus
extern "C" {
#endif
int xmlLoadCatalog (const char *URL);
void xmlCatalogCleanup (void);
void xmlCatalogDump (FILE *out);
#ifdef __cplusplus
}
#endif
#endif /* LIBXML_CATALOG_ENABLED */
#endif /* __XML_CATALOG_H__ */

View File

@ -61,6 +61,15 @@ extern void xmlCheckVersion(int version);
#define LIBXML_HTML_DISABLED
#endif
/*
* Whether the Catalog support is configured in
*/
#if @WITH_CATALOG@
#define LIBXML_CATALOG_ENABLED
#else
#define LIBXML_CATALOG_DISABLED
#endif
/*
* Whether the SGML Docbook support is configured in
*/

View File

@ -2495,11 +2495,18 @@ get_more:
}
nbchar = in - ctxt->input->cur;
if (nbchar > 0) {
if (IS_BLANK(*ctxt->input->cur) &&
areBlanks(ctxt, ctxt->input->cur, nbchar)) {
if (ctxt->sax->ignorableWhitespace != NULL)
ctxt->sax->ignorableWhitespace(ctxt->userData,
ctxt->input->cur, nbchar);
if (IS_BLANK(*ctxt->input->cur)) {
const xmlChar *tmp = ctxt->input->cur;
ctxt->input->cur = in;
if (areBlanks(ctxt, tmp, nbchar)) {
if (ctxt->sax->ignorableWhitespace != NULL)
ctxt->sax->ignorableWhitespace(ctxt->userData,
tmp, nbchar);
} else {
if (ctxt->sax->characters != NULL)
ctxt->sax->characters(ctxt->userData,
tmp, nbchar);
}
} else {
if (ctxt->sax->characters != NULL)
ctxt->sax->characters(ctxt->userData,

32
testCatalog.c Normal file
View File

@ -0,0 +1,32 @@
/*
* testCatalog.c : a small tester program for Catalog loading
*
* See Copyright for the status of this software.
*
* Daniel.Veillard@w3.org
*/
#include "libxml.h"
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <libxml/xmlversion.h>
#include <libxml/xmlmemory.h>
#include <libxml/uri.h>
#include <libxml/catalog.h>
int main(int argc, char **argv) {
#ifdef LIBXML_CATALOG_ENABLED
int i;
for (i = 1; i < argc; i++)
xmlLoadCatalog(argv[i]);
xmlCatalogDump(stdout);
xmlCatalogCleanup();
xmlMemoryDump();
#endif
return(0);
}

View File

@ -61,6 +61,15 @@ extern void xmlCheckVersion(int version);
#define LIBXML_HTML_DISABLED
#endif
/*
* Whether the Catalog support is configured in
*/
#if @WITH_CATALOG@
#define LIBXML_CATALOG_ENABLED
#else
#define LIBXML_CATALOG_DISABLED
#endif
/*
* Whether the SGML Docbook support is configured in
*/