summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Wellnhofer <wellnhofer@aevum.de>2021-05-08 21:20:05 +0200
committerNick Wellnhofer <wellnhofer@aevum.de>2021-05-08 22:16:49 +0200
commitce00c36e654f0a5291d48bc437e807daecbd8449 (patch)
tree1292089aedb6436efa4c73a31a22e6e61488d70f
parentde5b624f10e9d29ff1b3bbc07358774a3725898e (diff)
downloadlibxml2-ce00c36e654f0a5291d48bc437e807daecbd8449.tar.gz
Store per-element parser state in a struct
Make the parser context's "pushTab" point to an array of structs instead of void pointers. This avoids casting unrelated types to void pointers, improving readability and portability, and allows for more efficient packing. Ultimately, the struct could be extended to include the contents of "nameTab" and "spaceTab", further simplifying the code. Historically, "pushTab" was only used by the push parser (hence the name), so the change to the public headers should be safe. Also remove an unused parameter from xmlParseEndTag2.
-rw-r--r--include/libxml/parser.h4
-rw-r--r--parser.c83
2 files changed, 35 insertions, 52 deletions
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
index 1c86a97c..0ba1c387 100644
--- a/include/libxml/parser.h
+++ b/include/libxml/parser.h
@@ -169,6 +169,8 @@ typedef enum {
XML_PARSE_READER = 5
} xmlParserMode;
+typedef struct _xmlStartTag xmlStartTag;
+
/**
* xmlParserCtxt:
*
@@ -280,7 +282,7 @@ struct _xmlParserCtxt {
int nsMax; /* the size of the arrays */
const xmlChar * *nsTab; /* the array of prefix/namespace name */
int *attallocs; /* which attribute were allocated */
- void * *pushTab; /* array of data for push */
+ xmlStartTag *pushTab; /* array of data for push */
xmlHashTablePtr attsDefault; /* defaulted attributes if any */
xmlHashTablePtr attsSpecial; /* non-CDATA attributes if any */
int nsWellFormed; /* is the document XML Namespace okay */
diff --git a/parser.c b/parser.c
index dd582826..9bda9458 100644
--- a/parser.c
+++ b/parser.c
@@ -87,6 +87,13 @@
#include "buf.h"
#include "enc.h"
+struct _xmlStartTag {
+ const xmlChar *prefix;
+ const xmlChar *URI;
+ int line;
+ int nsNr;
+};
+
static void
xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);
@@ -1849,9 +1856,11 @@ static int
nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
const xmlChar *prefix, const xmlChar *URI, int line, int nsNr)
{
+ xmlStartTag *tag;
+
if (ctxt->nameNr >= ctxt->nameMax) {
const xmlChar * *tmp;
- void **tmp2;
+ xmlStartTag *tmp2;
ctxt->nameMax *= 2;
tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
ctxt->nameMax *
@@ -1861,8 +1870,8 @@ nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
goto mem_error;
}
ctxt->nameTab = tmp;
- tmp2 = (void **) xmlRealloc((void * *)ctxt->pushTab,
- ctxt->nameMax * 4 *
+ tmp2 = (xmlStartTag *) xmlRealloc((void * *)ctxt->pushTab,
+ ctxt->nameMax *
sizeof(ctxt->pushTab[0]));
if (tmp2 == NULL) {
ctxt->nameMax /= 2;
@@ -1870,17 +1879,18 @@ nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
}
ctxt->pushTab = tmp2;
} else if (ctxt->pushTab == NULL) {
- ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 4 *
+ ctxt->pushTab = (xmlStartTag *) xmlMalloc(ctxt->nameMax *
sizeof(ctxt->pushTab[0]));
if (ctxt->pushTab == NULL)
goto mem_error;
}
ctxt->nameTab[ctxt->nameNr] = value;
ctxt->name = value;
- ctxt->pushTab[ctxt->nameNr * 4] = (void *) prefix;
- ctxt->pushTab[ctxt->nameNr * 4 + 1] = (void *) URI;
- ctxt->pushTab[ctxt->nameNr * 4 + 2] = (void *) (ptrdiff_t) line;
- ctxt->pushTab[ctxt->nameNr * 4 + 3] = (void *) (ptrdiff_t) nsNr;
+ tag = &ctxt->pushTab[ctxt->nameNr];
+ tag->prefix = prefix;
+ tag->URI = URI;
+ tag->line = line;
+ tag->nsNr = nsNr;
return (ctxt->nameNr++);
mem_error:
xmlErrMemory(ctxt, NULL);
@@ -9652,10 +9662,8 @@ done:
*/
static void
-xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
- const xmlChar *URI, int line, int nsNr, int tlen) {
+xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlStartTag *tag) {
const xmlChar *name;
- size_t curLength;
GROW;
if ((RAW != '<') || (NXT(1) != '/')) {
@@ -9664,24 +9672,10 @@ xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
}
SKIP(2);
- curLength = ctxt->input->end - ctxt->input->cur;
- if ((tlen > 0) && (curLength >= (size_t)tlen) &&
- (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) {
- if ((curLength >= (size_t)(tlen + 1)) &&
- (ctxt->input->cur[tlen] == '>')) {
- ctxt->input->cur += tlen + 1;
- ctxt->input->col += tlen + 1;
- goto done;
- }
- ctxt->input->cur += tlen;
- ctxt->input->col += tlen;
- name = (xmlChar*)1;
- } else {
- if (prefix == NULL)
- name = xmlParseNameAndCompare(ctxt, ctxt->name);
- else
- name = xmlParseQNameAndCompare(ctxt, ctxt->name, prefix);
- }
+ if (tag->prefix == NULL)
+ name = xmlParseNameAndCompare(ctxt, ctxt->name);
+ else
+ name = xmlParseQNameAndCompare(ctxt, ctxt->name, tag->prefix);
/*
* We should definitely be at the ending "S? '>'" part
@@ -9703,25 +9697,22 @@ xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
*/
if (name != (xmlChar*)1) {
if (name == NULL) name = BAD_CAST "unparsable";
- if ((line == 0) && (ctxt->node != NULL))
- line = ctxt->node->line;
xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
"Opening and ending tag mismatch: %s line %d and %s\n",
- ctxt->name, line, name);
+ ctxt->name, tag->line, name);
}
/*
* SAX: End of Tag
*/
-done:
if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
(!ctxt->disableSAX))
- ctxt->sax->endElementNs(ctxt->userData, ctxt->name, prefix, URI);
+ ctxt->sax->endElementNs(ctxt->userData, ctxt->name, tag->prefix,
+ tag->URI);
spacePop(ctxt);
- if (nsNr != 0)
- nsPop(ctxt, nsNr);
- return;
+ if (tag->nsNr != 0)
+ nsPop(ctxt, tag->nsNr);
}
/**
@@ -9937,7 +9928,7 @@ xmlParseContent(xmlParserCtxtPtr ctxt) {
if ((ctxt->instate != XML_PARSER_EOF) && (ctxt->nameNr > nameNr)) {
const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1];
- int line = (ptrdiff_t) ctxt->pushTab[ctxt->nameNr * 4 - 2];
+ int line = ctxt->pushTab[ctxt->nameNr - 1].line;
xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
"Premature end of data in tag %s line %d\n",
name, line, NULL);
@@ -9969,7 +9960,7 @@ xmlParseElement(xmlParserCtxtPtr ctxt) {
if (CUR == 0) {
const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1];
- int line = (ptrdiff_t) ctxt->pushTab[ctxt->nameNr * 4 - 2];
+ int line = ctxt->pushTab[ctxt->nameNr - 1].line;
xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
"Premature end of data in tag %s line %d\n",
name, line, NULL);
@@ -10132,11 +10123,7 @@ xmlParseElementEnd(xmlParserCtxtPtr ctxt) {
* parse the end of tag: '</' should be here.
*/
if (ctxt->sax2) {
- const xmlChar *prefix = ctxt->pushTab[ctxt->nameNr * 4 - 4];
- const xmlChar *URI = ctxt->pushTab[ctxt->nameNr * 4 - 3];
- int line = (ptrdiff_t) ctxt->pushTab[ctxt->nameNr * 4 - 2];
- int nsNr = (ptrdiff_t) ctxt->pushTab[ctxt->nameNr * 4 - 1];
- xmlParseEndTag2(ctxt, prefix, URI, line, nsNr, 0);
+ xmlParseEndTag2(ctxt, &ctxt->pushTab[ctxt->nameNr - 1]);
namePop(ctxt);
}
#ifdef LIBXML_SAX1_ENABLED
@@ -11632,13 +11619,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
}
}
if (ctxt->sax2) {
- xmlParseEndTag2(ctxt,
- (void *) ctxt->pushTab[ctxt->nameNr * 4 - 4],
- (void *) ctxt->pushTab[ctxt->nameNr * 4 - 3],
- (int) (ptrdiff_t)
- ctxt->pushTab[ctxt->nameNr * 4 - 2],
- (int) (ptrdiff_t)
- ctxt->pushTab[ctxt->nameNr * 4 - 1], 0);
+ xmlParseEndTag2(ctxt, &ctxt->pushTab[ctxt->nameNr - 1]);
nameNsPop(ctxt);
}
#ifdef LIBXML_SAX1_ENABLED