applied a couple of patches from Peter Jacobi to start to get rid of
* parser.c: applied a couple of patches from Peter Jacobi to start
to get rid of ctxt->token, with a possible significant speed
improvement to be gained once done. Better compliance with PE
references constructs in DTDs too.
* test/valid/t[0-9]* result/valid/t[0-9]*: added a set of tests
from Peter too
Daniel
diff --git a/ChangeLog b/ChangeLog
index e1b802f..fe516b0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Tue Jun 11 12:07:04 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+ * parser.c: applied a couple of patches from Peter Jacobi to start
+ to get rid of ctxt->token, with a possible significant speed
+ improvement to be gained once done. Better compliance with PE
+ references constructs in DTDs too.
+ * test/valid/t[0-9]* result/valid/t[0-9]*: added a set of tests
+ from Peter too
+
Tue Jun 11 09:25:12 CEST 2002 Daniel Veillard <daniel@veillard.com>
* parser.c: Babak Vahedipour-Kunze reported that openTag in
diff --git a/parser.c b/parser.c
index 745bd89..f5827e0 100644
--- a/parser.c
+++ b/parser.c
@@ -665,6 +665,58 @@
}
/**
+ * xmlNewBlanksWrapperInputStream:
+ * @ctxt: an XML parser context
+ * @entity: an Entity pointer
+ *
+ * Create a new input stream for wrapping
+ * blanks around a PEReference
+ *
+ * Returns the new input stream or NULL
+ */
+
+static void deallocblankswrapper (xmlChar *str) {xmlFree(str);}
+
+xmlParserInputPtr
+xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
+ xmlParserInputPtr input;
+ xmlChar *buffer;
+ size_t length;
+ if (entity == NULL) {
+ ctxt->errNo = XML_ERR_INTERNAL_ERROR;
+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+ ctxt->sax->error(ctxt->userData,
+ "internal: xmlNewBlanksWrapperInputStream entity = NULL\n");
+ ctxt->errNo = XML_ERR_INTERNAL_ERROR;
+ return(NULL);
+ }
+ if (xmlParserDebugEntities)
+ xmlGenericError(xmlGenericErrorContext,
+ "new blanks wrapper for entity: %s\n", entity->name);
+ input = xmlNewInputStream(ctxt);
+ if (input == NULL) {
+ return(NULL);
+ }
+ length = xmlStrlen(entity->name) + 5;
+ buffer = xmlMalloc(length);
+ if (buffer == NULL) {
+ return(NULL);
+ }
+ buffer [0] = ' ';
+ buffer [1] = '%';
+ buffer [length-3] = ';';
+ buffer [length-2] = ' ';
+ buffer [length-1] = 0;
+ memcpy(buffer + 2, entity->name, length - 5);
+ input->free = deallocblankswrapper;
+ input->base = buffer;
+ input->cur = buffer;
+ input->length = length;
+ input->end = &buffer[length];
+ return(input);
+}
+
+/**
* xmlParserHandlePEReference:
* @ctxt: the parser context
*
@@ -765,6 +817,8 @@
*/
if ((ctxt->external == 0) && (ctxt->inputNr == 1))
return;
+ if (IS_BLANK(NXT(1)) || NXT(1) == 0)
+ return;
break;
case XML_PARSER_IGNORE:
return;
@@ -822,6 +876,9 @@
"PEReference: %%%s; not found\n", name);
ctxt->valid = 0;
}
+ } else if (ctxt->input->free != deallocblankswrapper) {
+ input = xmlNewBlanksWrapperInputStream(ctxt, entity);
+ xmlPushInput(ctxt, input);
} else {
if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
(entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
@@ -857,8 +914,6 @@
(NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
xmlParseTextDecl(ctxt);
}
- if (ctxt->token == 0)
- ctxt->token = ' ';
} else {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
@@ -3421,6 +3476,7 @@
xmlChar *ndata = NULL;
int isParameter = 0;
xmlChar *orig = NULL;
+ int skipped;
GROW;
if ((RAW == '<') && (NXT(1) == '!') &&
@@ -3428,10 +3484,10 @@
(NXT(4) == 'T') && (NXT(5) == 'I') &&
(NXT(6) == 'T') && (NXT(7) == 'Y')) {
xmlParserInputPtr input = ctxt->input;
- ctxt->instate = XML_PARSER_ENTITY_DECL;
SHRINK;
SKIP(8);
- if (!IS_BLANK(CUR)) {
+ skipped = SKIP_BLANKS;
+ if (skipped == 0) {
ctxt->errNo = XML_ERR_SPACE_REQUIRED;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
@@ -3439,11 +3495,11 @@
ctxt->wellFormed = 0;
ctxt->disableSAX = 1;
}
- SKIP_BLANKS;
if (RAW == '%') {
NEXT;
- if (!IS_BLANK(CUR)) {
+ skipped = SKIP_BLANKS;
+ if (skipped == 0) {
ctxt->errNo = XML_ERR_SPACE_REQUIRED;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
@@ -3451,7 +3507,6 @@
ctxt->wellFormed = 0;
ctxt->disableSAX = 1;
}
- SKIP_BLANKS;
isParameter = 1;
}
@@ -3464,7 +3519,8 @@
ctxt->disableSAX = 1;
return;
}
- if (!IS_BLANK(CUR)) {
+ skipped = SKIP_BLANKS;
+ if (skipped == 0) {
ctxt->errNo = XML_ERR_SPACE_REQUIRED;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
@@ -3472,8 +3528,8 @@
ctxt->wellFormed = 0;
ctxt->disableSAX = 1;
}
- SKIP_BLANKS;
+ ctxt->instate = XML_PARSER_ENTITY_DECL;
/*
* handle the various case of definitions...
*/
@@ -6037,6 +6093,9 @@
if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
ctxt->sax->warning(ctxt->userData,
"Internal: %%%s; is not a parameter entity\n", name);
+ } else if (ctxt->input->free != deallocblankswrapper) {
+ input = xmlNewBlanksWrapperInputStream(ctxt, entity);
+ xmlPushInput(ctxt, input);
} else {
/*
* TODO !!!
@@ -6060,8 +6119,6 @@
return;
}
}
- if (ctxt->token == 0)
- ctxt->token = ' ';
}
}
ctxt->hasPErefs = 1;
diff --git a/result/valid/t4.dtd b/result/valid/t4.dtd
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/result/valid/t4.dtd
diff --git a/result/valid/t4.dtd.err b/result/valid/t4.dtd.err
new file mode 100644
index 0000000..bd98d32
--- /dev/null
+++ b/result/valid/t4.dtd.err
@@ -0,0 +1,6 @@
+./test/valid/t4.dtd:1: error: xmlParseStartTag: invalid element name
+<!ENTITY % percent "%">
+^
+./test/valid/t4.dtd:1: error: Extra content at the end of the document
+<!ENTITY % percent "%">
+^
diff --git a/result/valid/t4.xml b/result/valid/t4.xml
new file mode 100644
index 0000000..c198f76
--- /dev/null
+++ b/result/valid/t4.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<!DOCTYPE root SYSTEM "t4.dtd">
+<root>&abc;</root>
diff --git a/result/valid/t4.xml.err b/result/valid/t4.xml.err
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/result/valid/t4.xml.err
diff --git a/result/valid/t4a.dtd b/result/valid/t4a.dtd
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/result/valid/t4a.dtd
diff --git a/result/valid/t4a.dtd.err b/result/valid/t4a.dtd.err
new file mode 100644
index 0000000..5d2a8d8
--- /dev/null
+++ b/result/valid/t4a.dtd.err
@@ -0,0 +1,6 @@
+./test/valid/t4a.dtd:1: error: xmlParseStartTag: invalid element name
+<!ENTITY % percent "%">
+^
+./test/valid/t4a.dtd:1: error: Extra content at the end of the document
+<!ENTITY % percent "%">
+^
diff --git a/result/valid/t4a.xml b/result/valid/t4a.xml
new file mode 100644
index 0000000..37e80f7
--- /dev/null
+++ b/result/valid/t4a.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<!DOCTYPE root SYSTEM "t4a.dtd">
+<root>&abc;</root>
diff --git a/result/valid/t4a.xml.err b/result/valid/t4a.xml.err
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/result/valid/t4a.xml.err
diff --git a/result/valid/t6.dtd b/result/valid/t6.dtd
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/result/valid/t6.dtd
diff --git a/result/valid/t6.dtd.err b/result/valid/t6.dtd.err
new file mode 100644
index 0000000..9eb7dc2
--- /dev/null
+++ b/result/valid/t6.dtd.err
@@ -0,0 +1,6 @@
+./test/valid/t6.dtd:1: error: xmlParseStartTag: invalid element name
+<!ENTITY % xdef "def">
+^
+./test/valid/t6.dtd:1: error: Extra content at the end of the document
+<!ENTITY % xdef "def">
+^
diff --git a/result/valid/t6.xml b/result/valid/t6.xml
new file mode 100644
index 0000000..23f2d25
--- /dev/null
+++ b/result/valid/t6.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<!DOCTYPE root SYSTEM "t6.dtd">
+<root>&abc;</root>
diff --git a/result/valid/t6.xml.err b/result/valid/t6.xml.err
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/result/valid/t6.xml.err
diff --git a/result/valid/t8.xml b/result/valid/t8.xml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/result/valid/t8.xml
diff --git a/result/valid/t8.xml.err b/result/valid/t8.xml.err
new file mode 100644
index 0000000..d3fdf73
--- /dev/null
+++ b/result/valid/t8.xml.err
@@ -0,0 +1,18 @@
+Entity: line 1: error: xmlParseInternalSubset: error detected in Markup declaration
+ %defroot;
+ ^
+Entity: line 1:
+<!ELEMENT root (middle) >
+^
+Entity: line 1: error: DOCTYPE improperly terminated
+ %defroot;
+ ^
+Entity: line 1:
+<!ELEMENT root (middle) >
+^
+Entity: line 1: error: Start tag expected, '<' not found
+ %defroot;
+ ^
+Entity: line 1:
+<!ELEMENT root (middle) >
+^
diff --git a/result/valid/t8a.xml b/result/valid/t8a.xml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/result/valid/t8a.xml
diff --git a/result/valid/t8a.xml.err b/result/valid/t8a.xml.err
new file mode 100644
index 0000000..d3fdf73
--- /dev/null
+++ b/result/valid/t8a.xml.err
@@ -0,0 +1,18 @@
+Entity: line 1: error: xmlParseInternalSubset: error detected in Markup declaration
+ %defroot;
+ ^
+Entity: line 1:
+<!ELEMENT root (middle) >
+^
+Entity: line 1: error: DOCTYPE improperly terminated
+ %defroot;
+ ^
+Entity: line 1:
+<!ELEMENT root (middle) >
+^
+Entity: line 1: error: Start tag expected, '<' not found
+ %defroot;
+ ^
+Entity: line 1:
+<!ELEMENT root (middle) >
+^
diff --git a/result/valid/t9.xml b/result/valid/t9.xml
new file mode 100644
index 0000000..6950b14
--- /dev/null
+++ b/result/valid/t9.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<!DOCTYPE root [
+<!ENTITY % deftest "<!ELEMENT test (#PCDATA) >">
+<!ENTITY % defmiddle "<!ELEMENT middle (test) >">
+<!ENTITY % defroot "<!ELEMENT root (middle) >">
+<!ELEMENT root (middle)>
+<!ELEMENT middle (test)>
+<!ELEMENT test (#PCDATA)>
+]>
+<root><middle><test>sample</test></middle></root>
diff --git a/result/valid/t9.xml.err b/result/valid/t9.xml.err
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/result/valid/t9.xml.err
diff --git a/result/valid/t9a.xml b/result/valid/t9a.xml
new file mode 100644
index 0000000..6950b14
--- /dev/null
+++ b/result/valid/t9a.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<!DOCTYPE root [
+<!ENTITY % deftest "<!ELEMENT test (#PCDATA) >">
+<!ENTITY % defmiddle "<!ELEMENT middle (test) >">
+<!ENTITY % defroot "<!ELEMENT root (middle) >">
+<!ELEMENT root (middle)>
+<!ELEMENT middle (test)>
+<!ELEMENT test (#PCDATA)>
+]>
+<root><middle><test>sample</test></middle></root>
diff --git a/result/valid/t9a.xml.err b/result/valid/t9a.xml.err
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/result/valid/t9a.xml.err
diff --git a/test/valid/t4.dtd b/test/valid/t4.dtd
new file mode 100644
index 0000000..27292bc
--- /dev/null
+++ b/test/valid/t4.dtd
@@ -0,0 +1,4 @@
+<!ENTITY % percent "%">
+<!ENTITY %percent; def "ghi">
+<!ENTITY abc "%def;">
+<!ELEMENT root (#PCDATA)>
diff --git a/test/valid/t4.xml b/test/valid/t4.xml
new file mode 100644
index 0000000..baeb9d0
--- /dev/null
+++ b/test/valid/t4.xml
@@ -0,0 +1,3 @@
+<?xml version='1.0'?>
+<!DOCTYPE root SYSTEM 't4.dtd'>
+<root>&abc;</root>
diff --git a/test/valid/t4a.dtd b/test/valid/t4a.dtd
new file mode 100644
index 0000000..b7cdc7c
--- /dev/null
+++ b/test/valid/t4a.dtd
@@ -0,0 +1,5 @@
+<!ENTITY % percent "%">
+<!ENTITY%percent;def "ghi">
+<!ENTITY abc "%def;">
+<!ELEMENT root (#PCDATA)>
+
diff --git a/test/valid/t4a.xml b/test/valid/t4a.xml
new file mode 100644
index 0000000..27fa603
--- /dev/null
+++ b/test/valid/t4a.xml
@@ -0,0 +1,3 @@
+<?xml version='1.0'?>
+<!DOCTYPE root SYSTEM 't4a.dtd'>
+<root>&abc;</root>
diff --git a/test/valid/t6.dtd b/test/valid/t6.dtd
new file mode 100644
index 0000000..7497c28
--- /dev/null
+++ b/test/valid/t6.dtd
@@ -0,0 +1,5 @@
+<!ENTITY % xdef "def">
+<!ENTITY % %xdef; "ghi">
+<!ENTITY abc "%def;">
+<!ELEMENT root (#PCDATA)>
+
diff --git a/test/valid/t6.xml b/test/valid/t6.xml
new file mode 100644
index 0000000..b9f62ca
--- /dev/null
+++ b/test/valid/t6.xml
@@ -0,0 +1,3 @@
+<?xml version='1.0'?>
+<!DOCTYPE root SYSTEM 't6.dtd'>
+<root>&abc;</root>
diff --git a/test/valid/t8.xml b/test/valid/t8.xml
new file mode 100644
index 0000000..c7c2b0a
--- /dev/null
+++ b/test/valid/t8.xml
@@ -0,0 +1,8 @@
+<?xml version='1.0'?>
+<!DOCTYPE root [
+<!ENTITY % deftest '<!ELEMENT test (#PCDATA) >' >
+<!ENTITY % defmiddle '<!ELEMENT middle (test) >' >
+<!ENTITY % defroot '<!ELEMENT root (middle) >' >
+%defroot; %defmiddle; %deftest;
+]>
+<root><middle><test>sample</test></middle></root>
diff --git a/test/valid/t8a.xml b/test/valid/t8a.xml
new file mode 100644
index 0000000..13470eb
--- /dev/null
+++ b/test/valid/t8a.xml
@@ -0,0 +1,8 @@
+<?xml version='1.0'?>
+<!DOCTYPE root [
+<!ENTITY % deftest '<!ELEMENT test (#PCDATA) >' >
+<!ENTITY % defmiddle '<!ELEMENT middle (test) >' >
+<!ENTITY % defroot '<!ELEMENT root (middle) >' >
+%defroot;%defmiddle;%deftest;
+]>
+<root><middle><test>sample</test></middle></root>
diff --git a/test/valid/t9.xml b/test/valid/t9.xml
new file mode 100644
index 0000000..645d35a
--- /dev/null
+++ b/test/valid/t9.xml
@@ -0,0 +1,8 @@
+<?xml version='1.0'?>
+<!DOCTYPE root [
+<!ENTITY % deftest '<!ELEMENT test (#PCDATA) >' >
+<!ENTITY % defmiddle '<!ELEMENT middle (test) >' >
+<!ENTITY % defroot '<!ELEMENT root (middle) >' >
+%defroot; %defmiddle; %deftest;
+]>
+<root><middle><test>sample</test></middle></root>
diff --git a/test/valid/t9a.xml b/test/valid/t9a.xml
new file mode 100644
index 0000000..23d3c06
--- /dev/null
+++ b/test/valid/t9a.xml
@@ -0,0 +1,8 @@
+<?xml version='1.0'?>
+<!DOCTYPE root [
+<!ENTITY % deftest '<!ELEMENT test (#PCDATA) >' >
+<!ENTITY % defmiddle '<!ELEMENT middle (test) >' >
+<!ENTITY % defroot '<!ELEMENT root (middle) >' >
+%defroot;%defmiddle;%deftest;
+]>
+<root><middle><test>sample</test></middle></root>