applied patch from Alfred Mickautsch for better DTD support. fixed bug
* xmlwriter.c include/libxml/xmlwriter.h doc/* : applied patch from
Alfred Mickautsch for better DTD support.
* SAX2.c HTMLparser.c parser.c xinclude.c xmllint.c xmlreader.c
xmlschemas.c: fixed bug #137867 i.e. fixed properly the way
reference counting is handled in the XML parser which had the
side effect of removing a lot of hazardous cruft added to try
to fix the problems associated as they popped up.
* xmlIO.c: FILE * close fixup for stderr/stdout
Daniel
diff --git a/xmlwriter.c b/xmlwriter.c
index 43e5f63..e5c7e5f 100644
--- a/xmlwriter.c
+++ b/xmlwriter.c
@@ -38,9 +38,13 @@
XML_TEXTWRITER_DTD,
XML_TEXTWRITER_DTD_TEXT,
XML_TEXTWRITER_DTD_ELEM,
+ XML_TEXTWRITER_DTD_ELEM_TEXT,
XML_TEXTWRITER_DTD_ATTL,
- XML_TEXTWRITER_DTD_ENTY,
- XML_TEXTWRITER_COMMENT
+ XML_TEXTWRITER_DTD_ATTL_TEXT,
+ XML_TEXTWRITER_DTD_ENTY, /* entity */
+ XML_TEXTWRITER_DTD_ENTY_TEXT,
+ XML_TEXTWRITER_DTD_PENT, /* parameter entity */
+ XML_TEXTWRITER_COMMENT,
} xmlTextWriterState;
typedef struct _xmlTextWriterStackEntry xmlTextWriterStackEntry;
@@ -87,6 +91,9 @@
const unsigned char *data);
static void xmlTextWriterStartDocumentCallback(void *ctx);
static int xmlTextWriterWriteIndent(xmlTextWriterPtr writer);
+static int
+ xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
+ xmlTextWriterStackEntry * p);
/**
* xmlNewTextWriter:
@@ -127,7 +134,7 @@
if (ret->nsstack == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlNewTextWriter : out of memory!\n");
- xmlFree(ret->nodes);
+ xmlListDelete(ret->nodes);
xmlFree(ret);
return NULL;
}
@@ -136,8 +143,14 @@
ret->ichar = xmlStrdup(BAD_CAST " ");
ret->qchar = '"';
- if (!ret->ichar)
+ if (!ret->ichar) {
+ xmlListDelete(ret->nodes);
+ xmlListDelete(ret->nsstack);
+ xmlFree(ret);
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlNewTextWriter : out of memory!\n");
return NULL;
+ }
return ret;
}
@@ -233,6 +246,12 @@
xmlTextWriterPtr ret;
xmlOutputBufferPtr out;
+ if (ctxt == NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlNewTextWriterPushParser : invalid context!\n");
+ return NULL;
+ }
+
out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
xmlTextWriterWriteDocCallback,
(xmlOutputCloseCallback)
@@ -301,8 +320,10 @@
return NULL;
}
- *doc = ctxt->myDoc;
- xmlSetDocCompressMode(*doc, compression);
+ xmlSetDocCompressMode(ctxt->myDoc, compression);
+
+ if (doc != NULL)
+ *doc = ctxt->myDoc;
return ret;
}
@@ -326,6 +347,8 @@
xmlParserCtxtPtr ctxt;
if (doc == NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlNewTextWriterTree : invalid document tree!\n");
return NULL;
}
@@ -342,16 +365,17 @@
return NULL;
}
- ctxt->myDoc = doc;
- ctxt->node = node;
-
ret = xmlNewTextWriterPushParser(ctxt, compression);
if (ret == NULL) {
+ xmlFreeParserCtxt(ctxt);
xmlGenericError(xmlGenericErrorContext,
"xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
return NULL;
}
+ ctxt->myDoc = doc;
+ ctxt->node = node;
+
xmlSetDocCompressMode(doc, compression);
return ret;
@@ -406,13 +430,16 @@
xmlLinkPtr lk;
xmlCharEncodingHandlerPtr encoder;
- if ((writer == NULL) || (writer->out == NULL))
+ if ((writer == NULL) || (writer->out == NULL)) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlTextWriterStartDocument : invalid writer!\n");
return -1;
+ }
lk = xmlListFront(writer->nodes);
if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
xmlGenericError(xmlGenericErrorContext,
- "xmlTextWriterStartDocument : only one prolog allowed in an XML document!\n");
+ "xmlTextWriterStartDocument : not allowed in this context!\n");
return -1;
}
@@ -517,8 +544,11 @@
xmlLinkPtr lk;
xmlTextWriterStackEntry *p;
- if (writer == NULL)
+ if (writer == NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlTextWriterEndDocument : invalid writer!\n");
return -1;
+ }
sum = 0;
while ((lk = xmlListFront(writer->nodes)) != NULL) {
@@ -548,6 +578,14 @@
sum += count;
break;
case XML_TEXTWRITER_DTD:
+ case XML_TEXTWRITER_DTD_TEXT:
+ case XML_TEXTWRITER_DTD_ELEM:
+ case XML_TEXTWRITER_DTD_ELEM_TEXT:
+ case XML_TEXTWRITER_DTD_ATTL:
+ case XML_TEXTWRITER_DTD_ATTL_TEXT:
+ case XML_TEXTWRITER_DTD_ENTY:
+ case XML_TEXTWRITER_DTD_ENTY_TEXT:
+ case XML_TEXTWRITER_DTD_PENT:
count = xmlTextWriterEndDTD(writer);
if (count < 0)
return -1;
@@ -573,11 +611,6 @@
return sum;
}
-
-
-
-
-
/**
* xmlTextWriterStartComment:
* @writer: the xmlTextWriterPtr
@@ -594,8 +627,11 @@
xmlLinkPtr lk;
xmlTextWriterStackEntry *p;
- if (writer == NULL)
+ if (writer == NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlTextWriterStartComment : invalid writer!\n");
return -1;
+ }
sum = 0;
lk = xmlListFront(writer->nodes);
@@ -611,6 +647,13 @@
if (count < 0)
return -1;
sum += count;
+ if (writer->indent) {
+ count =
+ xmlOutputBufferWriteString(writer->out, "\n");
+ if (count < 0)
+ return -1;
+ sum += count;
+ }
p->state = XML_TEXTWRITER_TEXT;
break;
default:
@@ -633,10 +676,6 @@
xmlListPushFront(writer->nodes, p);
if (writer->indent) {
- count = xmlOutputBufferWriteString(writer->out, "\n");
- if (count < 0)
- return -1;
- sum += count;
count = xmlTextWriterWriteIndent(writer);
if (count < 0)
return -1;
@@ -667,12 +706,18 @@
xmlLinkPtr lk;
xmlTextWriterStackEntry *p;
- if (writer == NULL)
+ if (writer == NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlTextWriterEndComment : invalid writer!\n");
return -1;
+ }
lk = xmlListFront(writer->nodes);
- if (lk == 0)
+ if (lk == 0) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlTextWriterEndComment : not allowed in this context!\n");
return -1;
+ }
p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
if (p == 0)
@@ -743,8 +788,11 @@
int rc;
xmlChar *buf;
- if (writer == NULL)
+ if (writer == NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlTextWriterWriteVFormatComment : invalid writer!\n");
return -1;
+ }
buf = xmlTextWriterVSprintf(format, argptr);
if (buf == 0)
@@ -1142,50 +1190,38 @@
xmlLinkPtr lk;
xmlTextWriterStackEntry *p;
- if (writer == NULL)
+ if (writer == NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlTextWriterWriteRawLen : invalid writer!\n");
return -1;
-
- lk = xmlListFront(writer->nodes);
- if (lk == 0)
- return 0;
-
- p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
- if (p == 0)
- return 0;
-
- sum = 0;
- switch (p->state) {
- case XML_TEXTWRITER_NONE:
- return -1;
- case XML_TEXTWRITER_NAME:
- count = xmlOutputBufferWriteString(writer->out, ">");
- if (count < 0)
- return -1;
- sum += count;
- p->state = XML_TEXTWRITER_TEXT;
- break;
- case XML_TEXTWRITER_PI:
- count = xmlOutputBufferWriteString(writer->out, " ");
- if (count < 0)
- return -1;
- sum += count;
- p->state = XML_TEXTWRITER_PI_TEXT;
- break;
- case XML_TEXTWRITER_DTD:
- count = xmlOutputBufferWriteString(writer->out, " [");
- if (count < 0)
- return -1;
- sum += count;
- p->state = XML_TEXTWRITER_DTD_TEXT;
- break;
- default:
- break;
}
- count = xmlOutputBufferWrite(writer->out, len, (const char *) content);
- if (count < 0)
+ if ((content == NULL) && (len > 0)) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlTextWriterWriteRawLen : invalid content!\n");
return -1;
- sum += count;
+ }
+
+ sum = 0;
+ lk = xmlListFront(writer->nodes);
+ if (lk != 0) {
+ p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+ count = xmlTextWriterHandleStateDependencies(writer, p);
+ if (count < 0)
+ return -1;
+ sum += count;
+ }
+
+ if (writer->indent)
+ writer->doindent = 0;
+
+ if (content != NULL) {
+ count =
+ xmlOutputBufferWrite(writer->out, len, (const char *) content);
+ if (count < 0)
+ return -1;
+ sum += count;
+ }
return sum;
}
@@ -1272,82 +1308,45 @@
int
xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
{
- int count = 0;
+ int count;
int sum;
xmlLinkPtr lk;
xmlTextWriterStackEntry *p;
- xmlChar *buf = NULL;
+ xmlChar *buf;
if (writer == NULL)
return -1;
- lk = xmlListFront(writer->nodes);
- if (lk == 0)
- return -1;
-
- p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
- if (p == 0)
- return -1;
-
sum = 0;
- switch (p->state) {
- case XML_TEXTWRITER_NONE:
+ buf = (xmlChar *) content;
+ lk = xmlListFront(writer->nodes);
+ if (lk != 0) {
+ p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+ if (p != 0) {
+ switch (p->state) {
+ case XML_TEXTWRITER_NAME:
+ case XML_TEXTWRITER_TEXT:
+ encode:
+ buf = xmlEncodeSpecialChars(NULL, content);
+ break;
+ case XML_TEXTWRITER_ATTRIBUTE:
+ buf = NULL;
+ xmlAttrSerializeTxtContent(writer->out->buffer, NULL,
+ NULL, content);
+ break;
+ }
+ }
+ }
+
+ if (buf != NULL) {
+ count = xmlTextWriterWriteRaw(writer, buf);
+ if (count < 0)
return -1;
- case XML_TEXTWRITER_NAME:
- count = xmlOutputBufferWriteString(writer->out, ">");
- if (count < 0)
- return -1;
- sum += count;
- p->state = XML_TEXTWRITER_TEXT;
- goto encode;
- case XML_TEXTWRITER_PI:
- count = xmlOutputBufferWriteString(writer->out, " ");
- if (count < 0)
- return -1;
- sum += count;
- p->state = XML_TEXTWRITER_PI_TEXT;
- /* fallthrough */
- case XML_TEXTWRITER_PI_TEXT:
- case XML_TEXTWRITER_TEXT:
- encode:
- buf = xmlEncodeSpecialChars(NULL, content);
- if (buf == NULL)
- count = -1;
- break;
- case XML_TEXTWRITER_ATTRIBUTE:
- xmlAttrSerializeTxtContent(writer->out->buffer, NULL,
- NULL, content);
- break;
- case XML_TEXTWRITER_DTD:
- count = xmlOutputBufferWriteString(writer->out, " [");
- if (count < 0)
- return -1;
- sum += count;
- p->state = XML_TEXTWRITER_DTD_TEXT;
- /* fallthrough */
- case XML_TEXTWRITER_DTD_TEXT:
- case XML_TEXTWRITER_DTD_ELEM:
- case XML_TEXTWRITER_CDATA:
- case XML_TEXTWRITER_COMMENT:
- buf = xmlStrdup(content);
- if (buf == NULL)
- count = -1;
- break;
- default:
- break;
- }
+ sum += count;
- if (writer->indent)
- writer->doindent = 0;
-
- if (buf != 0) {
- count =
- xmlOutputBufferWriteString(writer->out, (const char *) buf);
- xmlFree(buf);
+ if (buf != content) /* buf was allocated by us, so free it */
+ xmlFree(buf);
}
- if (count < 0)
- return -1;
- sum += count;
return sum;
}
@@ -1449,41 +1448,16 @@
if (writer == NULL)
return -1;
- lk = xmlListFront(writer->nodes);
- if (lk == 0)
- return 0;
-
- p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
- if (p == 0)
- return 0;
-
sum = 0;
- switch (p->state) {
- case XML_TEXTWRITER_NONE:
- return -1;
- case XML_TEXTWRITER_NAME:
- count = xmlOutputBufferWriteString(writer->out, ">");
+ lk = xmlListFront(writer->nodes);
+ if (lk != 0) {
+ p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+ if (p != 0) {
+ count = xmlTextWriterHandleStateDependencies(writer, p);
if (count < 0)
return -1;
sum += count;
- p->state = XML_TEXTWRITER_TEXT;
- break;
- case XML_TEXTWRITER_PI:
- count = xmlOutputBufferWriteString(writer->out, " ");
- if (count < 0)
- return -1;
- sum += count;
- p->state = XML_TEXTWRITER_PI_TEXT;
- break;
- case XML_TEXTWRITER_DTD:
- count = xmlOutputBufferWriteString(writer->out, " [");
- if (count < 0)
- return -1;
- sum += count;
- p->state = XML_TEXTWRITER_DTD_TEXT;
- break;
- default:
- break;
+ }
}
if (writer->indent)
@@ -1565,41 +1539,16 @@
if (writer == NULL)
return -1;
- lk = xmlListFront(writer->nodes);
- if (lk == 0)
- return 0;
-
- p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
- if (p == 0)
- return 0;
-
sum = 0;
- switch (p->state) {
- case XML_TEXTWRITER_NONE:
- return -1;
- case XML_TEXTWRITER_NAME:
- count = xmlOutputBufferWriteString(writer->out, ">");
+ lk = xmlListFront(writer->nodes);
+ if (lk != 0) {
+ p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+ if (p != 0) {
+ count = xmlTextWriterHandleStateDependencies(writer, p);
if (count < 0)
return -1;
sum += count;
- p->state = XML_TEXTWRITER_TEXT;
- break;
- case XML_TEXTWRITER_PI:
- count = xmlOutputBufferWriteString(writer->out, " ");
- if (count < 0)
- return -1;
- sum += count;
- p->state = XML_TEXTWRITER_PI_TEXT;
- break;
- case XML_TEXTWRITER_DTD:
- count = xmlOutputBufferWriteString(writer->out, " [");
- if (count < 0)
- return -1;
- sum += count;
- p->state = XML_TEXTWRITER_DTD_TEXT;
- break;
- default:
- break;
+ }
}
if (writer->indent)
@@ -2741,7 +2690,20 @@
return -1;
}
- count = xmlOutputBufferWriteString(writer->out, " PUBLIC \"");
+ if (writer->indent)
+ count = xmlOutputBufferWrite(writer->out, 1, "\n");
+ else
+ count = xmlOutputBufferWrite(writer->out, 1, " ");
+ if (count < 0)
+ return -1;
+ sum += count;
+
+ count = xmlOutputBufferWriteString(writer->out, "PUBLIC ");
+ if (count < 0)
+ return -1;
+ sum += count;
+
+ count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
if (count < 0)
return -1;
sum += count;
@@ -2752,7 +2714,7 @@
return -1;
sum += count;
- count = xmlOutputBufferWriteString(writer->out, "\"");
+ count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
if (count < 0)
return -1;
sum += count;
@@ -2760,13 +2722,25 @@
if (sysid != 0) {
if (pubid == 0) {
- count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
+ if (writer->indent)
+ count = xmlOutputBufferWrite(writer->out, 1, "\n");
+ else
+ count = xmlOutputBufferWrite(writer->out, 1, " ");
+ if (count < 0)
+ return -1;
+ sum += count;
+ count = xmlOutputBufferWriteString(writer->out, "SYSTEM ");
+ if (count < 0)
+ return -1;
+ sum += count;
+ } else if (writer->indent) {
+ count = xmlOutputBufferWriteString(writer->out, "\n ");
if (count < 0)
return -1;
sum += count;
}
- count = xmlOutputBufferWriteString(writer->out, " \"");
+ count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
if (count < 0)
return -1;
sum += count;
@@ -2777,7 +2751,7 @@
return -1;
sum += count;
- count = xmlOutputBufferWriteString(writer->out, "\"");
+ count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
if (count < 0)
return -1;
sum += count;
@@ -2797,6 +2771,7 @@
int
xmlTextWriterEndDTD(xmlTextWriterPtr writer)
{
+ int loop;
int count;
int sum;
xmlLinkPtr lk;
@@ -2806,34 +2781,59 @@
return -1;
sum = 0;
- lk = xmlListFront(writer->nodes);
- if (lk == 0)
- return -1;
-
- p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
- if (p == 0)
- return -1;
-
- switch (p->state) {
- case XML_TEXTWRITER_DTD_TEXT:
- count = xmlOutputBufferWriteString(writer->out, "]");
- if (count < 0)
- return -1;
- sum += count;
- /* fallthrough */
- case XML_TEXTWRITER_DTD:
- case XML_TEXTWRITER_DTD_ELEM:
- case XML_TEXTWRITER_DTD_ATTL:
- count = xmlOutputBufferWriteString(writer->out, ">");
- if (count < 0)
- return -1;
- sum += count;
+ loop = 1;
+ while (loop) {
+ lk = xmlListFront(writer->nodes);
+ if (lk == NULL)
break;
- default:
+ p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+ if (p == 0)
+ break;
+ switch (p->state) {
+ case XML_TEXTWRITER_DTD_TEXT:
+ count = xmlOutputBufferWriteString(writer->out, "]");
+ if (count < 0)
+ return -1;
+ sum += count;
+ /* fallthrough */
+ case XML_TEXTWRITER_DTD:
+ count = xmlOutputBufferWriteString(writer->out, ">");
+
+ if (writer->indent) {
+ if (count < 0)
+ return -1;
+ sum += count;
+ count = xmlOutputBufferWriteString(writer->out, "\n");
+ }
+
+ xmlListPopFront(writer->nodes);
+ break;
+ case XML_TEXTWRITER_DTD_ELEM:
+ case XML_TEXTWRITER_DTD_ELEM_TEXT:
+ count = xmlTextWriterEndDTDElement(writer);
+ break;
+ case XML_TEXTWRITER_DTD_ATTL:
+ case XML_TEXTWRITER_DTD_ATTL_TEXT:
+ count = xmlTextWriterEndDTDAttlist(writer);
+ break;
+ case XML_TEXTWRITER_DTD_ENTY:
+ case XML_TEXTWRITER_DTD_PENT:
+ case XML_TEXTWRITER_DTD_ENTY_TEXT:
+ count = xmlTextWriterEndDTDEntity(writer);
+ break;
+ case XML_TEXTWRITER_COMMENT:
+ count = xmlTextWriterEndComment(writer);
+ break;
+ default:
+ loop = 0;
+ continue;
+ }
+
+ if (count < 0)
return -1;
+ sum += count;
}
- xmlListPopFront(writer->nodes);
return sum;
}
@@ -2971,27 +2971,27 @@
}
p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
- if (p == 0)
- return -1;
-
- switch (p->state) {
- case XML_TEXTWRITER_DTD:
- count = xmlOutputBufferWriteString(writer->out, " [");
- if (count < 0)
+ if (p != 0) {
+ switch (p->state) {
+ case XML_TEXTWRITER_DTD:
+ count = xmlOutputBufferWriteString(writer->out, " [");
+ if (count < 0)
+ return -1;
+ sum += count;
+ if (writer->indent) {
+ count = xmlOutputBufferWriteString(writer->out, "\n");
+ if (count < 0)
+ return -1;
+ sum += count;
+ }
+ p->state = XML_TEXTWRITER_DTD_TEXT;
+ /* fallthrough */
+ case XML_TEXTWRITER_DTD_TEXT:
+ case XML_TEXTWRITER_NONE:
+ break;
+ default:
return -1;
- sum += count;
- p->state = XML_TEXTWRITER_DTD_TEXT;
- /* fallthrough */
- case XML_TEXTWRITER_DTD_TEXT:
- break;
- case XML_TEXTWRITER_DTD_ELEM:
- count = xmlTextWriterEndDTDElement(writer);
- if (count < 0)
- return -1;
- sum += count;
- break;
- default:
- return -1;
+ }
}
p = (xmlTextWriterStackEntry *)
@@ -3013,6 +3013,13 @@
xmlListPushFront(writer->nodes, p);
+ if (writer->indent) {
+ count = xmlTextWriterWriteIndent(writer);
+ if (count < 0)
+ return -1;
+ sum += count;
+ }
+
count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
if (count < 0)
return -1;
@@ -3026,6 +3033,57 @@
}
/**
+ * xmlTextWriterEndDTDElement:
+ * @writer: the xmlTextWriterPtr
+ *
+ * End an xml DTD element.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
+{
+ int count;
+ int sum;
+ xmlLinkPtr lk;
+ xmlTextWriterStackEntry *p;
+
+ if (writer == NULL)
+ return -1;
+
+ sum = 0;
+ lk = xmlListFront(writer->nodes);
+ if (lk == 0)
+ return -1;
+
+ p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+ if (p == 0)
+ return -1;
+
+ switch (p->state) {
+ case XML_TEXTWRITER_DTD_ELEM:
+ case XML_TEXTWRITER_DTD_ELEM_TEXT:
+ count = xmlOutputBufferWriteString(writer->out, ">");
+ if (count < 0)
+ return -1;
+ sum += count;
+ break;
+ default:
+ return -1;
+ }
+
+ if (writer->indent) {
+ count = xmlOutputBufferWriteString(writer->out, "\n");
+ if (count < 0)
+ return -1;
+ sum += count;
+ }
+
+ xmlListPopFront(writer->nodes);
+ return sum;
+}
+
+/**
* xmlTextWriterWriteFormatDTDElement:
* @writer: the xmlTextWriterPtr
* @name: the name of the DTD element
@@ -3110,10 +3168,6 @@
return -1;
sum += count;
- count = xmlTextWriterWriteString(writer, BAD_CAST " ");
- if (count == -1)
- return -1;
- sum += count;
count = xmlTextWriterWriteString(writer, content);
if (count == -1)
return -1;
@@ -3154,29 +3208,27 @@
}
p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
- if (p == 0)
- return -1;
-
- switch (p->state) {
- case XML_TEXTWRITER_DTD:
- count = xmlOutputBufferWriteString(writer->out, " [");
- if (count < 0)
+ if (p != 0) {
+ switch (p->state) {
+ case XML_TEXTWRITER_DTD:
+ count = xmlOutputBufferWriteString(writer->out, " [");
+ if (count < 0)
+ return -1;
+ sum += count;
+ if (writer->indent) {
+ count = xmlOutputBufferWriteString(writer->out, "\n");
+ if (count < 0)
+ return -1;
+ sum += count;
+ }
+ p->state = XML_TEXTWRITER_DTD_TEXT;
+ /* fallthrough */
+ case XML_TEXTWRITER_DTD_TEXT:
+ case XML_TEXTWRITER_NONE:
+ break;
+ default:
return -1;
- sum += count;
- p->state = XML_TEXTWRITER_DTD_TEXT;
- /* fallthrough */
- case XML_TEXTWRITER_DTD_TEXT:
- break;
- case XML_TEXTWRITER_DTD_ELEM:
- case XML_TEXTWRITER_DTD_ATTL:
- case XML_TEXTWRITER_DTD_ENTY:
- count = xmlTextWriterEndDTD(writer);
- if (count < 0)
- return -1;
- sum += count;
- break;
- default:
- return -1;
+ }
}
p = (xmlTextWriterStackEntry *)
@@ -3198,6 +3250,13 @@
xmlListPushFront(writer->nodes, p);
+ if (writer->indent) {
+ count = xmlTextWriterWriteIndent(writer);
+ if (count < 0)
+ return -1;
+ sum += count;
+ }
+
count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
if (count < 0)
return -1;
@@ -3211,6 +3270,57 @@
}
/**
+ * xmlTextWriterEndDTDAttlist:
+ * @writer: the xmlTextWriterPtr
+ *
+ * End an xml DTD attribute list.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
+{
+ int count;
+ int sum;
+ xmlLinkPtr lk;
+ xmlTextWriterStackEntry *p;
+
+ if (writer == NULL)
+ return -1;
+
+ sum = 0;
+ lk = xmlListFront(writer->nodes);
+ if (lk == 0)
+ return -1;
+
+ p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+ if (p == 0)
+ return -1;
+
+ switch (p->state) {
+ case XML_TEXTWRITER_DTD_ATTL:
+ case XML_TEXTWRITER_DTD_ATTL_TEXT:
+ count = xmlOutputBufferWriteString(writer->out, ">");
+ if (count < 0)
+ return -1;
+ sum += count;
+ break;
+ default:
+ return -1;
+ }
+
+ if (writer->indent) {
+ count = xmlOutputBufferWriteString(writer->out, "\n");
+ if (count < 0)
+ return -1;
+ sum += count;
+ }
+
+ xmlListPopFront(writer->nodes);
+ return sum;
+}
+
+/**
* xmlTextWriterWriteFormatDTDAttlist:
* @writer: the xmlTextWriterPtr
* @name: the name of the DTD ATTLIST
@@ -3295,10 +3405,6 @@
return -1;
sum += count;
- count = xmlTextWriterWriteString(writer, BAD_CAST " ");
- if (count == -1)
- return -1;
- sum += count;
count = xmlTextWriterWriteString(writer, content);
if (count == -1)
return -1;
@@ -3336,34 +3442,32 @@
sum = 0;
lk = xmlListFront(writer->nodes);
- if (lk == 0) {
- return -1;
- }
+ if (lk != 0) {
- p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
- if (p == 0)
- return -1;
-
- switch (p->state) {
- case XML_TEXTWRITER_DTD:
- count = xmlOutputBufferWriteString(writer->out, " [");
- if (count < 0)
- return -1;
- sum += count;
- p->state = XML_TEXTWRITER_DTD_TEXT;
- /* fallthrough */
- case XML_TEXTWRITER_DTD_TEXT:
- break;
- case XML_TEXTWRITER_DTD_ELEM:
- case XML_TEXTWRITER_DTD_ATTL:
- case XML_TEXTWRITER_DTD_ENTY:
- count = xmlTextWriterEndDTD(writer);
- if (count < 0)
- return -1;
- sum += count;
- break;
- default:
- return -1;
+ p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+ if (p != 0) {
+ switch (p->state) {
+ case XML_TEXTWRITER_DTD:
+ count = xmlOutputBufferWriteString(writer->out, " [");
+ if (count < 0)
+ return -1;
+ sum += count;
+ if (writer->indent) {
+ count =
+ xmlOutputBufferWriteString(writer->out, "\n");
+ if (count < 0)
+ return -1;
+ sum += count;
+ }
+ p->state = XML_TEXTWRITER_DTD_TEXT;
+ /* fallthrough */
+ case XML_TEXTWRITER_DTD_TEXT:
+ case XML_TEXTWRITER_NONE:
+ break;
+ default:
+ return -1;
+ }
+ }
}
p = (xmlTextWriterStackEntry *)
@@ -3381,17 +3485,28 @@
xmlFree(p);
return -1;
}
- p->state = XML_TEXTWRITER_DTD_ENTY;
+
+ if (pe != 0)
+ p->state = XML_TEXTWRITER_DTD_PENT;
+ else
+ p->state = XML_TEXTWRITER_DTD_ENTY;
xmlListPushFront(writer->nodes, p);
+ if (writer->indent) {
+ count = xmlTextWriterWriteIndent(writer);
+ if (count < 0)
+ return -1;
+ sum += count;
+ }
+
count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
if (count < 0)
return -1;
sum += count;
if (pe != 0) {
- count = xmlOutputBufferWriteString(writer->out, " % ");
+ count = xmlOutputBufferWriteString(writer->out, "% ");
if (count < 0)
return -1;
sum += count;
@@ -3406,6 +3521,63 @@
}
/**
+ * xmlTextWriterEndDTDEntity:
+ * @writer: the xmlTextWriterPtr
+ *
+ * End an xml DTD entity.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
+{
+ int count;
+ int sum;
+ xmlLinkPtr lk;
+ xmlTextWriterStackEntry *p;
+
+ if (writer == NULL)
+ return -1;
+
+ sum = 0;
+ lk = xmlListFront(writer->nodes);
+ if (lk == 0)
+ return -1;
+
+ p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+ if (p == 0)
+ return -1;
+
+ switch (p->state) {
+ case XML_TEXTWRITER_DTD_ENTY_TEXT:
+ count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+ if (count < 0)
+ return -1;
+ sum += count;
+ case XML_TEXTWRITER_DTD_ENTY:
+ case XML_TEXTWRITER_DTD_PENT:
+ enddtd:
+ count = xmlOutputBufferWriteString(writer->out, ">");
+ if (count < 0)
+ return -1;
+ sum += count;
+ break;
+ default:
+ return -1;
+ }
+
+ if (writer->indent) {
+ count = xmlOutputBufferWriteString(writer->out, "\n");
+ if (count < 0)
+ return -1;
+ sum += count;
+ }
+
+ xmlListPopFront(writer->nodes);
+ return sum;
+}
+
+/**
* xmlTextWriterWriteFormatDTDInternalEntity:
* @writer: the xmlTextWriterPtr
* @pe: TRUE if this is a parameter entity, FALSE if not
@@ -3493,13 +3665,12 @@
const xmlChar * ndataid,
const xmlChar * content)
{
- if (((content == NULL) && (pubid == NULL) && (sysid == NULL))
- || ((content != NULL) && ((pubid != NULL) || (sysid != NULL))))
+ if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
return -1;
if ((pe != 0) && (ndataid != NULL))
return -1;
- if (content != 0)
+ if ((pubid == NULL) && (sysid == NULL))
return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
content);
@@ -3536,22 +3707,10 @@
return -1;
sum += count;
- count = xmlTextWriterWriteString(writer, BAD_CAST " ");
- if (count == -1)
- return -1;
- sum += count;
- count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
- if (count < 0)
- return -1;
- sum += count;
count = xmlTextWriterWriteString(writer, content);
if (count == -1)
return -1;
sum += count;
- count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
- if (count < 0)
- return -1;
- sum += count;
count = xmlTextWriterEndDTDEntity(writer);
if (count == -1)
@@ -3570,7 +3729,7 @@
* @sysid: the system identifier, which is the URI of the DTD
* @ndataid: the xml notation name.
*
- * Write a DTD internal entity.
+ * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
*
* Returns the bytes written (may be 0 because of buffering) or -1 in case of error
*/
@@ -3585,8 +3744,7 @@
int count;
int sum;
- if ((name == NULL) || (*name == '\0')
- || ((pubid == NULL) && (sysid == NULL)))
+ if (((pubid == NULL) && (sysid == NULL)))
return -1;
if ((pe != 0) && (ndataid != NULL))
return -1;
@@ -3597,10 +3755,81 @@
return -1;
sum += count;
+ count =
+ xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
+ ndataid);
+ if (count < 0)
+ return -1;
+ sum += count;
+
+ count = xmlTextWriterEndDTDEntity(writer);
+ if (count == -1)
+ return -1;
+ sum += count;
+
+ return sum;
+}
+
+/**
+ * xmlTextWriterWriteDTDExternalEntityContents:
+ * @writer: the xmlTextWriterPtr
+ * @pubid: the public identifier, which is an alternative to the system identifier
+ * @sysid: the system identifier, which is the URI of the DTD
+ * @ndataid: the xml notation name.
+ *
+ * Write the contents of a DTD external entity.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
+ const xmlChar * pubid,
+ const xmlChar * sysid,
+ const xmlChar * ndataid)
+{
+ int count;
+ int sum;
+ xmlLinkPtr lk;
+ xmlTextWriterStackEntry *p;
+
+ if (writer == NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
+ return -1;
+ }
+
+ sum = 0;
+ lk = xmlListFront(writer->nodes);
+ if (lk == 0) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
+ return -1;
+ }
+
+ p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+ if (p == 0)
+ return -1;
+
+ switch (p->state) {
+ case XML_TEXTWRITER_DTD_ENTY:
+ break;
+ case XML_TEXTWRITER_DTD_PENT:
+ if (ndataid != NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
+ return -1;
+ }
+ break;
+ default:
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
+ return -1;
+ }
+
if (pubid != 0) {
if (sysid == 0) {
xmlGenericError(xmlGenericErrorContext,
- "xmlTextWriterWriteDTDEntity : system identifier needed!\n");
+ "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
return -1;
}
@@ -3670,11 +3899,6 @@
sum += count;
}
- count = xmlTextWriterEndDTDEntity(writer);
- if (count == -1)
- return -1;
- sum += count;
-
return sum;
}
@@ -3709,29 +3933,33 @@
}
p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
- if (p == 0)
- return -1;
+ if (p != 0) {
+ switch (p->state) {
+ case XML_TEXTWRITER_DTD:
+ count = xmlOutputBufferWriteString(writer->out, " [");
+ if (count < 0)
+ return -1;
+ sum += count;
+ if (writer->indent) {
+ count = xmlOutputBufferWriteString(writer->out, "\n");
+ if (count < 0)
+ return -1;
+ sum += count;
+ }
+ p->state = XML_TEXTWRITER_DTD_TEXT;
+ /* fallthrough */
+ case XML_TEXTWRITER_DTD_TEXT:
+ break;
+ default:
+ return -1;
+ }
+ }
- switch (p->state) {
- case XML_TEXTWRITER_DTD:
- count = xmlOutputBufferWriteString(writer->out, " [");
- if (count < 0)
- return -1;
- sum += count;
- p->state = XML_TEXTWRITER_DTD_TEXT;
- /* fallthrough */
- case XML_TEXTWRITER_DTD_TEXT:
- break;
- case XML_TEXTWRITER_DTD_ELEM:
- case XML_TEXTWRITER_DTD_ATTL:
- case XML_TEXTWRITER_DTD_ENTY:
- count = xmlTextWriterEndDTD(writer);
- if (count < 0)
- return -1;
- sum += count;
- break;
- default:
+ if (writer->indent) {
+ count = xmlTextWriterWriteIndent(writer);
+ if (count < 0)
return -1;
+ sum += count;
}
count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
@@ -4162,7 +4390,6 @@
int
xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
{
-
if (!str)
return -1;
@@ -4204,4 +4431,74 @@
return (lksize - 1);
}
+/**
+ * xmlTextWriterHandleStateDependencies:
+ * @writer: the xmlTextWriterPtr
+ * @p: the xmlTextWriterStackEntry
+ *
+ * Write state dependent strings.
+ *
+ * Returns -1 on error or the number of characters written.
+ */
+static int
+xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
+ xmlTextWriterStackEntry * p)
+{
+ int count;
+ int sum;
+ char extra[3];
+
+ if (writer == NULL)
+ return -1;
+
+ if (p == NULL)
+ return 0;
+
+ sum = 0;
+ extra[0] = extra[1] = extra[2] = '\0';
+ if (p != 0) {
+ sum = 0;
+ switch (p->state) {
+ case XML_TEXTWRITER_NAME:
+ extra[0] = '>';
+ p->state = XML_TEXTWRITER_TEXT;
+ break;
+ case XML_TEXTWRITER_PI:
+ extra[0] = ' ';
+ p->state = XML_TEXTWRITER_PI_TEXT;
+ break;
+ case XML_TEXTWRITER_DTD:
+ extra[0] = ' ';
+ extra[1] = '[';
+ p->state = XML_TEXTWRITER_DTD_TEXT;
+ break;
+ case XML_TEXTWRITER_DTD_ELEM:
+ extra[0] = ' ';
+ p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
+ break;
+ case XML_TEXTWRITER_DTD_ATTL:
+ extra[0] = ' ';
+ p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
+ break;
+ case XML_TEXTWRITER_DTD_ENTY:
+ case XML_TEXTWRITER_DTD_PENT:
+ extra[0] = ' ';
+ extra[1] = writer->qchar;
+ p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (*extra != '\0') {
+ count = xmlOutputBufferWriteString(writer->out, extra);
+ if (count < 0)
+ return -1;
+ sum += count;
+ }
+
+ return sum;
+}
+
#endif