1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-07-28 00:21:53 +03:00

new dictionary module to keep a single instance of the names used by the

* dict.c include/libxml/dict.h Makefile.am include/libxml/Makefile.am:
  new dictionary module to keep a single instance of the names used
  by the parser
* DOCBparser.c HTMLparser.c parser.c parserInternals.c valid.c:
  switched all parsers to use the dictionary internally
* include/libxml/HTMLparser.h include/libxml/parser.h
  include/libxml/parserInternals.h include/libxml/valid.h:
  Some of the interfaces changed as a result to receive or return
  "const xmlChar *" instead of "xmlChar *", this is either
  insignificant from an user point of view or when the returning
  value changed, those function are really parser internal methods
  that no user code should really change
* doc/libxml2-api.xml doc/html/*: the API interface changed and
  the docs were regenerated
Daniel
This commit is contained in:
Daniel Veillard
2003-08-18 12:15:38 +00:00
parent 23a52c5c38
commit 2fdbd32d51
52 changed files with 5131 additions and 5100 deletions

View File

@ -73,12 +73,12 @@ static void htmlParseComment(htmlParserCtxtPtr ctxt);
* Returns 0 in case of error, the index in the stack otherwise
*/
static int
htmlnamePush(htmlParserCtxtPtr ctxt, xmlChar * value)
htmlnamePush(htmlParserCtxtPtr ctxt, const xmlChar * value)
{
if (ctxt->nameNr >= ctxt->nameMax) {
ctxt->nameMax *= 2;
ctxt->nameTab =
(xmlChar * *)xmlRealloc(ctxt->nameTab,
ctxt->nameTab = (const xmlChar * *)
xmlRealloc(ctxt->nameTab,
ctxt->nameMax *
sizeof(ctxt->nameTab[0]));
if (ctxt->nameTab == NULL) {
@ -98,10 +98,10 @@ htmlnamePush(htmlParserCtxtPtr ctxt, xmlChar * value)
*
* Returns the name just removed
*/
static xmlChar *
static const xmlChar *
htmlnamePop(htmlParserCtxtPtr ctxt)
{
xmlChar *ret;
const xmlChar *ret;
if (ctxt->nameNr <= 0)
return (0);
@ -975,15 +975,16 @@ htmlTagLookup(const xmlChar *tag) {
**/
static int
htmlGetEndPriority (const xmlChar *name) {
int i = 0;
int i = 0;
while ((htmlEndPriority[i].name != NULL) &&
(!xmlStrEqual((const xmlChar *)htmlEndPriority[i].name, name)))
i++;
while ((htmlEndPriority[i].name != NULL) &&
(!xmlStrEqual((const xmlChar *)htmlEndPriority[i].name, name)))
i++;
return(htmlEndPriority[i].priority);
return(htmlEndPriority[i].priority);
}
/**
* htmlCheckAutoClose:
* @newtag: The new tag name
@ -996,28 +997,32 @@ htmlGetEndPriority (const xmlChar *name) {
* Returns 0 if no, 1 if yes.
*/
static int
htmlCheckAutoClose(const xmlChar *newtag, const xmlChar *oldtag) {
htmlCheckAutoClose(const xmlChar * newtag, const xmlChar * oldtag)
{
int i, indx;
const char **closed = NULL;
if (htmlStartCloseIndexinitialized == 0) htmlInitAutoClose();
if (htmlStartCloseIndexinitialized == 0)
htmlInitAutoClose();
/* inefficient, but not a big deal */
for (indx = 0; indx < 100;indx++) {
for (indx = 0; indx < 100; indx++) {
closed = htmlStartCloseIndex[indx];
if (closed == NULL) return(0);
if (xmlStrEqual(BAD_CAST *closed, newtag)) break;
if (closed == NULL)
return (0);
if (xmlStrEqual(BAD_CAST * closed, newtag))
break;
}
i = closed - htmlStartClose;
i++;
while (htmlStartClose[i] != NULL) {
if (xmlStrEqual(BAD_CAST htmlStartClose[i], oldtag)) {
return(1);
}
i++;
return (1);
}
i++;
}
return(0);
return (0);
}
/**
@ -1029,58 +1034,69 @@ htmlCheckAutoClose(const xmlChar *newtag, const xmlChar *oldtag) {
* The HTML DTD allows an ending tag to implicitly close other tags.
*/
static void
htmlAutoCloseOnClose(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
const htmlElemDesc * info;
xmlChar *oldname;
htmlAutoCloseOnClose(htmlParserCtxtPtr ctxt, const xmlChar * newtag)
{
const htmlElemDesc *info;
const xmlChar *oldname;
int i, priority;
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"Close of %s stack: %d elements\n", newtag, ctxt->nameNr);
for (i = 0;i < ctxt->nameNr;i++)
xmlGenericError(xmlGenericErrorContext,"%d : %s\n", i, ctxt->nameTab[i]);
xmlGenericError(xmlGenericErrorContext,
"Close of %s stack: %d elements\n", newtag,
ctxt->nameNr);
for (i = 0; i < ctxt->nameNr; i++)
xmlGenericError(xmlGenericErrorContext, "%d : %s\n", i,
ctxt->nameTab[i]);
#endif
priority = htmlGetEndPriority (newtag);
priority = htmlGetEndPriority(newtag);
for (i = (ctxt->nameNr - 1);i >= 0;i--) {
for (i = (ctxt->nameNr - 1); i >= 0; i--) {
if (xmlStrEqual(newtag, ctxt->nameTab[i])) break;
/*
* A missplaced endtag can only close elements with lower
* or equal priority, so if we find an element with higher
* priority before we find an element with
* matching name, we just ignore this endtag
*/
if (htmlGetEndPriority (ctxt->nameTab[i]) > priority) return;
if (xmlStrEqual(newtag, ctxt->nameTab[i]))
break;
/*
* A missplaced endtag can only close elements with lower
* or equal priority, so if we find an element with higher
* priority before we find an element with
* matching name, we just ignore this endtag
*/
if (htmlGetEndPriority(ctxt->nameTab[i]) > priority)
return;
}
if (i < 0) return;
if (i < 0)
return;
while (!xmlStrEqual(newtag, ctxt->name)) {
info = htmlTagLookup(ctxt->name);
if ((info == NULL) || (info->endTag == 1)) {
info = htmlTagLookup(ctxt->name);
if ((info == NULL) || (info->endTag == 1)) {
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"htmlAutoCloseOnClose: %s closes %s\n", newtag, ctxt->name);
xmlGenericError(xmlGenericErrorContext,
"htmlAutoCloseOnClose: %s closes %s\n", newtag,
ctxt->name);
#endif
} else if (info->endTag == 3) {
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"End of tag %s: expecting %s\n", newtag, ctxt->name);
xmlGenericError(xmlGenericErrorContext,
"End of tag %s: expecting %s\n", newtag,
ctxt->name);
#endif
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"Opening and ending tag mismatch: %s and %s\n",
newtag, ctxt->name);
ctxt->wellFormed = 0;
}
if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
ctxt->sax->endElement(ctxt->userData, ctxt->name);
oldname = htmlnamePop(ctxt);
if (oldname != NULL) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"Opening and ending tag mismatch: %s and %s\n",
newtag, ctxt->name);
ctxt->wellFormed = 0;
}
if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
ctxt->sax->endElement(ctxt->userData, ctxt->name);
oldname = htmlnamePop(ctxt);
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"htmlAutoCloseOnClose: popped %s\n", oldname);
if (oldname != NULL) {
xmlGenericError(xmlGenericErrorContext,
"htmlAutoCloseOnClose: popped %s\n", oldname);
}
#endif
xmlFree(oldname);
}
}
}
@ -1091,29 +1107,32 @@ htmlAutoCloseOnClose(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
* Close all remaining tags at the end of the stream
*/
static void
htmlAutoCloseOnEnd(htmlParserCtxtPtr ctxt) {
xmlChar *oldname;
htmlAutoCloseOnEnd(htmlParserCtxtPtr ctxt)
{
const xmlChar *oldname;
int i;
if (ctxt->nameNr == 0)
return;
return;
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"Close of stack: %d elements\n", ctxt->nameNr);
xmlGenericError(xmlGenericErrorContext,
"Close of stack: %d elements\n", ctxt->nameNr);
#endif
for (i = (ctxt->nameNr - 1);i >= 0;i--) {
for (i = (ctxt->nameNr - 1); i >= 0; i--) {
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"%d : %s\n", i, ctxt->nameTab[i]);
xmlGenericError(xmlGenericErrorContext, "%d : %s\n", i,
ctxt->nameTab[i]);
#endif
if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
ctxt->sax->endElement(ctxt->userData, ctxt->name);
oldname = htmlnamePop(ctxt);
if (oldname != NULL) {
if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
ctxt->sax->endElement(ctxt->userData, ctxt->name);
oldname = htmlnamePop(ctxt);
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"htmlAutoCloseOnEnd: popped %s\n", oldname);
if (oldname != NULL) {
xmlGenericError(xmlGenericErrorContext,
"htmlAutoCloseOnEnd: popped %s\n", oldname);
}
#endif
xmlFree(oldname);
}
}
}
@ -1130,44 +1149,49 @@ htmlAutoCloseOnEnd(htmlParserCtxtPtr ctxt) {
* and we should check
*/
static void
htmlAutoClose(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
xmlChar *oldname;
while ((newtag != NULL) && (ctxt->name != NULL) &&
htmlAutoClose(htmlParserCtxtPtr ctxt, const xmlChar * newtag)
{
const xmlChar *oldname;
while ((newtag != NULL) && (ctxt->name != NULL) &&
(htmlCheckAutoClose(newtag, ctxt->name))) {
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"htmlAutoClose: %s closes %s\n", newtag, ctxt->name);
xmlGenericError(xmlGenericErrorContext,
"htmlAutoClose: %s closes %s\n", newtag,
ctxt->name);
#endif
if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
ctxt->sax->endElement(ctxt->userData, ctxt->name);
oldname = htmlnamePop(ctxt);
if (oldname != NULL) {
if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
ctxt->sax->endElement(ctxt->userData, ctxt->name);
oldname = htmlnamePop(ctxt);
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"htmlAutoClose: popped %s\n", oldname);
#endif
xmlFree(oldname);
if (oldname != NULL) {
xmlGenericError(xmlGenericErrorContext,
"htmlAutoClose: popped %s\n", oldname);
}
#endif
}
if (newtag == NULL) {
htmlAutoCloseOnEnd(ctxt);
return;
htmlAutoCloseOnEnd(ctxt);
return;
}
while ((newtag == NULL) && (ctxt->name != NULL) &&
((xmlStrEqual(ctxt->name, BAD_CAST"head")) ||
(xmlStrEqual(ctxt->name, BAD_CAST"body")) ||
(xmlStrEqual(ctxt->name, BAD_CAST"html")))) {
((xmlStrEqual(ctxt->name, BAD_CAST "head")) ||
(xmlStrEqual(ctxt->name, BAD_CAST "body")) ||
(xmlStrEqual(ctxt->name, BAD_CAST "html")))) {
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"htmlAutoClose: EOF closes %s\n", ctxt->name);
xmlGenericError(xmlGenericErrorContext,
"htmlAutoClose: EOF closes %s\n", ctxt->name);
#endif
if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
ctxt->sax->endElement(ctxt->userData, ctxt->name);
oldname = htmlnamePop(ctxt);
if (oldname != NULL) {
if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
ctxt->sax->endElement(ctxt->userData, ctxt->name);
oldname = htmlnamePop(ctxt);
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"htmlAutoClose: popped %s\n", oldname);
#endif
xmlFree(oldname);
if (oldname != NULL) {
xmlGenericError(xmlGenericErrorContext,
"htmlAutoClose: popped %s\n", oldname);
}
}
#endif
}
}
@ -1242,7 +1266,7 @@ htmlCheckImplied(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"Implied element html: pushed html\n");
#endif
htmlnamePush(ctxt, xmlStrdup(BAD_CAST"html"));
htmlnamePush(ctxt, BAD_CAST"html");
if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
ctxt->sax->startElement(ctxt->userData, BAD_CAST"html", NULL);
}
@ -1262,7 +1286,7 @@ htmlCheckImplied(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"Implied element head: pushed head\n");
#endif
htmlnamePush(ctxt, xmlStrdup(BAD_CAST"head"));
htmlnamePush(ctxt, BAD_CAST"head");
if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
ctxt->sax->startElement(ctxt->userData, BAD_CAST"head", NULL);
} else if ((!xmlStrEqual(newtag, BAD_CAST"noframes")) &&
@ -1281,7 +1305,7 @@ htmlCheckImplied(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"Implied element body: pushed body\n");
#endif
htmlnamePush(ctxt, xmlStrdup(BAD_CAST"body"));
htmlnamePush(ctxt, BAD_CAST"body");
if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
ctxt->sax->startElement(ctxt->userData, BAD_CAST"body", NULL);
}
@ -1309,7 +1333,7 @@ htmlCheckParagraph(htmlParserCtxtPtr ctxt) {
if (tag == NULL) {
htmlAutoClose(ctxt, BAD_CAST"p");
htmlCheckImplied(ctxt, BAD_CAST"p");
htmlnamePush(ctxt, xmlStrdup(BAD_CAST"p"));
htmlnamePush(ctxt, BAD_CAST"p");
if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
ctxt->sax->startElement(ctxt->userData, BAD_CAST"p", NULL);
return(1);
@ -1323,7 +1347,7 @@ htmlCheckParagraph(htmlParserCtxtPtr ctxt) {
#endif
htmlAutoClose(ctxt, BAD_CAST"p");
htmlCheckImplied(ctxt, BAD_CAST"p");
htmlnamePush(ctxt, xmlStrdup(BAD_CAST"p"));
htmlnamePush(ctxt, BAD_CAST"p");
if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
ctxt->sax->startElement(ctxt->userData, BAD_CAST"p", NULL);
return(1);
@ -2150,7 +2174,7 @@ htmlNewDoc(const xmlChar *URI, const xmlChar *ExternalID) {
* *
************************************************************************/
static xmlChar * htmlParseNameComplex(xmlParserCtxtPtr ctxt);
static const xmlChar * htmlParseNameComplex(xmlParserCtxtPtr ctxt);
/**
* htmlParseHTMLName:
@ -2162,9 +2186,8 @@ static xmlChar * htmlParseNameComplex(xmlParserCtxtPtr ctxt);
* Returns the Tag Name parsed or NULL
*/
static xmlChar *
static const xmlChar *
htmlParseHTMLName(htmlParserCtxtPtr ctxt) {
xmlChar *ret = NULL;
int i = 0;
xmlChar loc[HTML_PARSER_BUFFER_SIZE];
@ -2181,9 +2204,7 @@ htmlParseHTMLName(htmlParserCtxtPtr ctxt) {
NEXT;
}
ret = xmlStrndup(loc, i);
return(ret);
return(xmlDictLookup(ctxt->dict, loc, i));
}
/**
@ -2195,10 +2216,10 @@ htmlParseHTMLName(htmlParserCtxtPtr ctxt) {
* Returns the Name parsed or NULL
*/
static xmlChar *
static const xmlChar *
htmlParseName(htmlParserCtxtPtr ctxt) {
const xmlChar *in;
xmlChar *ret;
const xmlChar *ret;
int count = 0;
GROW;
@ -2219,7 +2240,7 @@ htmlParseName(htmlParserCtxtPtr ctxt) {
in++;
if ((*in > 0) && (*in < 0x80)) {
count = in - ctxt->input->cur;
ret = xmlStrndup(ctxt->input->cur, count);
ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
ctxt->input->cur = in;
ctxt->nbChars += count;
ctxt->input->col += count;
@ -2229,9 +2250,8 @@ htmlParseName(htmlParserCtxtPtr ctxt) {
return(htmlParseNameComplex(ctxt));
}
static xmlChar *
static const xmlChar *
htmlParseNameComplex(xmlParserCtxtPtr ctxt) {
xmlChar buf[XML_MAX_NAMELEN + 5];
int len = 0, l;
int c;
int count = 0;
@ -2257,54 +2277,11 @@ htmlParseNameComplex(xmlParserCtxtPtr ctxt) {
count = 0;
GROW;
}
COPY_BUF(l,buf,len,c);
len += l;
NEXTL(l);
c = CUR_CHAR(l);
if (len >= XML_MAX_NAMELEN) {
/*
* Okay someone managed to make a huge name, so he's ready to pay
* for the processing speed.
*/
xmlChar *buffer;
int max = len * 2;
buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
if (buffer == NULL) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"htmlParseNameComplex: out of memory\n");
return(NULL);
}
memcpy(buffer, buf, len);
while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigname.xml */
(c == '.') || (c == '-') ||
(c == '_') || (c == ':') ||
(IS_COMBINING(c)) ||
(IS_EXTENDER(c))) {
if (count++ > 100) {
count = 0;
GROW;
}
if (len + 10 > max) {
max *= 2;
buffer = (xmlChar *) xmlRealloc(buffer,
max * sizeof(xmlChar));
if (buffer == NULL) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"htmlParseNameComplex: out of memory\n");
return(NULL);
}
}
COPY_BUF(l,buffer,len,c);
NEXTL(l);
c = CUR_CHAR(l);
}
buffer[len] = 0;
return(buffer);
}
}
return(xmlStrndup(buf, len));
return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
}
@ -2324,9 +2301,8 @@ htmlParseHTMLAttribute(htmlParserCtxtPtr ctxt, const xmlChar stop) {
xmlChar *buffer = NULL;
int buffer_size = 0;
xmlChar *out = NULL;
xmlChar *name = NULL;
xmlChar *cur = NULL;
const xmlChar *name = NULL;
const xmlChar *cur = NULL;
const htmlEntityDesc * ent;
/*
@ -2394,7 +2370,6 @@ htmlParseHTMLAttribute(htmlParserCtxtPtr ctxt, const xmlChar stop) {
}
*out++ = *cur++;
}
xmlFree(name);
} else {
unsigned int c;
int bits;
@ -2418,7 +2393,6 @@ htmlParseHTMLAttribute(htmlParserCtxtPtr ctxt, const xmlChar stop) {
for ( ; bits >= 0; bits-= 6) {
*out++ = ((c >> bits) & 0x3F) | 0x80;
}
xmlFree(name);
}
}
} else {
@ -2464,8 +2438,8 @@ htmlParseHTMLAttribute(htmlParserCtxtPtr ctxt, const xmlChar stop) {
* if non-NULL *str will have to be freed by the caller.
*/
const htmlEntityDesc *
htmlParseEntityRef(htmlParserCtxtPtr ctxt, xmlChar **str) {
xmlChar *name;
htmlParseEntityRef(htmlParserCtxtPtr ctxt, const xmlChar **str) {
const xmlChar *name;
const htmlEntityDesc * ent = NULL;
*str = NULL;
@ -3047,7 +3021,7 @@ htmlParseCharRef(htmlParserCtxtPtr ctxt) {
static void
htmlParseDocTypeDecl(htmlParserCtxtPtr ctxt) {
xmlChar *name;
const xmlChar *name;
xmlChar *ExternalID = NULL;
xmlChar *URI = NULL;
@ -3102,7 +3076,6 @@ htmlParseDocTypeDecl(htmlParserCtxtPtr ctxt) {
*/
if (URI != NULL) xmlFree(URI);
if (ExternalID != NULL) xmlFree(ExternalID);
if (name != NULL) xmlFree(name);
}
/**
@ -3126,9 +3099,10 @@ htmlParseDocTypeDecl(htmlParserCtxtPtr ctxt) {
* Returns the attribute name, and the value in *value.
*/
static xmlChar *
static const xmlChar *
htmlParseAttribute(htmlParserCtxtPtr ctxt, xmlChar **value) {
xmlChar *name, *val = NULL;
const xmlChar *name;
xmlChar *val = NULL;
*value = NULL;
name = htmlParseHTMLName(ctxt);
@ -3299,8 +3273,8 @@ htmlCheckMeta(htmlParserCtxtPtr ctxt, const xmlChar **atts) {
static void
htmlParseStartTag(htmlParserCtxtPtr ctxt) {
xmlChar *name;
xmlChar *attname;
const xmlChar *name;
const xmlChar *attname;
xmlChar *attvalue;
const xmlChar **atts = NULL;
int nbatts = 0;
@ -3345,7 +3319,6 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
ctxt->sax->error(ctxt->userData,
"htmlParseStartTag: misplaced <html> tag\n");
ctxt->wellFormed = 0;
xmlFree(name);
return;
}
if ((ctxt->nameNr != 1) &&
@ -3354,7 +3327,6 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
ctxt->sax->error(ctxt->userData,
"htmlParseStartTag: misplaced <head> tag\n");
ctxt->wellFormed = 0;
xmlFree(name);
return;
}
if (xmlStrEqual(name, BAD_CAST"body")) {
@ -3365,7 +3337,6 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
ctxt->sax->error(ctxt->userData,
"htmlParseStartTag: misplaced <body> tag\n");
ctxt->wellFormed = 0;
xmlFree(name);
return;
}
}
@ -3396,7 +3367,6 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
"Attribute %s redefined\n",
attname);
ctxt->wellFormed = 0;
xmlFree(attname);
if (attvalue != NULL)
xmlFree(attvalue);
goto failed;
@ -3413,7 +3383,6 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
xmlGenericError(xmlGenericErrorContext,
"malloc of %ld byte failed\n",
maxatts * (long)sizeof(xmlChar *));
if (name != NULL) xmlFree(name);
return;
}
} else if (nbatts + 4 > maxatts) {
@ -3424,7 +3393,6 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
xmlGenericError(xmlGenericErrorContext,
"realloc of %ld byte failed\n",
maxatts * (long)sizeof(xmlChar *));
if (name != NULL) xmlFree(name);
return;
}
}
@ -3462,7 +3430,7 @@ failed:
/*
* SAX: Start of Element !
*/
htmlnamePush(ctxt, xmlStrdup(name));
htmlnamePush(ctxt, name);
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"Start of element %s: pushed %s\n", name, ctxt->name);
#endif
@ -3470,13 +3438,12 @@ failed:
ctxt->sax->startElement(ctxt->userData, name, atts);
if (atts != NULL) {
for (i = 0;i < nbatts;i++) {
for (i = 1;i < nbatts;i += 2) {
if (atts[i] != NULL)
xmlFree((xmlChar *) atts[i]);
}
xmlFree((void *) atts);
}
if (name != NULL) xmlFree(name);
}
/**
@ -3495,47 +3462,50 @@ failed:
*/
static int
htmlParseEndTag(htmlParserCtxtPtr ctxt) {
xmlChar *name;
xmlChar *oldname;
htmlParseEndTag(htmlParserCtxtPtr ctxt)
{
const xmlChar *name;
const xmlChar *oldname;
int i, ret;
if ((CUR != '<') || (NXT(1) != '/')) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData, "htmlParseEndTag: '</' not found\n");
ctxt->wellFormed = 0;
return(0);
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"htmlParseEndTag: '</' not found\n");
ctxt->wellFormed = 0;
return (0);
}
SKIP(2);
name = htmlParseHTMLName(ctxt);
if (name == NULL) return(0);
if (name == NULL)
return (0);
/*
* We should definitely be at the ending "S? '>'" part
*/
SKIP_BLANKS;
if ((!IS_CHAR((unsigned int) CUR)) || (CUR != '>')) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData, "End tag : expected '>'\n");
ctxt->wellFormed = 0;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData, "End tag : expected '>'\n");
ctxt->wellFormed = 0;
} else
NEXT;
NEXT;
/*
* If the name read is not one of the element in the parsing stack
* then return, it's just an error.
*/
for (i = (ctxt->nameNr - 1);i >= 0;i--) {
if (xmlStrEqual(name, ctxt->nameTab[i])) break;
for (i = (ctxt->nameNr - 1); i >= 0; i--) {
if (xmlStrEqual(name, ctxt->nameTab[i]))
break;
}
if (i < 0) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"Unexpected end tag : %s\n", name);
xmlFree(name);
ctxt->wellFormed = 0;
return(0);
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"Unexpected end tag : %s\n", name);
ctxt->wellFormed = 0;
return (0);
}
@ -3552,15 +3522,15 @@ htmlParseEndTag(htmlParserCtxtPtr ctxt) {
*/
if (!xmlStrEqual(name, ctxt->name)) {
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"End of tag %s: expecting %s\n", name, ctxt->name);
xmlGenericError(xmlGenericErrorContext,
"End of tag %s: expecting %s\n", name, ctxt->name);
#endif
if ((ctxt->name != NULL) &&
(!xmlStrEqual(ctxt->name, name))) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"Opening and ending tag mismatch: %s and %s\n",
name, ctxt->name);
ctxt->wellFormed = 0;
if ((ctxt->name != NULL) && (!xmlStrEqual(ctxt->name, name))) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"Opening and ending tag mismatch: %s and %s\n",
name, ctxt->name);
ctxt->wellFormed = 0;
}
}
@ -3569,28 +3539,25 @@ htmlParseEndTag(htmlParserCtxtPtr ctxt) {
*/
oldname = ctxt->name;
if ((oldname != NULL) && (xmlStrEqual(oldname, name))) {
if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
ctxt->sax->endElement(ctxt->userData, name);
oldname = htmlnamePop(ctxt);
if (oldname != NULL) {
if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
ctxt->sax->endElement(ctxt->userData, name);
oldname = htmlnamePop(ctxt);
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"End of tag %s: popping out %s\n", name, oldname);
if (oldname != NULL) {
xmlGenericError(xmlGenericErrorContext,
"End of tag %s: popping out %s\n", name,
oldname);
} else {
xmlGenericError(xmlGenericErrorContext,
"End of tag %s: stack empty !!!\n", name);
}
#endif
xmlFree(oldname);
#ifdef DEBUG
} else {
xmlGenericError(xmlGenericErrorContext,"End of tag %s: stack empty !!!\n", name);
#endif
}
ret = 1;
ret = 1;
} else {
ret = 0;
ret = 0;
}
if (name != NULL)
xmlFree(name);
return(ret);
return (ret);
}
@ -3606,7 +3573,7 @@ static void
htmlParseReference(htmlParserCtxtPtr ctxt) {
const htmlEntityDesc * ent;
xmlChar out[6];
xmlChar *name;
const xmlChar *name;
if (CUR != '&') return;
if (NXT(1) == '#') {
@ -3668,7 +3635,6 @@ htmlParseReference(htmlParserCtxtPtr ctxt) {
if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
ctxt->sax->characters(ctxt->userData, out, i);
}
xmlFree(name);
}
}
@ -3804,11 +3770,11 @@ htmlParseContent(htmlParserCtxtPtr ctxt) {
void
htmlParseElement(htmlParserCtxtPtr ctxt) {
xmlChar *name;
const xmlChar *name;
xmlChar *currentNode = NULL;
const htmlElemDesc * info;
htmlParserNodeInfo node_info;
xmlChar *oldname;
const xmlChar *oldname;
int depth = ctxt->nameNr;
const xmlChar *oldptr;
@ -3819,7 +3785,7 @@ htmlParseElement(htmlParserCtxtPtr ctxt) {
node_info.begin_line = ctxt->input->line;
}
oldname = xmlStrdup(ctxt->name);
oldname = ctxt->name;
htmlParseStartTag(ctxt);
name = ctxt->name;
#ifdef DEBUG
@ -3837,12 +3803,8 @@ htmlParseElement(htmlParserCtxtPtr ctxt) {
(name == NULL)) {
if (CUR == '>')
NEXT;
if (oldname != NULL)
xmlFree(oldname);
return;
}
if (oldname != NULL)
xmlFree(oldname);
/*
* Lookup the info for that element.
@ -3853,12 +3815,6 @@ htmlParseElement(htmlParserCtxtPtr ctxt) {
ctxt->sax->error(ctxt->userData, "Tag %s invalid\n",
name);
ctxt->wellFormed = 0;
} else if (info->depr) {
/***************************
if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
ctxt->sax->warning(ctxt->userData, "Tag %s is deprecated\n",
name);
***************************/
}
/*
@ -3872,8 +3828,6 @@ htmlParseElement(htmlParserCtxtPtr ctxt) {
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"End of tag the XML way: popping out %s\n", oldname);
#endif
if (oldname != NULL)
xmlFree(oldname);
return;
}
@ -3895,8 +3849,6 @@ htmlParseElement(htmlParserCtxtPtr ctxt) {
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"End of start tag problem: popping out %s\n", oldname);
#endif
if (oldname != NULL)
xmlFree(oldname);
}
/*
@ -3922,8 +3874,6 @@ htmlParseElement(htmlParserCtxtPtr ctxt) {
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"End of empty tag %s : popping out %s\n", name, oldname);
#endif
if (oldname != NULL)
xmlFree(oldname);
return;
}
@ -4082,6 +4032,12 @@ htmlInitParserCtxt(htmlParserCtxtPtr ctxt)
if (ctxt == NULL) return;
memset(ctxt, 0, sizeof(htmlParserCtxt));
ctxt->dict = xmlDictCreate();
if (ctxt->dict == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlInitParserCtxt: out of memory\n");
return;
}
sax = (htmlSAXHandler *) xmlMalloc(sizeof(htmlSAXHandler));
if (sax == NULL) {
xmlGenericError(xmlGenericErrorContext,
@ -4127,7 +4083,7 @@ htmlInitParserCtxt(htmlParserCtxtPtr ctxt)
ctxt->node = NULL;
/* Allocate the Name stack */
ctxt->nameTab = (xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
ctxt->nameTab = (const xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
if (ctxt->nameTab == NULL) {
xmlGenericError(xmlGenericErrorContext,
"htmlInitParserCtxt: out of memory\n");
@ -4685,7 +4641,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
}
break;
case XML_PARSER_START_TAG: {
xmlChar *name, *oldname;
const xmlChar *name, *oldname;
int depth = ctxt->nameNr;
const htmlElemDesc * info;
@ -4713,7 +4669,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
(htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
goto done;
oldname = xmlStrdup(ctxt->name);
oldname = ctxt->name;
htmlParseStartTag(ctxt);
name = ctxt->name;
#ifdef DEBUG
@ -4734,12 +4690,8 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
(name == NULL)) {
if (CUR == '>')
NEXT;
if (oldname != NULL)
xmlFree(oldname);
break;
}
if (oldname != NULL)
xmlFree(oldname);
/*
* Lookup the info for that element.
@ -4750,13 +4702,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
ctxt->sax->error(ctxt->userData, "Tag %s invalid\n",
name);
ctxt->wellFormed = 0;
} else if (info->depr) {
/***************************
if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
ctxt->sax->warning(ctxt->userData,
"Tag %s is deprecated\n",
name);
***************************/
}
/*
@ -4771,8 +4716,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
xmlGenericError(xmlGenericErrorContext,"End of tag the XML way: popping out %s\n",
oldname);
#endif
if (oldname != NULL)
xmlFree(oldname);
ctxt->instate = XML_PARSER_CONTENT;
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext,
@ -4800,8 +4743,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
xmlGenericError(xmlGenericErrorContext,
"End of start tag problem: popping out %s\n", oldname);
#endif
if (oldname != NULL)
xmlFree(oldname);
}
ctxt->instate = XML_PARSER_CONTENT;
@ -4822,8 +4763,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"End of empty tag %s : popping out %s\n", name, oldname);
#endif
if (oldname != NULL)
xmlFree(oldname);
}
ctxt->instate = XML_PARSER_CONTENT;
#ifdef DEBUG_PUSH