1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-10-27 12:15:34 +03:00

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.
This commit is contained in:
Nick Wellnhofer
2021-05-08 21:20:05 +02:00
parent de5b624f10
commit ce00c36e65
2 changed files with 35 additions and 52 deletions

View File

@@ -169,6 +169,8 @@ typedef enum {
XML_PARSE_READER = 5 XML_PARSE_READER = 5
} xmlParserMode; } xmlParserMode;
typedef struct _xmlStartTag xmlStartTag;
/** /**
* xmlParserCtxt: * xmlParserCtxt:
* *
@@ -280,7 +282,7 @@ struct _xmlParserCtxt {
int nsMax; /* the size of the arrays */ int nsMax; /* the size of the arrays */
const xmlChar * *nsTab; /* the array of prefix/namespace name */ const xmlChar * *nsTab; /* the array of prefix/namespace name */
int *attallocs; /* which attribute were allocated */ 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 attsDefault; /* defaulted attributes if any */
xmlHashTablePtr attsSpecial; /* non-CDATA attributes if any */ xmlHashTablePtr attsSpecial; /* non-CDATA attributes if any */
int nsWellFormed; /* is the document XML Namespace okay */ int nsWellFormed; /* is the document XML Namespace okay */

View File

@@ -87,6 +87,13 @@
#include "buf.h" #include "buf.h"
#include "enc.h" #include "enc.h"
struct _xmlStartTag {
const xmlChar *prefix;
const xmlChar *URI;
int line;
int nsNr;
};
static void static void
xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info); xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);
@@ -1849,9 +1856,11 @@ static int
nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value, nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
const xmlChar *prefix, const xmlChar *URI, int line, int nsNr) const xmlChar *prefix, const xmlChar *URI, int line, int nsNr)
{ {
xmlStartTag *tag;
if (ctxt->nameNr >= ctxt->nameMax) { if (ctxt->nameNr >= ctxt->nameMax) {
const xmlChar * *tmp; const xmlChar * *tmp;
void **tmp2; xmlStartTag *tmp2;
ctxt->nameMax *= 2; ctxt->nameMax *= 2;
tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab, tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
ctxt->nameMax * ctxt->nameMax *
@@ -1861,8 +1870,8 @@ nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
goto mem_error; goto mem_error;
} }
ctxt->nameTab = tmp; ctxt->nameTab = tmp;
tmp2 = (void **) xmlRealloc((void * *)ctxt->pushTab, tmp2 = (xmlStartTag *) xmlRealloc((void * *)ctxt->pushTab,
ctxt->nameMax * 4 * ctxt->nameMax *
sizeof(ctxt->pushTab[0])); sizeof(ctxt->pushTab[0]));
if (tmp2 == NULL) { if (tmp2 == NULL) {
ctxt->nameMax /= 2; ctxt->nameMax /= 2;
@@ -1870,17 +1879,18 @@ nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
} }
ctxt->pushTab = tmp2; ctxt->pushTab = tmp2;
} else if (ctxt->pushTab == NULL) { } else if (ctxt->pushTab == NULL) {
ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 4 * ctxt->pushTab = (xmlStartTag *) xmlMalloc(ctxt->nameMax *
sizeof(ctxt->pushTab[0])); sizeof(ctxt->pushTab[0]));
if (ctxt->pushTab == NULL) if (ctxt->pushTab == NULL)
goto mem_error; goto mem_error;
} }
ctxt->nameTab[ctxt->nameNr] = value; ctxt->nameTab[ctxt->nameNr] = value;
ctxt->name = value; ctxt->name = value;
ctxt->pushTab[ctxt->nameNr * 4] = (void *) prefix; tag = &ctxt->pushTab[ctxt->nameNr];
ctxt->pushTab[ctxt->nameNr * 4 + 1] = (void *) URI; tag->prefix = prefix;
ctxt->pushTab[ctxt->nameNr * 4 + 2] = (void *) (ptrdiff_t) line; tag->URI = URI;
ctxt->pushTab[ctxt->nameNr * 4 + 3] = (void *) (ptrdiff_t) nsNr; tag->line = line;
tag->nsNr = nsNr;
return (ctxt->nameNr++); return (ctxt->nameNr++);
mem_error: mem_error:
xmlErrMemory(ctxt, NULL); xmlErrMemory(ctxt, NULL);
@@ -9652,10 +9662,8 @@ done:
*/ */
static void static void
xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix, xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlStartTag *tag) {
const xmlChar *URI, int line, int nsNr, int tlen) {
const xmlChar *name; const xmlChar *name;
size_t curLength;
GROW; GROW;
if ((RAW != '<') || (NXT(1) != '/')) { if ((RAW != '<') || (NXT(1) != '/')) {
@@ -9664,24 +9672,10 @@ xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
} }
SKIP(2); SKIP(2);
curLength = ctxt->input->end - ctxt->input->cur; if (tag->prefix == NULL)
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); name = xmlParseNameAndCompare(ctxt, ctxt->name);
else else
name = xmlParseQNameAndCompare(ctxt, ctxt->name, prefix); name = xmlParseQNameAndCompare(ctxt, ctxt->name, tag->prefix);
}
/* /*
* We should definitely be at the ending "S? '>'" part * 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 != (xmlChar*)1) {
if (name == NULL) name = BAD_CAST "unparsable"; if (name == NULL) name = BAD_CAST "unparsable";
if ((line == 0) && (ctxt->node != NULL))
line = ctxt->node->line;
xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH, xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
"Opening and ending tag mismatch: %s line %d and %s\n", "Opening and ending tag mismatch: %s line %d and %s\n",
ctxt->name, line, name); ctxt->name, tag->line, name);
} }
/* /*
* SAX: End of Tag * SAX: End of Tag
*/ */
done:
if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) && if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
(!ctxt->disableSAX)) (!ctxt->disableSAX))
ctxt->sax->endElementNs(ctxt->userData, ctxt->name, prefix, URI); ctxt->sax->endElementNs(ctxt->userData, ctxt->name, tag->prefix,
tag->URI);
spacePop(ctxt); spacePop(ctxt);
if (nsNr != 0) if (tag->nsNr != 0)
nsPop(ctxt, nsNr); nsPop(ctxt, tag->nsNr);
return;
} }
/** /**
@@ -9937,7 +9928,7 @@ xmlParseContent(xmlParserCtxtPtr ctxt) {
if ((ctxt->instate != XML_PARSER_EOF) && (ctxt->nameNr > nameNr)) { if ((ctxt->instate != XML_PARSER_EOF) && (ctxt->nameNr > nameNr)) {
const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1]; 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, xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
"Premature end of data in tag %s line %d\n", "Premature end of data in tag %s line %d\n",
name, line, NULL); name, line, NULL);
@@ -9969,7 +9960,7 @@ xmlParseElement(xmlParserCtxtPtr ctxt) {
if (CUR == 0) { if (CUR == 0) {
const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1]; 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, xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
"Premature end of data in tag %s line %d\n", "Premature end of data in tag %s line %d\n",
name, line, NULL); name, line, NULL);
@@ -10132,11 +10123,7 @@ xmlParseElementEnd(xmlParserCtxtPtr ctxt) {
* parse the end of tag: '</' should be here. * parse the end of tag: '</' should be here.
*/ */
if (ctxt->sax2) { if (ctxt->sax2) {
const xmlChar *prefix = ctxt->pushTab[ctxt->nameNr * 4 - 4]; xmlParseEndTag2(ctxt, &ctxt->pushTab[ctxt->nameNr - 1]);
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);
namePop(ctxt); namePop(ctxt);
} }
#ifdef LIBXML_SAX1_ENABLED #ifdef LIBXML_SAX1_ENABLED
@@ -11632,13 +11619,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
} }
} }
if (ctxt->sax2) { if (ctxt->sax2) {
xmlParseEndTag2(ctxt, xmlParseEndTag2(ctxt, &ctxt->pushTab[ctxt->nameNr - 1]);
(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);
nameNsPop(ctxt); nameNsPop(ctxt);
} }
#ifdef LIBXML_SAX1_ENABLED #ifdef LIBXML_SAX1_ENABLED